day 19 part 1

This commit is contained in:
Felix Van der Jeugt 2021-12-19 14:48:42 +01:00
parent 1660ee2536
commit 76bdf2cfdd
No known key found for this signature in database
GPG Key ID: 58B209295023754D

194
day19/part1.lua Executable file
View File

@ -0,0 +1,194 @@
#!/usr/bin/env luajit
require("utils")
require("pqueue")
local scanners = {}
local scanner = {}
for line in io.lines(arg[3]) do
if #line == 0 then
table.insert(scanners, scanner)
scanner = {}
elseif char(line, 2) == "-" then
else
local x, y, z = unpack(split(line, ","))
local beacon = { x = tonumber(x)
, y = tonumber(y)
, z = tonumber(z) }
-- , q = pqueue() }
table.insert(scanner, beacon)
end
end
table.insert(scanners, scanner)
for _, scanner in pairs(scanners) do
for i = 1, #scanner do
for j = i + 1, #scanner do
local d = (scanner[i].x - scanner[j].x) ^ 2
+ (scanner[i].y - scanner[j].y) ^ 2
+ (scanner[i].z - scanner[j].z) ^ 2
-- scanner[i].q:add(d)
-- if #scanner[i].q.items > 4 then scanner[i].q:pop() end
-- scanner[j].q:add(d); scanner[j].q:pop()
-- if #scanner[j].q.items > 4 then scanner[j].q:pop() end
end
end
end
local function minp(a, b)
return { x = a.x - b.x, y = a.y - b.y, z = a.z - b.z }
end
local function addp(a, b)
return { x = a.x + b.x, y = a.y + b.y, z = a.z + b.z }
end
local rotations = { function(p) return { x = p.x, y = p.y, z = p.z } end
, function(p) return { x = p.x, y = p.z, z = -p.y } end
, function(p) return { x = p.x, y = -p.y, z = -p.z } end
, function(p) return { x = p.x, y = -p.z, z = p.y } end
, function(p) return { x = p.y, y = -p.x, z = p.z } end
, function(p) return { x = p.y, y = p.z, z = p.x } end
, function(p) return { x = p.y, y = p.x, z = -p.z } end
, function(p) return { x = p.y, y = -p.z, z = -p.x } end
, function(p) return { x = -p.x, y = -p.y, z = p.z } end
, function(p) return { x = -p.x, y = -p.z, z = -p.y } end
, function(p) return { x = -p.x, y = p.y, z = -p.z } end
, function(p) return { x = -p.x, y = p.z, z = p.y } end
, function(p) return { x = -p.y, y = p.x, z = p.z } end
, function(p) return { x = -p.y, y = -p.z, z = p.x } end
, function(p) return { x = -p.y, y = -p.x, z = -p.z } end
, function(p) return { x = -p.y, y = p.z, z = -p.x } end
, function(p) return { x = p.z, y = p.y, z = -p.x } end
, function(p) return { x = p.z, y = p.x, z = p.y } end
, function(p) return { x = p.z, y = -p.y, z = p.x } end
, function(p) return { x = p.z, y = -p.x, z = -p.y } end
, function(p) return { x = -p.z, y = -p.y, z = -p.x } end
, function(p) return { x = -p.z, y = -p.x, z = p.y } end
, function(p) return { x = -p.z, y = p.y, z = p.x } end
, function(p) return { x = -p.z, y = p.x, z = -p.y } end
}
local function eqp(a, b)
return a.x == b.x and a.y == b.y and a.z == b.z
end
local function rotate(a, r)
local b = {}
for _, p in pairs(a) do
table.insert(b, r(p))
end
return b
end
local function move(a, d)
local b = {}
for _, p in pairs(a) do
table.insert(b, { x = p.x + d.x
, y = p.y + d.y
, z = p.z + d.z })
end
return b
end
local function similar(a, b)
local counter = 0
for i, pa in pairs(a) do
for j, pb in pairs(b) do
if eqp(pa, pb) then
counter = counter + 1
break
end
end
if counter >= 12 then
return counter
end
end
return 0
end
function compare(a, b)
for _, r in pairs(rotations) do
local br = rotate(b, r)
for _, pa1 in pairs(a) do
for _, pb1 in pairs(br) do
local d = minp(pa1, pb1)
local b_ = move(br, d)
if similar(a, b_) >= 12 then
return b_, d
end
end
end
end
return nil
end
-- printtable(scanners[2])
-- printtable(move(rotate(scanners[2],
-- {x="x", y="y", z="z"},
-- {x=-1, y=1, z=-1}),
-- {x=68, y=-1246, z=-43}))
-- print(similar(scanners[1], move(rotate(scanners[2],
-- {x="x", y="y", z="z"},
-- {x=-1, y=1, z=-1}),
-- {x=68, y=-1246, z=-43})))
-- print(compare(scanners[1], scanners[2]))
-- printtable(compare(scanners[1], scanners[2]))
-- for _, a in pairs(scanners) do
-- for _, b in pairs(scanners) do
-- moved = compare(a, b)
-- if moved == nil then
-- io.write(string.format("%3d", 0))
-- else
-- io.write(string.format("%3d", similar(a, moved)))
-- end
-- end
-- io.write("\n")
-- end
local beacons = {}
local counter = 0
local function countbeacons(scanner)
for _, b in pairs(scanner) do
local xs = beacons[b.x] or {}
local ys = xs[b.y] or {}
if ys[b.z] == nil then
ys[b.z] = true
counter = counter + 1
end
xs[b.y] = ys
beacons[b.x] = xs
end
end
local compareWiths = { scanners[1] }
local todos = { unpack(scanners, 2) }
while #todos > 0 do
print(#todos)
for _, scanner in pairs(compareWiths) do
countbeacons(scanner)
end
local newCompareWiths = {}
local newtodos = {}
for _, todo in pairs(todos) do
local found, d = nil
for _, compareWith in pairs(compareWiths) do
found, d = compare(compareWith, todo)
if found then break end
end
if found then
table.insert(newCompareWiths, found)
else
table.insert(newtodos, todo)
end
end
todos = newtodos
compareWiths = newCompareWiths
end
for _, scanner in pairs(compareWiths) do
countbeacons(scanner)
end
print(counter)