day 16, part 2!
This commit is contained in:
parent
1ef198fd5e
commit
20578ca8de
181
12023/16/16.lua
181
12023/16/16.lua
|
@ -12,50 +12,48 @@ for line in io.lines() do
|
||||||
local char = line:sub(c,c)
|
local char = line:sub(c,c)
|
||||||
if char:match("[^%.]") then
|
if char:match("[^%.]") then
|
||||||
map[r][c] = char
|
map[r][c] = char
|
||||||
print(char, c,r)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
r = r + 1
|
r = r + 1
|
||||||
end
|
end
|
||||||
local height = r-1
|
local height = r-1
|
||||||
print(width, height)
|
|
||||||
|
|
||||||
function coord(x,y)
|
function coord(x,y)
|
||||||
return y*1000+x
|
return y*1000+x
|
||||||
end
|
end
|
||||||
|
|
||||||
function energize(x, y)
|
function energize(e,x, y)
|
||||||
local c = coord(x,y)
|
local c = coord(x,y)
|
||||||
energized[c] = energized[c] and (energized[c]+1) or 1
|
e[c] = e[c] and (e[c]+1) or 1
|
||||||
end
|
end
|
||||||
|
|
||||||
function mark_energized(xo, yo, xf, yf)
|
function mark_energized(e, xo, yo, xf, yf)
|
||||||
if xo==xf then -- vertical
|
if xo==xf then -- vertical
|
||||||
yo, yf = math.min(yo,yf), math.max(yo,yf)
|
yo, yf = math.min(yo,yf), math.max(yo,yf)
|
||||||
yo = math.max(1,yo)
|
yo = math.max(1,yo)
|
||||||
yf = math.min(height, yf)
|
yf = math.min(height, yf)
|
||||||
for y=yo,yf do
|
for y=yo,yf do
|
||||||
energize(xo,y)
|
energize(e,xo,y)
|
||||||
end
|
end
|
||||||
elseif yo==yf then --horizontal
|
elseif yo==yf then --horizontal
|
||||||
xo, xf = math.min(xo, xf), math.max(xo, xf)
|
xo, xf = math.min(xo, xf), math.max(xo, xf)
|
||||||
xo = math.max(1,xo)
|
xo = math.max(1,xo)
|
||||||
xf = math.min(width, xf)
|
xf = math.min(width, xf)
|
||||||
for x=xo,xf do
|
for x=xo,xf do
|
||||||
energize(x,yo)
|
energize(e,x,yo)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function count_energized()
|
function count_energized(e)
|
||||||
local count = 0
|
local count = 0
|
||||||
for c,v in pairs(energized) do
|
for c,v in pairs(e) do
|
||||||
count = count + 1
|
count = count + 1
|
||||||
end
|
end
|
||||||
return count
|
return count
|
||||||
end
|
end
|
||||||
|
|
||||||
function next_beams(xs,ys,dx,dy,char)
|
function next_beams(xs,ys,dx,dy,char,conditions)
|
||||||
if not char then return nil end
|
if not char then return nil end
|
||||||
local cond = table.concat(com(xs,ys,dx,dy),",")
|
local cond = table.concat(com(xs,ys,dx,dy),",")
|
||||||
if conditions[cond] then return nil
|
if conditions[cond] then return nil
|
||||||
|
@ -93,15 +91,27 @@ function next_beams(xs,ys,dx,dy,char)
|
||||||
end
|
end
|
||||||
elseif char=="/" then --mirrors
|
elseif char=="/" then --mirrors
|
||||||
if dx~=0 then
|
if dx~=0 then
|
||||||
table.insert(beams, com(xs, ys-dx, 0, -dx))
|
ny = ys - dx
|
||||||
|
if ny>=1 and ny<=height then
|
||||||
|
table.insert(beams, com(xs, ny, 0, -dx))
|
||||||
|
end
|
||||||
elseif dy~=0 then
|
elseif dy~=0 then
|
||||||
table.insert(beams, com(xs-dy, ys, -dy, 0))
|
nx = xs - dy
|
||||||
|
if nx>=1 and nx<=width then
|
||||||
|
table.insert(beams, com(nx, ys, -dy, 0))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
elseif char=="\\" then
|
elseif char=="\\" then
|
||||||
if dx~=0 then
|
if dx~=0 then
|
||||||
table.insert(beams, com(xs, ys+dx, 0, dx))
|
ny = ys+dx
|
||||||
|
if ny>=1 and ny<=height then
|
||||||
|
table.insert(beams, com(xs, ny, 0, dx))
|
||||||
|
end
|
||||||
elseif dy~=0 then
|
elseif dy~=0 then
|
||||||
table.insert(beams, com(xs+dy, ys, dy, 0))
|
nx = xs + dy
|
||||||
|
if nx>=1 and nx<=width then
|
||||||
|
table.insert(beams, com(nx, ys, dy, 0))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return beams
|
return beams
|
||||||
|
@ -110,64 +120,99 @@ end
|
||||||
com = table.pack
|
com = table.pack
|
||||||
exp = table.unpack
|
exp = table.unpack
|
||||||
|
|
||||||
energized = {}
|
|
||||||
local beams = {}
|
|
||||||
conditions = {}
|
|
||||||
table.insert(beams, com(1,1,1,0))
|
|
||||||
--table.insert(beams, com(3,9,-1,0))
|
|
||||||
|
|
||||||
repeat
|
function activate(x, y, dx, dy)
|
||||||
local beam = table.remove(beams)
|
local beams = {}
|
||||||
local x,y,dx,dy = exp(beam)
|
local energized = {}
|
||||||
print("\nbeam", x, y, dx, dy)
|
local conditions = {}
|
||||||
local xf, yf = 0,0
|
table.insert(beams, com(x,y,dx,dy))
|
||||||
local charf = nil
|
repeat
|
||||||
--search next
|
local beam = table.remove(beams)
|
||||||
if dx~= 0 then
|
local x,y,dx,dy = exp(beam)
|
||||||
local xm = x
|
--print("\nbeam", x, y, dx, dy)
|
||||||
local found = nil
|
local xf, yf = 0,0
|
||||||
repeat
|
local charf = nil
|
||||||
if map[y][xm] then
|
--search next
|
||||||
found = map[y][xm]
|
if dx~= 0 then
|
||||||
else
|
local xm = x
|
||||||
xm = xm + dx
|
local found = nil
|
||||||
end
|
repeat
|
||||||
until found or xm<1 or xm>width
|
if map[y][xm] then
|
||||||
xf, yf = xm, y
|
found = map[y][xm]
|
||||||
charf = found
|
else
|
||||||
elseif dy~= 0 then
|
xm = xm + dx
|
||||||
local ym = y
|
end
|
||||||
local found = nil
|
until found or xm<1 or xm>width
|
||||||
repeat
|
xf, yf = xm, y
|
||||||
if map[ym][x] then
|
charf = found
|
||||||
found = map[ym][x]
|
elseif dy~= 0 then
|
||||||
else
|
local ym = y
|
||||||
ym = ym + dy
|
local found = nil
|
||||||
end
|
repeat
|
||||||
until found or ym<1 or ym>height
|
if map[ym][x] then
|
||||||
xf,yf = x,ym
|
found = map[ym][x]
|
||||||
charf = found
|
else
|
||||||
end
|
ym = ym + dy
|
||||||
|
end
|
||||||
print("found", charf, xf, yf)
|
until found or ym<1 or ym>height
|
||||||
-- mark energized
|
xf,yf = x,ym
|
||||||
mark_energized(x,y,xf,yf)
|
charf = found
|
||||||
local nb = next_beams(xf, yf, dx, dy, charf)
|
|
||||||
if nb then
|
|
||||||
for _, b in ipairs(nb) do
|
|
||||||
table.insert(beams, b)
|
|
||||||
end
|
end
|
||||||
end
|
|
||||||
until #beams==0
|
|
||||||
|
|
||||||
|
--print("found", charf, xf, yf)
|
||||||
|
-- mark energized
|
||||||
|
mark_energized(energized,x,y,xf,yf)
|
||||||
|
local nb = next_beams(xf, yf, dx, dy, charf, conditions)
|
||||||
|
if nb then
|
||||||
|
for _, b in ipairs(nb) do
|
||||||
|
table.insert(beams, b)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
until #beams==0
|
||||||
|
|
||||||
for y=1,height do
|
--[[
|
||||||
local s = ""
|
for y=1,height do
|
||||||
for x=1,width do
|
local s = ""
|
||||||
local char = energized[coord(x,y)] and "#" or "."
|
for x=1,width do
|
||||||
s = s..char
|
local char = energized[coord(x,y)] and "#" or "."
|
||||||
|
s = s..char
|
||||||
|
end
|
||||||
|
print(s)
|
||||||
end
|
end
|
||||||
print(s)
|
--]]
|
||||||
|
return count_energized(energized)
|
||||||
end
|
end
|
||||||
|
|
||||||
print("part 1", count_energized())
|
|
||||||
|
print("part 1", activate(1,1,1,0))
|
||||||
|
|
||||||
|
local max = 0
|
||||||
|
local max_conds = com(0,0,0,0)
|
||||||
|
|
||||||
|
-- from the top and bottom
|
||||||
|
for x=1,width do
|
||||||
|
local r = activate(x,1,0,1)
|
||||||
|
if r>max then
|
||||||
|
max, max_conds = r, com(x,1,0,1)
|
||||||
|
end
|
||||||
|
r = activate(x,height,0,-1)
|
||||||
|
if r>max then
|
||||||
|
max, max_conds = r, com(x,height,0,-1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- from the left and right
|
||||||
|
for y=1,height do
|
||||||
|
local r = activate(1,y,1,0)
|
||||||
|
if r>max then
|
||||||
|
max, max_conds = r, com(1,y,1,0)
|
||||||
|
end
|
||||||
|
r = activate(width,y,-1,0)
|
||||||
|
if r>max then
|
||||||
|
max, max_conds = r, com(width,y,-1,0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
print(table.concat(max_conds,","))
|
||||||
|
print("part 2", max)
|
||||||
|
|
Loading…
Reference in New Issue