Advent of Code in Haskell 2023 - Day 16 and Day 17 sneakpeek
Watch on YouTubeVideo summary
The video begins with the host tackling Day 16 of the Advent of Code challenge, which involves simulating light beams moving through a grid of mirrors and splitters to energize tiles. The core task is to parse the input layout into a mutable array using Haskell's `Data.Array` library for efficient random access, defining specific types for empty spaces, reflectors, and splitters that alter beam directions. The solution involves implementing a simulation where beams are tracked as a list of coordinates and directions; when a beam hits a splitter or mirror, its path is updated, and if it splits into two new paths, those are added to the queue for further processing. A critical optimization implemented is checking a set of visited tiles to ensure that if a beam returns to a tile in the exact same direction it previously traversed, the simulation can stop early because no new tiles will be energized by that specific beam path.
After successfully solving Part 1 and verifying the logic against the example input, the host moves on to Part 2, which requires finding a starting position on any of the grid's edges that maximizes the number of energized tiles. This involves iterating through all possible edge coordinates, launching beams from each point, and recording the total count of unique tiles activated by each configuration. The host notes that while the simulation logic remains largely the same, the sheer volume of calculations required for Part 2 makes performance important, though the array-based approach handles the workload efficiently enough to solve the puzzle within a reasonable timeframe. The segment concludes with the host successfully completing Day 16 and preparing to transition to the next challenge.
The video then provides a sneak peek at Day 17, titled "Clumsy Crucible," which introduces a pathfinding problem involving minimizing heat loss while transporting a heavy object from a lava pool to a factory. Unlike standard shortest-path problems, this puzzle imposes a specific constraint: the path cannot consist of more than three consecutive moves in the same direction without turning. The host discusses potential approaches, including Breadth-First Search (BFS) and greedy algorithms, but highlights the complexity of enforcing the "turning" rule within a search algorithm. He realizes that a simple BFS might not suffice because it typically finds the shortest path regardless of directional constraints, and he needs to carefully manage state to ensure valid turns are made before exceeding the three-block limit in any single direction.
Due to the time remaining in the stream and the need for further thought on how to correctly implement the constrained pathfinding logic for Day 17, the host decides to pause the coding session. He acknowledges that while he has a general idea of using a priority queue or a modified search algorithm, the specific implementation details require more debugging and refinement than can be accomplished in the current timeframe. Consequently, he wraps up the stream after finishing Day 16, promising to return tomorrow with a more complete solution for Day 17 once he has had time to work through the algorithmic challenges posed by the heat loss constraints.
Read the full video transcript
all right welcome to the
stream we're doing day 16 of the Advent
of
code
um I took a break
yesterday to go to a wedding but we're
back let's see if we manage to catch
up and uh solve it quickly maybe we'll
manage to catch up today I don't know
I'm waiting for maybe 2
hours not too long but let's see let's
get on with day 16 all right the floor
will be Lava so we use the lens Library
I like that shout
out uh light is complete focus on where
lava production
facility the Cave the okay finally the
hard the mountain you see bright light
Inc ahe okay we focus the light on
something camera close the facility
pulling okay the contraction seem to be
a flat two dimensional Square grid nice
empty space mirrors and
Glitters okay the contration most of the
beams around the grid but each tile in
the grid converts some of the beams L
into heat to move the rock in the cavern
so we have the layout comes in in the
upper left top left corner from the left
and heading to the right then its
behavior depends on what it encounters
as it moves if the beam encounters empty
space it continues in the same direction
theam encounters a just check
mirror ah the beam is reflected right so
it goes like
Ching it goes through here and here so
if it goes here it would start going
downwards
okay if the beam encounters the pointy
end of a
splinter the beam passes through
SP okay
but flat side of the splitter as here
the BL split into two beams going in
each of the two directions and the
Splitters Point these ends are pointing
aha
okay one that goes up and one that goes
down
cool
okay let's parse this quickly into
something that makes
sense I think we're going to use a an
array cuz we're going to be navigating
around
and we want that that random access
bro it's the best kind of access well
you have to
[Music]
uh keep it all in memory though but
that's okay that's what we're going to
do anyway
example okay also my mouse is working
again it's not working for a while but
now it's working again let's all
celebrate that it's also third
Advent this
Sunday
um because Christmas Day is on a Monday
so like next so the Christmas Eve is
actually fourth
Advent that is crazy yo anyway in
Iceland uh we lit light four candles but
we haven't been home these uh advents so
we haven't really been doing that
uh
but that's
okay we're doing ad of
code
instead wow feel like my uh laptop is
slow
today like the rendering is just a bit
slow but it's okay we're still we're
still on a server so Solutions time
shouldn't be
affected but I'm going to go ahead
and
um
save everything here now how do we do uh
an
array let me see so
um the things in this uh grade are going
to be
data G create entry so we're going to
have
a empty
space we are going to
have reflect
90 okay so let's have another data type
that just says data angle how is the
audio by the
way is everything good I feel like like
my laptop is not in a good mood today I
hope it's going okay OBS is reporting
things okay but yeah you never know
let's see
up
down
left
right okay
[Music]
um
um I'm actually going to just make it at
an array of characters
right
[Music]
um reflect 90 and then it's
either
uh it's going from
from left to
[Music]
up left comma
up uh it's reflect H and then it's angle
angle so we're going to have
the left corner and upper
right right corner okay then we're going
to have a
splitter and that's all so angle
angle
um left
right left right or
uh right
or
damn I feel like um
I feel like it's actually like a you can
imagine these slashes uh uh also as as a
splitter but it's just
um just it it's changing the direction
um but it's not creating to anyway
um so let's see hle
dat.
array I never
remember how these things
work uh we're not doing B
arrays
um maybe it's in container I think it
should be in containers it's like Ira
and mras
and
uh
has scale container
[Music]
package what what is going on today
Jesus we go
so map.
strict data.
map any
containers yes okay
good containers don't have uh arrays
data do
array yeah it's an ARR array package
makes
[Music]
sense
let me see
um I want to just say here
uh um let's just import data. array I'm
just going to make it figure out the
types
itself uh do
print so um read
file
example into print. pars so pars is
equal
to Lin a pars is equal to uh map pars
[Music]
entry
pars this of strings into and this is
just going to be a list of list of grade
entry no uh let's see
pars
where uh par
entry dot is equal to
empty first
entry uh Slash is equal
to reflect a
from a left
to right so it's either left to right or
right to left right
[Music]
how do they describe it in the text so
right from the continue
upward let's actually make this just an
angle
okay uh so this one if I'm coming from
the right I'm going to go
up fars
entry I think these are all the same
okay I think it's it's actually you know
it's like this so so
uh data grid entry is just a GE of list
of angle
okay so this is GE
Mt this is GE
[Music]
up and
uh if you come from the left okay
okay this is
G down maybe these type selections are
going to bite Us in the end that's
it we need to do it like this CU
otherwise it's going to be messed
up par
entry so I think it's a nice choice of
entries here that would actually let
this up down let's kind of say if you go
through
this these are the copies you're
supposed to
um
create okay let's
see D see o day
16 day 16 T CH and time
16 it's a member oh my God install
liay what it's a bit annoying with
the GT up is it doesn't come with all
the batteries included so now I feel
like see and then we just installed it
it it was already there which just kind
of not
exposed uh
globally okay map
[Music]
map dering
show we should probably add you know EQ
or whatever
here okay so we have empty list up down
dot dot
okay now I want to make this
into an
array and there's going to be a mutable
arrays uh um let me
see B of the array spe lowest and
highest bound ofray
extrac and a one origin
okay okay then we're going to just say
um let's make this into int
common and then these are going to be
int
comma okay and this is going to be a map
so we're going to
sip and then we're going to
[Music]
zip map is applied to yeah okay I need
to do dot here
[Music]
okay
[Music]
um the zip
WID okay and then instead
of doing like this I'm going to say here
I uh ILS
to
um we're going to map
A J comma e
to I comma J comma
[Music]
e
let okay and
right and then it's like
[Music]
this let's see
again okay now we have the all the
[Music]
associations and now let's just
concave
[Music]
why can't
[Music]
I conat all of
these
[Music]
um print parts and then
[Music]
conet
I feel like I should be able to do conad
here ah it's because I didn't change the
type here
okay nice okay and
now I am going to make this into an my
array
um what is this U array it's that uh
un it's
unboxed okay array
and let's see
array int
int grd entry and then we are going to
say
here import or qualify data array as R
import data array
[Music]
array and then what I'm going to say
here is I'm going to
say r dot
from list a list array
here
um
ah
array and we just say that the bounds
should
be 0
0 and 9A 9
right
yes
do
nice okay and
and then I can kind of move around in
the array
right so now let's
[Music]
see do so a r is it just this and now
let's
see return
here print
our and I should be do
print
are uh
1.2 yeah okay so now I have fast access
to to the values in the
array
cool this is all quite nice and fast so
now we have
the layout in here
here so now I'm going to
[Music]
um
let's see now I need to write the
opposite
[Music]
function
opposite Up Is
Down
opposite down is
up
opposite left is
right and the
opposite of right is
left so we will let's just always
start
um we start at 0
0 and what we're going to do is that
every time we are supposed to split the
beam we're just going to save that in a
list of beams that we have to process
next okay so we are going to say here
um
part
one and then we can probably memorize it
later it's going to be
go so this going to be um empty so we're
going to start with the beam 0 comma 0
that's going
right
okay and that's going to be our initial
one so where
go and what I want to see
[Music]
is if I so what uh what tiles have
I
seen okay so we do
um we have to have a set for this
import data do set set import
qualify data do set as
set so we're going to have here um set.
empty so go uh so if I don't have any
beams
anymore I'm just going to here in set.
size
scene now okay go
[Music]
scene
uh beam
coordinates and beam
Direction and these are the other
beams
[Music]
uh m
[Music]
okay so
here oh okay so what I know is actually
that
[Music]
um let's make this a map. empty
actually map. empty
um and we're going to make this import
data.
map map import qualified data. map as
so we're going to make this a map.
empt and map.
scene okay so here we're going to say a
gohing
case
um so
just H visit it so
seen uh just uh at
BC uh uh scene map. bang question
mark
um let me
see if I've never seen it
before case
um scene map.
bang
um
and BC
of so just there's okay so now I'm going
to see if
um if I've seen it
before and it was going in the same
direction it's not going to change
anything cuz it's just going to hit
everything
again uh so uh
if BD uh set.
member
let see set
dot what is the type of set. member
again I never remember it I never
remember the which comes first the map
or
the okay the element cons froms uh if a
PD set out member
uh
de then go other
beams otherwise then go see other beams
else
um okay
[Music]
so it's basically this okay it so let's
just do it here just
of
seen scen
map.
BC uh so we we have seen this style
before first of all and
H
BD set
that remember there's is equal to go
seeing
other themes
otherwise
[Music]
um okay otherwise
um okay otherwise we haven't seen
[Music]
it
before then we have to create
[Music]
um
okay
otherwise so then we say uh
let scene Prime
equal
um map.
Singleton
a oh does map not single T
[Music]
work okay it says key value okay map.
single turn
um BC and then set.
Singleton BD
in
[Music]
um in
a
scene okay so we say map do
insert
ah okay I don't need to do that so map.
insert
with uh this and then
BC and
um set. single volon
PD and this is a set.
union let
same Prime is equal to to this so this
is a new set so we're just going to add
this new Direction let C Prime equals
map. insert with set. Union and then the
coordinate and then this new and then
scene so that's
the
in
uh go scene
Prime beams Prime
um now we need to say beams Prime okay
so
beams so
um now we have to add new
beams
so let's say we actually figured out the
new scene Prime so let's say uh
case um and then now we're going to look
look up in this
array right R we're going to say case
r r do bang VC
[Music]
of okay
um let's see here
move uh X comma
y uh so we're moving to the
left is equal
to uh but I yeah I zipped it so it's
actually y comma X as
usual X as usual so this is going to be
y comma x
-1 if I go right it's going to be x +
1 if I go up it's going to be x minus
one
actually and if I
go down it's going to be y +
one okay case RBD of G
empty so if we hit the empty
list then
um the new
beam then we're just going to say um
uh let's
see new
beam is equal to
okay okay if we
um hit the empty list then this is going
to
be um the same
as move
[Music]
um BC
BD let me see data. array we look
up and
[Music]
um what happens if it's out of
bounds probably get an error
right okay
and okay so the new beam is
just uh we just do it we just have one
element okay if I hit
the uh one with a one
case then
um
let me see I think
[Music]
they let's see okay if I hit uh an
up uh that is a k
b a BD of so if I hitting one that goes
up which is
[Music]
a this one right yes so if I'm coming
from the
a right so if I'm going
right if if this is so case speed of
right the new direction is uh
up so we are just going to say move
BC uh move BC
BD and then the next one and is also BD
okay move BC
a
up
up okay if I'm coming from
the
left it's move
BC
um down
down if I'm coming from the if I'm
coming
up then
it's move
VC uh then we're going we go
right and
down then we go left
[Music]
and the other case here is down so if
I'm coming down okay and if I'm coming
from the right I want to go
down if I'm coming to the left I want to
go
up if I'm coming if I'm going up I want
to go
left
and if I'm going down I want to go
[Music]
right okay now they are two more cases
the
[Music]
Splitters uh oh this one is up down this
one's supposed to
be left
right
[Music]
okay so if I'm coming from
the uh from coming from the right or
left if I come to the right or
left the
um
[Music]
the is left or the is
right then I want to go
um
one that goes
up
[Music]
and
um otherwise it is just move
bcbd same here with left and right
left
right um if I was going
up so this one uh this one was going up
or down then I want to go this is be
down and going be left and
left and right and
right otherwise I just continue
going and this is the new
beam
[Music]
in let me make this a bit smaller
[Music]
maybe okay in go S
Prime and we want to do new
beam
other
[Music]
mes okay
[Music]
um last do be depending where it
moves
okay I
guess if it
um if it
um if it escapes the
bounds
then
um if it escapes the bounds then we
[Music]
just
[Music]
so let's just first make sure we
remove anything that's not within pounds
okay
um
BC bcpd and I don't care about
this and I I want to say um
case so let's see these are and then
let's see
[Music]
um b y okay let's just make sure
that
um so uh bound so R not
bounds let me see
um XY so let's see
um X is larger equal z and y is less
larger than equal
Z let's get a a BX comma py out of
um array bounds f
r and then let's check that X is larger
than
zero and Y is larger than
zero and X is less than
or equal to
BX and Y is less than or equal to b y
right um and then this is
just RS so if this
is if not this then
go then just keep going go s
RS let's see probably going
[Music]
to Let's import
preload hiding left right these are from
either
[Music]
so language GC
2021
M um num angle
[Music]
move and in Comm
[Music]
in angle to in my
[Music]
in
let me see and the go is supposed to
be um go is a takes a map
of um int comma
int and set
angle I call it Angle now yeah uh to a
uh
[Music]
um a list
of in comma in comma
angle these are the beams and we'll
return an
[Music]
INT and it's because I looked up the
wrong thing here okay or B
see
[Music]
okay part
one array in comma
int
um gr and TR
to
um
in okay so the bi
I uh because it gives the lower
bounds and the upper bounds I get it
okay
um LBX lb
y ubx UB y
LX
y
ubx
[Music]
UI okay
um it does do something now let's see
print part one
R okay give us 46 for the
example and it does so quite fast
[Music]
um let's see
um part
[Music]
one great entry H and I just need to
print
it
does seem to work for the example now
let's just see if it works
for the
input um before we start
debugging I think it should
[Music]
work basically we kind of memorize it at
the same time as we write it
with this
um error in Array
[Music]
index
[Music]
okay
[Music]
let me see
um Trace show
[Music]
um Prett show
um let's just do try show actually uh
BC
[Music]
um indentations go
bur yeah a
import debug.
[Music]
Trace
[Music]
H
[Music]
what is it just not
even uh print. part one
[Music]
okay it works for the
[Music]
example I thought I specifically checked
the
[Music]
let me um first pause it and say R2 um
print bounds
R2 okay
return
return error in Array index is it just
failing on the pars
then ah
okay that's
funny
Ah that's okay that's the problem uh it
should start with 0 comma
0 and it should end
[Music]
with R
[Music]
equals
h f red equals
f f
STS um okay so to start with z0 and we
should end
with the first of the
last
of
r
where this is
St okay now we have the
actual index here
and
print part
[Music]
one 8539
okay seems like a reasonable
number
all right we did part one
whoop took us 40 minutes though but we
did a lot of
work uh the reinder talks in your Shir
collection any Edge tile and heading
away from that
edge for the beam starts in the bottom
right corner start heading either left
or
upward so the beam could start on any
tile any tile in
left the bottom row any tile in left
most
column or any tile in the rightmost
column to produce lava you need to find
the configuration that energizes as many
tiles as
possible this is going to 51 tiles are
energized find ini being configuration
eniz is the largest number of
tiles uh
okay
um let's just write here uh
fun takes
in
and in comma
int and
angle and returns and and then takes an
array
[Music]
and then a list of
this and returns and int
okay and we're going to call this
part fun
our
beams
beams part
[Music]
one uh R is equal to fun
R
and 0 comma 0
[Music]
right no this this
work
yes
[Music]
okay now
um I think I'll just run it over all of
them
okay
um so part
two are it's going to
take
um
so we're going to have a
where LBX lb
y ubx u y is equal to r.
bounds
R okay
so um the
edges are going to be
um oh my go
edges are going to be
um it's going to
be uh how do I do this so H we we're
going to have
the left Edge is going to
be
map I
a to so 0 comma
I comma
right
um ages is equal to uh this mapped over
zero uh it's actually yeah but it's
going to
be
this lb X and then this
is we're going to have this be Y and
this is y and this is from LBX no from
LB
y to
Ubbi concatenated
with um so these are the ones going
right so this is the right Edge
and then we have the left Edge and then
we're going to have
the uh little going left and that's
going to be
the
ubx I think I need to say
uh plus one actually to make it to the
end and then we're going to do for the
X's we're going to do X
and lower b y and this is going to be
going down and it's going to go from low
X to u x +
one and then we're going to do upper
bound
X go
up and then it's going to be lower b x
okay let's just write edges here
first and see what
[Music]
happens
and part
[Music]
two so we got all the right ones from
zero to
nine ah it goes
to 10
also okay so we don't need this plus one
here
okay this one goes to 0
to9 and then we have
a I think these are all the edges okay
um
maximum
of
um
[Music]
maximum of um
map f
[Music]
r e fun
r
[Music]
e oh let's just actually make this like
this this is just fun our
um
probably be better if we like share
[Music]
the share the cashes between
them um
but
whatever let's see if this is super slow
or
[Music]
not
when r e
edges uh gives
[Music]
51 that's not 51 that's
[Music]
48 a being can start on any tile in a h
on heading
downward ah I messed it
up these are actually
um the coordinates are flipped right so
it's
actually these are supposed to be
yse y y and this will be
LX Y and these are going to be
x and
x um but I think they're both
actually let me get 51 I think cuz
they're all square these things here
actually don't
matter
um let's have it
correct let's have this correct okay
so now this is the right end and the
left Edge but this one should actually
be going
from
a yeah they are they are
correct let's just see how bad is it for
the
input it's going to take some while
um okay 7
Seconds
all right we did
D16 whoop
whoop didn't take us too
long but all through the power
of
aray let's see get status get add day
16. HS
input here commit
M day 60
you push okay let's go to day 17
then I don't know if we're going to
finish it
today um but it' be good to get some
progress on
it uh and then maybe we'll finally call
catch up
right oh not finally like we're just one
day
behind CU we skipped one day let me see
okay day 17
anyway I like the solution here it was a
just erase and then we just brand the
thing there was not clever this it was
just about getting it correct memorizing
with
this so just realizing that if you're
getting have a
[Music]
beam
um going hitting the same tile going the
same direction it's not going to do
anything new right okay but now day
17
Oscar Allen says it wasn't too
bad oo look at these CSS effects there
is lava coming
down this is crazy stuff okay uh let's
[Music]
see clumsy
Crucible
ly okay there's a parachute CU we get to
gear
Island and there's a giant Factory here
okay we have a lava
fall large Crucible top heavy
unfortunately difficult to steer and so
I can't C to go straight line for very
long okay you need to find the best way
to get The Crucible from the lava pool
to the machine parts
factory to do this you need to minimize
heat loss while choosing a route that
doesn't require The Crucible to go in a
straight line for too long
fortunately the elves here have a map
that uses traffic patterns Happ damage
parameters okay this is going to be some
breath for search kind of yes
anyway
that's I think we implemented
it so many
times er in the past few
years and it's high time we did it this
year
right let see
module main
wear main iio main equals
return and
um first let's par the
example I feel
like each City B single digit repr
amount of heat
loss uh the starting point pop left City
Block the
destination
the machine parts factory is a bottom
right City
Block because you already start in the
top left block you don't incur that
Block's heat loss unless you leave that
block and then return it to it
okay okay can move at most three blocks
in a single Direction before it must
turn 90 degrees left or
right so that basically says um
[Music]
hello yeah day 17 little Lenny we
finished day 16 we're going to take a
quick look I think I'm going to stop in
like 40
minutes uh I need to sleep
also
okay one way to minimize heat loss is is
this
path never moves more than three
consecutive blocks in the same
direction incre a heat loss of only
102 okay so cuz it's it's not just
breath ver search right it is
also
we also need to be careful that the path
uh satisfies
the
[Music]
property it may nor only turn left
continue straight or turn
[Music]
right
[Music]
m
okay let's um just start with um the
breath for search
[Music]
then how do you do the breath for search
again
um we also we don't need
[Music]
to just uh remember what it was
bre
[Music]
search three that
property okay and then we do the on
explored and then route and if we is a
go then return
[Music]
we
maybe I should like for every note say
that you can
[Music]
do let me oh I'm getting some milk
delivered while Q is not empty too so we
need like a priority
Cube
and then we just need to be
careful with the path that we take
right because it's not valid to just say
oh we take the shortest path right
um
[Music]
um
[Music]
so what if I do breath first search and
then um for the
Neighbors that's the thing right I can't
just say ah for the neighbors just if
you've gone three times to the right
just throw out those neighbors right
because uh the the path it's path
independent right
[Music]
um
[Music]
cuz I'm not like I'm also you know we're
also in that case where
um I just have like half an hour
left and I'm like I'm going to start
doing breath first search and then
that's not going to
work
um so what I want to kind of do is just
uh pause it here and let's just do day
17 tomorrow
right and just give me some time to
think about it I feel like I feel like I
need uh to think about this a bit
so let's see
um path here so it's goes 34 and then 32
[Music]
31
we could also you know
[Music]
try just the super greedy algorithm
right it always just chooses
the
um chooses the smallest one it
can this is say kind of you know the
shortest path to this point
is the shortest valid path to all of
these points
right and then the shortest valid path
to any of these points and so on right
so you will kind of do it
recursively uh but
backwards but that's problematic by
saying that
um yeah maybe we can do it like
backwards like backwards shortest path
kind of
[Music]
okay let's but let's start at least by
um Haring
it we're going to do something similar
as in day 16 we're just going
to we're just going to have all
these things you know we're going to
talk about directions
and angles and
stuff
let's call this uh there section and
then we're going to
do uh import preload hiding
left left
right so and we're going to we have to
import all the all these
[Music]
dependencies
okay a grid entry here and this is
actually not great entries it's just
numbers
in
um and pars
entry C is going to be read at
in
see and we have the pars
and they are
directions well let's do read file
example um
print do
bars
ni GT o day 17
just 17 h no day
17 day 17 30 CH and
[Music]
time okay then we have this
grid array
sorry
[Music]
okay then we can have something like
paths and like
scene I just don't know how to like if
we just supposed to find the shortest
path that would be easy right but I
don't know how
to it's quite hard to put this extra
constraint on the path
[Music]
that
[Music]
so what I want to do is I want
to yeah okay but at least we have uh we
have it parsed for now and uh we can
move around in it
right
[Music]
yeah I'm going to pause for now sorry
about that I am just not I'm not getting
like a oh this is how we can do
it
so I'll pause for today and H hopefully
to come back tomorrow with you know
something written down like I had for
green serum
and uh yeah we'll see how we fix it all
right but thank you for tuning in today
uh hope you enjoy day break and I'll see
you again tomorrow for uh well day
17 uh
again thank you
Oscar okay
byebye