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 :-/ ) )  • 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))))  • 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()  or for coord in myCoord.near8() val in map.near8(myCoord) ( .. )  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$$ )


or

res=Match.CountDouble()( for v in list (\add(v) \times(2\) )