Compare commits

..

4 Commits

Author SHA1 Message Date
Bryce Allen
4d8a104945 day11 p2 2022-12-11 16:27:42 -05:00
Bryce Allen
298d0c3439 day11 p1 2022-12-11 16:01:08 -05:00
Bryce Allen
94c6ccb87b day10 p2 2022-12-11 13:18:24 -05:00
Bryce Allen
4191470b86 day10 p1 2022-12-11 12:00:50 -05:00
8 changed files with 596 additions and 0 deletions

104
day10/day10.jl Normal file
View File

@@ -0,0 +1,104 @@
#!/usr/bin/env julia
using Test
mutable struct Instruction
cycles :: UInt
add :: Int
end
function parse_instruction_line(line)
parts = split(line, limit=2)
if parts[1] == "noop"
return Instruction(1, 0)
elseif parts[1] == "addx"
return Instruction(2, parse(Int, parts[2]))
else
throw(DomainError("Unknown instruction: " * line))
end
end
function signal_strength_sum(io; end_cycle=220)
X :: Int = 1
cycle :: Int = 1
signal_strength_sum :: Int = 0
next_test_cycle = 20
for line in eachline(io)
if mod(cycle - 20, 40) == 0 && cycle <= end_cycle
println(cycle, " ", X)
signal_strength_sum += cycle * X
next_test_cycle += 40
end
inst = parse_instruction_line(line)
new_cycle = cycle + inst.cycles
if new_cycle > next_test_cycle
signal_strength_sum += next_test_cycle * X
next_test_cycle += 40
end
cycle = new_cycle
X += inst.add
end
println("last inst cycle ", cycle)
signal_strength_sum += X * sum(filter(x -> x >= cycle, 20:40:end_cycle))
return signal_strength_sum
end
function get_crt(io; end_cycle=240)
X :: Int = 2 # Note: add 1 to simplify 1-based indexing
pending_instruction :: Union{Instruction, Nothing} = nothing
screen = fill('.', (Int(ceil(end_cycle / 40)), 40))
nrows, ncols = size(screen)
for i in 1:nrows
for j in 1:ncols
if abs(X - j) <= 1
screen[i, j] = "#"[1]
else
screen[i, j] = '.'
end
if pending_instruction === nothing
if eof(io)
continue
end
inst = parse_instruction_line(readline(io))
pending_instruction = inst
end
pending_instruction.cycles -= 1
if pending_instruction.cycles == 0
X += pending_instruction.add
pending_instruction = nothing
end
end
end
return join(reduce(*, screen, dims=2, init=""), "\n")
end
function test()
@testset "signal strength sum" verbose=true begin
@test signal_strength_sum("example.txt") == 13140
@test signal_strength_sum("input.txt") == 13220
end
@testset "crt test" verbose=true begin
open("example.txt") do io
@test get_crt(io) == chomp(read("example_crt.txt", String))
end
open("input.txt") do io
@test get_crt(io) == chomp(read("input_crt.txt", String))
end
end
end
function main()
if size(ARGS, 1) == 0
test()
else
infile = ARGS[1]
println("infile = ", infile)
println("signal strength sum = ", signal_strength_sum(infile))
open(infile, "r") do io
println(get_crt(io))
end
end
end
main()

146
day10/example.txt Normal file
View File

@@ -0,0 +1,146 @@
addx 15
addx -11
addx 6
addx -3
addx 5
addx -1
addx -8
addx 13
addx 4
noop
addx -1
addx 5
addx -1
addx 5
addx -1
addx 5
addx -1
addx 5
addx -1
addx -35
addx 1
addx 24
addx -19
addx 1
addx 16
addx -11
noop
noop
addx 21
addx -15
noop
noop
addx -3
addx 9
addx 1
addx -3
addx 8
addx 1
addx 5
noop
noop
noop
noop
noop
addx -36
noop
addx 1
addx 7
noop
noop
noop
addx 2
addx 6
noop
noop
noop
noop
noop
addx 1
noop
noop
addx 7
addx 1
noop
addx -13
addx 13
addx 7
noop
addx 1
addx -33
noop
noop
noop
addx 2
noop
noop
noop
addx 8
noop
addx -1
addx 2
addx 1
noop
addx 17
addx -9
addx 1
addx 1
addx -3
addx 11
noop
noop
addx 1
noop
addx 1
noop
noop
addx -13
addx -19
addx 1
addx 3
addx 26
addx -30
addx 12
addx -1
addx 3
addx 1
noop
noop
noop
addx -9
addx 18
addx 1
addx 2
noop
noop
addx 9
noop
noop
noop
addx -1
addx 2
addx -37
addx 1
addx 3
noop
addx 15
addx -21
addx 22
addx -6
addx 1
noop
addx 2
addx 1
noop
addx -10
noop
noop
addx 20
addx 1
addx 2
addx 2
addx -6
addx -11
noop
noop
noop

6
day10/example_crt.txt Normal file
View File

@@ -0,0 +1,6 @@
##..##..##..##..##..##..##..##..##..##..
###...###...###...###...###...###...###.
####....####....####....####....####....
#####.....#####.....#####.....#####.....
######......######......######......####
#######.......#######.......#######.....

137
day10/input.txt Normal file
View File

@@ -0,0 +1,137 @@
noop
noop
addx 5
addx 3
addx -2
noop
addx 5
addx 4
noop
addx 3
noop
addx 2
addx -17
addx 18
addx 3
addx 1
noop
addx 5
noop
addx 1
addx 2
addx 5
addx -40
noop
addx 5
addx 2
addx 3
noop
addx 2
addx 3
addx -2
addx 2
addx 2
noop
addx 3
addx 5
addx 2
addx 3
addx -2
addx 2
addx -24
addx 31
addx 2
addx -33
addx -6
addx 5
addx 2
addx 3
noop
addx 2
addx 3
noop
addx 2
addx -1
addx 6
noop
noop
addx 1
addx 4
noop
noop
addx -15
addx 20
noop
addx -23
addx 27
noop
addx -35
addx 1
noop
noop
addx 5
addx 11
addx -10
addx 4
addx 1
noop
addx 2
addx 2
noop
addx 3
noop
addx 3
addx 2
noop
addx 3
addx 2
addx 11
addx -4
addx 2
addx -38
addx -1
addx 2
noop
addx 3
addx 5
addx 2
addx -7
addx 8
addx 2
addx 2
noop
addx 3
addx 5
addx 2
addx -25
addx 26
addx 2
addx 8
addx -1
addx 2
addx -2
addx -37
addx 5
addx 3
addx -1
addx 5
noop
addx 22
addx -21
addx 2
addx 5
addx 2
addx 13
addx -12
addx 4
noop
noop
addx 5
addx 1
noop
noop
addx 2
noop
addx 3
noop
noop

6
day10/input_crt.txt Normal file
View File

@@ -0,0 +1,6 @@
###..#..#..##..#..#.#..#.###..####.#..#.
#..#.#..#.#..#.#.#..#..#.#..#.#....#.#..
#..#.#..#.#..#.##...####.###..###..##...
###..#..#.####.#.#..#..#.#..#.#....#.#..
#.#..#..#.#..#.#.#..#..#.#..#.#....#.#..
#..#..##..#..#.#..#.#..#.###..####.#..#.

115
day11/day11.jl Normal file
View File

@@ -0,0 +1,115 @@
#!/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}; part=1)
modulus = prod(m.test_divisor for m in monkeys)
for m in monkeys
for item in m.items
new_value = m.op(item, m.op_value)
if part == 1
new_value = Int(floor(new_value / 3))
else
new_value = mod(new_value, modulus)
end
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, part=1)
for _ in 1:rounds
simian_shenanigans(monkeys, part=part)
end
return prod(sort([m.inspected for m in monkeys])[end-1:end])
end
function test()
@testset "monkey business 1" verbose=true begin
@test monkey_business(read_monkeys("example.txt")) == 10605
@test monkey_business(read_monkeys("input.txt")) == 64032
end
@testset "monkey business 2" verbose=true begin
@test monkey_business(
read_monkeys("example.txt"), rounds=10000, part=2) == 2713310158
@test monkey_business(
read_monkeys("input.txt"), rounds=10000, part=2) == 12729522272
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 1 ",
monkey_business(monkeys, rounds=20, part=1))
monkeys = read_monkeys(infile)
println("monkey business 2 ",
monkey_business(monkeys, rounds=10000, part=2))
end
end
main()

27
day11/example.txt Normal file
View File

@@ -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

55
day11/input.txt Normal file
View File

@@ -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