 All right, welcome to today's stream We're doing advent of code and Yesterday I struggled with day 17 again. I didn't get part one done And no matter what I tried it was just too slow So I eventually gave in and I did what the good programmers slash good software engineers do and I looked at what others had done So I figured I rewrote everything from scratch Most of the code I saw was in Python. So I Adapted it a bit for Haskell We're still using the arrays because those are quite easy. We removed all the Modification stuff so we don't have like the ST monad hang around anymore And it works for the example and it finishes on the input quite fast with a Special trick that I figured out So let's go through it again. So the parsing is the same right? We just have an array of weights or the the heat but We simplified it a lot right so it's quite So now instead of keeping another array that we're modifying and writing the shortest distance to To a given position we just keep a heap of the positions and the directions the direction we took to get there and the length of the path it took to get there and then we just Keep inserting the speed so we for seeing something again We know that because we're always looking at a heap. We're always getting the shortest path So far so then we're gonna get seeing something again, then we know we have a shorter path to it Then we skip it and then the trick is if we see something again from the same direction Right, so we got there from the same direction before So that that's the trick right so instead of so so I think my approach would have worked Given enough time But the problem with it was that we kept trying to maintain all these paths and all the possible paths And then you were gonna look at the path in the end and it was just too slow But with this implementation we just have us two sets, you know what we have visited So have you seen this note from this direction before and then we have this heap and this is a nice trick a sets in Haskell are actually just heaps Except you know the elements have to be unique, but in our case the elements are unique so just works out so instead of So what I do now is I Say so now we just always turn Okay Instead of saying okay, you can go up down left right We just say you know if you're coming from up you're gonna turn come down you can turn but check is that we're gonna take three steps at once or So we're gonna take one step two steps and three steps and we're gonna add that all to the heap at once With the shortest path there and then we can always turn because if we were have if you would have gotten there in a valid way From without turning It will already be in the heap so we don't need to think about them Then we simply generate So all so we take the steps right so we left or right or up and down and then we just generate all combinations of those right so taking up So not all combinations, but all A number of times we can take the steps right so you can go up once twice or three times And what we do here is just so you just replicate it right so you have one two and three and then We figure out from the From the paths we figure from the directions which is calculate the path and the direction that we took and And then we just make sure that they're all in bounds. We're not escaping the grid and Then we map this PF function. What does that do? Well, it takes the current path like the current length of the path from this node and then We just add up the length of the path so we get the new length of the right and this just involves looking up This array piece so instead of so here is where we would have like be writing it through the array or something like that We don't need to leave that and now the trick right so these is gonna be a list of New nodes for the heap Hi, little Annie Icelandic keyboard happening here She might make a guest appearance later today I Have heard I'm getting vanilla cookies. Not bad Not bad at all Okay, so yes, what was I saying? Yes, so instead of like creating a list of new nodes we create a set of new nodes Which is cool because Then when you add it to the heap you just take the union of the two sets What does this do? Well, it makes sure that so it's it's a it's a very fast operation, right? I think it's like log n log m Or like min and m log n where it's like the size of the two and because one of them is quite small It's gonna be super fast and then we can do this. This is basically heap pop right delete find min So we take the smallest element In the heap and we take the rest right so What do we gain here now we have a proper binary tree heap Meaning that so even though popping takes log n and inserting takes log n That's a lot better than Popping taking of one which is good, but that insertion took o event, right? Which is not good. So now it's super fast and it takes 1.67 seconds on the Doing the example and part one and I'm pretty sure this correct, but we I haven't checked it yet. So I'm gonna pop it in here and see boom We did part one finally continue to part two It also gonna upgrade to ultra crucibles. So they're even part of the steer Not only did they have trouble going to straight line, but they also trouble turning I saw it needs to me a minimum of four blocks to move Okay, so before it was minimum one I was known for however We eventually to get to start good wobbly and it will make them 10 consecutive blocks without turning In the above example ultra closer. We could follow this back to minimize heat loss 94 here's another example Let me just say yeah, so let's just take in these Mean step max step Didi didi didi and then so instead of saying one and three here we say mean step Max And then die extra so for the example We're gonna be getting So because this is saying okay, we replicated before we replicated it once up to ten times Nice indeed, but now we're doing no one two three times. Now we're doing it four to ten times So let me see here mean steps. This was one and three for the example. This is gonna be four and ten We see One or two still works 94 it gets the example right 1171 in six seconds Not too shabby. What is the least heat loss they can incur boom Part two done and that's it. So this is also what I figured about day 17 Is it Android from Jane Street? We're not doing a camel though But we love those guys anyway I've been wearing a lot of their t-shirts on the stream So it's kind of like a double-sponsoring Anyway, it works as I expected Because I had seen what others had done in Python and We adapted that we don't have the EPQ or whatever, but we can use sets Because we and we get you know decent performance, right? We could make it better by like unboxing the integers or whatever But that seems like a lot of trouble For something that only takes seven seconds So again first of all What we were doing wrong initially and why I was hacking for like six hours and never getting anywhere Was I was keep I kept trying to track the path because I wanted to debug But that just made everything super slow because I had to build all the possible paths Which was not good So and instead of using lists We used heaps and that took it down from like So this was before was like one and a half minute And it went down to for just part one And it went down to like one place six seconds so using the heap really made a difference and And then the only thing that matters is the direction that we came from and then we just do the turns and That was also the trick like do three steps at a time so do the one and two and three steps at a time and then We have the Then we can just always turn we're not deciding whether to go up or down and then checking if In case we go up that the path will be valid and all that We just take the steps that we know are valid and then put them in the heap not just write them to this path Right. That was also what was messing it up, right? We had this Distance array and we had this parent array and we were trying to make it juggle the things and it was just not working out Okay, and yeah, like I said, we had the right idea We were at the end taking multiple steps at the same time by generating all the valid paths but Because we just did it like one step at a time and then we were filtering and adding that it just didn't work out I Think also the problem was that we didn't like sync up as we took and the past. Yeah, I was just a mess. Anyway We did day 17 now. Let's a Let's go back and do day 18 But I think we're good for now Let me see So and then again, how did I do it? Well Like any good software engineer. I You just you gotta you gotta look at what people have done before right? You know, we're not gonna do it like right away, but I feel like if you worked at something for six hours And it's just not working out Maybe you should consider Listening to someone Seeing what they've done. Let me say touch day 18 dot HS Module main where Do-do-do-do I did also have a sneak peek at day 18 and I Love these effects by the way and I it's gonna see it looks like this. We're gonna do green serum again Luckily, we already have green serum Okay, so what are we gonna do here? So these factories back one of the first okay, so elves already treated so To make sure the lagoon will be big enough. They asked you to look at the dig plan Your puzzle input for example rdl D rdinka lu Rulu Then they dig the specified mirror up down left or right clean one for one meter cubes as they go The directions are given as seen above Zoe for the northern right will be east and so on one. Each trench is also listed with the color of that edge of the trench. So let's take this example input here. I think it was day 10, that was greens theorem. Yes. This is indeed green theorem. Okay. We're going to be copying that. Well, let's say pars, elusive string. So what do I need for greens theorem? So dare north, south, east, west. So this is going to be a list of, let's actually make it up. No, north, south, east, west. Okay. That's easier. So it's going to be dare, and then a number, and then some RGB code, parse, stir, parse equals map, parse, stir, parse, one, where parse prime equal. Okay. So now we are going to, I'm sure I have split on somewhere here as well. It grab, split on. Oops. In day 14, we have it. Let's go to day 14. It's nice that we, you know, we don't know this pre-work previous days. So we can just reuse it. Okay. Let me see. Parse string. Let me see. d n s is split on, split on, split on, space, stir. Okay. And then we are going to say, we're going to say parse, dare d, read add int n s equals a, which is like this, parse, dare. And now if it says, parse is equal to east, l is equal to west, d is equal to south, r stir, u is equal to up, module, no, main, ire, main is equal to read file. Example into, into. Oh, this'll be north, actually. Day 18. Let me see. Day 18. Day 18, Rybalot and scope, d d d, yeah. Okay, east to south, five. Okay. Nice. The digger starts one meter whole cube in the ground. When viewed from above, the above example dick plant would result in the following loop of Trench having me dug out from otherwise ground level terrain. Okay, so let me see. We can actually grab from day 17 also the moose, right? So this is going to be now this is going to be west, east, north. So we're going to get the, we're actually going to get it. It's going to be upside down, but that's fine. Okay. Okay. Now we're going to see part one. Okay, let me just part one stress equals where P equals a parse stress. Okay. And now I'm going to make just make a path. So path is going to be empty is empty path a this is D and then times and then we don't care about this one is equal to replicate and D concatenated with a path. So now we're creating the path which is suboptimal, but it's okay. We can optimize that away later, right? Let me say path. Then we are going to say moose print part one. So this is the path and now go back to day 10 and we want to say we had here green area and how did we do it? So if we are going east, we add the y coordinate. If we're going south, we don't do anything. If we're going west, we deduct, right? Let me see. Green area, gsf is equal to gsf and let me make this like this green area of x comma y. So here we have so west. Okay, so I want, so east is adding and okay, you're right. So it's not, it's yx, right? Okay, green area, y comma x, d, let's see, is equal to delta is equal to and gsf is equal to a case d of. So if we're going east, we're going to add, we're going to add y. If we're going west, we are going to minus y. Otherwise it's zero and let's see, green area, gsf plus delta, gs. So we got minus 42. I think we should just take the absolute value. When viewed from the above, the above example, I think we did the wrong thing. Let's see, west, east, I should just get 42. Okay, the digger starts in a one meter cube hole in the ground. They then dig a specific number of meters up, down, left, or right. Clearing full one meter cubes as they go. Let's actually, let's start from one one, right? We're getting the same because we're going around the path. They then dig the specific number of meters up, down, left, or right. I think otherwise we are just adding one to the y plus one, because we're also counting the area of the curve. Okay, this is 60, but we're supposed to be getting 62. Let's see, what is the area of the curve, which is to say the length of, and then length as p. This is 38. Let's not count the path here. Don't get this 80 number. It did take us a long time to get this green area correct. Let's see what we get here. We have the, okay, so it goes, it goes north again, right? It goes east. Okay, so first of all, they have dug 30 cubic meters of lava so that it is one meter deep. Let me see, gti 62 minus 38. We should be getting, okay, because we're going the other way around also. We're getting 42, 38. We should be getting 62. So here, now we're also counting, now we're also counting when we go north and south. I think maybe something to do with the corners, or maybe not, let's say south one, north minus one. Yeah, okay, they cancel each other out. So the total length, if we count all of them, is 80. Is it just 80 minus 38? I think so. Then we get the right number, right? Now then we get the 42 image. Let me see, so 80 minus 18, and now I'm doing also minus length paths which is messing me up, 80, 70, 60. So here I do get 62. If I count the trenches when I go right, I want to go, if I count those trenches, and then I think it's because I do add the, let's just see what happens. This is certainly 62, which is what it says. It should be for the interior of the lava. Now let's see what it says for the input, five, two, one, eight, eight. The answer is too low. Okay, we didn't get it. Right there, right on time, and it was too low. And maybe the directions are just, I think maybe the path, so the directions are not really true. Okay, let me, I had this nice from function, right, before, let's see, from x1, x2, y1, x2, y2 is equal to, so if x1 is equal to, let's keep it in the same coordinate. So if y1 is equal to y2, if x1 is less than x2, then to go from x1 to x2, you have to go east, else west, x1, x2, if x1, y2, so let me see, we added, so north, so if then north, else south. Then let's let our good old turns function again, x, y, x is equal to from, x, y, turns, axis, turns of, anything else is equal to an empty list. Okay, now let's see most path p, let's see mp, and we want to see path p, I want to see turns, dollar, map, first, mp, we run it on the input, so it says east, east, east, south, south, south, south, it says let's actually sip these two together, length path p, length turns, mp, map, first mp, and I want to see, I want to see sip, turns, map, first mp, with path p, okay, yeah, so they don't agree and all of them, right? So, but turns is one shorter, and the path, because let me see, turns of x is equal to from, x, zero comma zero, and because we end in the origin, right? What is it saying here? We go up twice, now both of them are the same length, and I want to actually flip it around to make it easier for me to understand it. Let's see, and so we go north, actually when I reverse the path, I think, because I wanted to start at the origin, okay, then it goes north, it ends up going west. Okay, let me see, mp, mpms is equal to turns, reverse, map, f is the mp. Now, okay, this is mpms, and we are going to sip this with reverse, map, first mp, and then we're going to pick the green area of the mpms, it has to be the other way around, and then if we're going west, we're deducting, otherwise we're adding, and then we still get 80, which is off by 18. Okay, so there was no point in all this, let's just go back to this then. I think this is maybe also, maybe I have to do again, this is kind of the synion again, right, two times y plus one, and then this was supposed to be divided somehow, right, four, four, two, and we added two, something like two, four, right, mhm, so 38, this is supposed to be something else, right, let me see, so we had some back on day 10, we did this, right, okay, yfh7 only contributes one, mhm, so then we had these pipes, right, so that was like if we're going east through a corner, then east was, then the delta was four times y, and delta is minus four times y, we're going north, it was just zero, and if we were going south, it was also zero, let me see, mhm, so here the curve always takes it itself, okay, minus, yes, I think I'm having the same issues as when I was doing Grinks earth here and before, so we go clockwise around, and then we need to come forward with the corners, all right, I think it's because the corners are being counted now, right, so now the corners are being counted, that's the problem, mhm, so let's say we have the path, let's say and then we have the, okay, so we have the path, and then we move the path, let me bring that up, so I really want to look at two points at the same time, let me see here, I really don't care about the x's here, I actually don't care about x's at all, mhm, let me do like this, map, map a x comma y comma d, no, y comma x comma d, y comma d, so mp is just a list of integers, comma d, it should be y1, right, in area 0 mp, divided by 4, okay, now let's look at d1 and y2, d2, I actually don't care about the y1 and y2, so case d1, d2, of if we're going east, east, if we're going west to west, then we deduct, now here we go again, okay, so this is west west, so if we're going east and north, this is the, this is the seven case, okay, so this is a plus two times y, okay, this is two times y, if we're going east, east south, then we are, we can't go east south, because we are never, no wait, maybe, yeah, okay, we're going east south, then we're in the seven case, that's also a plus two y, okay, now this is the east, the east west doesn't exist, so west west, west south, so this is the f case, so this is minus two y, um, then we have the eight west north, this is minus two y as well, okay, and then we have north comma north, zero, and we have north and then east, this is two times y, this is the f case, and we have north west, this is the seven case, now south and south, and then east, this is the lk, so it's two y, and south and west, minus two y, here I really do need to add, like I really do need the x's here, because I need for the last one I need to figure out uh, but it did, it goes to the origin, the last one is, let's see, so if I have, this is like this, so this is a delta, d1, d2 is equal to k's, d1, d2, of, it's complaining here that east north is redundant, south, I forgot a south comma south, let's keep it the other way, okay, just write this function just here, delta, d1, because I didn't write d2 here, good, pattern matching, catching us, from disaster, now green area, gsf, I imagine we have one left, is equal to, where d2 is equal to from yx2, and is equal to green area, gsf plus delta, a, y, d1, d2, d1, d2, now this should not probably not be like this, green area to this, oh, here doesn't matter, but this is oric, so we're gonna say from to oric, and here we say oric, so we know, so in that case we go back to the origin, and then we just have to say zero comma zero, ah no, head and P, okay, now we're getting minus 21, which is not great, but it is not terrible, let's see, I think maybe we screwed something up somewhere, so east east is four, we go east and then north, that's plus two, we go east and then south, that's plus two, we go west and then west, that's minus four, we go west and then south, that's minus two, we go west and then north, that's minus two as well, now we go north, north, that's nothing, we go north and then to the right, that's plus, we go north and then west, that's two, and then we go south south, that's zero, we go south and east, that's correct, south and west is minus, I think we should flip the sign or all of these, let me see, minus, so we're gonna go the other way around, then we get 21, now let's add a curve area, so we're just gonna add the curve area here, okay, so south south, it's gonna be two, this is south and then east and then this is two and then this is north and then east, okay, now west, west west two, west south was one, west north plus three, east south plus two, east north plus one, okay, now we get 31, we're supposed to get 32, okay, but here we divide by two, maybe we should just divide by two, let's see, we are suspiciously close, we are getting the right, we don't need the curve here, five, two, two, three, six, that's too high, let's see, let's keep dividing by four then, but here it's not such a just before, so the corners are one and three, but let's not calculate the area of the curve here, I think they should be two, I feel like because I think I felt like we had green serum like nailed down, you know, sorry, here I am skipping a lot, maybe that was just the thing, all right, good, we got part one done, okay, we just copy pasted our code from day 10, and we had some issues with, we just had the issue with, so we did the same counting, same green area, same curve kind of thing, except now we count the curve also, so we don't deduct the curve, but we were then, when we were doing it, we were just dropping things, okay, now what is the, I feel like we're much as small, so we'll swap the color and instruction parameters, each hexadecimal code is six hexadecimal digits long, first five distancing meters as a five digit hexadecimal number, the last hexadecimal digit encodes the direction to dig, the hexadecimal can go right away to the true instructions, okay, now it's gonna bite us that we did the path, but that's okay, let me see, parse string, fire text digit hexadecimal number, let me see, so let's convert these numbers then, a five digit hexadecimal number, okay, the last digit, so then let's part one parse stirs, let's just write then part, let's have this then be deer, what is it actually, deer int string, let's just have this be deer int, and here we're not gonna start by parsing, it was a parse to deer int, my parse prime, it's also gonna be deer int string, deer int, and we are just going to crop that one, and here we're also just going to crop that one for now, and then p, now fp, and now we're just gonna ignore this one then, part one, parse one, part one dot parse, let's see if it still works, it still works, so now we got a parse two, so let me see, parse two, the last digit, so zero means r, zero means r, one means d, two means l, and three means u, so we have the d and n, so we don't care about that, so we have the s, you see we have the d and the n, and the s, and the s will start with a parenthesis, so six hexadecimal digits, zero, so one, two, three, four, five, six, so this is gonna be like this, and then like hash, and then let's see x digs is a take six s, and so and then a deer dig is going to be, let's just take five of s, and this is a drop five take one dot drop, take one drop five s equals a parse deer dig, now how to convert from hexadecimal beta dot char, hex, we have a, we have a, we have it, how do you convert, let's go convert from base 16, show, add base, printf, this is from base, okay, okay numeric, show int at base, readbin, readdecredoc, read hex, nice, let's say hex num is read hex, hex num, now I have to import numeric, let's see read file, example, print dot parse to dot line, let's see is it correct, four six one nine three seven, yes, okay, so it's converting correctly, now I think we should, and instead of like creating the, let's just see what happens, okay, let's just see what happens, how long does it take for the example, for example, that's not too bad, in the meantime we can see what happens here, so let's see, no let's say path d and then ns, it finished, all right, it finished in one minute, that's not too bad, I mean so what we could have otherwise done is kind of try to, instead of, so we kind of just calculate the area of the joints, and yeah so kind of just jumping faster, but okay, get status, get at day 18 dot eds, example, input, get status, all right, we did it, let's just leave it at that, we're trying to catch up, so we're not gonna get commit, day 18, hit push, so because it is the 90th day, let's just start with two days, see if we can catch up, yeah, I mean like I said we could do this faster, right, by, let me sketch it out, sketch for speed, just calculate joints, so we would have instead of replicate, then we would just have you know east, north, west, make sure to increment the i, add, so you know east six is equal to east five plus a joint point, east six would contribute, east five, east six would contribute, six minus would be then you know a minus four times would be a east n would be n minus one times minus four times y plus two etc, right, that's a sketch, we're not gonna implement it because we're trying to catch up, but I think it would have been good, all right, let's go on to day 19, which is today's and then we are catching up, you know, get commit, add, sketch, more faster, day 18, ding, ding, ding, okay, let me start here, touch, day 19.hs, input example, module, let's see, language gtsy 2021, module mainware, we're here, main IO, main equals, okay, gtsy 02, day 19.hs, oh, day 19, and time, day 19, okay, let me now do close others, I think what saves us here is actually laziness, because replicate is not generating like this path, and this moves, right, it's not generating the whole thing, and then doing it, right, it's consuming it as it goes, and then because we're careful, we consume, we consume, right, but because we're careful, we don't build up like a huge thunk because we make sure that the addition is evaluated, right, so it works, it's kind of cool, and you know, it's not super fast, but it's not slow either, because of laziness, take that, all the cameras, no, we love those guys, and gals, let me see, paste the example here, now let's close the others, we're probably gonna have to couple it, okay, day 19, I feel like we're doing good on the stats, a lot of people fell out after day 17, which is fair, it's quite difficult, so now we're in like the second half, oh, yes, I had sneak peek this before also, it's a, so it's like an avalanche system, so we have to accept or reject, and so there's a workflow, and there's some rules, and then you send it to the workflow, so it's a funny input, that's gonna take some parsing, but we will just start with a, oh, split on, our favorite, let me see, okay, and then we are gonna do, so read file example, print.parse, so pars is gonna take a string, and let's just not do anything yet, so parse string is equal to, so let's do here, so close, and items is split on, and we're gonna split on an empty line, linester is equal to close, items, let's see what this gives us, excellent, so now we have the flows and items, so we're gonna say here map parse flow, map parse item, where parse flow is the, okay, so here we are going to have a name, comma rest, and we're gonna say take, so span not equal to this one, okay, and then, so that's the name of flow, okay, then it just says a, and then rfg, what is this rfg, okay, the parse more than x, rule a, otherwise because no other rules match the part, the part's maybe accepted, actually the musical item might not match any, okay, name as a, okay, so I'm just gonna, I'm gonna say here, I'm just gonna drop a rules, it's gonna be filter not equal on rest, and then let's return a nm, comma, let's say here split on span st, okay, now parse item is equal to, so this is gonna be like this, and then items, and we are going to say it's, it's gonna be, let's get the puzzle input, I'm just wondering if there's a lot of workflows, okay, but all the items always have all of the values, okay, good, filter not equal to items, okay, and so then we're gonna have x, x, m, e, s, split on, comma, it's, and we're gonna drop the first two here on all of them, let's see, map, drop to, split on, xmas, and we are going to return item, dot, dot, um, language, record, puns, and let's say data item is equal to item, x int, m int, a int, s int, deriving, eq, show, port, read, let me see here, gsi, we could actually probably get away with parse item because the syntax is similar, um, parse item is equal to read, add item, item, nice, quite easy to read the items, okay, um, so we have the, we have the rules, data rule is gonna be, um, it's gonna be one of the, one of the, um, ints, it's gonna be, let me see, it's gonna take, let's not make it too opaque, so it's either, uh, accept, reject, or, um, let me see, a rule, so a re, re-salt is accept, or reject, or send to string, um, let's say, uh, instance, so parse, right, okay, so parse result, a string to result is gonna be a parse result, a, a is able to accept a parse result, oh, a new follower, welcome to the stream, reject, parse result, a str is equal to send to str, now, um, so a rule is a data rule is a maybe condition result, and, uh, data condition, condition, if we have a condition, it's going to be a, a, uh, cond, it's gonna be label, which is gonna be, uh, character, uh, it's gonna be, then it's gonna say, we're gonna say comparison, so each rule, x larger than 10, m less than, so it's either larger or less than, uh, check, so LT is just a bool, so if it's not LT, it's a greater than, then, well, it's just int, okay, now, parse, result, parse, rule, so let's see, map, parse, rule, rules, so a parse, rule, st, let's see, uh, split, so if, if it's only one thing, r, split, on, on, golden, a, st, this is just nothing comma, um, um, parse, parse, result, parse, parse, rule, parse, rule, taking the string and returns a rule, mm-hmm, mm-hmm, it's supposed to be like this, okay, if we have only one thing, it's just a result, otherwise, it's gonna be, c comma, r, split, on, st, equal, a, a, just, um, parse, condition, cond, c comma, r, result, r, now, parse, condition, parse, cond, takes in a string, returns a condition, condit, parse, cond, so we're gonna have a character here, and if this is larger then, then val, a, s is equal to cond, and a, c, uh, forms, um, read, add int, val, otherwise, this is LT, and let's just make this, uh, if LT is equal to less than, then, this is just this one, actually. Okay, parse, rule, print, parse, no, show, condition, I should say, deriving, show, eq, word, all that jazz, no, show, result, deriving, show, let's say, instance, show, show, result, where, let's just say, show, accept, is equal to a, show, reject, is equal to r, show, send, to, stir, is equal to stir, so what I should do is, I think, I need to like, look at the, I don't remember the overlapping pragma, I want to just do this overlapping, because you can't do this, actually, but it comes right after here, okay, where a show, nothing, r is equal to show, r, show, just, c, r is equal to, um, show, c, show, r, okay, and now, what does it say now, let me see here, and let's not derive this one, a show, instance, show, condition, where, show, con, l, l, t, v, v, is equal to, um, we do l, concatenated with, if, l, t, then, less, else, larger than, a, concatenated with, show, v, okay, now we've shown all the rules, so I think, let's just do part one, where we just send them around, okay, hmm, okay, so, part one, and str is equal to, let's just make it take in string, let's actually make this right away, just map string list of rules, okay, import data dot map, map, import qualified, qualified data dot map as map, and then a map dot from list, and then we have all the, so what you would want to do is like, symbolic evaluation, right, where you kind of, symbolically evaluate, figure out for all these rules, and so I'm guessing that the rules are applied top to bottom, system works, but it's not keeping with the corner of weird middle, for example, works of the list is first, and the ratings, all parts beginning work named in, okay, so let's see, process item, can we get either, so we take in the map string, we take in a item, and we return true, we return false, true or false, process item rules item, okay, let's see where, so in, so get sent to, let's do a, so match, and we take a list of rule, and we take an, okay, so, all right, okay, so process item, process item, okay, let's pause this, let's say first here, and match, list of rule, and an item, and a, we get a result, okay, and then let's see, chart to sell, chart to item to int, chart to sell, if it's x, this is x, this is m, this is m, a is a, s is s, match, let's see, r, so if it's nothing, we return except, I think if there's nothing, okay, let's see, match, rrs is equal to, now let's look at the rule, nothing, r, so if there's no condition, we just return r, match, adjust, count, okay, so then we have, okay, there's no count, it's count, and now I want to just see it also here, then we do, I want to have it open in both windows, so this is count, and how this condition look, a, where s, sell is equal to chart to sell, a, l, and then a, comp is equal to, if l then, if lt, then else, okay, so let's just say, so fun is equal to, i is equal to chart to sell, l, apply to, i, this is applied to comp, well, just count, let's see, if chart, let's see, if chart to sell, l, it, comp, well, if then, r, l, match, r, s, a, t, language, record, wildcard, it's called, it's the extension that I want, okay, so now let's say, process item, map, string, rule, item, pool, so we're just checking whether it's accepted or rejected, process item rules, right, is equal to, where, so in rule is equal to rules, a map.bang, in, okay, and then we say here, case, a match in our hit of accept, true, reject, false, reject, reject, send to k, we have here this process item, period, and in, and then where process item, period, and key is equal to case, rules, map.bang, k, send to k prime is equal to process item, I just need to do it like this, process item, k prime, okay, ooh, another party, belay, welcome to the stream, I hope you are enjoying the habit of code, we are doing day 19 today, we started by explaining the solution to day 17, then we did day 18, which took a bit, and now we are doing day 19, part one, okay, so let's see here, part one takes in a, whatever this, returns map, string, rule and then list item, ding, ding, ding, ding, ding, ding, ding, let me see, and adding up the xmas rating for each of the accepted parts, add up item, add up item equal to x plus n plus a plus s do int. Part one and I'm going to say rules items is equal to sum map add up a filter process item rules items one nine one one four well okay it was not too slow for the example at least I mean the way to do it is to make it uh like just figure out like given given what range what items and where but okay non exhaustive functions and function parts maybe I never oh I didn't paste the input that was quite fast all right we did part one of day 18 not bad oh day 19 sorry now let's figure out day two process still isn't fast enough each of the four ratings can't have an integer value ranging from a minimum of one to a maximum of 4 000 of all possible distinct combinations of ratings your job is to figure out which ones will be accepted it would be super nice here if we had the if we computed the thing like we said we should do let's see uh what is uh 4 000 times 4 000 times 4 000 times 4 000 it's a large number but uh let me see part two where items is equal to um item over uh so all possible x's so one four thousand one one four thousand one one four thousand one one four thousand one these are all the items a from one to four thousand let's just see what happens oh we didn't do we say part one I'm being so lazy right now okay it's not doing great on time for part two which we kind of suspected but uh okay so I think we need to like make a like a decision tree we have to convert the whole thing into a decision tree so funny this work though it works very fast for part one that's for sure that's kind of nice so what we want ultimately is we want we want a list of ranges that will be accepted and a list of ranges that will be rejected hmm so let's uh let's get cracking this is not gonna finish it's not gonna run out of memory though I'm pretty confident each top but it's going to run for a while hmm let's just see import oh it doesn't even start let's batch all right let's not do it this way um let's just first uh inspect the rules let's make a tree let's make it into a decision tree how do we do that let's see and so let's see data we have a rose tree hugo rose tree tree a tiki tiki tiki tiki tiki so we have trees in Haskell which are actually just import data.tree tree import qualified a data.tree has tree so we are going to create a decision tree and then we're going to view it okay let's see deck tree takes in the rules string rule and returns a um a tree of uh conditions I think of a cond okay so uh deck tree is equal to um let's actually make this like this it has a rules and then we have the current rules okay let's do like this deck tree rules is equal to deck tree prime map a rose map dot bang in where deck tree prime of um empty is just so this is a so we don't have any more rules and then we default to accepting okay so this one is a note nothing comma accepts let's import tree tree and it's constructors note nothing accepts and then deck tree takes in prime takes in rule and returns tree condition no what does a condition look like ah no that's not what I want um takes a list of rules and returns a rule and and this so this one is nothing comma accept okay now however okay so we are figuring out the tree here deck tree prime if we have a rule and it has no condition nothing comma r if it has no condition then we do note nothing comma r and then there is no subtree however deck tree prime um just c comma r r s this is going to be um i'm not ready i don't think this is correct so let's write it down okay so we kind of want to say okay as we have here x we have here you know we want to say like for the first one so the crn you want to say so it's okay for the first one it's going to be so s less than one three five one so it is a condition and uh how do i it's a condition right and then if it holds then we have like the tree for px okay um if it does not hold then we have a qq set so the notes are conditions which was correct condition okay and so let me say here note condition and if there is let me see if there is no condition then we've uh it's just an error i guess error no okay so deck tree of um just see maybe condition let's see how that no i don't know okay a decision tree so let's just do this condition here okay just c comma r r s this is going to be tree and then we have the condition okay then we have a so then we want to have one subtree which is like the condition and then we want to have one subtree which is the like the r s the rest okay so here we check on the condition let's have either condition result and then this is either condition or assault okay this is just going to be tree right except and then nothing okay tree just so if we have deck tree here deck tree um let's see uh nothing comma r rest is going to be right r and then nothing because we're not going to check the condition here we are gonna say um where lb we're gonna say um lb equals case r of if it's accept then it's just a tree and right so actually if it's sent to s then we do something otherwise it's just always right r but i'm only seeing tree here i should be seeing node right node node and case r of sent to s this is going to be left condition okay left c and it's going to be deck tree prime of rules map dot bang s so let's see deck tree rules part one so this is the whole tree now let me we want to say a print tree draw tree draw tree and i think i'm going to do tree dot map i can probably do f map to stir to stir so left c is equal to show c to stir right r is equal to show r and then i don't want to print this i just want to put stir ellen so okay let's go back to the example so in um so if s is uh less than 130 135 one then we send it to px and px s is a is less than 2006 we send it to k g g g6 vex is less than 1416 and send it to a otherwise we send it to c r n uh-huh i need this here also um so here i just have the condition but it's always like that um so it's going to be actually i'll be uh-huh see and now i have like a nice decision tree um and then and then we have accept or reject right reject or accept accept or reject it's a nice tree let me see what it says for the input now we'll have a lot bigger tree um okay it's just a lot bigger so this one actually let's they split the range right okay so it's oh no so now let me see do we're getting there we are doing okay i feel we got the tree going let me just run it here as well we need to um so now we need to figure out how they split the range so in this one right if s is less than let's see here okay um so let's assume that um so accepted it's going to be like it to it into it into it into it okay um now okay so let me see so we're gonna say take the like the range of acceptance and we are going to create two ranges when you write here type range equals n comma int okay we have a range comma range comma range comma range and we have a decision tree tree either condition result and this is going to split it up into two different ranges okay so we actually we're just gonna do like this okay accept it so we have x min x and max x no it's not it's actually a list of ranges okay and it's gonna return and I may actually just make this into like a list of list of ranges and we are gonna return ranges okay let's see ranges accepted ranges and then let's see if we are looking at a node write accept we don't care then it's is equal to ranges accepted ranges if we're looking at a node write a reject this is equal to then none of them are accepted right this is the let's have not have this like a let's have this map char range right map char range now if everything except it nothing then everything except it but got there is accepted a map map mm okay so these are the the travel your cases mm-hmm okay now um now I'm gonna see okay accepted ranges accepted ranges and now we have a node with the left condition how the conditions look again cond is gonna be char it's gonna be less than it's gonna be about then we might have and we won't have right we'll have accept tree reject tree is equal to okay so I have the ranges so now I'm gonna say here split ranges so I have the see let me see where affected ranges equal to ranges map up and see this is gonna be the affected range okay and the affected range is a list of ranges so we're gonna create now so that for that range we have to create two branches right those that are will be accepted in that range and those will be rejected in that range okay so now we're gonna say SPL ranges where so SPL and now we are talking about the right value and SPL takes in a range and and returns a list of ranges which is actually gonna be two ranges split a range min range max okay let's just return nothing here for now so accept ranges okay and let's just say this is min range max and then this is range max range max so affected range so we're actually gonna unzip arc of range range of range okay so we are gonna say AC map is equal to map update map dot insert and then a key and then back range into ranges okay so this is the accept map and then there's the rich map map dot insert see range range ranges okay and then I want I want to do is I want to say okay this one so this one just actually map dot empty okay and now I want to say map dot union accepted and AC map AC map accept three accepted uh rich map reject three so the ones that are gonna be accepted are the ones there is actually the left hand side and the ones that are accepted the right hand side okay and okay and they accept and then so to split a range like this now I have to see if LT so then we are saying C is less than valve then else we have C is larger than valve then and so this is the range of accepted values so this is gonna be um this is then just gonna be range min up to valve and this is not inclusive okay and the ones that are going to be rejected accepted are these and the ones that are going to be rejected are val to range max so the ones that are going to be if it in this case the ones that are going to be accepted are val uh but it's max so this is min range max val and this is a max range min val okay and here it's going to be the ones that are going to be accepted are the ones from then we just actually just it's the same but we flip it so let below equals and above is these okay this might work oh running like a pro coming up not bad so if less than then we accept those below comma above in below comma above else and we accept those above and retract those below wow not bad I just got some vanilla cookies let me have one hey I'm gonna need some paper though hmm that's good stuff now let me filter out uh invalid ranges filter not empty and not empty m x y so uh range from x y is not empty it's equal to so x is less than or equal to y simple step no x would be if x is equal to y it's actually empty now let me see here what happens for example here accept it so now we have this we're doing this part too okay and we have the the decision tree let's see the tree of rules is going to be decision tree rules let me just okay d tree so tree string okay so now we're going to say ranges is going to be so we're just going to repeat the range one two so from from zero um so numbers in the range if it's larger than the bottom and less than the zero to four thousand one and this is just gonna be this and then we're gonna say um x m a s ranges char any any this is going to be mapped out from list so let me sprint here ranges is going to be map char list of range okay so we then we need to repeat actually like this I'm just wondering um where do we actually I don't think it's a list of ranges actually I think it's just um I think it's just range SPL this is just going to be map char range map char range okay now it's no longer let me see okay now what if I do accept it ranges d tree oh okay and I need the union width here merge range okay where um so that's the trick right is a merge range x one to y one um x two to y two and now we are getting it back into the intersection problem grab inter section we had some of this in like day five I think uh see two ranges so these are the two ways ranges can enter five right ways ranges can intersect okay let's uh let's just do this again we have a case one x one y one x two y two so this one should be empty okay none of these are accepted then we have x one x two y two let me make it clearer which one is which y one okay then we have this case here and then we have this case here x two x one y one y two then we have the case um where they intersect on there so x one um x two y one y two and I think this is the fifth case um is the other one right x two e and then x two and then x one and then y two and then x wide ding ding okay so how do we check for this if um y one is less than y uh x two if y one is less than x two then we get the empty range here which is going to be uh no yeah okay so there's going to be empty range x two y one here x one is less than or equal to x two and uh y two is less than or equal to y one it's just going to be x two to y two same here uh x two less than or equal to x one and y one less than or equal to y two let me make sure first that if if one of them is inconsistent so case y one is large it's less than or equal to x one x two y two case um x two y two is less than or equal to x two so we prefer the same one and if they're both bad then we don't care because over here y one is less than or equal to x two okay and this is supposed to be this is the comment right so here we go x one comma y one okay and here we have that x one is less than or equal to x two and y one is less than or equal to y two um x two is less than or equal to y one and we get an x two comma y one that's where these two intersect now here is probably we're gonna say here um x two less than or equal to x one and x one less than or equal to y two and y two less than or equal to y one is equal to so here the correct range is x one to y two now those are all the cases I can think of so otherwise error merge range show merge range x one y one x two white so and then we here we have um well if s is less than um we get here um num accept it it's gonna be um it's gonna be um map jar range um accept that equal to uh int we're gonna say map dot lm sum no product i think this should all be less than product um map a y y minus x okay merge range a b case okay this probably has to be if y one is okay this merge range is just uh we need to have these lists I think and then we can figure out the length of them later map union ways let's bail on this and let's say and say accepted ranges and then we're gonna so accept range one 2006 I think I should uh I should not I should do num accepted and I don't have to do this I don't have to do any range merging let's just say here num accept it map range add to int num accept it equals trace show rngs rngs zero num accept it uh okay this should be sharp so this should be um so here it's all there's no um merging business going on so we can actually just have it like this and then we can do again do this and this is just map jar range and now we we're not going to be doing any of that like merging multiple ranges business I think that's just gonna be a big mess um so here so these are the ones accepted in this branch of the tree so I am going to say um trace show where na is equal to um map dot lm's rngs and then map so for each range how many elements are in the range and then we take the product on that and I'm gonna say trace show rngs na na oh 164 this thing comes so we're not far away maybe it is if I have x I could do one inclusive and make the ranges a bit bigger no so here we are looking at the okay let me change this this is gonna be um y minus one minus x plus one we are so close though so the ranges are going to be from one to four thousand so the ranges are inclusive mm okay and so below the number well minus one above the number so the number is not there you see are we almost there and then we do so now this is the number of numbers in the range I counted the plus one here we are so close all of them are good except that one ones except and these are the it's going to be inclusive okay then we need actually we are off by a few you see um now let's check so this s is less than one three five two five zero s is this a one three five one this is less than 2006 and x is less than 14 15 in fact is larger than 2662 and we count those okay I think that one is correct now a is less than 2006 but so these are the first two here so if a is larger than 2006 okay then we have this one and then m is okay then we accept we accept all of these now here it's in this branch so a is larger than 2006 and m is less than 20 90 okay so yeah okay and it says a larger than 333 uh reject otherwise reject yeah okay so s has to be larger than 537 and x has to be less than 2440 yeah I mean I think the ranges are being correctly handled so if it's less than that we should accept the ones below and reject the ones above otherwise we should accept the ones above and reject the ones below if less than then less than some 1674 we are so close of all possible distinct combinations so we can have a maximum of zero yeah and I think I think this is correct right so then then the second my y minus one minus x so from zero to 4001 there should be 4000 distinct possibilities but it should be 399 I think let me see accept it and node right accept ranges so if I just accept everything this is um 4000 times 4000 exactly okay so I think the accepted is correct and the ranges are correct maybe val is also supposed to be accepted node right accept mm-hmm distinct combinations of ratings will be accepted you see because I feel like we are almost there but um we're getting a too high of an answer if it's supposed to be inclusive we need to I feel like we're quite close we're just we're not getting I think we have the right idea but uh you're looking for the right to see maybe so I feel like we could simplify the tree also we see simplify and node right accept let me see okay is accept node right accept true is accept false is reject all right let me see okay all same let me see simplify node a children a comma b equals let a prime equals simplify a b prime equals simplify b in if in if a prime equals b prime then a prime else node node left c a prime b prime simplify let me see and now simplify the tree deriving eq and I need to derive eq for result also I should not have simplified things and do not have changed the number but it did because because it um because it removes one number right I think that's what I am messing up here I think that um yeah I think that's the thing I should simplify and now let's print the tree again let me see um tree string so I can simplify the tree because if both are accept then I can just replace that with accept both are reject I can just replace that with reject okay and now let's go back to this and I think the problem is that that whenever I split it it should be like plus one right so so these are not exactly correct so if less than then it is a range min range min min range max then val minus one that should be accepted and it should be max range min val right so because val it should be less than or equal to for val here range max now if anything above should be accepted it should go from max range min val plus one a to range max and what should be rejected is anything from range min min range range max val because otherwise I was like dropping one here in the air so one seven four seven four zero nine zero nice this is the right number that was it okay so what was the problem um problem was that we did we we were not including the value right because the above should be less than or equal to right we were cutting it out on both ends which is not good now let's say not trace show here I don't think it matters okay we have a new number all right we did day 19 so now we're all caught up did take us a while though but that's okay we did we exploit the solution to day 17 uh we chugged through day 18 we got off by being lazy we sketched up how we would do it but we just it's has come it's fast we didn't have to do too much and then for day 19 we were so close for so long but we just messed up the split but we had the right idea all right let me add get add day 19.hs input example get status get commit m day 19 get push all right that's all for today we've caught up to everything okay I want to say one last look at day 17 that took so long so what was the trick to day 17 take multiple steps at the same time and then always turn because if you took multiple steps you or you should turn next keep track of the directions and you sets as heaps don't track the path that kills the performance anyway thank you for tuning in uh we'll be back tomorrow well legally today in Sweden and with day 20 of the admin of code all right thank you for tuning in bye