parent
94c6ccb87b
commit
298d0c3439
@ -0,0 +1,99 @@
|
||||
#!/usr/bin/env julia
|
||||
|
||||
using Test
|
||||
|
||||
mutable struct Monkey
|
||||
index :: UInt
|
||||
items :: Vector{Int}
|
||||
op :: Function
|
||||
op_value :: Int
|
||||
test_divisor :: Int
|
||||
test_result :: NTuple{2, UInt}
|
||||
inspected :: Int
|
||||
end
|
||||
|
||||
function parse_monkey(text)
|
||||
lines = split(text, '\n')
|
||||
# Monkey 0:
|
||||
match_index = match(r"Monkey (\d+):", lines[1])
|
||||
index = parse(UInt, match_index.captures[1])
|
||||
# Starting items: 79, 98
|
||||
match_items = match(r" *Starting items: (.*)", lines[2])
|
||||
items_list = split(match_items.captures[1], ", ")
|
||||
items = parse.(Int, items_list)
|
||||
# Operation: new = old * 19
|
||||
match_op = match(r" *Operation: new = old (.) (old|\d+)", lines[3])
|
||||
if match_op.captures[1] == "+"
|
||||
op = +
|
||||
elseif match_op.captures[1] == "*"
|
||||
op = *
|
||||
else
|
||||
throw(DomainError("Unknown op: " * match_op.captures[1]))
|
||||
end
|
||||
if match_op.captures[2] == "old"
|
||||
op = ^
|
||||
op_value = 2
|
||||
else
|
||||
op_value = parse(Int, match_op.captures[2])
|
||||
end
|
||||
# Test: divisible by 13
|
||||
match_test = match(r" *Test: divisible by (\d+)", lines[4])
|
||||
test_divisor = parse(Int, match_test.captures[1])
|
||||
# If true: throw to monkey 1
|
||||
# If false: throw to monkey 3
|
||||
match_true = match(r" *If true: throw to monkey (\d+)", lines[5])
|
||||
match_false = match(r" *If false: throw to monkey (\d+)", lines[6])
|
||||
test_result = (parse(UInt, match_true.captures[1]) + 1,
|
||||
parse(UInt, match_false.captures[1]) + 1)
|
||||
return Monkey(index, items, op, op_value, test_divisor, test_result, 0)
|
||||
end
|
||||
|
||||
function read_monkeys(infile)
|
||||
open(infile) do io
|
||||
monkey_strings = split(read(io, String), "\n\n")
|
||||
return parse_monkey.(monkey_strings)
|
||||
end
|
||||
end
|
||||
|
||||
function simian_shenanigans(monkeys :: Vector{Monkey})
|
||||
for m in monkeys
|
||||
for item in m.items
|
||||
new_value = m.op(item, m.op_value)
|
||||
new_value = Int(floor(new_value / 3))
|
||||
new_monkey = (mod(new_value, m.test_divisor) == 0
|
||||
? m.test_result[1] : m.test_result[2])
|
||||
push!(monkeys[new_monkey].items, new_value)
|
||||
m.inspected += 1
|
||||
end
|
||||
empty!(m.items)
|
||||
end
|
||||
end
|
||||
|
||||
function monkey_business(monkeys; rounds=20)
|
||||
for _ in 1:rounds
|
||||
simian_shenanigans(monkeys)
|
||||
end
|
||||
return prod(sort([m.inspected for m in monkeys])[end-1:end])
|
||||
end
|
||||
|
||||
function test()
|
||||
@testset "monkey business" verbose=true begin
|
||||
@test monkey_business(read_monkeys("example.txt")) == 10605
|
||||
@test monkey_business(read_monkeys("input.txt")) == 64032
|
||||
end
|
||||
end
|
||||
|
||||
function main()
|
||||
if size(ARGS, 1) == 0
|
||||
test()
|
||||
else
|
||||
infile = ARGS[1]
|
||||
println("infile = ", infile)
|
||||
monkeys = read_monkeys(infile)
|
||||
display(monkeys)
|
||||
println()
|
||||
println("monkey business ", monkey_business(monkeys))
|
||||
end
|
||||
end
|
||||
|
||||
main()
|
||||
@ -0,0 +1,27 @@
|
||||
Monkey 0:
|
||||
Starting items: 79, 98
|
||||
Operation: new = old * 19
|
||||
Test: divisible by 23
|
||||
If true: throw to monkey 2
|
||||
If false: throw to monkey 3
|
||||
|
||||
Monkey 1:
|
||||
Starting items: 54, 65, 75, 74
|
||||
Operation: new = old + 6
|
||||
Test: divisible by 19
|
||||
If true: throw to monkey 2
|
||||
If false: throw to monkey 0
|
||||
|
||||
Monkey 2:
|
||||
Starting items: 79, 60, 97
|
||||
Operation: new = old * old
|
||||
Test: divisible by 13
|
||||
If true: throw to monkey 1
|
||||
If false: throw to monkey 3
|
||||
|
||||
Monkey 3:
|
||||
Starting items: 74
|
||||
Operation: new = old + 3
|
||||
Test: divisible by 17
|
||||
If true: throw to monkey 0
|
||||
If false: throw to monkey 1
|
||||
@ -0,0 +1,55 @@
|
||||
Monkey 0:
|
||||
Starting items: 83, 88, 96, 79, 86, 88, 70
|
||||
Operation: new = old * 5
|
||||
Test: divisible by 11
|
||||
If true: throw to monkey 2
|
||||
If false: throw to monkey 3
|
||||
|
||||
Monkey 1:
|
||||
Starting items: 59, 63, 98, 85, 68, 72
|
||||
Operation: new = old * 11
|
||||
Test: divisible by 5
|
||||
If true: throw to monkey 4
|
||||
If false: throw to monkey 0
|
||||
|
||||
Monkey 2:
|
||||
Starting items: 90, 79, 97, 52, 90, 94, 71, 70
|
||||
Operation: new = old + 2
|
||||
Test: divisible by 19
|
||||
If true: throw to monkey 5
|
||||
If false: throw to monkey 6
|
||||
|
||||
Monkey 3:
|
||||
Starting items: 97, 55, 62
|
||||
Operation: new = old + 5
|
||||
Test: divisible by 13
|
||||
If true: throw to monkey 2
|
||||
If false: throw to monkey 6
|
||||
|
||||
Monkey 4:
|
||||
Starting items: 74, 54, 94, 76
|
||||
Operation: new = old * old
|
||||
Test: divisible by 7
|
||||
If true: throw to monkey 0
|
||||
If false: throw to monkey 3
|
||||
|
||||
Monkey 5:
|
||||
Starting items: 58
|
||||
Operation: new = old + 4
|
||||
Test: divisible by 17
|
||||
If true: throw to monkey 7
|
||||
If false: throw to monkey 1
|
||||
|
||||
Monkey 6:
|
||||
Starting items: 66, 63
|
||||
Operation: new = old + 6
|
||||
Test: divisible by 2
|
||||
If true: throw to monkey 7
|
||||
If false: throw to monkey 5
|
||||
|
||||
Monkey 7:
|
||||
Starting items: 56, 56, 90, 96, 68
|
||||
Operation: new = old + 7
|
||||
Test: divisible by 3
|
||||
If true: throw to monkey 4
|
||||
If false: throw to monkey 1
|
||||
Loading…
Reference in new issue