DEV Community 👩‍💻👨‍💻

Marco Servetto
Marco Servetto

Posted on

Advent of code Day 9

I'm very satisfied for my solution today.
This problem fits very well with AdamsTowel matrixes.
You can see a video description of my solution at
(https://www.youtube.com/watch?v=tSTDJlICst8)
Some highlights of the solution:
(1)

(new=that.with(row=\row-1\) catch error Any _ void \add(new))
Enter fullscreen mode Exit fullscreen mode

This is making a new coordinate and adding it to the list under construction. If the coordinate would be outside of the matrix, an error is raised and ignored.
(2)

sizes=I.List()( for i in Range(seeds.size()) 
    \add(Match.Count()(for v in matrix \add(v==i+100I)))
    )
Enter fullscreen mode Exit fullscreen mode

Here we taint the seeds using a number much bigger than any height.
The number can be tracked back as the corresponding seed index.

(3)

GrowBasin={class method Void(mut Matrix matrix)=(
  for c in matrix.coords() var h in matrix {
    if h>=9I return void
    return for ci in Near(c) if matrix.val(ci)>99I return h:=matrix.val(ci)
    }
Enter fullscreen mode Exit fullscreen mode

To grow a basin one step, we search for all the coordinates c of height h; if there is a ci near c that is tainted with a basin number, we taint the current height too.

Here is the full code.

reuse [L42.is/AdamsTowel]

Fs = Load:{reuse[L42.is/FileSystem]}

Matrix = Collection.matrix(I.List,row=100I, col=100I)

Coords = Collection.list(Matrix.Coord)

Split={class method S.List (S that)=\()(//should be in adamsTowel
  for c in that.replace(S"" with=S",").split(S",")\add(c)
  )}
Near={class method Coords (Matrix.Coord that)=Coords()((
  (new=that.with(row=\row-1\) catch error Any _ void \add(new))
  (new=that.with(row=\row+1\) catch error Any _ void \add(new))
  (new=that.with(col=\col-1\) catch error Any _ void \add(new))
  (new=that.with(col=\col+1\) catch error Any _ void \add(new))
  ))}
GrowBasin={class method Void(mut Matrix matrix)=(
  for c in matrix.coords() var h in matrix {
    if h>=9I return void
    return for ci in Near(c) if matrix.val(ci)>99I return h:=matrix.val(ci)
    }
  )}
NeedsMore={class method Bool(read Matrix matrix) = 
  Match.Some()(for e in matrix \add(e<9I))  
  }
PopMax ={class method I (mut I.List that)=(
  var i = 0I
  var e = 0I
  for ei in that, ii in Range(that.size()) if ei>e (
    e:=ei, i:=ii
    )
  that.remove(i)
  e
  )}

MainPart2 = (
  input = Fs.Real.#$of().read(\"input")
  matrix = Matrix(\()(
    for s in input.split(S.nl()) for si in Split(s) \add(I(string=si))
    ))
  seeds = Coords()(for c in matrix.coords() h in matrix (
    min = Match.All()(for ci in Near(c) \add(matrix.val(ci)>h))
    if min \add(c)
    ))
  for c in seeds, i in Range(seeds.size()) (matrix.set(c val=i+100I))
  while NeedsMore(matrix=matrix) ( GrowBasin(matrix=matrix) )
  sizes=I.List()( for i in Range(seeds.size()) 
    \add(Match.Count()(for v in matrix \add(v==i+100I)))
    )
  v1=PopMax(sizes)
  v2=PopMax(sizes)
  v3=PopMax(sizes)
  Debug(v1*v2*v3)//882942
  )

Enter fullscreen mode Exit fullscreen mode

Oldest comments (0)

DEV

Thank you.

 
Thanks for visiting DEV, we’ve worked really hard to cultivate this great community and would love to have you join us. If you’d like to create an account, you can sign up here.