Add day 11

This commit is contained in:
Stanislav Nikolov 2022-12-11 21:15:08 +02:00
parent ffb4d5f95a
commit 610e89eae6
4 changed files with 248 additions and 0 deletions

55
day11/prod.in.txt Normal file
View File

@ -0,0 +1,55 @@
Monkey 0:
Starting items: 50, 70, 89, 75, 66, 66
Operation: new = old * 5
Test: divisible by 2
If true: throw to monkey 2
If false: throw to monkey 1
Monkey 1:
Starting items: 85
Operation: new = old * old
Test: divisible by 7
If true: throw to monkey 3
If false: throw to monkey 6
Monkey 2:
Starting items: 66, 51, 71, 76, 58, 55, 58, 60
Operation: new = old + 1
Test: divisible by 13
If true: throw to monkey 1
If false: throw to monkey 3
Monkey 3:
Starting items: 79, 52, 55, 51
Operation: new = old + 6
Test: divisible by 3
If true: throw to monkey 6
If false: throw to monkey 4
Monkey 4:
Starting items: 69, 92
Operation: new = old * 17
Test: divisible by 19
If true: throw to monkey 7
If false: throw to monkey 5
Monkey 5:
Starting items: 71, 76, 73, 98, 67, 79, 99
Operation: new = old + 8
Test: divisible by 5
If true: throw to monkey 0
If false: throw to monkey 2
Monkey 6:
Starting items: 82, 76, 69, 69, 57
Operation: new = old + 7
Test: divisible by 11
If true: throw to monkey 7
If false: throw to monkey 4
Monkey 7:
Starting items: 65, 79, 86
Operation: new = old + 5
Test: divisible by 17
If true: throw to monkey 5
If false: throw to monkey 0

164
day11/solution.go Normal file
View File

@ -0,0 +1,164 @@
package day11
import (
"fmt"
"sort"
"strconv"
"strings"
)
type Solver struct {
monkeys []*MonkeySpec
}
type MonkeySpec struct {
itemWorryLevels []uint64
advancedItemWorryLevels []ItemWorryLevel
opType string
opValue uint64
testDivisor uint64
targetMonkeyIfTrue int
targetMonkeyIfFalse int
numInspections int
}
type ItemWorryLevel struct {
multipliers []uint64
additive uint64
}
func (i *ItemWorryLevel) Value() uint64 {
v := uint64(1)
for _, m := range i.multipliers {
v *= m
}
return v + i.additive
}
func (i *ItemWorryLevel) Mod(d uint64) uint64 {
currentDivisor := uint64(1)
for _, m := range i.multipliers {
currentDivisor *= m % d
}
currentDivisor += i.additive
currentDivisor %= d
return currentDivisor
}
func (i *ItemWorryLevel) TimesConst(c uint64) *ItemWorryLevel {
r := *i
r.multipliers = append(r.multipliers, c)
r.additive *= c
return &r
}
// func (i *ItemWorryLevel) Squared() *ItemWorryLevel {
// r := *i
// r.multipliers = append(r.multipliers, (2*i.additive)%allDivisors)
// r.multipliers = append(r.multipliers, i.multipliers...)
// r.additive *= i.additive
// return &r
// }
func (s *Solver) ParseInput(input []string) {
s.monkeys = make([]*MonkeySpec, 1+len(input)/7)
for m := 0; m < len(s.monkeys); m++ {
offset := 7 * m
startingItemsLine := strings.Split(strings.Split(input[offset+1], ": ")[1], ", ")
startingItems := make([]uint64, len(startingItemsLine))
advancedStartingItems := make([]ItemWorryLevel, len(startingItemsLine))
for i, item := range startingItemsLine {
startingItems[i], _ = strconv.ParseUint(item, 10, 64)
advancedStartingItems[i] = ItemWorryLevel{[]uint64{startingItems[i]}, 0}
}
operationLine := strings.Split(strings.Split(input[offset+2], " old ")[1], " ")
opType := operationLine[0]
opValue, _ := strconv.ParseUint(operationLine[1], 10, 64)
divisor, _ := strconv.ParseUint(strings.Split(input[offset+3], " by ")[1], 10, 64)
trueTargetMonkey, _ := strconv.Atoi(strings.Split(input[offset+4], " monkey ")[1])
falseTargetMonkey, _ := strconv.Atoi(strings.Split(input[offset+5], " monkey ")[1])
s.monkeys[m] = &MonkeySpec{
itemWorryLevels: startingItems,
advancedItemWorryLevels: advancedStartingItems,
opType: opType,
opValue: opValue,
testDivisor: divisor,
targetMonkeyIfTrue: trueTargetMonkey,
targetMonkeyIfFalse: falseTargetMonkey,
}
}
}
func (s *Solver) SolvePart1() any {
return s.solve(20, true)
}
func (s *Solver) SolvePart2() any {
return s.solve(10000, false)
}
func (s *Solver) solve(numberOfRounds uint64, divideByThree bool) any {
allDivisors := uint64(1)
for _, d := range s.monkeys {
allDivisors *= d.testDivisor
}
for r := 0; r < int(numberOfRounds); r++ {
for _, monkey := range s.monkeys {
for _, item := range monkey.itemWorryLevels {
monkey.numInspections++
newWorryLevel := item
var opValue uint64
if monkey.opValue == 0 {
opValue = item
} else {
opValue = monkey.opValue
}
switch monkey.opType {
case "*":
newWorryLevel *= opValue
case "+":
newWorryLevel += opValue
}
if divideByThree {
newWorryLevel /= 3
} else {
newWorryLevel %= allDivisors
}
var targetMonkey int
if newWorryLevel%monkey.testDivisor == 0 {
targetMonkey = monkey.targetMonkeyIfTrue
} else {
targetMonkey = monkey.targetMonkeyIfFalse
}
s.monkeys[targetMonkey].itemWorryLevels = append(s.monkeys[targetMonkey].itemWorryLevels, newWorryLevel)
// fmt.Printf("-> Throwing to monkey: %d\n", targetMonkey)
}
monkey.itemWorryLevels = []uint64{}
}
// fmt.Printf("\nround %d:\n", r)
// s.printMonkeys()
}
var numInspections []int
for _, m := range s.monkeys {
numInspections = append(numInspections, m.numInspections)
}
sort.Ints(numInspections)
return uint64(numInspections[len(numInspections)-1]) * uint64(numInspections[len(numInspections)-2])
}
func (s *Solver) printMonkeys() {
for _, m := range s.monkeys {
fmt.Printf("%+v\n", m)
}
}

27
day11/test.in.txt Normal file
View File

@ -0,0 +1,27 @@
Monkey 0:
Starting items: 79, 98
Operation: new = old * 19
Test: divisible by 23
If true: throw to monkey 2
If false: throw to monkey 3
Monkey 1:
Starting items: 54, 65, 75, 74
Operation: new = old + 6
Test: divisible by 19
If true: throw to monkey 2
If false: throw to monkey 0
Monkey 2:
Starting items: 79, 60, 97
Operation: new = old * old
Test: divisible by 13
If true: throw to monkey 1
If false: throw to monkey 3
Monkey 3:
Starting items: 74
Operation: new = old + 3
Test: divisible by 17
If true: throw to monkey 0
If false: throw to monkey 1

View File

@ -16,6 +16,7 @@ import (
"snikolov.me/aoc2022/day08"
"snikolov.me/aoc2022/day09"
"snikolov.me/aoc2022/day10"
"snikolov.me/aoc2022/day11"
"snikolov.me/aoc2022/utils"
)
@ -60,6 +61,7 @@ func solve(args Args, inputFileName string) {
8: &day08.Solver{},
9: &day09.Solver{},
10: &day10.Solver{},
11: &day11.Solver{},
}
solver, ok := solvers[args.DayNumber]
if !ok {