## DEV Community is a community of 851,150 amazing developers

We're a place where coders share, stay up-to-date and grow their careers.

Marco Servetto

Posted on

# Advent of code Day 20

Finally a day where I can feel satisfied with my code results.
I explain this code in the detail on my youtube channel, (https://www.youtube.com/watch?v=lqA_XT0U4ng)

Point = Data.AddList:Data:{ I x, I y
method Point +(Point that) =
\(x=this.x()+that.x(),y=this.y()+that.y())
method Point max(Point that)=(
(x0,y0) = this
(x1,y1) = that
Point(x=x0.max(x1),y=y0.max(y1))
)
method Point min(Point that) =
this.with(x=\x.min(that.x()))<:This.with(y=\y.min(that.y()))
}

Map = Data:{
M = Collection.map(key=Point,val=Bool)
mut M map=\()
var Bool outer=Bool.false()
var Point topLeft = Point(x=0I,y=0I)
var Point bottomRight = Point(x=0I,y=0I)

mut method Void put(Point key, Bool val) = (
\#map.put(key=key,val=val)
\topLeft(\topLeft.min(key))
\bottomRight(\bottomRight.max(key))
)
read method Bool val(Point key) =
\map.val(key=key).val(orElse=this.outer())

read method I nearBin(Point that) = 0I.acc()((
var n = 512I
for xi in Range(I"-1" to=2I), for yi in Range(I"-1" to=2I) (
n/=2I
)
))
read method mut This step(Key that) = (
mut This new = This()
(x0,y0) = \topLeft
(x1,y1) = \bottomRight
for x in Range(x0-1I to=x1+2I), for y in Range(y0-1I to=y1+2I) (
key=Point(x=x,y=y)
i=\nearBin(key)
X[i.isInRange(0I to=512I)] // is my binary conversion correct?
new.put(key=key,val=that.val(i))
)
new.outer(if this.outer() that.right() else that.left())
new
)
}
Key = Collection.list(Bool)

Main=(
imm key = Key()( for i in input().split() \add(i==S"#") )
X[key.size()==512I]
var map = Map()
for line in input().split(S.nl()), li in Range.unbounded() (
for c in line.split(), ci in Range.unbounded() (
map.put(key=\(x=li,y=ci),val=c==S"#")
)
)
for i in Range(2I) ( map:=map.step(key) )  //50I
tot = 0I.acc()(for (val) in map.map() \addIf(val))
Debug(tot)
)