 All right, welcome to today's episode of Haskell in the admin of code Today we're gonna be doing day 16 We've been at it for quite a while now, right? Let's go admin of code Where did I put it? What? Let's just open code code knows where it is How's everyone doing today? It's like Wednesday, I love Wednesdays. There was a wrong writing meme It was like it is Wednesday my dude It's pretty funny. See make this bigger so y'all can see and I made the terminal a bit smaller Because I was looking at it yesterday. Let's make it bigger Let's make it bigger You can see the remains of Terminal font size you can see the remains of day 12, which we did yesterday It was pretty cool. We could use like We could use like a complex numbers to kind of do all the rotations for us and It just worked See now I can see All right Clear it Let's see. Oh wait. Oh my god Let's just open up a new shell, huh? There we go Alright There's no one on chat today What's going on? Wait, is my stream even live? Let me see twitch.tv Twitch.tv about Because like it's saying that is I've been streaming for zero minutes when I have in fact been streaming Well, it says live here All right If it says live here And that's what counts, you know Okay, it's my Facebook Um, COVID test tomorrow, but it's good. I already got one negative COVID test We're gonna get another one tomorrow And we're gonna make sure that I didn't catch it during transport and if I didn't Well, I'm gonna go hug my grandma. I'll be COVID free Quite good, no Let's see Here's all my emails Good emails now See day 16 All right, let's see what today has for us Let me see You're so walking to yet another connecting flight. You realize that one of the legs of your route and reroute a trip Coming up is on a high speed train Let's I kind of want to review the story so far. Okay. Let's see. So day one We were doing our budget, right Day two we went from The coast to the coast by a toboggan. Okay That's nice in day three We we yeah, we we were like planning our trip after the toboggan log in This is like fixing the passport. We're actually arrived at the airport I took a flight and we were we didn't know where to sit Then There was some issues in luggage this was It's fun, right? We had a we fixed the handheld console. It was kind of cool Right then nine We we we helped them with the decoding. What was this? Oh, yeah, we fixed the port like the little screen in front That worked out now number 10 Okay, we got oh shit so Okay, yeah, then we had to charge our Our battery Okay with a jolt so it's kind of fun. That's hard I mean we did it very fast, but it was it was a bit hard. All right, then we had Then we went to the ferry And that this was we skipped this originally, but We did it later. You can see it on the YouTube channel which I linked In the about page Okay, then we had a ferry and then we fixed it. So this is what we did yesterday in a double stream We kind of figured out where we were going Then say 13 right, okay, this is like this is on Sunday. I was like what what happened so it made it To buy the ferry and then we had to take a bus To the airport Near the airport, okay and Then we were on the ferry and Okay, yeah, we had to like fix a docking program move Day 15 yesterday, what did we do yesterday? Oh, yeah, we We helped the elves with their game that was fun. I like that part and Finally today's day 16. Let's look at it okay, we're Walking to yet another connecting flight one of the likes of your area, okay high-speed train cool Train ticket you were given is in a luggage. You don't understand Language you don't understand, right? You should probably figure out what it says before you get to the train station of an excite Unfortunately can't actually read the words on the ticket. You can't ever read the numbers And so you figure out the field these tickets must have are the valid ranges Okay, we figure out The fields these tickets must have Okay, and then we figure out the rallied ranges for values You collect the rules for ticket fields the numbers on your ticket and the numbers on other nearby tickets for the same train service While we're just hacking everything here stealing data from Blaster, right? That's I Don't know is that legal. I don't think that is legal. Let me fix my My webcam a bit Why you focus keeps resetting to auto Here now you can see the keyboard much better, right? All right, let's see Rules for tickets. It's a specified list of Alex exists somewhere on the ticket Okay, so we take a look at the ticket so we don't look at these we just look at the volcano values on them and then Okay. Yeah, cool. Cool. Cool. Cool Let's see Start by determining which tickets are completely invalid These are tickets that contain valid which aren't valid for any field Ignore your ticket for now Okay, your ticket nearby tickets. It doesn't matter which position or point which field you can go to a Once your ticket scanning error, okay In this example the value on the first nearby ticket are all valid at least on the field It's not true of the other nearby three tickets the values four fifty five and twelve Not valid for any field adding together all of the invalid values reduces your ticket scanning error rate Or plus fifty five plus twelve plus equal seventy one Okay, so we're just gonna take these tickets. This is our following notes. I'm gonna get the influence you can see Okay, so you have a bunch of fields And then a bunch of tickets Okay, so We are going to we're gonna have to parse this a bit Did it do the did it do? We had I don't know code open here. Let's see. Let's create it Let's start day 15. Let's go whoop whoop How's everyone doing today? Yeah, I started saying earlier. I love Wednesdays. It was like our long-running meme on reddit On our dank memes which had these this frog and it would say It is Wednesday my dudes Hey, it is Wednesday my dudes. Oh my good It is not Any of these? Why isn't it the first? Yeah, this one? This is a good meme. Okay, and it was posted every Wednesday on reddit our dank memes Let's see See I browse our Haskell that's subreddit right dank memes What do you guys think about the music? It's a bit more intense now? Oh my god Nobody has posted it That is not okay Anyway, they posted it for years. It is Wednesday my dudes Best day of the day week All right, module Module main main where so okay, let's look at the input Close everything else new input new file test input and then we're gonna have we're gonna have another file called Input because like the input file is quite different From our test input, right? So it's gonna be parsed as a bunch of things And we're probably gonna have to Pick up which ones here This is gonna be a Let's write a parser. We're gonna write a parser. Whoop. Whoop. Oh, it's nice to write parses Let's see. I'm gonna change the music. This is too intense This is not a lo-fi music. I just like I just like this one song But yeah, that's It's not as intense. It's not quite the fixer, but I guess I like it. Let's play this one Hey Druid 4. Have you learned any Haskell syntax yet? Druid 4 has been Regular viewer and we convinced them. I think me and Chrono Kirby. I think we convinced them to Learn Haskell because of security types Another stuff also, but security types are cool. So let's say Import text.parsec.bystream Now Import text.parsec import text.parsec.char Yeah, I mean it's worth it. I think it's definitely worth it Now parse range is gonna be parser for a pair of hints parse Range is gonna be Dude, we're gonna parse a take while one is Digit No, so we're gonna say Many one dig it dig one so from To Many one digit so then we have so we have a char and we have a like this and Then we're gonna say return read from read to Parts field valves is gonna be a parser So let's use a range type range equals Int comma int And this is gonna be a range Now this is gonna be a pair of ranges parse Field valves where you at good for Like like, where are you in your Haskell education? I'm gonna save First let me see Yeah, these all have only two first a first range And then it's gonna be string or second first second Parts parse range Return first comma second Okay, you know we published field valve so Parts field a key parser It's gonna just return stream, which is the key parse field key We're gonna do many tail So key return key. This is not good because It takes in any okay, so we say any char and then we say Try okay char Colon that's the parts of a field key now parts field is going to be a parser so a field Type field is gonna be it's gonna be a string. That's a key and it's going to be a pair of ranges Parts for a field that's gonna be parse field So we're gonna be parsing so it's gonna be dope key Parts field key And it's gonna be bars field Valves and then it's good. Okay, so here's gonna be spaces spaces The house and then we're gonna return key comma valves pretty sweet. No Okay, now we parse one of these fields here Then We are just gonna be parsing the rest of the input okay, so So we're gonna say parts input It's gonna be due so it's gonna be pars So we're gonna have we're gonna have a We're gonna have a list of fields data input equals Input of so the fields We're gonna be a list of field Your ticket is gonna be list of ints and Other tickets list of events Now parse input is gonna pick is from bars to input parse input equal to do first we say a Sep by right, okay, so Sep by one What is it? Sep and by okay separated By set and by piece bars is one or more occurrences of P separated and optionally ended by set End by one set parts of zero more occurrences of P separated and ended by Sep so we want to say do the fields is gonna be end by one Yeah parse field and it's gonna be So and it's gonna be ended by a so This is gonna be sep by one parts input line Set by one set by this is gonna be okay. Let's see They're gonna be they're gonna be separated by New lines Let's do this first. So parse fields Pariser list of fields Pars fields It's gonna be a Sep by new line Sep by and Sep and by one by one I don't want this expansion. It started doing this for some reason and I don't want it end of line Parse field Good match type. How is it like this? Okay, so they're separated by end of lines now cars your ticket that it's gonna be a do string Your ticket and then Sep by one We're gonna have ours Digit it's gonna be read over and dig it It's gonna be separated by jar comma. What's wrong here? Par sour ticket. Oh, no Part your ticket. Okay. Now. This is gonna be straight do string Nearby tickets, that's where just pars ticket Or is there paint pars ticket So this is end of line and then sep by one Pars ticket Okay, now pars input, let's see go to the bottom your ticket fields Pars input is gonna be do so it's gonna be parts fields Your ticket other tickets, let's say return Input let's enable Language record while cards now. Let's see if this works by string Pars from file. So let's see parts from file Test input and the parsing input from test input You know, it's gonna print friends And what's wrong with this? We have to derive show here. Let's compile it see what happens compiles, let's see Let's see we actually did I'm not sure this works on I think the parser is wrong See measure Day 16.exe Into We get the parser unexpected end of input expecting colon So parse fields sub and sub and I parse field Pars field key Let's see so many till Oh, right. Oh, I didn't paste the input here Test input wasn't there makes sense No, let's try it again unexpected comma line six column two Expecting digit or dash Okay, let's see. Let's see So it parses all the field keys and then it's like failing on the your ticket I think it's because we are parsing too many We're parsing the range and we don't stop the range Let's see. Is this just end of No parse field vals So parse field is going to be key in the spaces and then field vals and then end of line And then this is just going to be I think this is going to be many one pars fields So just build the end of line into the field there So line six column two unexpected comma Pars your ticket. So it says your ticket then end of line then parse ticket Okay, and parse ticket So by Let's take a we take a many one digit and then we read that add int Let's see parse field vals So we parse a range and then we parse a range and then we return first and second And when we parsing a range we say many one digit many one digit So tricky tricky parser Let's see from two read from read two Let's see here Trace show it See what we're parsing import debug dot trace. It doesn't finish anything So parse field Okay, let's just let's just say first. So let's just parse the field in one go So it's gonna be many tail Key it's gonna be many tail Any char Right char Like this, okay So then we're there and then we're gonna be spaces and we're gonna parse field vals So we're gonna say your pars So first it's gonna be pars range And then it's gonna be a string or It's gonna be second Part range So that way and then it's gonna be oh, is there a space here? No, there's no space, right? And then end of line I'm gonna be first second. No still feeling. Okay. Now we're not using the field key anymore Not using field vals anymore So we say many one a digit So whatever you say here many tail digit try space detail digit Try space Expecting space or digit Okay, so this is gonna be many tail try choice between space and This is gonna be a choice of try space Or try end of line Oh, no oof What is going on here Trace show head Okay, so it's not Let's say so it's we eat the first spaces and then we say string It's his space or space And then we parse the second This is gonna be many one digit ash and then another many one digit second parse range So parse fields Let's say this is set by one parse field End of line Okay, so Let's see. So we parse fields end of line Anyone have any ideas here? Because it's like it's like in this column here six comma two So it's trying to parse a field still for some reason. I'm not so good at writing parsers. That's for sure Let's see How we have some things we can say we can like parse trace parser trace Show key so class So we parse the key here This parser succeeds when he returns the parts character many till Let's see. Can I do like this? So class colon. Okay one One three or five. Okay, so let's write here parse the first one comma three Okay, and then I show the second Let's see So we parse the second one To say class one three five seven Okay, row 11 and it does 455 and then it's tries starts saying So parse fields set by one Let me see many till Let's have the end of line here. Okay, so Expecting new line Line five column one unexpected y Okay, a Try a left test input to f's parser trace f's Turn f has I don't see like it did that one finish Uh Like this let's see So we parse the fields And the rest of the input is your ticket Okay, good And then parse so we say Parser your ticket. Okay, so I think it's like this We parse the fields then parse your ticket And now parsing your ticket Will be your ticket and then end of line then parse ticket and then End of line Ticket We're getting there. We parse the fields now. It's good And it says, okay. Yeah, so we're gonna return the ticket. Okay, you know, we've got that so we have nearby tickets colon end of line Others And then end of line Now we don't actually have So let's see here parser trace Show ticket Okay, so we parsed Or and then it says your ticket So we parsed we parsed this right the classes. Okay And then it says your ticket and then we pass our ticket and it says an rn. Okay, so we have to say Uh powers your ticket Yeah, so it's that's gonna be Two end of lines, right? No, so for parse ticket, this should actually be Uh When it's like this It's gonna be ticket So if I read my immediate char end of line Return ticket, this is like an operator for this, right? I can do something like this. I think It's a type of this FFA. Yeah, I know so it's the other way around Exactly. Okay, so Now we don't need to show this trace anymore We want to show this trace anymore. We need these spaces. Okay. We don't need to show this trace anymore Okay, let's see. All right. So what's happening? Okay, we parsed it successfully Let me see parser trace Okay, and then doing something here too, right parse range. What is it? Why is it still showing us the These things class row Print res, yeah parse field end of line trace show id, right? Okay, let's see. Let's see. What's happening? Okay, we're gonna actually say here field is going to be field It's going to be key string so then it's going to be first We use a range And then second Also range and we're going to use the same trick as for input data field grabbing show Okay, nice Okay, so now we have all the ranges Then we have to merge the ranges That's for the first part other tickets We only get the first one parser by one I think Let's see Many till Let's see what happens So it's it's not giving us all the other tickets So parse other tickets. Okay, that's going to be this Parse of step and by one What if I do many Many bars ticket Does it's like separating and checking and then no it's still failing right parser trace Show ticks We don't want ticks They can be very dangerous So I'm from Iceland and we don't really have any forests here So we don't have ticks but In sweden there's a bunch of ticks Apparently and they are nasty like little bugs that eat Your face not not your face, but they eat you Like that's not nice So can we just do this? Okay, so let's see what we do when we get parser other tickets What's the state then? Yeah, okay, so here. Okay, so and then we gave What if we just do We just whatever you just parse one ticket So we can't parse tickets I thought that was what many one did Why doesn't this work then? Tails unexpected end of input So the many till Parse ticket because it's failing line Column line a 12 common lm8 Do I have to like finish the file? An end of line unexpected end of input expecting try. Okay try euf Nice, you know it works Parse trace Right here it's saying Why not? Yeah, okay This is wrong. I'm gonna make this a little bit more succinct It's a kint Okay, see okay, this works for this one This is the input We have to put in here I'm just gonna see if it works or the parser works for the real input parts from file parts input Input Then what do we see let's see a print other tickets Input okay manages parsing real input too, which is nice All right Now let's see. Uh, so the solution takes an input Return some int, right? It doesn't matter. So so ticket scanning error rate. Okay, let's just see Solution, okay, so input Now let's look at the ranges We're gonna map to the fields the first second like this We're taking the field and we're gonna change it to First second So so far field first second so far on the Let's in here Parts input fields. Yeah, and we're gonna start with the empty list and we're gonna map it. I don't know. It's gonna be starting up with the empty list ranges need this bracket So we're gonna say right input Right test input. We're gonna because we know it's not gonna fail print Uh, let's print it want to become famous Do I Solution test Input That's actually just say here. It's gonna leave a list of range I don't see the Okay, so now we have the ranges Now I want to see like I want to merge some of these ranges, right? That would be nice, right? Because like five and seven is It's contained in it, right? so five and seven Uh, so six so this would this would these two would merge to five to eleven, right? Uh, let's uh, sort the ranges Sort by first We will say import data.list Import data.function So one three five seven Six eleven thirteen forty forty thirty three forty four Okay, so and then we say So then we're just gonna merge the ranges How do we merge a range? Well two ranges can be merged If the If the start point of the second one is contained in the is is like Lesson or equal to the end point of the other one plus one. So let's see Let's let's first write here a contains Int int comma int Go S a comma b is this is A less than equal to i and a This contains Okay, let's see I see here merge ranges. I'm gonna take a list of ranges I'm going to return all this the range Now merge ranges of one range So nothing is going to be nothing Okay, so okay, so it's going to be merge range a and b The rest and now merge range. So if we have you know one or nothing Uh, another that's going to be other Now if we have two ranges We say here a x a no a x a and b x Uh a y comma b y a and b a cons So, okay Now these are going to be sorted So we're gonna say a Okay, so merge range. Okay, so This is going to be so if a contains Uh, if a contains a y then We can just We can just merge them Then merge ranges Of uh A x comma b y on the rest So if a does not contain So, uh, let's see here So this is actually going to be if a contains a y or or B x plus one Equals a y it's because like they can be like adjacent to each other Then we can merge them else It's just going to be a Merge ranges a concatenate to Merge ranges b rest I don't need this Merge ranges If a contains a y okay. Yeah, wait, so this is Let's flip these now. Let's see Merge merge Ranges of the solution Do do do Non-accessive pattern in function Merge ranges wet Oh, so now we merged all these ranges. Cool So let's print the ranges again So now it should be a lot easier to check if they're members of the range, right? So we merge five and seven so six is contained in this, right? so it's going to be five to eleven and then Five to eleven that's going to be one range right and then thirteen to forty so thirty three is contained here So it's going to be like this and then these are adjacent. So it's going to be fine I like it um Now we check uh Now let's see um Okay, so now we have this we have the ranges uh, so Merged ranges It's going to be a this here sort by compare ranges And then we're going to do merge ranges on this Okay, and now we have to look at the nearby tickets so a In any range it's going to take an int and it's going to turn a boom So in any range is equal. So i is equal to We're gonna we're gonna flip contains Contains an i We are going to say filter flip contains i Merge ranges So if a Not no, so if if any of if it is in any of the ranges It's going to be no and what is it complaining about? Why not any flip contains. Okay. Yeah, sure. Any not any And if it's in any range Uh, what? So if this should be in any range, so if it if it's in any of them This should be okay. So Let's see So Adding together all the invalid values produces your ticket scanning error rate. So let's see here invalid It's going to be a list of ints. So invalid. It's going to be filter in any Filter in any range Of uh Concat we're going to concatenate the other tickets And then we're going to we're going to return our range of ints. So this is going to be invalid oops Merge ranges. Okay. Yeah, we can't do this anymore but okay Let's see if we get the invalid values Let's see what happens Oh, so right. So this should be 455 and 12 Yeah, so we take the sum of invalid That's our solution Seems good, right Not too hard 71 let's check What's the solution for the input? I think the tree key trick here is this merge ranges thing, you know by assorting them And then merging them We make it quite fast 50 milliseconds. Let's see If this is correct. All right We did the first one Took us so long to write the parser though Better have been worth it Now let's part two Nothing for take discard those tickets entirely Okay, uh Then we cannot uh, so Solution two So then we have to discard those tickets entirely so So we want to say uh has invalid. It's going to take in a list of ints I'm going to turn a bull has invalid And then we say Has invalid equals any Not in any range So has invalid it's going to be a list of ints to bull No, don't need this This is so dumb. It wants me to do This H-link to come on flip is totally a valid function Why not not all in any range? Yeah, okay, that means it's not Uh Not Now so valid tickets It's going to be a filter Not uh god has invalid other tickets Valid tickets filter not has invalid other tickets That's actually defined here Type ticket is going to be a list of ints Now prison does You're going to replace all Int list of ints with a ticket Oops Gc not this one but it's a parser for ticket parse your ticket parse other tickets just so It looks good Okay, now we have the valid tickets Discard those so the main valid tag is eternal which field is which Using the valid ranges for each field determine what order the fields appear on the ticket The order is consistent between all tickets if seat is the third field It is the third field on every ticket including your ticket. Hmm. Hey, Timmy You did this already is it? We should have a private leaderboard with timmy Just to check if he's done with it or not Okay, so based on the nearby ticket Okay, we found the valid tickets quite fast Now each value in the invalid ticket we have to go for Okay, so this is going to be like a sudoku, right? So zero one or four two nineteen second position must be Using the valid ranges for each tree to determine what order the fields appear on the tickets The order is consistent between all tickets if seat is the third field and is the third field on every ticket including your ticket Can we just Get the range So let's let's take a have that time to finish part two. Damn That hard Okay, so Field Tea tea fields It's going to be transpose of valid tickets Not transpose just transpose valid tickets a Okay, so tea So field range is going to be Ah, right. There's gaps in the ranges Do do do do do ding ding ding do do ding ding Okay, so we have these tea fields. Let's Return list of list of inks here a tea fields Now let's see here We're gonna run solution two on test input. Let's see Let's see what happens Ding do ding so these are the ranges Hmm. Oh, yeah, these are the ranges for the valid tickets. Okay, let's see here print let's say map dollar take three take three Over these But on the actual input. I don't see how these things look like Let's see a map take three Just like a first three values for all the fields This is six eight eight six eighty six six six ten eighty nine Two hundred two forty two. Okay. Okay Now I think we want to sort map sort on the transpose you can sort the all the values And like this is fast, right? So it's fine and we're still in 40 milliseconds runtime and actually we can a We'll go we can Knob Knob remains duplicates This is actually faster I think let's see We're gonna import import data.set And we're gonna say because we don't want the n squared here But we've and we've already sorted it Let's open a log n and then we can do Qualify qualified There's a set as set import data dot set set This is gonna be From ask list, right? Set dot to list We're just going to sort them and then we take put them into The set and then we take them out of the set and now we no longer have any duplicates actually, I think we Let's just not sort them. We don't even need to sort them Just set it out from list It's actually going to be a list of sets game it size Set dot size How big are these sets? Pretty big sets Lots of different values This is some here 330 30 33355 different sets Okay Now we want to kind of so we want to figure out the ranges of the sets. Okay, so We have these sets of ints And we want to kind of associate each set of ints with a field Okay, let's just uh, I mean so we're gonna have to check the values Because we can't really tell you know if they stop Okay, so this is always like So we have a big range and then we have like an excluded range, right? And these always they start and they end. Okay Uh, so let's check The excludes it's going to pick a field and it's going to turn us uh List of ranges two ranges range comma range Field to excludes Uh, so it's going to be field. So this is going to be field and first equals Fa comma fb and second Equals sa comma sp equal to so this is going to be two ranges. It's going to be The includes uh, so it's going to be fa to sp And it's going to be so that's like the entire set and then it's going to be a The ones that the exclude We're going to be fb plus one and A sa minus one. Let's look here at the map fields to excludes of fields list of pair of ranges Let's see Let's just see what says in that case For the test input. I wish we had more stuff in the test input So yeah, so the for the test input Let's look here back at the end of code We're doing day 16 We're just tuning in. We already done part one Was quite fast and now we're doing part two We're trying to find like valid tickets. Oh here. We actually have better test input I think yeah, this is better test input two There's actually a better test input. I think We're just going to go ahead and not even check if this is a bar zero We're just going to say paste to to solution to It's going to compile it around it. Oh shit, and it's going to crash Because we didn't do the end of file here So these are the valid tickets here So we have one and five and 15 one and 14 Okay for the first field So it can be so zero to 19, but not so not between two and three Second one is zero to 19 to not between the six and seven and zero to 19 and not between 14 and 15 So I basically have to check so Now I'm going to see a say right here Let's see could be field it's going to take a set Of ints and it's going to take a field and it's going to return a bool Could be field. Okay, so evals and and The field and then okay, this is going to be where so include Exclude equals fields to excludes of f Now I'm going to say the minimum of the set minimum data.set data.set data.set has come minimum Look up min right So we are going to check okay, so min max It's going to be What is min fine min Okay, so So this is uh, okay. Okay. I'm just going to say fine min and it's going to be Find set dot find min of evals comma set dot set dot find max of evals Now we're going to say include it's going to be include contains min So first of all includes have to contain the min Contains max now. I think the range here You see that the the exclusive range is often quite small See here is like 23 elements here. It's nine elements Here it's like 13 elements Let's see here size range It's going to take in a range. I'm going to turn this It's going to be a range size range size range x comma y it's going to be my minus x right That's the number of numbers a range contains So if it could be that set And uh The expression split is a pair set one set two where set one comprises the elements of the set less than x And set two comprises the elements of set greater than x This is what we want to use We want to split So we want to say I'm in my maximum So x clue it's going to be It's going to be a x a comma x b Now we're going to say LT x a GT x a We're going to say and this is going to be split No, this is going to be a data dot split. No, this is going to be set a dot split Vals So these this is log n. This is log n And now split is also log n No, let's split first Set split vals x a Set split vals, I think it's like set split x a vals we want to see So we split it at the edge of the range right So we want to see okay So the includes has to contain min it has to contain max And we want a Now a ma xa and then me q2 So so max less than and main gt that's going to be set Set dot find min Find max of the LT x a and it's going to be the set Dot find min Of gt e x a um So and then we have to say not x cool And okay now we don't actually have to check that we just have to check that the The max of the less than is less than Is is less than e x a the minimum of the greater than is less than e x is Bigger than e xb. So This is this operation here So this is this is log n This is all log n This is all log which is even less than an So all of these operations here are log n. This is all one So all of this is all of log n for each of the sets now We have the list uh Sets and the list of fields Let's check. Okay, let's check. Okay so for each of the sets of ints T fields that's going to be the list of Fields is going to be the list of sets of int Is this hung just on repeat? Oh, it's a different song. I just want to hear a different song Uh, we're going to take the Kind of so for each field map Could be So for each of the fields I'm going to say filter Could be field No, so we're going to say me. So we're going to say No, we're going to say f Yes, no Okay, so for each field could be field F and we're going to map that over the The fields T fields now could Be is going to be a list of list of fields and actually we're going to say here. We're going to say it's going to be sip width and we're going to say one is going to be filter of Which and this doesn't it doesn't like this because so sip width Could match type integer field expected type list of list of field the output. Yeah, that's what I want here Int the fields. So let's see here. Let's return this list of int comma List of int comma so which field which set are we talking about and then this field So it could be now. Let's see Empty set has no maximal element Oosh, I guess that's coming from here, right? Let's see here Look up max and then this is going to be look up min and this is going to be a case mold of just a MLT It's going to be MLT less than X, right? That's what I was replacing Yeah Nothing is going to be true because if there's no minimal element, that's okay. There's no nothing that range minked MGT MGT less than 3 to the next be So first Oh, shit. No, I pasted stuff in damn it. At least it was only the Let's print out the list of set Well, okay, let's actually let's actually not do it this way Let's not do these fields to exclude stuff That's just confusing So we're going to have f a f b First field and then this is going to be S a comma S b Okay, and then we are going to Find the minimum of maximum of valves This is going to be you know first and second Where this here is You know Okay Now we just check Okay Min is greater than or equal to F a Okay, and Max is less than or equal to s b and then we split The set I we split it on We split it on F b plus One that's always going to be one number not in the range, right? So, yeah Yeah, yeah Yeah, yeah Yes Yes, yes, yes, yes, yes I think there's always going to be one number not in the range. So we split it Okay on the and now this we just have to check that so if you split them on the f b plus one That's going to take uh wait, let's just check split Split So so set comprises the elements of set less than x and set to comprise the Elements of set greater than x Can what what does it mean? Let's see here I want to see like if it contains the thing it's splitting on Or to do it at set A From list one two Three four five Split hat three Oops Split three from list one two three four five Okay, so it splits. Yeah, okay. So that was what is happening. It doesn't It doesn't include the items, right? It doesn't include the split element So then we will want to split on fb Okay, and then we want to see the lookup max Okay, so and then so this will not contain fb So we are going to say the max of less than Max let's call this max lt in gt max lt Min gt less than fb and then greater than fb And now we find the maximum in the less than fb You're finding the greater's number in greater than fb This this this would be Max lt fb and min gt fb. So if there is any element max lt fb and Then we check So this one is always going to be fine So we don't really have to check this because this is always going to just take out all the elements That's less than fb So what we really have to check Is that the min gt fb At the minimum of the greater than fb is actually l is actually a It's actually The element is Larger than or equal to s a we already checked min f a and we already checked max sp And if this is a least element in fb is greater than equal to s a that means that there is no element From fb to You know fb to fb to s a exclusive Find the exclusive in the end So we don't need this We actually just need We actually only need this Save one operation there Quite nice new Okay, let's see. So five fifteen it says it could be So five and nine so that could be The the the field first So the first one five to fifteen could be the first field And so it could be class and it could be row second one could be class Or row the third one could be class And row and seat Okay, that's a bit weird So the first one To the first run, okay, so let's say test input two. This is three fifteen and five And okay, so this first ticket here is invalid So because it's like one of these numbers Is not in any of the ranges well The five and fifteen one and fourteen and five and nine But it's wrong with this ticket here So three is in might be a row, right? Nine Might be a class or a row Or a seat In eighteen Might be a class or a row or a seat There's something wrong with the check here, right? I think that's Clear Let's look at some of the truck like the merged ranges A Trace show ID For this one. So what's the what's the merged ranges here? Let's see So the merged ranges here are zero to one And four to nineteen Yeah, exactly Now Let's see trace show ID They're just ignoring the first ticket Three nine eighteen fifteen one five five fourteen nine Let's see here trace Show ID of a trace show ID Now we'll just see like the how the filter is going Let's see Three nine eighteen false Valid ticket Oh three is not in any of these ranges Did I merge the ranges wrong? The zero to five or eight to nineteen So the range for row should be zero to Zero to one or four to nineteen. So this one gets merged These are all sorted Hmm yeah, I'm merging the ranges wrong somehow Let's say here Trace show ID Because three should be there, right? But it's not in the merged ranges for some reason weird Okay, so here we're merging the ranges You're merging zero and thirteen Okay, so we just kind of throw out the second one Let's say we have to fix merged ranges Okay, so okay, so if a contains a i or Bx plus one is equal to a y then we merge the range that way Then we just merge the range. Okay else if Now, okay, I think we have to check the other one also we have to check if a if a Contains So we say if if a contains a y Oh Right the problem here is how we need to take the Max Max B X B Y I think Yeah, so that's the thing right So then we merge these two These two become, you know zero to thirteen And then this one becomes zero to thirteen and then Zero yeah, so then we merge all of them because they're all invalid Okay, so the first one could be row Second one could be class or row Third one could be class or row or seat So, I mean what we do there Well, let me just check my notifications here. There's nothing important going on. Oh, do I also think I have to take the No, yeah, we we already checked that. Okay. I think this is fine So three five fifteen And one nine fourteen and five nine eighteen Blip blip blip so the first one might be row essentially the second one might be class and row Let's have this be see, you know, let's have this be string and now Could be field so could be Just going to set up the strings And do this now we have to do some constraint solving So first one could be row second one could be class or row third one could be class row or seat As there's only one element then we pick that one we remove it from all the other lists And then we check recursively. Okay, let's do that This is actually going to be a Set dot from Distinct List it's gonna be a set of strings Okay, it doesn't help that. I know that it's this thing. Let's just say set for list. Oops, what did I do wrong? Yeah There'll be a set of strings Okay, now I have I only need this List of uh Int set string Let's delete these fields here Okay, and now we have you know first one could be us from list a Let's just create a map from this stuff map of int to a set of strings We're gonna import data dot map Could be it's going to be a It's going to be It's going to be map dot from Sitches like yeah, we have we're doing the keys here I think I would like to invert this list let's say here um Invert map if we have a map of uh, you know a set of b now, of course we need Or the a and we need or the b map set of b to a map of b to a set of a's Invert map, okay, so let's take S ox Yeah, yeah, we we're just gonna write this constraint solver Uh, I mean that's the hard part here right the constraint solver I think this invert map function is going to be a bit too much Let's just not just not worry about it We just have a map of int to set of strings, okay Actually, let's keep it as a list of these pairs So and then we're gonna say, okay a solution to So we're gonna say No need size range anymore We're gonna say solve Takes a list of ints and a set of Strings map int String to map int string Now solve equals So we have here possibilities Now where sorted is going to be a sort by compare On size dot second Possibilities now it's here. So I think uh compare on what Ding ding ding ding is going to be set dot size Sort by set dot size This is going to be you know the first the i This is going to be a pair of you know i and then it's going to be Uh, it's going to be St set So let's see case set dot size st So let's see if set dot size St Is one Then We're gonna say so far then Then the from singleton. So let's how can we like look up the first element in a set like the only element in a set? Uh Then we just say then a You know, this is going to be actually as map of strings to int map of string to int Then we are going to say we're going to insert then we're going to say set dot find min st So mst that's going to be set dot find min st Okay, then we're going to say Map dot insert Uh st now we're going to say mst Uh so far And we're going to say solve possibilities prime We're going to insert it there else we don't know and Where possibilities prime is map i comma st uh, yes going to be i comma set dot delete mst st Of the possibilities else error set to set too big So what i'm hoping is that the the input is such that this will never happen Probably gonna happen it doesn't happen for a test input Uh now let's see. Let's say flip solve map dot empty dollar for the test input oh shit We ended up deleting all of them. That's weird. So it's going to be map. Maybe Uh We also have to remove the i from the list Let's just do Let's do the the stupid way filter Oh, wait. No, this is gonna be we're gonna just do the rest. We we never have we don't have a base case solve No possibilities so far equal so far Figure everything out Do do do do do Uh set wrong sides Uh, let's show here and then let's show a i comma st rest like this It's like when does this happen? Let's remove some trace dot show id see trace show id We're not looking at these anymore Do do do do How can this happen? What is what is so far at this point? So now we've decided that row is one All right, this is supposed to be s Okay, it works for our test input This is gonna say it's gonna be f map Why not data dot by functor dot second? Jays. Yeah, why not? It's actually gonna be uh f map set dot delete mst Because pairs you map over the f map the second part Let's see. Let's see if it actually works on our input I don't think it will but it would be nice Oh, it just works See the input is constructed in such a way that That like there's not gonna be You don't have to do the proper constraint solver. It's nice Okay, uh, so we want the places where it's We want the places where it is So let's let's say here that solution Is a solve map dot empty could be Map of string to int And this is gonna be map map dot empty So because it always works like there's always gonna be Someone's ticket has a zero Yeah, we are supposed to throw out every invalid Every invalid ticket. So it's just no valid ticket for that This is only for valid tickets to me, right? So you throw out that invalid ticket And then it's going to match onto some column right So here we're also We're also lucky We're lucky that, you know, we never have to kind of You know, we always have a field that's that only works for exactly one And a beginning and then there's only so there's like an ascending order of field numbers, right? So what could have happened is like that we can have You would have to like solve You know this field could be this and something and then the other field could be It's other thing and something Yeah, so we would have to write like a proper proper constraint solver, but we don't actually have to do that now Which is nice Okay, now what was the problem We have to Find the ones that say departure, which ones are the departures? Okay, let's see here. So we just all right, and we just do solution two Past input now We're gonna say Is departure string to bull Is departure Where depth equals Departure Now it is departure If the take length Of depth Of uh something So if a you know Equal Departure no equal Dep Dot take length depth. So so this is these are the departures And then we say Let sol equals Solution for the input now then we say Oh, thanks for the follow kill christian Appreciate it Uh, let's see A then we say depths equals A filter Uh Is Departure dot first Of a map dot from To list Of sol Now we're gonna print depths Have you tried the uh, have you tried the channel emote? Tritlow It's the best emote Let's see and our depths are these A map second All the depths so these are the gonna be the depths Let's see. What are the departures here? All right noise Okay, now we have the departures So these are gonna be the keys that we're gonna look up in our ticket, right? Oh, shoot We're gonna look up these keys in our ticket now your ticket Print a Dapps, okay, so Let okay, we're gonna say Let Look up in ticket lid It's gonna be a Input It's gonna be your ticket of input bang Something lid eye is gonna be Uh lid eye is gonna be look up and take it So we're gonna say map print Map lid in depths Not good on lid lid goes from inch to inch And it's complaining about this Oh, yeah, I think it's bang bang for lists nice bang bang, uh, we look up our values In the ticket index too large, right? It's gonna be eye minus one Because it's a zero index for some reason And then we map some some Yeah, it's gonna be our solution Let's check Check if it works 41 milliseconds That's like not so much longer than What do you get if you multiply those six values together? These are six values, right? 23456, yeah That's not the right answer damage Okay, now we need to figure something out Multiply those six values together. Okay. I I sum them Makes sense Always read the instructions, right? That's a trick to most things Oh my god, I have to wait 27 seconds All right, y'all we have 27 seconds to kill What's your favorite programming language? I can't stand the boredom I am so incredibly bored for these 27 seconds Geez Has kick Best language, right? All right, let's uh, let's push it again. You ready? All right, we got it It was nice I like the fact that we did not actually have to write a constraint solver That would have been a mess And I also think you know, add a bit of code is like you shouldn't You shouldn't have to write an Entire constraint solver to do it, right? Anyway So no, this is wrong How did we do it? How how we did it? Well, it's a lot of code I think the key Key thing here is this could be a field function That was pretty optimized Because we like we split the set and then that set Made it possible for us to kind of To kind of check if the middle range Was there or not That would have been a mess like in a list. You can't do that, right? You can't split the list into Well, you could quick select it, right? Um in o event time, so we could have done quick select to do this even faster But this is fine. This is 40 milliseconds. It's not too bad Um, we wrote a lot of parsing code It took us like a like like 40 minutes just to write the parser We could have like not parsed it properly and just kind of split it and stuff and that would have been way easier, but you know We did it Um, now we have the input We did the fields to excludes we didn't we don't actually need this function Because we don't we don't use it Uh, yeah, I think this is all just pretty pretty good stuff And I mean like, you know the runtime is 40 milliseconds, right? And you notice that you know, okay if I Comment this out all of it And I just do Print hello world Like I literally don't do any work It takes 27 milliseconds to not do any work Just booting the rts doing all that jazz And so, you know The fact that we did all this processing In 13 milliseconds You know, that's less than 16 milliseconds. So we can do this at Well at that 60 fps, you know, we could do this every frame And you know if you can do it every frame I'm not gonna I'm not gonna spend time optimizing that right Because it already is optimized in some sense get status Get add day 16 dot hs. We're gonna add test input Test input star we're gonna add input get status get commit a Day 16 I get diff head. It's always super slow So I'm using windows and it's like I wish I was using vsl 2. Anyway Let's push it All right We did it that's gonna be all for today. Oh like was there any crazy optimization tricks we use here not really? Like this thing here is just because the input is constructed in the way that In the way that we don't actually have to look so we don't actually have to consider If the if there is like a possibility if there's more than one possibility like we don't have to do anything We don't have to like pick and try and then backtrack or whatever. We just do it this way Which is nice merge range is that was cool That allowed us to do the range check super quickly Because we just Frigged out the ranges Could probably do that faster If we like put in the volume like put in the values in a set And then split that set For each of the ranges or something like that, but you know It's it just worked fast. So we don't need to Transposing the valid ticket. That was nice. This could be feel like I said This is the key This set dot split call Is the key to doing that fast this is gonna be n log n And that's why we can just simply you know map it over all the fields for Uh for like all of the all of the different values We could just map it Because it's log n and there's not that many Uh, I mean Yeah, it's just because yeah, it's log n and like there are like 3 000 lines of Of stuff here like 260. So each of these sets is going to contain 260 values And Which like even less is going to contain like 160 because like it's just the set right Uh, so and like log log 160. That's nothing Okay, so This is fast So all of this is log n For each of the fields. So it's log look at log n where n is such as a set Per field. So it's m times log n, but there's There's like so log 2 of 160 is going to be like 8 log 2 160 There's a mole form. Uh, what is this? I don't want to go to wall from alpha evaluate Yeah, it's like less than eight and then Uh, we have all these fields. That's 20 fields 20 times. I mean, there's not a lot of operations per per check Which is nice and a A Yeah, so it's all just very fast I think it's quite good Quite good. I like this one. I was afraid we would have to write a constraint solver That would have been too much. That's why I just wanted to try if not doing that work I did so we're good We're all good. Let's look here Oh, this map is starting to flesh out I don't really know what it's doing. Like is this like the locations? I guess we'll know in the end All right, but that's gonna be all for today. Uh, thanks for tuning in And uh, if you want to see previous episodes, they're all on youtube Um, and you know, I hope this Helps you learn Haskell. I hope this uh, you know, you just kind of show how How we program in Haskell, you know It's like a regular programming problem. So you can just you can do all of them, right? So Haskell has this Uh word on it that, you know, you always have to use a lot of category theory or whatever, but you don't like we were just using regular Haskell Like list operations and stuff and like nothing. There's nothing happening here That's uh, but let's just set operations and stuff, right? And we just The way we write it is like we do these data transformations, right? So this goes From this list of t-fields Into this right and then it's just going to be a map So like I just want to show you all, you know, how How do we, you know, what are we what are we thinking? What are we doing when we're programming Haskell? And like what are the mistakes people make? Because you know, I make a lot of mistakes myself And I've been doing it for quite long five years or something like that So, you know, and it's a perfectly capable language doing anything you want. So don't don't be afraid of Haskell It is a good language And like, you know, it compiles and we usually get it right We don't often fail unless we're like, oh, we're gonna use this unsafe thing Because we think it'll never fail Like we when we use this bang bang, you know, that was It's not a safe operation, but uh, yeah All right, thanks for tonight and uh, see you all tomorrow five o'clock utc at six o'clock european time or central european time That is noon in the u.s. And uh, yeah, again Have you Wednesday? All right, see you around