Initial commit
This commit is contained in:
commit
cd6cc0be1e
73 files changed
+10338
No files matched your search
@@ -0,0 +1,116 @@
|
||||
using Pkg
|
||||
Pkg.add("Match")
|
||||
using Match
|
||||
|
||||
include("utils.jl")
|
||||
|
||||
function parse_input(filename)
|
||||
reverse(collect(collect(non_empty_lines(filename))[1]))
|
||||
end
|
||||
|
||||
mutable struct BinaryReader
|
||||
input
|
||||
rest
|
||||
BinaryReader(input) = new(input, [])
|
||||
end
|
||||
|
||||
function fill_rest(reader)
|
||||
char = pop!(reader.input)
|
||||
code = codepoint(char)
|
||||
number = code < 0x3A ? code - 0x30 : code - (0x41 - 10)
|
||||
reader.rest = reverse(parse.(Int, collect(string(number, base=2, pad=4))))
|
||||
end
|
||||
|
||||
function read_bits(reader, count)
|
||||
result = []
|
||||
while length(result) < count
|
||||
if length(reader.rest) == 0
|
||||
fill_rest(reader)
|
||||
end
|
||||
push!(result, pop!(reader.rest))
|
||||
end
|
||||
result
|
||||
end
|
||||
|
||||
function reader_length(reader)
|
||||
length(reader.rest) + length(reader.input) * 4
|
||||
end
|
||||
|
||||
function to_int(bits)
|
||||
parse(Int, reduce(*, string.(bits)), base=2)
|
||||
end
|
||||
|
||||
function parse_literal(reader, version)
|
||||
result = []
|
||||
cont = 1
|
||||
while cont == 1
|
||||
cont = read_bits(reader, 1)[1]
|
||||
result = [result; read_bits(reader, 4)]
|
||||
end
|
||||
(version, 4, to_int(result))
|
||||
end
|
||||
|
||||
function parse_operator(reader, version, type)
|
||||
length_type = read_bits(reader, 1)[1]
|
||||
subpackets = []
|
||||
if length_type == 0
|
||||
subpacket_bits = to_int(read_bits(reader, 15))
|
||||
start_remaining = reader_length(reader)
|
||||
while reader_length(reader) + subpacket_bits > start_remaining
|
||||
push!(subpackets, parse_packet(reader))
|
||||
end
|
||||
else
|
||||
subpacket_count = to_int(read_bits(reader, 11))
|
||||
for _ in 1:subpacket_count
|
||||
push!(subpackets, parse_packet(reader))
|
||||
end
|
||||
end
|
||||
(version, type, subpackets)
|
||||
end
|
||||
|
||||
function parse_packet(reader)
|
||||
version = to_int(read_bits(reader, 3))
|
||||
type = to_int(read_bits(reader, 3))
|
||||
if type == 4
|
||||
parse_literal(reader, version)
|
||||
else
|
||||
parse_operator(reader, version, type)
|
||||
end
|
||||
end
|
||||
|
||||
function sum_versions(packet)
|
||||
result = packet[1]
|
||||
if packet[2] != 4
|
||||
result += reduce(+, sum_versions.(packet[3]))
|
||||
end
|
||||
result
|
||||
end
|
||||
|
||||
function solution16_1()
|
||||
input = parse_input("16.data")
|
||||
reader = BinaryReader(input)
|
||||
packet = parse_packet(reader)
|
||||
sum_versions(packet)
|
||||
end
|
||||
|
||||
function value(packet)
|
||||
@match packet[2] begin
|
||||
0 => reduce(+, value.(packet[3]))
|
||||
1 => reduce(*, value.(packet[3]))
|
||||
2 => reduce(min, value.(packet[3]))
|
||||
3 => reduce(max, value.(packet[3]))
|
||||
4 => packet[3]
|
||||
5 => value(packet[3][1]) > value(packet[3][2]) ? 1 : 0
|
||||
6 => value(packet[3][1]) < value(packet[3][2]) ? 1 : 0
|
||||
7 => value(packet[3][1]) == value(packet[3][2]) ? 1 : 0
|
||||
end
|
||||
end
|
||||
|
||||
function solution16_2()
|
||||
input = parse_input("16.data")
|
||||
reader = BinaryReader(input)
|
||||
packet = parse_packet(reader)
|
||||
value(packet)
|
||||
end
|
||||
|
||||
solution16_2()
|
||||
Reference in new issue
Block a user