Day 11 part 2
const ROUNDS = 10_000
type
Monkey = ref object
items: seq[Natural]
pow: bool
riskOp: proc(risk: Natural): Natural
divisor, passTrue, passFalse, inspectCount: Natural
var
monkeys = newSeq[Monkey]()
lcd: Natural = 1
answer: Natural
proc inspectItems(m: var Monkey) =
m.items.apply(m.riskOp)
for item in m.items:
m.inspectCount.inc
let targetMonkey = if item mod m.divisor == 0: m.passTrue else: m.passFalse
monkeys[targetMonkey].items.add (item mod lcd)
m.items = @[]
proc newMonkey(s: string): Monkey =
result = Monkey()
var attrs = s.splitLines
while attrs.len > 0:
var a = attrs.pop.split(':')
case a[0]
of " Starting items":
a[1] = a[1].replace(" ", "")
for i in a[1].split(','): result.items.add i.parseInt
of " Operation":
let parsed = a[1].rsplit(' ', 2)
if parsed[1] == "*" and parsed[2] == "old":
result.riskOp = proc(risk: Natural): Natural = risk * risk
elif parsed[1] == "*":
result.riskOp = proc(risk: Natural): Natural =
risk * parsed[2].parseInt
elif parsed[1] == "+":
result.riskOp = proc(risk: Natural): Natural =
risk + parsed[2].parseInt
of " Test":
result.divisor = a[1].rsplit(' ', 1)[1].parseInt
lcd *= result.divisor
of " If true":
result.passTrue = a[1].rsplit(' ', 1)[1].parseInt
of " If false":
result.passFalse = a[1].rsplit(' ', 1)[1].parseInt
else: discard
for m in "input.txt".readFile().split("\n\n"):
monkeys.add newMonkey(m)
for _ in 0..<ROUNDS:
for i in 0..<monkeys.len:
if monkeys[i].items.len > 0: monkeys[i].inspectItems()
var inspectCounts = newSeq[Natural](monkeys.len)
for i in 0..<monkeys.len:
inspectCounts[i] = monkeys[i].inspectCount
inspectCounts.sort(Descending)
answer = inspectCounts[0] * inspectCounts[1]
Answer is: 14106266886