1
0
Fork 0

2020 day 17

What have I done…
This commit is contained in:
Lucidiot 2020-12-17 07:25:02 +01:00
parent 9746694a7b
commit 12d3bd86be
Signed by: lucidiot
GPG Key ID: 3358C1CA6906FB8D
2 changed files with 174 additions and 1 deletions

173
2020/17/day17.lua Normal file
View File

@ -0,0 +1,173 @@
-- Three-dimensional table of cubes.
-- {x={y={z=true}}}
local cubes = {}
-- Four-dimensional!
local hypercube = {}
local i = 0
for line in io.lines() do
i = i + 1
-- Create deep copies immediately
local row, row2 = {}, {}
line:gsub(".", function (c) table.insert(row, {c == '#'}) end)
line:gsub(".", function (c) table.insert(row2, {{c == '#'}}) end)
cubes[i] = row
hypercube[i] = row2
end
local function list_neighbors(x, y, z, w)
local neighbors = {}
for dx = -1, 1 do
for dy = -1, 1 do
for dz = -1, 1 do
if w then
for dw = -1, 1 do
if dx ~= 0 or dy ~= 0 or dz ~= 0 or dw ~= 0 then
table.insert(neighbors, {x+dx, y+dy, z+dz, w+dw})
end
end
else
if dx ~= 0 or dy ~= 0 or dz ~= 0 then
table.insert(neighbors, {x+dx, y+dy, z+dz})
end
end
end
end
end
return neighbors
end
local function count_active(x, y, z)
local total = 0
for _, neighbor in ipairs(list_neighbors(x, y, z)) do
local nx, ny, nz = table.unpack(neighbor)
if cubes[nx] and cubes[nx][ny] and cubes[nx][ny][nz] then
total = total + 1
end
end
return total
end
local function cycle()
local new_cubes = {}
-- Set of new neighboring cubes that will be checked after the first loop
local new_neighbors = {}
for x, row in pairs(cubes) do
new_cubes[x] = {}
for y, column in pairs(row) do
new_cubes[x][y] = {}
for z, state in pairs(column) do
local active = count_active(x, y, z)
new_cubes[x][y][z] = (state and active == 2) or active == 3
-- Load the new neighbors if the cube was active
if state then
for _, neighbor in ipairs(list_neighbors(x, y, z)) do
new_neighbors[neighbor] = true
end
end
end
end
end
for neighbor, _ in pairs(new_neighbors) do
local x, y, z = table.unpack(neighbor)
local active = count_active(x, y, z)
if active == 3 then
if not new_cubes[x] then
new_cubes[x] = {}
end
if not new_cubes[x][y] then
new_cubes[x][y] = {}
end
new_cubes[x][y][z] = true
end
end
cubes = new_cubes
end
for _ = 1, 6 do
cycle()
end
local part1 = 0
for _, row in pairs(cubes) do
for _, column in pairs(row) do
for _, state in pairs(column) do
if state then
part1 = part1 + 1
end
end
end
end
print(part1)
-- I'm lazy as always: copy-pasting half of the code to add the fourth dimension.
local function count_hyper_active(x, y, z, w)
local total = 0
for _, neighbor in ipairs(list_neighbors(x, y, z, w)) do
local nx, ny, nz, nw = table.unpack(neighbor)
if hypercube[nx] and hypercube[nx][ny] and hypercube[nx][ny][nz] and hypercube[nx][ny][nz][nw] then
total = total + 1
end
end
return total
end
-- Mmmhhh… Tasty O(n⁴)
local function hyper_cycle()
local new_hypercube = {}
-- Set of new neighboring cubes that will be checked after the first loop
local new_neighbors = {}
for x, plan in pairs(hypercube) do
new_hypercube[x] = {}
for y, row in pairs(plan) do
new_hypercube[x][y] = {}
for z, column in pairs(row) do
new_hypercube[x][y][z] = {}
for w, state in pairs(column) do
local active = count_hyper_active(x, y, z, w)
new_hypercube[x][y][z][w] = (state and active == 2) or active == 3
-- Load the new neighbors if the cube was active
if state then
for _, neighbor in ipairs(list_neighbors(x, y, z, w)) do
new_neighbors[neighbor] = true
end
end
end
end
end
end
for neighbor, _ in pairs(new_neighbors) do
local x, y, z, w = table.unpack(neighbor)
local active = count_hyper_active(x, y, z, w)
if active == 3 then
if not new_hypercube[x] then
new_hypercube[x] = {}
end
if not new_hypercube[x][y] then
new_hypercube[x][y] = {}
end
if not new_hypercube[x][y][z] then
new_hypercube[x][y][z] = {}
end
new_hypercube[x][y][z][w] = true
end
end
hypercube = new_hypercube
end
for _ = 1, 6 do
hyper_cycle()
end
local part2 = 0
for _, plan in pairs(hypercube) do
for _, row in pairs(plan) do
for _, column in pairs(row) do
for _, state in pairs(column) do
if state then
part2 = part2 + 1
end
end
end
end
end
print(part2)

View File

@ -27,7 +27,7 @@ is acceptable; anything goes as long as I solve it myself!
14 ██ ██ ██
15 ██ ██
16 ██ ██ ██
17 ██
17 ██ ██
18 ██
19
20 ██