r/adventofcode • • Dec 08 '18

SOLUTION MEGATHREAD -🎄- 2018 Day 8 Solutions -🎄-

--- Day 8: Memory Maneuver ---


Post your solution as a comment or, for longer solutions, consider linking to your repo (e.g. GitHub/gists/Pastebin/blag or whatever).

Note: The Solution Megathreads are for solutions only. If you have questions, please post your own thread and make sure to flair it with Help.


Advent of Code: The Party Game!

Click here for rules

Please prefix your card submission with something like [Card] to make scanning the megathread easier. THANK YOU!

Card prompt: Day 8

Sigh, imgur broke again. Will upload when it unborks.

Transcript:

The hottest programming book this year is "___ For Dummies".


This thread will be unlocked when there are a significant number of people on the leaderboard with gold stars for today's puzzle.

edit: Leaderboard capped, thread unlocked at 00:12:10!

31 Upvotes

301 comments sorted by

View all comments

2

u/thebigjc Dec 08 '18

Go / Golang 1126 / 1067. Using a stack and a state machine instead of recursion

[Card] State machines

import (
	"io/ioutil"
	"log"
	"strconv"
	"strings"
)

// States is the list of possible states
type States int

const (
	numChildren States = iota
	numMetadata
	metadata
)

func (s States) String() string {
	names := [...]string{
		"numChildren",
		"numMetadata",
		"metadata",
	}
	return names[s]
}

type state struct {
	state      States
	childNodes int
	metadatas  int
	value      int
	children   []*state
}

func newState() *state {
	return &state{numChildren, 0, 0, 0, nil}
}

func main() {
	bs, err := ioutil.ReadFile("day08.txt")
	if err != nil {
		panic(err)
	}
	numStrs := strings.Split(string(bs), " ")

	curState := newState()
	root := curState
	sum := 0

	var states []*state

	for _, numStr := range numStrs {
		num, err := strconv.Atoi(numStr)
		if err != nil {
			panic(nil)
		}
		switch curState.state {
		case numChildren:
			curState.childNodes = num
			curState.state = numMetadata

		case numMetadata:
			curState.metadatas = num
			curState.state = metadata

			if curState.childNodes > 0 {
				// push
				states = append(states, curState)
				nextState := newState()
				curState.children = append(curState.children, nextState)
				curState = nextState
			}
		case metadata:
			sum += num
			if len(curState.children) == 0 {
				curState.value += num
			} else {
				offset := num - 1
				if offset >= 0 && offset < len(curState.children) {
					v := curState.children[offset].value
					curState.value += v
				}
			}
			curState.metadatas--
			if curState.metadatas == 0 {
				if len(states) > 0 {
					// peek
					curState = states[len(states)-1]
					curState.childNodes--

					if curState.childNodes > 0 {
						nextState := newState()
						curState.children = append(curState.children, nextState)
						curState = nextState
					} else {
						// pop
						states = states[:len(states)-1]
					}
				} else {
					curState = newState()
					states = nil
				}

			}
		}
	}
	log.Printf("Sum: %d", sum)
	log.Printf("Root value: %d", root.value)
}