Day 13: Distress Signal
file:src/day13.jl
module Day13
<<function-split-on>>
struct Packet
x
end
function read_input(io::IO)
get_args(x::Int) = x
get_args(x::Vector{Any}) = x .|> get_args
get_args(x::Expr) = x.args |> get_args
[(Packet(get_args(Meta.parse(i))), Packet(get_args(Meta.parse(j))))
for (i, j) in split_on(eachline(io), "")]
end
@enum Check Ok NotOk Continue
compare(a::Int, b::Int) = a < b ? Ok : (a > b ? NotOk : Continue)
compare(a::Int, b::Vector) = compare([a], b)
compare(a::Vector, b::Int) = compare(a, [b])
compare(a::Vector, b::Vector) =
if isempty(a) && isempty(b)
Continue
elseif isempty(a)
Ok
elseif isempty(b)
NotOk
else
let x = compare(a[1], b[1])
if x == Continue
compare(a[2:end], b[2:end])
else
x
end
end
end
Base.:<(a::Packet, b::Packet) = compare(a.x, b.x) == Ok
function main(inp::IO, out::IO)
input = read_input(inp)
part1 = sum(i for (i, (a, b)) in enumerate(input) if a < b)
println(out, "Part 1: $part1")
packets = foldl(vcat, ([a, b] for (a, b) in input))
idx1 = length(filter(p -> p < Packet([[2]]), packets)) + 1
idx2 = length(filter(p -> p < Packet([[6]]), packets)) + 2 # [[2]] is also smaller
part2 = idx1 * idx2
println(out, "Part 2: $part2")
end
end # module