-
Notifications
You must be signed in to change notification settings - Fork 0
/
20.jl
64 lines (63 loc) · 2.31 KB
/
20.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
open("20.txt") do f
to_rx = nothing
broadcast = []
flips::Dict{String, Array{Any}} = Dict()
cons::Dict{String, Array{Any}} = Dict()
for l ∈ eachline(f)
name, _, outputs... = split(l, r" |, ")
"rx" ∈ outputs && (to_rx = name[2:end])
if startswith(l, "broadcaster")
broadcast = split(l, r" |, ")[3:end]
elseif startswith(l, "%")
name, _, outputs... = split(l, r" |, ")
flips[name[2:end]] = [false, outputs]
elseif startswith(l, "&")
name, _, outputs... = split(l, r" |, ")
cons[name[2:end]] = [Dict(), outputs]
end
end
for c ∈ keys(cons)
for (from, (_, outputs)) ∈ flips
for o ∈ outputs
c==o && (cons[c][1][from] = false)
end
end
for (from, (_, outputs)) ∈ cons
for o ∈ outputs
c==o && (cons[c][1][from] = false)
end
end
end
function solve()
lows, highs = 0, 0
cycles::Array{Int} = []
for button ∈ Iterators.countfrom(1)
lows += 1
ins = [(from="broadcast", to=n, pulse=false) for n ∈ broadcast]
while !isempty(ins)
highs += sum([i.pulse for i ∈ ins])
lows += sum([!i.pulse for i ∈ ins])
filter!(s->s.to≠"rx", ins)
outs = []
for i ∈ ins
if i.to ∈ keys(flips)
i.pulse==true && continue
flips[i.to][1] = !flips[i.to][1]
send = flips[i.to][1]
append!(outs, [(from=i.to, to=n, pulse=send) for n ∈ flips[i.to][2]])
else
cons[i.to][1][i.from] = i.pulse
send = !all(values(cons[i.to][1]))
append!(outs, [(from=i.to, to=n, pulse=send) for n ∈ cons[i.to][2]])
end
end
ins = outs
peek = filter(s->(s.to==to_rx && s.pulse), outs)
!isempty(peek) && push!(cycles, button)
length(cycles)==4 && return lcm(cycles)
end
button==1000 && println("Part 1: ", lows*highs)
end
end
println("Part 2: ", solve())
end