Jump to content
Wikipedia The Free Encyclopedia

Module:User:Cscott/Advent Of Code 2023/Day 16

From Wikipedia, the free encyclopedia
Module documentationcreate purge
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.
 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)()

AltStyle によって変換されたページ (->オリジナル) /