1
0
Fork 0

Compare commits

...

2 Commits

Author SHA1 Message Date
Lucidiot 503ecd1c04
2020 day 14 2020-12-14 06:58:07 +01:00
Lucidiot e064c79542
2020 day 13 part 1 2020-12-13 09:00:31 +01:00
3 changed files with 113 additions and 2 deletions

29
2020/13/day13.lua Normal file
View File

@ -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))

82
2020/14/day14.lua Normal file
View File

@ -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))

View File

@ -23,8 +23,8 @@ is acceptable; anything goes as long as I solve it myself!
10 ██ ██ ██
11 ██ ██ ██
12 ██ ██ ██
13 ██
14 ██ ██
13 ██
14 ██ ██ ██
15 ██
16 ██ ██
17 ██