Module:User:Cscott/Advent Of Code 2023/Day 16
Appearance
From Wikipedia, the free encyclopedia
You might want to create a documentation page for this Scribunto module.
Editors can experiment in this module's sandbox (create | mirror) and testcases (create) pages.
Add categories to the /doc subpage. Subpages of this module.
Editors can experiment in this module's sandbox (create | mirror) and testcases (create) pages.
Add categories to the /doc subpage. Subpages of this module.
return(function() localbuilders={} localfunctionregister(name,f) builders[name]=f end register('llpeg',function()returnrequire[[Module:User:Cscott/llpeg]]end) register('day16',function(myrequire) --[[ DAY 16 ]]-- locall=myrequire('llpeg') --[[ PARSING ]]-- localSpot={} Spot.__index=Spot functionSpot:new(args) returnsetmetatable(args,self) end functionSpot:is_mirror()returnself.char=='/'orself.char=='\\'end functionSpot:is_splitter()returnself.char=='-'orself.char=='|'end functionSpot:is_empty()returnself.char=='.'end functionSpot:__tostring() returnself.char end localnl=l.P"\n" functionmake_spot(s) returnSpot:new{char=s} end localpatt=l.P{ "Graph", Graph=l.Ct(l.V"Row"*(nl^1*l.V"Row")^0*nl^0)*-1, Row=l.Ct(l.V"Spot"^1), Spot=l.S".\\/-|"/make_spot, } localGraph={} Graph.__index=Graph functionparse(source) --print(inspect(source)) localast,errlabel,pos=patt:match(source) ifnotastthen error(string.format("Error at pos %s label '%s'",pos,errlabel)) end --print('Parsed with success!') --print(inspect(ast)) returnGraph:new(ast) end --[[ Part 1 ]]-- functionGraph:new(data) returnsetmetatable({data=data},self) end functionGraph:at(row,col,default) return(self.data[row]or{})[col]ordefault end functionGraph:rowN() return#(self.data) end functionGraph:colN() return#(self.data[1]) end functionGraph:print() forr,rowinipairs(self.data)do forc,valinipairs(row)do ifval==nilthen val=" " elseifval.energizedthen val="#" end io.write(tostring(val)) end io.write("\n") end end functionGraph:link() forr=1,self:rowN()do forc=1,self:colN()do localsp=self:at(r,c) sp.r,sp.c=r,c ifr>1thensp.n=self:at(r-1,c)end ifc>1thensp.w=self:at(r,c-1)end ifr<self:rowN()thensp.s=self:at(r+1,c)end ifc<self:colN()thensp.e=self:at(r,c+1)end end end end functionGraph:clearAndScore() localsum=0 forr=1,self:rowN()do forc=1,self:colN()do localsp=self:at(r,c) ifsp.energizedthen 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 returnsum end localmirror_effect={ -- east becomes north, north -> east, south-west, west-south ['/']={e='n',n='e',s='w',w='s'}, -- east becomes south, south->east, north->west, west->north ['\\']={e='s',s='e',n='w',w='n'}, ['|']={e='ns',w='ns',n='n',s='s'}, ['-']={e='e',w='w',n='ew',s='ew'}, ['.']={n='n',e='e',s='s',w='w'}, } functionray_cast(sp,dir) ifsp['seen_'..dir]~=nilthenreturnend sp.energized=true sp['seen_'..dir]=true localndir=mirror_effect[sp.char][dir] if#ndir==1then localnsp=sp[ndir] ifnsp~=nilthen returnray_cast(nsp,ndir)-- tail call end else fori=1,#ndirdo localnsp=sp[ndir:sub(i,i)] ifnsp~=nilthen ray_cast(nsp,ndir:sub(i,i)) end end end end functionpart1(source) localgraph=parse(source) graph:link() --graph:print() --print() ray_cast(graph:at(1,1),"e") --graph:print() returngraph:clearAndScore() end functionpart2(source) localgraph=parse(source) graph:link() localmax=0 localfunctioncheck(r,c,dir) ray_cast(graph:at(r,c),dir) localscore=graph:clearAndScore() ifscore>maxthenmax=scoreend end forr=1,graph:rowN()do check(r,1,"e") check(r,graph:colN(),"w") end forc=1,graph:colN()do check(1,c,"s") check(graph:rowN(),c,"n") end returnmax end --[[ CLI ] ]-- local source = io.input("day16.input"):read("a") print('Sum:', part1(source)) print('Sum:', part2(source)) --[ [ END CLI ]]-- return{ part1=function(frame) locals=mw.title.new(frame.args[1]):getContent() returnpart1(s) end, part2=function(frame) locals=mw.title.new(frame.args[1]):getContent() returnpart2(s,tonumber(frame.args[2])) end, } end) localmodules={} modules['table']=require('table') modules['string']=require('string') modules['strict']={} localfunctionmyrequire(name) ifmodules[name]==nilthen modules[name]=true modules[name]=(builders[name])(myrequire) end returnmodules[name] end returnmyrequire('day16') end)()