diff options
| author | Mike Vink <mike1994vink@gmail.com> | 2022-12-11 20:10:38 +0100 |
|---|---|---|
| committer | Mike Vink <mike1994vink@gmail.com> | 2022-12-11 20:10:38 +0100 |
| commit | 999c05159c1f67e60e2d287179776d29f070c5da (patch) | |
| tree | d5e9595fc2921e21fc16ab7f7bb9756907f10b66 | |
| parent | 76e924fa212f275206730337ebaae5059f3a9d21 (diff) | |
day10 and day11
| -rw-r--r-- | day10.go | 102 | ||||
| -rw-r--r-- | day10.txt | 136 | ||||
| -rw-r--r-- | day11.go | 212 | ||||
| -rw-r--r-- | day11.txt | 55 |
4 files changed, 505 insertions, 0 deletions
diff --git a/day10.go b/day10.go new file mode 100644 index 0000000..e0deaa0 --- /dev/null +++ b/day10.go @@ -0,0 +1,102 @@ +package main + +import ( + "bufio" + "fmt" + "log" + "os" + "regexp" + "strconv" +) + +type cpu struct { + register int + cycle int + signalLog []int +} + +func (c *cpu) instruction(op string, arg []string) { + addx := func(arg []string) { + x, err := strconv.Atoi(arg[0]) + if err != nil { + log.Fatal("Got invalid arg to addx", err) + } + c.signalLog = append(c.signalLog, (c.cycle+1)*c.register, (c.cycle+2)*c.register) + c.register += x + c.cycle += 2 + } + noop := func(arg []string) { + c.signalLog = append(c.signalLog, (c.cycle+1)*c.register) + c.cycle += 1 + } + + switch op { + case "addx": + addx(arg) + case "noop": + noop(arg) + default: + log.Fatal("Got unexpected input") + } +} + +func NewCpu() *cpu { + return &cpu{ + register: 1, + cycle: 0, + signalLog: []int(nil), + } +} + +func main() { + f, err := os.Open("day10.txt") + if err != nil { + log.Fatal("could open input file", err) + } + + // Part 1: Keep a logahead of signals + cpu := NewCpu() + s := bufio.NewScanner(f) + for s.Scan() { + r := regexp.MustCompile(`(?P<instruction>\w+) ?(?P<arg>[-0-9 ]+)?`) + m := r.FindStringSubmatch(s.Text()) + switch words := len(m[1:]); words { + case 0: + log.Fatal("Got unexpected input") + case 1: + cpu.instruction(m[1], []string(nil)) + default: + cpu.instruction(m[1], m[2:]) + } + } + + runningSum := 0 + for _, c := range []int{20, 60, 100, 140, 180, 220} { + signal := cpu.signalLog[c-1] + fmt.Println(fmt.Sprintf("cycle %d:", c), signal) + runningSum += signal + } + fmt.Println("Part 1:", runningSum) + + // Part 2: Scan the signal log + spri, te := 0, 2 + for cycle, signal := range cpu.signalLog { + spri, te = (signal/(cycle+1))-1, (signal/(cycle+1))+1 + c := cycle % 40 + if spri <= c && c <= te { + cpu.signalLog[cycle] = 1 + } else { + cpu.signalLog[cycle] = 0 + } + } + for i := 0; i < len(cpu.signalLog); i += 40 { + for _, visi := range cpu.signalLog[i : i+40] { + if visi == 1 { + fmt.Print("#") + } else { + fmt.Print(".") + } + } + fmt.Println() + } +} diff --git a/day10.txt b/day10.txt new file mode 100644 index 0000000..39384f8 --- /dev/null +++ b/day10.txt @@ -0,0 +1,136 @@ +noop +noop +addx 5 +addx 3 +noop +addx 14 +addx -12 +noop +addx 5 +addx 1 +noop +addx 19 +addx -15 +noop +noop +noop +addx 7 +addx -1 +addx 4 +noop +noop +addx 5 +addx 1 +addx -38 +noop +addx 21 +addx -18 +addx 2 +addx 2 +noop +addx 3 +addx 5 +addx -6 +addx 11 +noop +addx 2 +addx 19 +addx -18 +noop +addx 8 +addx -3 +addx 2 +addx 5 +addx 2 +addx 3 +addx -2 +addx -38 +noop +addx 3 +addx 4 +addx 5 +noop +addx -2 +addx 5 +addx -8 +addx 12 +addx 3 +addx -2 +addx 5 +addx 11 +addx -31 +addx 23 +addx 4 +noop +noop +addx 5 +addx 3 +addx -2 +addx -37 +addx 1 +addx 5 +addx 2 +addx 12 +addx -10 +addx 3 +addx 4 +addx -2 +noop +addx 6 +addx 1 +noop +noop +noop +addx -2 +addx 7 +addx 2 +noop +addx 3 +addx 3 +addx 1 +noop +addx -37 +addx 2 +addx 5 +addx 2 +addx 32 +addx -31 +addx 5 +addx 2 +addx 9 +addx 9 +addx -15 +noop +addx 3 +addx 2 +addx 5 +addx 2 +addx 3 +addx -2 +addx 2 +addx 2 +addx -37 +addx 5 +addx -2 +addx 2 +addx 5 +addx 2 +addx 16 +addx -15 +addx 4 +noop +addx 1 +addx 2 +noop +addx 3 +addx 5 +addx -1 +addx 5 +noop +noop +noop +noop +addx 3 +addx 5 +addx -16 +noop diff --git a/day11.go b/day11.go new file mode 100644 index 0000000..abcba52 --- /dev/null +++ b/day11.go @@ -0,0 +1,212 @@ +package main + +import ( + "bufio" + "fmt" + "log" + "os" + "regexp" + "strconv" + "strings" +) + +type monkey struct { + items []*item + operation func(item *item) int + test func(item *item) *monkey + by int + inspections int +} + +func NewMonkey(items []int, by int, op func(i *item) int, test func(i *item) *monkey) *monkey { + itemPtrs := make([]*item, len(items)) + for i, worry := range items { + itemPtrs[i] = NewItem(worry) + } + return &monkey{items: itemPtrs, operation: op, test: test, by: by} +} + +func (m *monkey) throw(receiver *monkey) { + throw, leftover := m.items[0], m.items[1:] + m.items = leftover + receiver.items = append(receiver.items, throw) +} + +type item struct { + worry int +} + +func (i *item) operation(m *monkey, r, mod int) { + worry := m.operation(i) + m.inspections += 1 + i.worry = (worry / r) % mod +} + +func (i *item) test(m *monkey) *monkey { + return m.test(i) +} + +func NewItem(worry int) *item { + return &item{ + worry: worry, + } +} + +// Can someone tell me how to do this better? Multiline regex? +func makeMonkeys(monkeyCount int, f *os.File) []*monkey { + startingItemsRegex := regexp.MustCompile(`\s+Starting items: ([0-9 ,]+)`) + operationRegex := regexp.MustCompile(`\s+Operation: new = ([0-9A-Za-z]+) ([+\*]{1}) ([0-9A-Za-z]+)`) + testRegex := regexp.MustCompile(`\s+Test: divisible by (\d+)`) + testConditionRegex := regexp.MustCompile(`\s+If (true|false): throw to monkey (\d+)`) + + monkeys := make([]*monkey, monkeyCount) + makeTest := func(by int, mtrue, mfalse int) func(i *item) *monkey { + return func(i *item) *monkey { + if i.worry%by == 0 { + return monkeys[mtrue] + } else { + return monkeys[mfalse] + } + } + } + makeOp := func(a1, comb, a2 string) func(i *item) int { + b := []string{a1, a2} + var c func(a, b int) int + if comb == "+" { + c = func(a, b int) int { + return a + b + } + } else if comb == "*" { + c = func(a, b int) int { + return a * b + } + } + b0, _ := strconv.Atoi(b[0]) + b1, _ := strconv.Atoi(b[1]) + return func(i *item) int { + switch { + case b[0] == "old" && b[1] == "old": + return c(i.worry, i.worry) + case b[0] == "old": + return c(i.worry, b1) + case b[1] == "old": + return c(b0, i.worry) + default: + return c(b0, b1) + } + } + } + + f.Seek(0, 0) + s := bufio.NewScanner(f) + startingItems := []int{} + testMap := make(map[string]int) + opMap := make(map[string]string) + monkeyPtr := 0 + for { + eof := s.Scan() + + if !eof || len(s.Bytes()) == 0 { + monkeys[monkeyPtr] = NewMonkey( + startingItems, + testMap["by"], + makeOp(opMap["arg1"], opMap["combination"], opMap["arg2"]), + makeTest(testMap["by"], testMap["true"], testMap["false"]), + ) + monkeyPtr += 1 + testMap = make(map[string]int) + opMap = make(map[string]string) + if monkeyPtr >= len(monkeys) { + break + } + } + + m := startingItemsRegex.FindStringSubmatch(s.Text()) + if len(m) == 2 { + itemStr := strings.Split(m[1], ", ") + startingItems = make([]int, len(itemStr)) + for i, strItem := range itemStr { + v, err := strconv.Atoi(strItem) + if err != nil { + log.Fatal("Could not get item worry from string", err) + } + startingItems[i] = v + } + } + m = operationRegex.FindStringSubmatch(s.Text()) + if len(m) == 4 { + opMap["arg1"] = m[1] + opMap["combination"] = m[2] + opMap["arg2"] = m[3] + } + m = testRegex.FindStringSubmatch(s.Text()) + if len(m) == 2 { + by, err := strconv.Atoi(m[1]) + if err != nil { + log.Fatal("Could not convert divisible by", err) + } + testMap["by"] = by + } + m = testConditionRegex.FindStringSubmatch(s.Text()) + if len(m) == 3 { + to, err := strconv.Atoi(m[2]) + if err != nil { + log.Fatal("Could not convert monkey to throw to", err) + } + testMap[m[1]] = to + } + } + return monkeys +} + +func monkeyBusiness(monkeys []*monkey, rounds, worryFactor, mod int) int { + for round := 0; round < rounds; round++ { + for _, m := range monkeys { + for len(m.items) > 0 { + item := m.items[0] + item.operation(m, worryFactor, mod) + to := item.test(m) + m.throw(to) + } + } + } + + monkey, business := 0, 0 + for _, m := range monkeys { + if m.inspections > monkey { + monkey, business = m.inspections, monkey + } else if m.inspections > business { + monkey, business = monkey, m.inspections + } + } + return monkey * business +} + +func main() { + f, err := os.Open("day11.txt") + if err != nil { + log.Fatal("could open input file", err) + } + + monkeyRegex := regexp.MustCompile(`Monkey (\d+)`) + monkeyCount := 0 + s := bufio.NewScanner(f) + for s.Scan() { + m := monkeyRegex.FindStringSubmatch(s.Text()) + if len(m) > 0 { + monkeyCount += 1 + } + } + + monkeys := makeMonkeys(monkeyCount, f) + mod := 1 + for _, m := range monkeys { + mod *= m.by + } + mb := monkeyBusiness(monkeys, 20, 3, mod) + fmt.Println("Part 1:", mb) + + monkeys = makeMonkeys(monkeyCount, f) + mb = monkeyBusiness(monkeys, 10_000, 1, mod) + fmt.Println("Part 2:", mb) +} diff --git a/day11.txt b/day11.txt new file mode 100644 index 0000000..4a696d9 --- /dev/null +++ b/day11.txt @@ -0,0 +1,55 @@ +Monkey 0: + Starting items: 91, 66 + Operation: new = old * 13 + Test: divisible by 19 + If true: throw to monkey 6 + If false: throw to monkey 2 + +Monkey 1: + Starting items: 78, 97, 59 + Operation: new = old + 7 + Test: divisible by 5 + If true: throw to monkey 0 + If false: throw to monkey 3 + +Monkey 2: + Starting items: 57, 59, 97, 84, 72, 83, 56, 76 + Operation: new = old + 6 + Test: divisible by 11 + If true: throw to monkey 5 + If false: throw to monkey 7 + +Monkey 3: + Starting items: 81, 78, 70, 58, 84 + Operation: new = old + 5 + Test: divisible by 17 + If true: throw to monkey 6 + If false: throw to monkey 0 + +Monkey 4: + Starting items: 60 + Operation: new = old + 8 + Test: divisible by 7 + If true: throw to monkey 1 + If false: throw to monkey 3 + +Monkey 5: + Starting items: 57, 69, 63, 75, 62, 77, 72 + Operation: new = old * 5 + Test: divisible by 13 + If true: throw to monkey 7 + If false: throw to monkey 4 + +Monkey 6: + Starting items: 73, 66, 86, 79, 98, 87 + Operation: new = old * old + Test: divisible by 3 + If true: throw to monkey 5 + If false: throw to monkey 2 + +Monkey 7: + Starting items: 95, 89, 63, 67 + Operation: new = old + 2 + Test: divisible by 2 + If true: throw to monkey 1 + If false: throw to monkey 4 |
