package main import ( "flag" "fmt" "strings" "github.com/alexchao26/advent-of-code-go/cast" "github.com/alexchao26/advent-of-code-go/util" ) func main() { var part int flag.IntVar(&part, "part", 1, "part 1 or 2") flag.Parse() fmt.Println("Running part", part) if part == 1 { ans := part1(util.ReadFile("./input.txt")) fmt.Println("Output:", ans) } else { ans := part2(util.ReadFile("./input.txt")) fmt.Println("Output:", ans) } } type TreeNode struct { children []*TreeNode metadata []int } func part1(input string) int { nums := parseInput(input) root, _ := makeTree(nums) return sumMetadataOnly(root) } func part2(input string) int { nums := parseInput(input) root, _ := makeTree(nums) return sumMetadataViaChildrenIndices(root) } func parseInput(input string) []int { split := strings.Split(input, " ") parsed := make([]int, len(split)) for i, v := range split { parsed[i] = cast.ToInt(v) } return parsed } func makeTree(nums []int) (node *TreeNode, recursiveValuesHandled int) { if len(nums) == 0 { return nil, 0 } if len(nums) == 2 { return &TreeNode{nil, []int{}}, 2 } childrenCount := nums[0] metadataCount := nums[1] newNode := TreeNode{} valuesHandled := 2 for i := 2; childrenCount > 0 || metadataCount > 0; { if childrenCount > 0 { // recursively make child child, subValuesHandled := makeTree(nums[i:]) newNode.children = append(newNode.children, child) valuesHandled += subValuesHandled childrenCount-- i += subValuesHandled } else { newNode.metadata = append(newNode.metadata, nums[i]) valuesHandled++ metadataCount-- i++ } } return &newNode, valuesHandled } // part1 func sumMetadataOnly(node *TreeNode) int { var sumMetadata int for _, v := range node.metadata { sumMetadata += v } for _, child := range node.children { sumMetadata += sumMetadataOnly(child) } return sumMetadata } // part2 func sumMetadataViaChildrenIndices(node *TreeNode) int { var sumMetadata int if len(node.children) == 0 { for _, v := range node.metadata { sumMetadata += v } return sumMetadata } // ONE INDEXED for _, valAsChildOneIndex := range node.metadata { if valAsChildOneIndex == 0 || valAsChildOneIndex > len(node.children) { continue } sumMetadata += sumMetadataViaChildrenIndices(node.children[valAsChildOneIndex-1]) } return sumMetadata }