Hi Everyone! here I show you my solution for Day 10.
It was fun and it allowed me to show an interesting programming pattern, that I do not see around very commonly: We can have a list of possible cases so that we can grow our set of available parenthesis.
In particular, in 42 we can hard code the list and then use metaprogramming at a later stage to update the list with more cases. That is, while executing a specific version of the code we can be certain of the behavior, but when we can sill extend the code behavior on need.
You can also see a video comment on this code here
(https://www.youtube.com/watch?v=F7SZrh4HxsU)
reuse [L42.is/AdamsTowel] Fs = Load:{reuse [L42.is/FileSystem]} Split={class method S.List (S that)=\()( for c in that.replace(S"" with=S",").split(S",")\add(c) )} PopMax ={class method Num (mut Num.List that)=( var i = 0I, var e = 0Num for ei in that, ii in Range(that.size()) if ei>e ( e:=ei, i:=ii ) that.remove(i) e )} Sort ={class method Num.List (mut Num.List that)=\()( while !that.isEmpty() \add(PopMax(that)) )} Par=Organize:{ $ = {interface [HasToS] class method S open() class method S close() method Num points1() method Num points2() class method Bool fitsO(S that) class method Bool fitsC(S that) method $ next() method $ push(S that)[$] class method This ($ that) } Round$={[$]}, Square$={[$]}, Curly$={[$]}, Angle$={[$]} ParB=Data.AddList:Data:{class $ par} Pars={@Cache.Lazy class method ParB.List() = \[\(par=Round$);\(par=Square$);\(par=Curly$);\(par=Angle$);]} ParTrait = Trait:{[$] method fitsO(that)=that==\open method fitsC(that)=that==\close class method This($ next) method (that)=This(next=that) method push(that)={ if This.fitsC(that) return \next for (par) in Pars() (if par.fitsO(that) return par(this)) for (par) in Pars() (if par.fitsC(that) exception par(this)) error X"Unexpected %that" } } Round = Class:Data:ParTrait:{[$] method open()=S"(",,,method close()=S")" method points1()=3\,,,method points2()=1\ } Square = Class:Data:ParTrait:{[$] method open()=S"[",,,method close()=S"]" method points1()=57\,,,method points2()=2\ } Curly = Class:Data:ParTrait:{[$] method open()=S"{",,,method close()=S"}" method points1()=1197\,,,method points2()=3\ } Angle = Class:Data:ParTrait:{[$] method open()=S"<",,,method close()=S">" method points1()=25137\,,,method points2()=4\ } End = Class:Data:ParTrait:{[$] method open()=S"@",,,method close()=S"@" method points1()=0\,,,method points2()=0\ class method This($ next)=This() method next()=this } } Main = ( var points1 = 0Num ps = Num.List() for line in Fs.Real.#$of().read(\"input").split(S.nl()) ( var points2 = 0Num var Par par = Par.End() for c in Split(line) ( par:= par.push(c) ) catch Par p ( points1+=p.points1() ) while par.points1()!=0Num ( points2:=(points2*5Num)+par.points2() par:=par.next() ) ps.add(points2) ) Debug(S"Part1 %points1")//464991 Debug(S"Part2 %Sort(ps).val(\size/2I)")//3662008566 )
What do you think about this style of coding?
Top comments (0)