aoc-2022/day11/task1.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]