return (functionlocal builders = local function register(name, f) builders[name] = fendregister('llpeg', function return require end)
register('day16', function(myrequire)--DAY 16 --local l = myrequire('llpeg')
--PARSING --local Spot = Spot.__index = Spotfunction Spot:new(args) return setmetatable(args, self)endfunction Spot:is_mirror return self.char
'\\' endfunction Spot:is_splitter return self.char
'|' endfunction Spot:is_empty return self.char
local nl = l.P"\n"
function make_spot(s) return Spot:newend
local patt = l.P
local Graph = Graph.__index = Graph
function parse(source) --print(inspect(source)) local ast, errlabel, pos = patt:match(source) if not ast then error(string.format("Error at pos %s label '%s'", pos, errlabel)) end --print('Parsed with success!') --print(inspect(ast)) return Graph:new(ast)end
--Part 1 --
function Graph:new(data) return setmetatable(self)end
function Graph:at(row,col,default) return (self.data[row] or)[col] or defaultend
function Graph:rowN return #(self.data)end
function Graph:colN return #(self.data[1])end
function Graph:print for r,row in ipairs(self.data) do for c,val in ipairs(row) do if val
function Graph:link for r=1,self:rowN do for c=1,self:colN do local sp = self:at(r,c) sp.r, sp.c = r,c if r > 1 then sp.n = self:at(r-1,c) end if c > 1 then sp.w = self:at(r,c-1) end if r < self:rowN then sp.s = self:at(r+1,c) end if c < self:colN then sp.e = self:at(r,c+1) end end endend
function Graph:clearAndScore local sum = 0 for r=1,self:rowN do for c=1,self:colN do local sp = self:at(r,c) if sp.energized then sum = sum + 1 sp.energized = nil sp.seen_n = nil sp.seen_e = nil sp.seen_w = nil sp.seen_s = nil end end end return sumend
local mirror_effect =
function ray_cast(sp, dir) if sp['seen_'..dir] ~= nil then return end sp.energized = true sp['seen_'..dir] = true local ndir = mirror_effect[sp.char][dir] if #ndir
function part1(source) local graph = parse(source) graph:link --graph:print --print ray_cast(graph:at(1,1),"e") --graph:print return graph:clearAndScoreend
function part2(source) local graph = parse(source) graph:link local max = 0 local function check(r,c,dir) ray_cast(graph:at(r,c),dir) local score = graph:clearAndScore if score > max then max = score end end for r=1,graph:rowN do check(r,1,"e") check(r,graph:colN,"w") end for c=1,graph:colN do check(1,c,"s") check(graph:rowN,c,"n") end return maxend
--CLI ]--local source = io.input("day16.input"):read("a")print('Sum:', part1(source))print('Sum:', part2(source))--[[ END CLI ]]--
return
end)
local modules = modules['table'] = require('table')modules['string'] = require('string')modules['strict'] = local function myrequire(name) if modules[name]