-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathday20.lua
More file actions
150 lines (119 loc) · 3.59 KB
/
day20.lua
File metadata and controls
150 lines (119 loc) · 3.59 KB
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
require 'util'
DAY = 20
local filename = string.format("inputs/input_%02d.txt", DAY)
local f = assert(io.open(filename, "r"))
-- Function definitions here
local modules = {}
for line in f:lines() do
-- Process the file here
local type = line:sub(1, 1)
local outputs = split(line, ", ", line:find("-> ") + 3)
local ot = {}
for o in outputs do
ot[#ot + 1] = o
end
if type == "%" then
-- Flip-Flop
local name = line:match("([%a]+) %->")
local module = { outputs = ot, state = "off", inputs = {} }
function module:process(from, sig)
if sig == "low" then
local outPulse
if self.state == "off" then
-- Turn on and send out high pulses
self.state = "on"
outPulse = "high"
else
-- Turn off and send out low pulses
self.state = "off"
outPulse = "low"
end
local res = {}
for _, o in ipairs(self.outputs) do
res[#res + 1] = { o, outPulse, name }
end
return res
elseif sig == "high" then
return {}
end
end
modules[name] = module
elseif type == "&" then
-- Conjuction
local name = line:match("&([%a]+) %->")
local module = { outputs = ot, inputs = {} }
function module:process(from, sig)
self.inputs[from] = sig
local outPulse = "low"
for _, v in pairs(self.inputs) do
if v == "low" then
outPulse = "high"
end
end
local res = {}
for _, o in ipairs(self.outputs) do
res[#res + 1] = { o, outPulse, name }
end
return res
end
modules[name] = module
elseif type == "b" then
-- Broadcaster - Just returns all of its outputs with the same signal, doesn't need state
modules["broadcaster"] = {
outputs = ot,
inputs = {},
process = function(self, from, sig)
local res = {}
for _, o in ipairs(self.outputs) do
res[#res + 1] = { o, sig, "broadcaster" }
end
return res
end
}
end
end
for k, m in pairs(modules) do
for _, o in ipairs(m.outputs) do
if modules[o] then
modules[o].inputs[k] = "low"
end
end
end
-- Do everything else here
local part1 = 0
local part2 = 0
local moduleQ = {}
local countHigh = 0
local countLow = 0
local function sendSignal(s)
local m, type = modules[s[1]], s[2]
if type == "low" then
countLow = countLow + 1
elseif type == "high" then
countHigh = countHigh + 1
end
for i, v in ipairs(m:process(s[3], type)) do
table.insert(moduleQ, v)
end
while #moduleQ > 0 do
local cur = table.remove(moduleQ, 1)
local m, type = modules[cur[1]], cur[2]
if type == "low" then
countLow = countLow + 1
elseif type == "high" then
countHigh = countHigh + 1
end
if m then
for i, v in ipairs(m:process(cur[3], type)) do
table.insert(moduleQ, v)
end
end
end
end
for i = 1, 1000 do
sendSignal({ "broadcaster", "low", "button" })
end
part1 = countHigh * countLow
part2 = math.floor(lcm(lcm(4021, 4013), lcm(3889, 3881)))
print("Part 1:", part1)
print("Part 2:", part2)