81 lines
1.8 KiB
Nim
81 lines
1.8 KiB
Nim
import rdstdin
|
|
import algorithm
|
|
import strutils
|
|
import sequtils
|
|
import sugar
|
|
import math
|
|
|
|
const NUM_ROUNDS = 20
|
|
|
|
type Monkey = object
|
|
items: seq[int]
|
|
operation: string
|
|
test: int
|
|
if_true: int
|
|
if_false: int
|
|
|
|
proc eval_operation(operation: string, old: int): int =
|
|
let operands = operation.split(" ")
|
|
assert operands[0] == "new"
|
|
assert operands[1] == "="
|
|
|
|
let op0 = case operands[2]:
|
|
of "old": old
|
|
else: operands[2].parseInt
|
|
|
|
let op1 = case operands[4]:
|
|
of "old": old
|
|
else: operands[4].parseInt
|
|
|
|
if operands[3] == "*":
|
|
op0 * op1
|
|
else:
|
|
op0 + op1
|
|
|
|
var line: string
|
|
var monkeys: seq[Monkey]
|
|
var monkey: Monkey
|
|
|
|
while true:
|
|
let ok = readLineFromStdin("", line)
|
|
if not ok:
|
|
monkeys.add(monkey)
|
|
break
|
|
if line.isEmptyOrWhitespace:
|
|
monkeys.add(monkey)
|
|
continue
|
|
|
|
let statement = collect:
|
|
for data in line.split(":"): data.unindent
|
|
|
|
case statement[0]:
|
|
of "Monkey": monkey = Monkey()
|
|
of "Starting items":
|
|
monkey.items = collect:
|
|
for i in statement[1].split(", "): i.parseInt
|
|
of "Operation":
|
|
monkey.operation = statement[1]
|
|
of "Test":
|
|
monkey.test = statement[1].split(" ")[2].parseInt
|
|
of "If true":
|
|
monkey.if_true = statement[1].split(" ")[3].parseInt
|
|
of "If false":
|
|
monkey.if_false = statement[1].split(" ")[3].parseInt
|
|
|
|
var monkeyCounts = newSeq[int](monkeys.len)
|
|
|
|
for _ in 1 .. NUM_ROUNDS:
|
|
for m in 0 .. monkeys.len - 1:
|
|
for i in countdown(monkeys[m].items.len - 1, 0):
|
|
let item = monkeys[m].operation.eval_operation(monkeys[m].items[i]).floorDiv(3)
|
|
let target = case item mod monkeys[m].test:
|
|
of 0: monkeys[m].if_true
|
|
else: monkeys[m].if_false
|
|
|
|
monkeys[target].items.add(item)
|
|
monkeys[m].items.del(i)
|
|
monkeyCounts[m].inc
|
|
|
|
monkeyCounts.sort(order = SortOrder.Descending)
|
|
echo monkeyCounts[0] * monkeyCounts[1]
|