 alright welcome to day 14 of the advent of code in Haskell we've been at it for 13 days now and we're more than halfway through right so but it's getting harder so let's see if we can keep it up yesterday was pretty easy in Haskell but yeah we're not always that lucky but now we have more tools available right and breath first search is so fast anyway some Haskell I'm also using this bottle it's not a Haskell bottle but I actually got it from soon known for such things as the processors in almost everything no anyway thanks for tuning let's get started on day 14 I already created some skull tin here make it bigger so a lot of our viewers are actually on YouTube not live and one of them said make the font bigger I can't read it on my mobile and now for those people I just had to say you know pretty impressive that you're watching these in my mobile anyway let's get started and what are we doing today we did some distress signals yesterday we were figuring out packets we went up the hill we fixed the screen so much you're doing okay so now the signal is coming from the waterfall and then we go behind the waterfall okay there's a large cave system oh my god my familiarity okay so we are definitely like it's like a continuum we're like the same person all right you begin a moment if you're gonna you feel ground ground movement sad because pouring into the cave if you don't quickly figure out what is going you could quickly become trapped fortunately your familiarity with analyzing the path of fall material will come handy here you scan a two-dimensional vertical slice of the cave above you and discover that it's mostly air with structures made of rock your scan traces the path of each solid rock structure and reports the x y coordinates that form the shape of that path where x represents a distance to the right and y represents the distance down each path appears as a single line of text in your scan after the first point of each path each point is the actual input okay so this is the input now let's see here for example who pays it into our example a each path appears as a single line of text in your scan after the first point of each path each point indicates in the end of a straight horizontal vertical line to be drawn from the point for example 498 4 498 6 496 6 this can means that there are a two paths of rock the first path consists of two straight lines and second path consists of three straight lines oh yeah by the way I'm not drinking I'm drinking what I call Martian coffee it's just a caffeine as an alpheanine in hot water it's not good anyway okay so it scan this okay let's see in front of 8 2 4 9 8 6 4 2 6 and then 6 to yeah okay the side is pointing into the cave on the point 500 point comma 0 okay yes okay areas dot plus this becomes... sand is produced one unit at a time and the next unit of sand is not produced on the previous unit of sand. It comes to rest. Unit of sand is large enough to build one tile of air in your scan. A unit of sand always falls down one step if possible. If the tile immediately below is blocked by rock or sand, the unit of sand attempts to diagonally one step down and to the left. If that tile is blocked, the unit of sand becomes... okay, by rock or sand. If that tile is blocked, the unit becomes sand because I only want to step down to the right. The sand key is moving along as long as it's able to do so. At each step, trying to move down, then down left, then down right. If all three possible destinations are blocked, the unit of sand comes to rest and no longer moves, at which point the next unit of sand is created back at this source. So drawing a sand is kind of like this. Oh, okay. Yeah, and then ding. Okay, this is a bit fun. Okay. Finally, only two more sand can possibly come to rest. Once all 24 units of sand shown above have come to rest, all further sand flows out of the bottom, falling into the end of the void. Just for the fun of the path of any new sand before falling forever soon, hair was tilled up. Using your scan, simulate the falling sand. How many units of sand come to rest before the sand starts flowing into the abyss below? Okay, now let's start scanning these. Okay, data input. This is going to be i and it's going to be a pair of integers and comma int. Okay, so each line is going to be, yeah, a list of integers. Okay, now a deriving show. Okay, instance read input, where? Now I want to, so we should probably put this in the utils, where it's like this reads preq equals util. So I want to do import a read text dot parser combinators. Combinate. Okay, so I'm going to actually re-export it. So text, this is going to be chunks. And I'm going to, so I'm going to say this read a preq pars is equal to text in pars and reads this. Combinators dot read p and then we just re-export the module text dot parser combinator. Can I do this like this? No, I'll just say module. Okay, import text dot parser combinators. Ah, somebody's watching reads read preq a import qualified text dot parser combinator combinators read preq as rp. Okay, preq pars takes in rp and returns. Okay, and we'll export req pars as well. Now we will import util here, import util. Now read input will be a where reads preq equals a pars preq pars where pars equals undefined. Now, it won't, it doesn't want this preq pars, I call it pars. Let's call it pars preq because that's the one I guess it was then we should probably be named like that. Pars preq. Pars preq, that's probably where pars sec comes from actually. Let me see a manager. Okay, so pars preq. We have to do all these explicit in exports because we are re-exporting a module. Okay, so pars, so this is going to be do pars pair is equal to do a reads, read as to p reads, read as in. This is going to be a pars pair. So a sap by, okay, sap by one, pars pair, and then this is going to be skip spaces, and then a string skip spaces. Now, and then this is a read p of p. Now reads add in a jar comma read x, read as to p return x comma one. Okay, rent this a read input to input io input, a list of input, read input equals a map read map result. We're going to fmap dot lines over read file. All right, now do read input x, the day 14 example. Okay, at least the type checks and we get the input. Now we have to simulate this. Okay. Okay, first of all, I want to shift it all a by a 500. Okay, I don't care. Let me see. This is all 500 for some reason. Okay, it doesn't actually matter, but it's still I feel like. Okay, so Okay, so we can have this map and we can like make it update. Let's just see here. So for a, okay. So where does it stop? Okay, let's take here and blocked takes an input and returns. It returns a range. It returns a set of chords set import data dot set set import the set as set. So block takes an input and it we will like generate the range that off of the ones that are blocked. Okay, blocked. Okay, empty equals set dot empty input. Yeah, so this is actually I have empty is set of empty. How to do this in let me see. Okay, so, so I'm actually just gonna do like I of x, y, p one, p two, rest. Okay, now. So anything else will just be set that empty. This is equal to set that union p two, p two, r. Okay, and where Ellen said, okay, where Ellen said is set of eight comma eight. So Ellen said and then we're gonna just give it p one, p two. Okay, Ellen said we could actually Okay, this might be like a very long lines. So they might have a lot of points. Okay, so let's just aim. So let's a let's not do it like that. Let's actually do here. So blocked takes a list an input and then and then chord and a and we will actually check whether it's between those two chords. So yeah, okay. Okay, so we're taking an x here x, this is just equal to false. Now x comma y. So let's do a p add. Okay, so x one comma x two, p one. Okay, let's not do it this way. So let's say p one, p two, we're just simplified. Okay, and p and then we say if between between between between p one, p two, p, then target is actually between p one or p two or blocked i, p two, r. Okay, I'll just have this c set of functions. Okay, and now between, oh my god, let's not call it between then because that's reserved, it's called between between in comma in in command a x one x two y two x and y. This is equal to okay. Now if a point is between two points, then it's a So, so either of a, okay, so it's always going to be okay. First, we have to sort the points. Do we do this some other day? Okay, so if x one is equal to x two, so then there is a line like this. If x one equal to x two, then we have to check that a y one less than equal to y and y two less than equal to y less than equal to y two or y two less than equal to y less than equal to y one. We don't know which order that points are in else. And let's actually just, okay, so if they're not equal, then else if y one equals y two do the same but for, hi, do you know how I can go from one comma two to one plus two in Haskell? I'm trying to change it together with a custom fold. So yeah, I would use a fold one. Let me show. Ah, Haskell question. G-H-E-I-T fold l one. So fold l one plus one comma two. Okay, did you get that? Did that answer your question? Okay, so okay, so the twix there, it will, well, okay, so what do I need to know here? Well, I know that either x one equals x two or because all the point will always have one of them will be equal because we're always checking the line. So I don't actually need to check if x equals x two and x equals x one else if y equals y one, then we check this otherwise false. But I know that the lines are always, they're always going to be equal. All right, just ask again. We also do Haskell help sessions. Let's see, I think betwixt is correct. No, let's load day 14 slash day 14. Okay, let's say one comma two and three comma two. And then I want to check if two comma two is betwixt. Okay, three comma two is betwixt. Four comma two is should not be betwixt. Okay, now two comma two is betwixt, but two comma one should not be betwixt. And three is just for a, okay. I think this is the betwixt formula now blocked. So okay, now we're going to be checking a lot of betwixts. I feel like we should take all the inputs. We get all the betwixts, right? And they should have some, we should have some markers, right? So let's actually not do it like this. Let's actually just go from inputs to pairs. Okay, cancel this hashtag canceled. Okay, so I want to go from a two lines equals, go from list of input to a list of list of int comma in two lines. Okay, so empty is empty two lines. A A B rest R as of input. Okay, so let's for one input prime equals input to list of, it's actually like, okay, so let's write here type code equals int comma int. Now I want to go to code. Now this one should go to a list to go or a code. So this is actually two lines. Court a court. Okay. A concat map a two lines. Okay, this is fine. We just concat map two lines prime. So two lines prime of I A B R RS is equal to a comma B two lines prime. B R two lines prime. There's actually nothing. We're just doing one line two lines I B R. Thanks. It could work, but it gave me, can I turn to fold one plus two plus three plus four a Jedi tri fold R one instead of fold L one to fold R one. That is exactly the other associated. Now, what is wrong here? Thank you. You are amazing. Wow. How's that for a start to your day? Okay. Now let's do print. Let's say two lines. So these are okay. No, wait. Yeah. These are all the lines we have. Oh, yeah. And two lines prime of anything else is just empty. These are all the lines we have. Okay. Now we want to divide this into X lines and Y lines. Okay. Is a vertical is X line line takes a court. Then this is type line equal court comma court. Now is X line line to full is X line X. So this is going to be X one. Y one. Okay. X two equals X one equals X two. Okay. Now we are going to partition is X line. This is from data.list. Okay. And now we have the X lines here. Okay. And then we have the Y lines. Okay. Now we are going to accept it. So that's what fold R one is, right? It's like fold L, but it does it from the other direction. You probably should be using fold R if you can. But I never remember which one is which. Okay. Now. So let's go. So to X map. This is takes in a line. We're going to assume it's an X line for to X map. It takes in X one comma Y one X two X two comma Y two case X one not equal to X two equals error. Not the next time. We can actually add. We don't actually have to do this. We just do is X line. Okay. Two. And then we don't even need to disrupt it. Okay. Now to X map. The whole thing equals into math. So I am dot single ton. And the key is going to be X and the value is going to be Y one comma Y two int map. Actually int comma int data dot int map int map import qualified data dot int map as I did ding ding ding ding. Okay. Now we do the same for the Y map. If it is X line and we say not a Y line. Okay. And then the Ys are equals X one X two. I am single ton Y X one. And I'm actually going to be a bit more clever about this. So I'm going to say here mean Y one Y two and max Y one Y two. So they're always going to be in order mean X one X two X one X two max X one X two. Okay. Now let's do here. So task one takes a list of input and returns a pair of int map. So a collision map is so a call map so collision map call map type call map equals int map my int. And this one takes and it will give us two call maps. I'm actually going to be very clever here and just say int map int comma int. Okay. Task one input to call map map. So task one equals a so this one gives us a wind map. Okay. Yeah. Yeah. Yeah. Yeah. It's because what might have like multiple lines in the same like non non contiguous lines. Okay. And then this is actually going to be the list of these. Okay. And now task one going to give me a call map. So I got to take the I'm going to take the imps equals a so where X is Y equals partition is X line of two lines in and then I'm going to do I am that unions with plus plus X's. I am that unions with plus plus Y's. And then this is because dollar two X map to X map and then this was going to be the same to Y map. Now let's actually not do this. We do print task one. So then I have these collision maps for X and Y. Okay. Now I want to be able to add a point to those. And it would be nice if we could kind of unify let's write here compact int map in command to int map in command. So compact takes a fmap come back compact where compact prime. Oh my god. You see I don't think there was anything funny there. Sorry about that. So compact. Are we are we too eager here? So I want to be like I want to be like so I want to kind of join together lines that are together. Okay. Let me let's wait with this. Okay. Probably don't need this so far. Okay. But like because we're going to be adding grains of sand grain in comma in. So where it ends up to the call map grain X my L equals so we insert into so I am okay this is going to be I am dot alter adjust. I am adjust. Okay. So we're going to do I am dot adjust. Let's put that up in the here. So I want to adjust. So for the X lines I want to adjust adjust and I just want to add a Y comma Y I want to add that to the X XL I am dot adjust. So we add a grain of sand. I knew you can see now why I would like to kind of be able to merge together things that are like if I add something I just want to merge it but let's uh I mean it's pretty efficient already because we just kind of look up in the map and then we look up and it's always going to be increasing because we add the grain. Okay. Let's just do a collision call map in my end so collision and XL YL X Y then I'm going to say if we check the X collision so we take XL I am dot bang X okay and then we check just a axis any uh so we get uh we get the Y1 Y2 here uh Y1 less than equal to Y and Y2 less than equal to and Y less than equal to Y2 of the axis. Okay. Either that or I complains equals either that let's see where X call equals so that's going to be this so we check the X call okay this is actually a Y call but anyway Y call so then we check the axis nothing X call is the same but the other way right then it's YL and Y and Y X1 X2 X1 less than X2 and Y is here nothing falls uh X call or Y call okay now a lot a lot faster if we can binary search search okay so let me take how we can actually do that so instead of checking all of them you see the idea right we have this collision map and we're going to add the grains so we're actually gonna just take okay just let's just say here compact we're actually gonna pretend we compact but compact equals eight we're not gonna do it but we we we should do it okay and okay let me actually print up this map and we're gonna do it with the same ranges here so we're gonna print zero to nine and four ninety four to five hundred and three just to check that the collision map works okay so let's generate all the coordinates EX EX coordinates equals a let so we're gonna do the combination over 493 to 503 all right 494 to 503 zero to EX coordinates all right okay now we're gonna now we're gonna print these these are actually the X coordinates no they're supposed to be like this yeah okay and uh now print a map collision X okay so now we're gonna print these X coordinates okay so let's say um do four import control dot mona and we do 494 to 503 and do maybe we can do four loops in a four m a zero to no now we want to do it already the other way zero to nine it's gonna be a y2 494 to 503 it's gonna be a x2 do now if let's say let's get the call map first here let's go task one cmap is task one over read input if collision cmap a x comma y then putster dot uh putster dot else putster hashtag and then we're gonna do putster ln okay now let's see what this does right and then this one needs to be outside the four okay if collision we want the hashtag otherwise we want this okay so the collision map does work we could have we could have we could have screwed up there but we did not now let me compact the let me compact the map okay so so let's see so what is the grain end up first one that ends up at a so it's about 500 comma 8 so let's see here a a grain 500 500 comma 8 okay we're doing it every round or whatever that did not work okay so how do i uh so here i want to actually uh maybe i want to but it is 500 and let's see 500 comma 0 okay so my add grain function is not doing the correct thing let's print out the results uh print add grain 500 comma 8 uh cmap let a c equals where do you see okay if i am adjust okay let's see uh maybe it's because it's not there i am adjust update uh so alter i need to alter actually so it's not adjust it's actually so if it's something there just l equals just pl afp of nothing equals just so we're gonna say here uh and then i think it's the no so the x this is all the y coordinates yeah okay x x okay so eight okay so let's see how the way we're okay a y x x y okay now we've added to the list okay now i'm gonna add two grains a add grain 500 comma 7 right so that's like the next one i mean it's not the next one but we imagine we added something there now i want to now i want to i want to combine this a to come back compact okay so first of all i am dot a so we're gonna fmap compact over f my compact frame where fmap so where compact prime is going to be first of all sort okay we gotta we gotta sort it import control dot monad sort but is it going to be very i'm probably going to be very expensive to sort it every single time so let's assume that it is sorted so let's construct it and then we sort it fmap a sort sort so we maintain them sorted import a yeah it's actually pretty insane that sort is not there by default okay so we maintain them sorted uh variable monoscope sort didn't i just add it here i did okay now uh okay so because i think the initial one will actually will be fine okay so now i'm adding to the list and i want to change the and we're not going to compact it every time we're just going to do the alter function okay so if there's already a list there i mean so um okay so it's going to be sorted a okay so this is just going to be let's let's actually because we're adding single points here y x no yeah y and x okay so it's going to be i okay so we have just the list okay now we're not going to add it to the front so let's actually make it so that we can actually see this happen to 508 and then this is okay now we're gonna see this happening so we are gonna say a equal so we're gonna do uh first and then rest a equals where so uh span we have start and end and we are gonna say start is greater than the end of the i uh so while the end okay so we're taking until the ends are are so while we're taking while it holds right ggi doc span what do you think it's not possible dude i think we can do it uh we're longest prefixed element that's satisfied okay yeah so while it's smaller than i okay a of l now uh so we have start and we have start and so it might be like putting a line in like between and we're gonna we might be okay so there's gonna be some head of this list so this list is not gonna be empty okay let's actually do it like this extend so we want to kind of retain the the so it will only ever extend by a one point right okay so then we can just do a so maybe if it extends a starting point okay so just a let's say uh just pl okay let's uh let's actually just sort here can i do insert somehow like in a insert i can just do insert just insert verify data dot list as least and then this is listed insert okay now not actually compacting because we just maintain it here so we insert now so we can insert it into the list okay insert okay let's just be a bit shameless here now okay where l prime is equal to uh insert l prime now i want to see where that ended up so we're gonna say just a let's call this x here x comma x a let's see a let's call this p equals x comma x and then we insert the p not just e is a list dot index of in fine index now let's just list dot find index okay and we find the a uh lm index list dot lm index p l prime lm index index piece oh piece okay now we find the index uh so here i'm gonna say okay so now we're gonna check whether we can merge with the start or the end of some other list okay let's see a let's write that merge in comma in comma in comma in so they're off by merge okay x one y one oh x one so i start one start two uh e one uh start one and one and then start two e two is equal to okay so if uh so if the distance between e one if f so s two minus e one so the distance between those is less than equal to one then s one comma e two yeah and i'm gonna assume they're sorted let's say maybe now okay now let's see here uh okay now uh okay so let's uh so we could like potentially merge all the pairs here i think maybe yeah maybe that's just fine if we just kind of that's the original compact idea right there's check it we can merge anything and then merge it uh but let's actually in this case it's actually only one there's only one there's only always just one place we can merge okay so we're gonna want to like do it like this okay so l prime prime a is equal to if i is larger than equal to if so i if i is a larger than zero okay so i mean it's going to be larger than equal to zero um so if it's larger than so if it got inserted at the front then case l a prime of then it's a point here and there's another point and there's a rest and then we just do case merge p p two p one p two of just r and just p three of p three r otherwise it goes to be it's just p one p two r okay and then this one will always hold because if we have uh we inserted someone and then the list was not empty then we're gonna have this something at the end else okay then we're gonna do case gt lsc split at one one two three case a split at uh okay i minus one actually l prime oh so we're gonna have here the front of the list we're gonna have the p zero like point previous point the current like the new point and the point after that and then the rest now this might not okay so if it's p zero p one empty list then a case merge p zero p one of uh case merge p three per one of just p three and then it's f plus p three p three otherwise it's just f plus otherwise it's just l prime we actually yeah we can do that here l prime and then here we don't even have to have the error okay it's just l prime okay so if if there if it happens to be this way uh but then so this is okay anyway now otherwise we have the front and then we have p zero p one p two and the rest case merge p zero p one of just p three so then we're gonna do case uh case merge uh p three p three p two p one prime case merge p one prime of just p three so then it becomes so then we merge all those three points and become f plus p three r okay now uh okay we cannot merge p one prime and p two then we just f plus p one prime p two r now if we cannot merge p one prime then we are gonna say case merge p one p two of just it's gonna be a nightmare to debug if we have to debug it a p one p two of a p two prime and then we do uh f plus p zero p two prime rest otherwise we didn't manage to merge anything we just return okay so i'm thinking can we remove this uh so split at minus i minus one zero okay so if it's zero i think we can remove this if statement here so if i is zero let's see split at zero and what if i do split at minus one okay so it will just kind of work okay okay case merge okay like this okay now this is crazy okay let me print that five seven seven eight eight okay all right then i'm not returning so i'll return all prime prime see and now i got merged to seven eight now let me add a hundred comma six and we come six eight so let me add five here then it's five five and seven eight and if i add grain five hundred comma six ah it merges the whole line all right so now we can add grain super efficiently and it will kind of maintain the invariant now uh so collision so i don't have to check for all so i can actually just do um i feel like i think so much time optimizing this one it's probably completely useless um let me see here uh x call case i lmx y call so these x is okay so um let's you see take case uh take while uh e s as in take while s larger than y so if i take while s is larger than y so it will break once x is smaller than equal to uh so if it's empty and it just falls if we have an s comma e uh and then i check if s of y less y less than equal to e right and this is x is so then i can kind of just yeah collage collision like that now we don't have to check all of them but we do have to kind of scan through the list okay it would be nice if we could simplify this even further but uh let's say because we should be able to do like a binary search of the list and something like that but i think it's just premature i mean we're doing we've done a lot already right oh no i did it why did it work for the other one but not oh okay it didn't work ah let's just keep it any we've done a lot of work merging them we should still be able to utilize the fact that they're sorry we did all this work i should be able to check do this again uh is take while s comma e that we take while uh s is drop while s s larger than y oh s uh we're doing a lot of these collision stuff let's write them function okay into it and just so it's sorted uh but it's a list right so we don't actually have like a an array yeah okay so it doesn't matter because we don't have an array we don't have random access to the list we have to do it all anyway so it doesn't actually it doesn't actually matter but okay but it's nice to be able to merge things okay uh now let's actually go do the task um so grain so we're we're gonna do a grain falls okay so we're gonna have the current call map okay um now we're gonna do grain form int comma int comma and okay so grain fall it's gonna take an int to int to an x int to int we're gonna take the call map into uh int to int to um either so either the new coordinate or it's going to um turn maybe final coordinate either maybe uh this is a bit too bulky anyway grain fall call map okay then um g okay so we're gonna say a if collision cmg x gy if collision a a dmg there's something in the way then if collision cmg x go it's gonna fall down one step always falls one down one step if possible okay so so we have the current state of the set so if collision gx comma gy plus one so if that if there's a collision if not collision then grain falls cm gx gy plus one so then it keeps on falling else else if collision gx if it so it falls uh the other side i don't want to want to set it down and to the left gx minus one um gy plus one else if not collision then grain fall cm gx minus one gy plus one else if not collision cm gx plus one gy plus one then grain fall cm gx plus one gy plus one okay so if all of these collide then four possible collision is about then okay left gx gy okay now and i'm gonna check here also that so i have the x map okay and i have the uh so it's out of it's pulling into the void if there so uh cm add care about the what i forgot about the y here and i'm gonna say the like the min key min max and uh find min minimal key of the map find max delete update max okay we don't we don't care about that uh look up min equals uh look up max and we don't care about it and we don't care about the we don't care we care about that we care about okay so we look at max in name and it's gonna be just a okay uh so if this is the case and y max and when gy gy is larger than equal to um okay let's just actually do the grain fall and the current and then we actually just return a new call map okay so if it's larger than y max we are done we return cm okay this is the base case a now we do otherwise grain fall a equals m dot look up max so if we're not um if we're not out of the out of bounds a let's say init pause equals 500 comma zero so grain fall then else a add grain a so cm prime equals add grain a g cm in grain fall cm prime init a pause okay now if anything if it falls into the void then we are done okay so okay so here's where it goes and if not okay otherwise it goes to rest and and we end when okay let's just see what this does okay let's um if collision let's say cmap if collision cmap like this now let a g map equals a grain fall cmap init pause if collision cmap then put string else if collision g map x comma y let's put string dot okay it looks exactly like that yeah okay now we need to figure out we have the g map a and we have the cmap okay now let's figure out how we can how do we figure out intersect because we uh we joined all the we joined all the lines so now we actually don't have the okay left bias intersection so we actually want the difference a difference difference okay so then we do a let a diff equals a g map without a cmap g x we don't care about the gy here a cx and then let's print out the x cx without a gx sorry gx i am dot slash slash gx okay let me print diff okay and say here um range size x int to int a a range size s comma e equals e minus s plus what okay so the diff is going to be the i am dot lm's box lee i am dot four i am dot lm's conkat conkat map map range size we're gonna sum 22 uh there's 24 let's see a quite annoying uh right because uh because uh merging okay these will just be the keys that are not in the map so let me just do here grainfall 24 okay now let's not print the collision map a cmap task one read input task one okay let's see here a we're gonna be the cmap and then task one is first of grainfall zero cmap init bonds not task one see if it still works still works no did i fetch the input already no this is the old input i didn't fetch the input 737 let's see if that's correct all right we got task one what does cmap at mean zenith is asked so this is a trick in haskell one lot of trick it just means that a we are going to give this thing here a name let me explain so we're because we're kind of unfolding the pattern and we don't want to repeat the whole thing again so we actually so here so right so instead of so you say v at and then we say whatever the pattern matches and match against and then instead of having to say i comma cm again here we can actually just say a v right so we we gave whatever this pattern matches and name right i'm called that v all right a okay now let's go for task two i hope all this collision stuff was worth it there is not there wasn't one who's got there's a floor and you're standing on it you don't have times gone far so you assume the floor is an infinite horizontal line with a y coordinate equal to two plus the highest y coordinate of any point in your scan okay the two plus the highest y coordinate of any point in your scan any example above the highest y coordinate of any point is nine and so the floor is at y plus 11 okay and let's see two lines in ps and we have the highest y coordinate is the black box on the corner oh no there we go don't know what happened camera seems to have stopped broadcasting that's how long this stream is uh sorry about that i hope it wasn't too long okay but thanks for pointing it out anyway a now we're gonna have to figure out the highest y to task two okay so we have these all these inputs and we want to figure out the highest y point just stop there task y in ps and a let's get just no input so what is an input an input uh okay let's do two lines what do we need to two lines the input is just an i and okay let's do uh we will find the highest y of all of them a y of a x comma i've been having some trouble with the camera i don't know con concat map yet y and then maximum so let's see what the maximum is task two should be 11 no it's nine okay and then and so floor is equal to two plus this okay so this is the floor and the highest okay so minus infinity to infinity with the add floor the example about now looks like this okay so now we do this again but we will add a line to the y's uh right and now where y's is gonna be okay so the line uh minus a min well i think what is it called again uh enum enum has a no max min bound yes so the x coordinate here is a min bound map floor and the y coordinate x quarter max bound for oh let's print it again call map c map now uh c map is read input task two i need to check my camera because it's a shouldn't be doing that day 14 example okay and let's just let's just call this g-map no okay if collision g-map so we're doing it twice but whatever okay uh and now we need to print to 11 let's print from 490 to 505 okay now we have that we have the floor okay the final summary you look like in the example above the situation follow looks like this until a unit of sand comes to rest at 500 comma zero okay so a grainfall we have to change this is a grainfall two now it's not actually a y max we actually check uh if we have a collision case a collision cm init pause i comma cm and then it's just the same uh so this is two two two two and we have the grain and uh it doesn't like this grainfall have two different number of arguments i think is i don't care about this one let me see here now uh let's see i comma the c map is the original one now let's see and now let g map equals grainfall zero comma c map a init pause a i comma bar comma to the rest init and then we're gonna say g-map here again oh it's not good so they never stop trace show aid okay so let's do here a okay this is just supposed to be trace show sorry about that okay it never seems to hit the floor which makes sense ah wait okay so the c map is the correct one right i mean it's just like it's like they keep falling let's see if not collision okay let me keep going and then we add it so it's like the first one keeps falling right it's not actually finishing anything so it's not the condition that's wrong you print the c map here okay so this is the 11 okay let's not do collision there right let's just so instead of uh let's just have this int here and then this is just wise and we're gonna need this okay and this is gonna be uh int comma comap and it's gonna be the floor okay and here we have the floor okay so if it hits the floor then okay so we say a okay so we want to end the whole thing here now grainfall to floor a v y comma c m a g at g x comma g y and the case is that g y plus one is larger than you get the floor okay so when i'm on the floor equals let c m prime equals add grain okay i think this might work g c m and grainfall to y plus one comma c m prime it wasn't even running it okay okay let's add the floor here just because it looks better y is equal main bound comma floor as already let me print it this way so we need to add a few more 85 to 515 okay but let's print the r here 93 okay quite fast now let's see i want to do just a print task one and i want to do input print task two let's see the floor okay and i'm not gonna print the c map it's r am i tracing somewhere trace oh i'm with me printing out task two okay a we print out this and then we're gonna do task two on the input and then a c map i g map i r i floor i task two reading before i c map print might take a while up five seconds two eight one four five all right we finished day two yeah sorry about the camera issues took my camera out and i put it back in and now it's misbehaving i'll see what i can do about that i have a backup webcam but you know that's not as cool anyway thanks for tuning in sorry about the camera issues let me do git status git add day 14 git status git add util git commit am day 14 all right thank you for today and let's see what happens ah little lanny is here nice let's see let me see if i can fix the video for tomorrow oh sad i think it's like the power something blah blah i'll just take it out fix it up but anyway thanks for tuning in day 14 we are more than halfway through not bad ah i could share on masked it on ah that's very cool all right thanks again and uh yeah see you tomorrow all right bye bye