-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday16.jl
82 lines (73 loc) · 2.11 KB
/
day16.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
using BitBasis: packbits
struct Packet
version::Int
type::Int
value::Int
children::Vector{Packet}
end
function Base.show(io::IO, p::Packet)
if p.type == 4
print(io, "Packet[v$(p.version), $(p.value)]")
else
print(io, "Packet[v$(p.version), op=$(p.type), children=$(p.children)]")
end
end
function parsebits(bits)
version = packbits(reverse(bits[1:3]))
type = packbits(reverse(bits[4:6]))
if type == 4
buf::Vector{Bool} = []
i = 7
while true
append!(buf, bits[i+1:i+4])
i += 5
if bits[i-5] == 0
break
end
end
return Packet(version, type, packbits(reverse(buf)), []), i-1
else
children = []
start = 0
offset = 0
if bits[7] == 0
# bound by number of bits
start = 23
while offset < packbits(reverse(bits[8:22]))
(packet, consumed) = parsebits(@view bits[(start+offset):end])
offset += consumed
push!(children, packet)
end
else
# bound by number of packets
start = 19
for i ∈ 1:packbits(reverse(bits[8:18]))
(packet, consumed) = parsebits(@view bits[(start+offset):end])
offset += consumed
push!(children, packet)
end
end
return Packet(version, type, 0, children), start+offset-1
end
end
part1(p) = p.version + (p.type == 4 ? 0 : sum(part1.(p.children)))
function part2(p)
c = part2.(p.children)
p.type == 0 && return sum(c)
p.type == 1 && return prod(c)
p.type == 2 && return minimum(c)
p.type == 3 && return maximum(c)
p.type == 4 && return p.value
p.type == 5 && return c[1] > c[2] ? 1 : 0
p.type == 6 && return c[1] < c[2] ? 1 : 0
p.type == 7 && return c[1] == c[2] ? 1 : 0
end
for l ∈ eachline("data/day16.txt")
println("\n", l, "\n")
bits = reverse(digits(Bool, parse(BigInt, l, base=16), base=2, pad=length(l)*4))
packet = parsebits(bits)[1]
# Part 1 - What do you get if you add up the version numbers in all packets?
println("part1 = ", part1(packet))
# Part 2 - What do you get if you evaluate the expression represented by your hexadecimal-encoded BITS transmission?
println("part2 = ", part2(packet))
end