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\) )
Top comments (0)