Compare commits
2 Commits
7e411a5e42
...
503ecd1c04
Author | SHA1 | Date |
---|---|---|
Lucidiot | 503ecd1c04 | |
Lucidiot | e064c79542 |
|
@ -0,0 +1,29 @@
|
|||
local start_timestamp = tonumber(io.read('l'))
|
||||
local buses = {}
|
||||
|
||||
-- 'x' is translated to -1
|
||||
io.read('l'):gsub('[^,]*', function (bus) table.insert(buses, tonumber(bus) or -1) end)
|
||||
|
||||
-- Copy and sort the buses, ignoring 'x' for part 1
|
||||
local sorted_buses = {}
|
||||
for _, bus in ipairs(buses) do
|
||||
if bus > 0 then
|
||||
table.insert(sorted_buses, bus)
|
||||
end
|
||||
end
|
||||
table.sort(sorted_buses)
|
||||
|
||||
local function find_bus(timestamp)
|
||||
for _, bus in ipairs(sorted_buses) do
|
||||
if bus > 0 and timestamp % bus == 0 then
|
||||
return bus
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local timestamp, bus_id = start_timestamp - 1, nil
|
||||
repeat
|
||||
timestamp = timestamp + 1
|
||||
bus_id = find_bus(timestamp)
|
||||
until bus_id
|
||||
print(bus_id * (timestamp - start_timestamp))
|
|
@ -0,0 +1,82 @@
|
|||
local instructions = {}
|
||||
|
||||
for line in io.lines() do
|
||||
local name, value = line:match('^(.+) = ([X%d]+)$')
|
||||
table.insert(instructions, {name, value})
|
||||
end
|
||||
|
||||
local function run(func)
|
||||
local context = {mem={}}
|
||||
for _, instruction in ipairs(instructions) do
|
||||
context = func(context, table.unpack(instruction))
|
||||
end
|
||||
|
||||
local sum = 0
|
||||
for _, value in pairs(context.mem) do
|
||||
sum = sum + value
|
||||
end
|
||||
return sum
|
||||
end
|
||||
|
||||
local function part1(context, name, value)
|
||||
if name == 'mask' then
|
||||
context.and_mask = tonumber(value:gsub('X', '1'), 2)
|
||||
context.or_mask = tonumber(value:gsub('X', '0'), 2)
|
||||
else
|
||||
local address = tonumber(name:match('%[(%d+)%]'))
|
||||
context.mem[address] = tonumber(value) & context.and_mask | context.or_mask
|
||||
end
|
||||
return context
|
||||
end
|
||||
|
||||
-- Recursive method that sets both 0 and 1 versions of each X character in an address
|
||||
local function part2_set(context, base_address, value)
|
||||
local found = nil
|
||||
for i = 1, #base_address do
|
||||
if base_address[i] == "X" then
|
||||
found = i
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if not found then
|
||||
context.mem[tonumber(table.concat(base_address), 2)] = value
|
||||
return
|
||||
end
|
||||
|
||||
base_address[found] = '0'
|
||||
part2_set(context, base_address, value)
|
||||
base_address[found] = '1'
|
||||
part2_set(context, base_address, value)
|
||||
base_address[found] = 'X'
|
||||
end
|
||||
|
||||
-- Binary representation of a decimal number
|
||||
local function dectobin(value)
|
||||
local t = {}
|
||||
for i = 36, 1, -1 do
|
||||
t[i] = math.fmod(value, 2)
|
||||
value = math.floor((value - t[i]) / 2)
|
||||
end
|
||||
return table.concat(t)
|
||||
end
|
||||
|
||||
local function part2(context, name, value)
|
||||
if name == 'mask' then
|
||||
context.mask = value
|
||||
return context
|
||||
end
|
||||
|
||||
local base_address = dectobin(tonumber(name:match('%[(%d+)%]')))
|
||||
local masked_address = {}
|
||||
for i = 1, #context.mask do
|
||||
local bit = context.mask:sub(i, i)
|
||||
table.insert(masked_address, bit == "0" and base_address:sub(i, i) or bit)
|
||||
end
|
||||
|
||||
part2_set(context, masked_address, value)
|
||||
return context
|
||||
end
|
||||
|
||||
print(run(part1))
|
||||
print(run(part2))
|
Loading…
Reference in New Issue