Day 11
This commit is contained in:
305
day11/common/monkey.go
Normal file
305
day11/common/monkey.go
Normal file
@@ -0,0 +1,305 @@
|
|||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
type WorryLevel interface {
|
||||||
|
Plus(int) WorryLevel
|
||||||
|
Times(int) WorryLevel
|
||||||
|
Power(int) WorryLevel
|
||||||
|
Relief() WorryLevel
|
||||||
|
Modulo(int) int
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
type WorryLevelWithRelief struct {
|
||||||
|
level int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (worryLevel WorryLevelWithRelief) Plus(operand int) WorryLevel {
|
||||||
|
return WorryLevelWithRelief{worryLevel.level + operand}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (worryLevel WorryLevelWithRelief) Times(operand int) WorryLevel {
|
||||||
|
return WorryLevelWithRelief{worryLevel.level * operand}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (worryLevel WorryLevelWithRelief) Power(operand int) WorryLevel {
|
||||||
|
result := 1
|
||||||
|
for i := 0; i < operand; i++ {
|
||||||
|
result *= worryLevel.level
|
||||||
|
}
|
||||||
|
return WorryLevelWithRelief{result}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (worryLevel WorryLevelWithRelief) Relief() WorryLevel {
|
||||||
|
return WorryLevelWithRelief{worryLevel.level / 3}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (worryLevel WorryLevelWithRelief) Modulo(operand int) int {
|
||||||
|
return worryLevel.level % operand
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
type WorryLevelWithoutReliefBase struct {
|
||||||
|
level int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (worryLevel *WorryLevelWithoutReliefBase) Plus(operand int) WorryLevel {
|
||||||
|
return &WorryLevelWithoutReliefPlus{worryLevel, operand, make(map[int]int)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (worryLevel *WorryLevelWithoutReliefBase) Times(operand int) WorryLevel {
|
||||||
|
return &WorryLevelWithoutReliefTimes{worryLevel, operand, make(map[int]int)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (worryLevel *WorryLevelWithoutReliefBase) Power(operand int) WorryLevel {
|
||||||
|
return &WorryLevelWithoutReliefPower{worryLevel, operand, make(map[int]int)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (worryLevel *WorryLevelWithoutReliefBase) Relief() WorryLevel {
|
||||||
|
return worryLevel
|
||||||
|
}
|
||||||
|
|
||||||
|
func (worryLevel *WorryLevelWithoutReliefBase) Modulo(operand int) int {
|
||||||
|
return worryLevel.level % operand
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
type WorryLevelWithoutReliefPlus struct {
|
||||||
|
worryLevel WorryLevel
|
||||||
|
operand int
|
||||||
|
modulos map[int]int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (worryLevel *WorryLevelWithoutReliefPlus) Plus(operand int) WorryLevel {
|
||||||
|
return &WorryLevelWithoutReliefPlus{worryLevel, operand, make(map[int]int)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (worryLevel *WorryLevelWithoutReliefPlus) Times(operand int) WorryLevel {
|
||||||
|
return &WorryLevelWithoutReliefTimes{worryLevel, operand, make(map[int]int)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (worryLevel *WorryLevelWithoutReliefPlus) Power(operand int) WorryLevel {
|
||||||
|
return &WorryLevelWithoutReliefPower{worryLevel, operand, make(map[int]int)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (worryLevel *WorryLevelWithoutReliefPlus) Relief() WorryLevel {
|
||||||
|
return worryLevel
|
||||||
|
}
|
||||||
|
|
||||||
|
func (worryLevel *WorryLevelWithoutReliefPlus) Modulo(operand int) int {
|
||||||
|
if val, ok := worryLevel.modulos[operand]; ok {
|
||||||
|
return val
|
||||||
|
} else {
|
||||||
|
val = (worryLevel.worryLevel.Modulo(operand) + worryLevel.operand % operand) % operand
|
||||||
|
worryLevel.modulos[operand] = val
|
||||||
|
return val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
type WorryLevelWithoutReliefTimes struct {
|
||||||
|
worryLevel WorryLevel
|
||||||
|
operand int
|
||||||
|
modulos map[int]int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (worryLevel *WorryLevelWithoutReliefTimes) Plus(operand int) WorryLevel {
|
||||||
|
return &WorryLevelWithoutReliefPlus{worryLevel, operand, make(map[int]int)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (worryLevel *WorryLevelWithoutReliefTimes) Times(operand int) WorryLevel {
|
||||||
|
return &WorryLevelWithoutReliefTimes{worryLevel, operand, make(map[int]int)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (worryLevel *WorryLevelWithoutReliefTimes) Power(operand int) WorryLevel {
|
||||||
|
return &WorryLevelWithoutReliefPower{worryLevel, operand, make(map[int]int)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (worryLevel *WorryLevelWithoutReliefTimes) Relief() WorryLevel {
|
||||||
|
return worryLevel
|
||||||
|
}
|
||||||
|
|
||||||
|
func (worryLevel *WorryLevelWithoutReliefTimes) Modulo(operand int) int {
|
||||||
|
if val, ok := worryLevel.modulos[operand]; ok {
|
||||||
|
return val
|
||||||
|
} else {
|
||||||
|
val = (worryLevel.worryLevel.Modulo(operand) * (worryLevel.operand % operand)) % operand
|
||||||
|
worryLevel.modulos[operand] = val
|
||||||
|
return val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
type WorryLevelWithoutReliefPower struct {
|
||||||
|
worryLevel WorryLevel
|
||||||
|
operand int
|
||||||
|
modulos map[int]int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (worryLevel *WorryLevelWithoutReliefPower) Plus(operand int) WorryLevel {
|
||||||
|
return &WorryLevelWithoutReliefPlus{worryLevel, operand, make(map[int]int)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (worryLevel *WorryLevelWithoutReliefPower) Times(operand int) WorryLevel {
|
||||||
|
return &WorryLevelWithoutReliefTimes{worryLevel, operand, make(map[int]int)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (worryLevel *WorryLevelWithoutReliefPower) Power(operand int) WorryLevel {
|
||||||
|
return &WorryLevelWithoutReliefPower{worryLevel, operand, make(map[int]int)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (worryLevel *WorryLevelWithoutReliefPower) Relief() WorryLevel {
|
||||||
|
return worryLevel
|
||||||
|
}
|
||||||
|
|
||||||
|
func (worryLevel *WorryLevelWithoutReliefPower) Modulo(operand int) int {
|
||||||
|
if val, ok := worryLevel.modulos[operand]; ok {
|
||||||
|
return val
|
||||||
|
} else {
|
||||||
|
mod := worryLevel.worryLevel.Modulo(operand)
|
||||||
|
result := 1
|
||||||
|
for i := 0; i < worryLevel.operand; i++ {
|
||||||
|
result *= mod
|
||||||
|
}
|
||||||
|
val = result % operand
|
||||||
|
worryLevel.modulos[operand] = val
|
||||||
|
return val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
type Item struct {
|
||||||
|
worryLevel WorryLevel
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewItem(worryLevel WorryLevel) *Item {
|
||||||
|
return &Item{worryLevel}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
type Operation interface {
|
||||||
|
Apply(WorryLevel) WorryLevel
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
type Addition struct {
|
||||||
|
operand int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (operation Addition) Apply(operand WorryLevel) WorryLevel {
|
||||||
|
return operand.Plus(operation.operand)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
type Multiplication struct {
|
||||||
|
operand int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (operation Multiplication) Apply(operand WorryLevel) WorryLevel {
|
||||||
|
return operand.Times(operation.operand)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
type Power struct {
|
||||||
|
operand int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (operation Power) Apply(operand WorryLevel) WorryLevel {
|
||||||
|
return operand.Power(operation.operand)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
type Test struct {
|
||||||
|
divisible int
|
||||||
|
targets map[bool]*Monkey
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
type Monkey struct {
|
||||||
|
heldItems []Item
|
||||||
|
operation Operation
|
||||||
|
test Test
|
||||||
|
nInspections int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (monkey *Monkey) ReceiveItem(item Item) {
|
||||||
|
monkey.heldItems = append(monkey.heldItems, item)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (monkey *Monkey) GetNumberOfInspections() int {
|
||||||
|
return monkey.nInspections
|
||||||
|
}
|
||||||
|
|
||||||
|
func (monkey *Monkey) NextRound() {
|
||||||
|
for len(monkey.heldItems) > 0 {
|
||||||
|
monkey.nInspections++
|
||||||
|
item := monkey.heldItems[0]
|
||||||
|
monkey.heldItems = monkey.heldItems[1:]
|
||||||
|
worryLevel := item.worryLevel
|
||||||
|
worryLevel = monkey.operation.Apply(worryLevel)
|
||||||
|
worryLevel = worryLevel.Relief()
|
||||||
|
monkey.test.targets[worryLevel.Modulo(monkey.test.divisible) == 0].ReceiveItem(Item{worryLevel})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func Parse(scanner bufio.Scanner, relief bool) []Monkey {
|
||||||
|
monkeys := []Monkey{}
|
||||||
|
targets := make(map[int]map[bool]int)
|
||||||
|
var monkey Monkey
|
||||||
|
|
||||||
|
for scanner.Scan() {
|
||||||
|
line := scanner.Text()
|
||||||
|
|
||||||
|
if line == "" {
|
||||||
|
monkeys = append(monkeys, monkey)
|
||||||
|
} else if line[:6] == "Monkey" {
|
||||||
|
monkey = Monkey{}
|
||||||
|
} else if line[:16] == " Starting items" {
|
||||||
|
items := strings.Split(line[18:], ", ")
|
||||||
|
for _, item := range(items) {
|
||||||
|
itemInt, _ := strconv.Atoi(item)
|
||||||
|
if (relief) {
|
||||||
|
monkey.heldItems = append(monkey.heldItems, *NewItem(WorryLevelWithRelief{itemInt}))
|
||||||
|
} else {
|
||||||
|
monkey.heldItems = append(monkey.heldItems, *NewItem(&WorryLevelWithoutReliefBase{itemInt}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if line[:11] == " Operation" {
|
||||||
|
if line[23] == '+' {
|
||||||
|
operand, _ := strconv.Atoi(line[25:])
|
||||||
|
monkey.operation = Addition{operand}
|
||||||
|
} else if line[23] == '*' {
|
||||||
|
operand, err := strconv.Atoi(line[25:])
|
||||||
|
if err == nil {
|
||||||
|
monkey.operation = Multiplication{operand}
|
||||||
|
} else {
|
||||||
|
monkey.operation = Power{2}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if line[:6] == " Test" {
|
||||||
|
divisible, _ := strconv.Atoi(line[21:])
|
||||||
|
monkey.test.divisible = divisible
|
||||||
|
targets[len(monkeys)] = make(map[bool]int)
|
||||||
|
} else if line[:11] == " If true" {
|
||||||
|
targets[len(monkeys)][true] = int(line[29] - '0')
|
||||||
|
} else if line[:12] == " If false" {
|
||||||
|
targets[len(monkeys)][false] = int(line[30] - '0')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
monkeys = append(monkeys, monkey)
|
||||||
|
|
||||||
|
for i, target := range targets {
|
||||||
|
monkeys[i].test.targets = make(map[bool]*Monkey)
|
||||||
|
monkeys[i].test.targets[true] = &monkeys[target[true]]
|
||||||
|
monkeys[i].test.targets[false] = &monkeys[target[false]]
|
||||||
|
}
|
||||||
|
|
||||||
|
return monkeys
|
||||||
|
}
|
||||||
28
day11/ex1/main.go
Normal file
28
day11/ex1/main.go
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"aoc2022/day11/common"
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"sort"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
monkeys := common.Parse(*bufio.NewScanner(os.Stdin), true)
|
||||||
|
|
||||||
|
for i := 0; i < 20; i++ {
|
||||||
|
for j := 0; j < len(monkeys); j++ {
|
||||||
|
monkey := &monkeys[j]
|
||||||
|
monkey.NextRound()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nInspections := make([]int, len(monkeys))
|
||||||
|
for i := 0; i < len(monkeys); i++ {
|
||||||
|
nInspections[i] = monkeys[i].GetNumberOfInspections()
|
||||||
|
}
|
||||||
|
sort.Ints(nInspections)
|
||||||
|
|
||||||
|
fmt.Println(nInspections[len(nInspections)-1] * nInspections[len(nInspections)-2])
|
||||||
|
}
|
||||||
28
day11/ex2/main.go
Normal file
28
day11/ex2/main.go
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"aoc2022/day11/common"
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"sort"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
monkeys := common.Parse(*bufio.NewScanner(os.Stdin), false)
|
||||||
|
|
||||||
|
for i := 0; i < 10000; i++ {
|
||||||
|
for j := 0; j < len(monkeys); j++ {
|
||||||
|
monkey := &monkeys[j]
|
||||||
|
monkey.NextRound()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nInspections := make([]int, len(monkeys))
|
||||||
|
for i := 0; i < len(monkeys); i++ {
|
||||||
|
nInspections[i] = monkeys[i].GetNumberOfInspections()
|
||||||
|
}
|
||||||
|
sort.Ints(nInspections)
|
||||||
|
|
||||||
|
fmt.Println(nInspections[len(nInspections)-1] * nInspections[len(nInspections)-2])
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user