Advent of code, Day 10
Tags: adventofcode, adventofcode2021, 42, programming
Published: 2021-12-10 11:22:11

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?