DEV Community

Marco Servetto
Marco Servetto

Posted on

Advent of code Day 11

This was a nice puzzle, I appreciate the short input, so that I can simply cut-pasting into a multiline string.
Thanks to this experience I'm getting more and more feedback on what I should add to AdamsTowel. See after the code for details:

reuse [L42.is/AdamsTowel]
Split={class method S.List (S that)=\()(
  for c in that.replace(S"" with=S",").split(S",")\add(c)
  )}
Matrix=Collection.matrix(I.List,row=10I,col=10I)
Coords = Collection.list(Matrix.Coord)
Near={class method Coords (Matrix.Coord that) = Coords()(
  for r in Range(I"-1" to=2I)
    for c in Range(I"-1" to=2I)
      if r!=0I || c!=0I (
        new = that.with(row=\row+r).with(col=\col+c)
        catch error Any _ void
        \add(new)
        )
  )}
Step={
  class method I (mut Matrix that)=(
    for var v in that ( v+=1I )
    \flashes(m=that)
    )
  class method I flashes(mut Matrix m) = {
    flashes=Match.Count()(
      for c in m.coords() var v in m if v>9I (
        \add(\.true())
        v:=0I
        for n in Near(c) (
          vi = m.val(n) 
          if vi!=0I m.set(n val=vi+1I)
          )
        ))
    if flashes==0I return 0I
    return flashes+\flashes(m=m)
    }
  }
Main11=(
  input=S"""
    |3113284886
    |2851876144
    |2774664484
    |6715112578
    |7146272153
    |6256656367
    |3148666245
    |3857446528
    |7322422833
    |8152175168
  """
  m1=Matrix(\()(for l in input.split(S.nl())
    for s in Split(l) \add(I(string=s))))
  var tot = 0I
  for i in Range(100I) ( tot+=Step(m1) )
  Debug(tot)//1705  
  m2=Matrix(\()(for l in input.split(S.nl())
    for s in Split(l) \add(I(string=s))))
  for i in Range.unbounded() if Step(m2)==100I (
    Debug(i+1I)//of course the puzzle wants it
    Break()//starting from one, so 265 not 264 :-/
    )
  )
Enter fullscreen mode Exit fullscreen mode
  • Splitting on all characters seams to be very common, so I should add it to my spliterators. for example we could have
m1=Matrix(\()(for l in input.split(S.nl())
    for s in l.split() \add(I(string=s))))
Enter fullscreen mode Exit fullscreen mode
  • Near elements of matrixes are quite a common feature too, ideally I would like to allow either:
for (coord,val) in myCoord.near8(map) ( .. ) //or near4()
Enter fullscreen mode Exit fullscreen mode

or

for coord in myCoord.near8() val in map.near8(myCoord) ( .. )
Enter fullscreen mode Exit fullscreen mode

What would be better? the first one requires boxing objects, the second requires two iterations and thus double checks for what coordinates actually are in the range.

  • Should I change Match.Count to offer \addOne,\addIf(Bool that) \add(I that) and may be other operations like \times and \divide ? If so, that would remove the need to make an Accumulator for I... but what about Num and Math.Long? or even Math.Double?? That is, do we want to write
res=Double.Count()( for v in list (\add(v) \times(2\) )
Enter fullscreen mode Exit fullscreen mode

or

res=Match.CountDouble()( for v in list (\add(v) \times(2\) )
Enter fullscreen mode Exit fullscreen mode

Top comments (0)