2022 Day 11 Complete
This commit is contained in:
188
2022/day11/main.go
Normal file
188
2022/day11/main.go
Normal file
@@ -0,0 +1,188 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
h "git.bullercodeworks.com/brian/adventofcode/helpers"
|
||||
)
|
||||
|
||||
func main() {
|
||||
inp := h.StdinToStringSlice()
|
||||
part1(inp)
|
||||
part2(inp)
|
||||
}
|
||||
|
||||
func part1(inp []string) {
|
||||
monkeys := BuildMonkeys(inp, 1)
|
||||
for i := 0; i < 20; i++ {
|
||||
for _, m := range monkeys.monkeys {
|
||||
m.Do(monkeys)
|
||||
}
|
||||
}
|
||||
fmt.Println("# Part 1")
|
||||
fmt.Println("Monkey Business:", monkeys.Business())
|
||||
}
|
||||
|
||||
func part2(inp []string) {
|
||||
monkeys := BuildMonkeys(inp, 2)
|
||||
mod := uint64(1)
|
||||
for _, m := range monkeys.monkeys {
|
||||
mod = mod * m.Div
|
||||
}
|
||||
for i := 0; i < 10000; i++ {
|
||||
for _, m := range monkeys.monkeys {
|
||||
for len(m.Items) > 0 {
|
||||
m.Inspected++
|
||||
var v uint64
|
||||
v, m.Items = m.Items[len(m.Items)-1], m.Items[:len(m.Items)-1]
|
||||
v = m.Op(v) % mod
|
||||
if v%m.Div == 0 {
|
||||
monkeys.Find(m.TrueTo).Catch(v)
|
||||
} else {
|
||||
monkeys.Find(m.FalseTo).Catch(v)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fmt.Println("# Part 2")
|
||||
fmt.Println("Monkey Business:", monkeys.Business())
|
||||
}
|
||||
|
||||
type AllMonkeys struct {
|
||||
monkeys []*Monkey
|
||||
Part uint64
|
||||
}
|
||||
|
||||
func BuildMonkeys(inp []string, part uint64) *AllMonkeys {
|
||||
var ret []*Monkey
|
||||
for i := range inp {
|
||||
if strings.HasPrefix(inp[i], "Monkey") {
|
||||
ret = append(ret, NewMonkey(inp[i:]))
|
||||
}
|
||||
}
|
||||
return &AllMonkeys{
|
||||
monkeys: ret,
|
||||
Part: part,
|
||||
}
|
||||
}
|
||||
|
||||
func (a *AllMonkeys) Find(id int) *Monkey {
|
||||
for i := range a.monkeys {
|
||||
if a.monkeys[i].Id == id {
|
||||
return a.monkeys[i]
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *AllMonkeys) Business() uint64 {
|
||||
// Find the 2 most active monkeys, multiply their inspections together
|
||||
var top1, top2 *Monkey
|
||||
for _, m := range a.monkeys {
|
||||
if top1 == nil {
|
||||
top1 = m
|
||||
} else if m.Inspected > top1.Inspected {
|
||||
top1, top2 = m, top1
|
||||
} else if top2 == nil || m.Inspected > top2.Inspected {
|
||||
top2 = m
|
||||
}
|
||||
}
|
||||
fmt.Println("Top Two")
|
||||
fmt.Println(top1)
|
||||
fmt.Println(top2)
|
||||
return top1.Inspected * top2.Inspected
|
||||
}
|
||||
|
||||
type Monkey struct {
|
||||
Id int
|
||||
Items []uint64
|
||||
Inspected uint64
|
||||
Op func(uint64) uint64
|
||||
Value uint64
|
||||
TrueTo int
|
||||
FalseTo int
|
||||
Div uint64
|
||||
}
|
||||
|
||||
func NewMonkey(inp []string) *Monkey {
|
||||
monkey := &Monkey{}
|
||||
fmt.Sscanf(inp[0], "Monkey %d:", &monkey.Id)
|
||||
pts := strings.Fields(inp[1])
|
||||
for i := 2; i < len(pts); i++ {
|
||||
wrk := strings.TrimSuffix(pts[i], ",")
|
||||
monkey.Items = append(monkey.Items, h.Atoui(wrk))
|
||||
}
|
||||
// Parse out this Monkey's Operation Function
|
||||
pts = strings.Fields(inp[2])
|
||||
var p1, p2 uint64
|
||||
p1S := pts[3]
|
||||
if p1S != "old" {
|
||||
p1 = h.Atoui(p1S)
|
||||
}
|
||||
p2S := pts[5]
|
||||
if p2S != "old" {
|
||||
p2 = h.Atoui(p2S)
|
||||
}
|
||||
op := pts[4]
|
||||
// And the Test
|
||||
monkey.Div = h.Atoui(inp[3][21:])
|
||||
|
||||
switch op {
|
||||
case "*":
|
||||
monkey.Op = func(v uint64) uint64 {
|
||||
first, second := v, v
|
||||
if p1S != "old" {
|
||||
first = p1
|
||||
}
|
||||
if p2S != "old" {
|
||||
second = p2
|
||||
}
|
||||
return first * second
|
||||
}
|
||||
case "+":
|
||||
monkey.Op = func(v uint64) uint64 {
|
||||
first, second := v, v
|
||||
if p1S != "old" {
|
||||
first = p1
|
||||
}
|
||||
if p2S != "old" {
|
||||
second = p2
|
||||
}
|
||||
return first + second
|
||||
}
|
||||
}
|
||||
monkey.TrueTo = h.Atoi(inp[4][29:])
|
||||
monkey.FalseTo = h.Atoi(inp[5][30:])
|
||||
return monkey
|
||||
}
|
||||
|
||||
func (m *Monkey) Do(all *AllMonkeys) {
|
||||
for i := range m.Items {
|
||||
item := m.Items[i]
|
||||
pre := item
|
||||
item = m.Op(item)
|
||||
if item < pre {
|
||||
log.Fatalf("%s; Was %d; Now: %d\n", m, pre, item)
|
||||
}
|
||||
if all.Part == 1 {
|
||||
item = item / 3
|
||||
}
|
||||
if item%m.Div == 0 {
|
||||
all.Find(m.TrueTo).Catch(item)
|
||||
} else {
|
||||
all.Find(m.FalseTo).Catch(item)
|
||||
}
|
||||
m.Inspected++
|
||||
}
|
||||
m.Items = []uint64{}
|
||||
}
|
||||
|
||||
func (m *Monkey) Catch(item uint64) {
|
||||
m.Items = append(m.Items, item)
|
||||
}
|
||||
|
||||
func (m Monkey) String() string {
|
||||
return fmt.Sprintf("Monkey %d; Inspected %d; Items: %v", m.Id, m.Inspected, m.Items)
|
||||
}
|
||||
Reference in New Issue
Block a user