 all right welcome to today's advent of code how's my sound is it is it okay let me check hello hello hello hello hello hello hello hello hello I feel like it's a bit hello hello hello it's like my settings have changed a little bit right let me let me sort this out one two three hello hello hello hello hello okay let me check hello hello this is better right seems like yeah sounds a bit better right I yeah I didn't don't know what happened there all right good that's what's important and it sounds good all right yeah I cuz I I just turned the power off and on my microphone so maybe had a bad initialization or something I don't know all right let's also make sure that the color theme is better right just too much all right welcome to today's advent of code we're gonna be you also hear that what is going on today something is up with my son there's like a buzz I think we should try and fix this right this is not a good start to the double feature right just like a main sound right now it's gone okay this is the problem with sound right you you can never know what's why it happens but yeah all right let's get this rolling let's just hope that the sound stays okay that means what I only thing I did is like I unplug things and plug them back again again I don't know all right so let's go for day three of the advent of code let me actually pop out the chat here all right now we should be good all right so we're on date three it's actually day four now but we skipped day one and now we skipped a bit I'm using a bit higher than voice okay it's not as well this work was working fine yesterday my knobs don't work all right everything is messed up but now is better right now it should be fine okay we have a saying in Icelandic right when it's when it it's the same as when it rains it pours right it's like today the whole sound system seems to have been misbehaving and maybe maybe it's just yeah I can put my voice a bit higher as well all right that should be fine okay let's get to the programming and hope that nothing more happens because you can test the picture right you can see oh everything looks good but then like to test the audio you have to like record it look at it and because it was working fine I kind of assumed that it would keep working but all right let's go for day three of the advent of code in Haskell oh actually I have to change the name of the stream right now we're doing day three and four all right done let's get to it so submarine has been making some odd so okay so what we've done so far is that we like scan the bottom and then we next up we we were like controlling the boat itself so we're on the submarine to find the keys to the sleigh because they were dropped in the ocean or something so we have to find all the stars and then we can find the sleigh all right and so we're supposed to make some yeah okay so but submarines make them odd creaking noises so you ask it to produce the diagnostic report just the diagnostic report consists of a list of binary numbers which one decoded properly can tell you many useful things about the condition of the submarine first parameter Jack is the power consumption you need to use the binary numbers in a diagnostic report to generate two new binary numbers called a gamma rate and the epsilon rate power consumption can then be found by multiplying the gamma rate by the absolute all right each bit in the gamma rate can be determined by finding the most common bit in the corresponding position of all the numbers in the diagnostic report for example giving the following go against it for considering only bits of the first is first of each number there are five zero bits and seven one bits since the most common bit is one the first bit of the gamma rate is one all right so I think yeah okay I think we'll take this list we will transpose it take the sum of the number and then see if it's yeah see if it's less than half the length of the list and I assume that then we will always get like an odd number of bits okay let's get to it so we will take the input and we open up this is day two now let's open up day three and yeah I'm just gonna go ahead and go here make your day three touch day 3.h's and now we're going to open file and then we're just gonna open this file in VS code oh now yeah we want to open open folder because we wanted to like have all the right paths for the language server right okay so we say example we're just gonna do the same as before paste our input here now we need to increase the size all right and here our language server is already helping just click here all right now let's see read input so what we're going to have okay it's gonna be a file path and how are you gonna model this okay it's a list of binary numbers so and we're gonna have to end up turning them into binary so how do we I think it's data.bits in Haskell yes okay we have a way to look at bits I think I had like a function that was like bits to number or something like that but let's just make it into a list of bits so what is a list of bits just make it a list of balls to start with right input equals okay so it's gonna be refile and then we are going to map over the time so enough now it's crackling again so what I did between last time and now is that I like unplugged my sound processor and I re-plugged it and then now like the whole whole system seems to be in a big mess I don't know yeah it is not no cracking right now right okay let's see read at okay how are we gonna read these numbers let's just say read num so read num is gonna take a string and it's gonna return as a list of boons so read num of empty is going to be empty read num of one rest it's going to be next let's read num equals map read one where read one zero is false and if it's anything else it's going to be true map read one so we're gonna map map read num over the we're gonna map this over the lines right this is actually gonna be I oh all right this is gonna be a list of list of balls of course right because it's gonna return a list now it's complaining that a it's a list of list of boons oh yeah okay I think we do map read num right we have to F map this all right like this and let's see it's the ID three now we're gonna go in read input example okay and now we have the input ready each bit in the gamma ray can't be determined by finding the most common bit in the current position so what I'm thinking is like if we do at transpose of aim we like transpose it so now then we have like it will be a list of all the first bits a list of all the second bits and so on right and some right no instance for num boom so let's actually just have this be it's right it's gonna be zero and it's gonna be one and we're gonna have this to be a map list of list of ones and then you reload and we run it again 75875 concerning only bits of each number there are five one zero bits and seven one bits yeah okay so we take in we also need to know how many right so task one is going to take at least a list of inks and give us a list of inks a list of bull right the task one so it will we will do in okay this is gonna be equal to something right and we're gonna say where team is transpose of in and we are going trans trans okay so we're gonna map over it right so we're gonna so the check bit is going to be so this is like the list one so let's just imagine we're looking at the first digit right or let's just say digit here and we say check bit digit is equal to a sum of bit less than equal to length of it so considering only in the five you get to be number five your first bit of the gamma rate is one sum digit we have to import data.list here okay now we're gonna say map check bit digit no map check bit in okay and this is not the final one right but we need to okay so task one in right in let's read the input again it's giving us true for all of it was the in here okay wait so we're getting too many truths right all right we have to map check bit temp exactly let's relearn again the most common second bit of the numbers in the dick is to get port is zero okay so we let's look at the transpose in why is the audio like this ah that's the worst right if you have bad audio how's the music of it hello hello my phone right I'll keep it somewhere else in case yeah length of digit oh yeah yeah that's true we forgot to we forgot to divide this by two that's good because you want to see I find the most common one right so zero yeah but I think it's the opposite it's gonna be larger than or equal to let's put the Christmas music on yeah I'll fix the audio right after this this is yeah cuz it was it's been fine for like months now that I just do this true false true true false right and that's that's the gamma rate one zero one one zero and then and then we say set bit so I think we need like a list of bulls to hint to hint I have been too in okay and that's the type been to in a we can like what we do here is that we say I think we say like index or something so we can take the but I with value set and clear so a int there was like a nice way to do this I think great okay so what we're gonna do is we're gonna say bit been to int so okay let's import data dot bits right data dot bits and we say set bit to and we say zero bits right now let's do this at the end and then we get three why do we get three I thought we would get two we said one we said bit three this is weird right we should be getting if I set the second bit I should be getting two all right okay let's just do it the other way we can take the okay so we just do we just do this manually right a so we sip like one or zero to infinity in we see zero with the bones okay then we filter on second right so we filtered the ones that are true let's show this here filter second sip like falls true true then we get one true and two true right but we're gonna reverse the bulls and then we filter on second and then we map first then we map to the power I think it's like this now maybe it's yeah two to the power right and then two to the power of five 32 so we just we just sum it up right been into bulls is this and then we can actually we can just merge these right away and then we just do period and we don't need the period now what's wrong with this want to let's reload it been to int so we're saying like a true true false and this should be two plus four six nice who needs to figure out the library we can just do this okay I'm a match map check been Tim and then we just we in here and we're gonna say been to in this okay now we're gonna load and we go up and 22 okay that was all you were supposed to get for this one so that's the gamma rate the absolute gather and similarly rather than use the most common bit the least common bit is used yes okay so we say a check bit digit this is like gamma digit and then we have apps digit is equal to it's gonna be the same right except we reverse this here and I think like it will never be equal right because if we need to have it less than here actually let's say what map apps gives our task one that gives nine yeah okay so it's gonna be nine times 22 now we don't actually need to calculate the sum twice right so let's we just we map the sum over it okay map sum over the tin goes to transpose and we map sums over it we get like the how many there are okay so some is equal to map some tin and then gamma digit gamma this is gonna be gamma s for the sum so this is just like oh yeah no we need to lay but they're all gonna be the same right it's gonna be the yeah sorry my audio is very bad today I don't know why but it is the worst actually let's just not bother right let's just do both here we'll see if it bites us before the end of this short so pin to end map gamma 10 times pin to end map apps like this 198 yes let's just see if this is good enough right because it's quite I don't think it should be too bad at least not for the first one right so that here it's gonna be a thousand that we're gonna do let's see okay pretty fast right so we didn't we didn't need to optimize it because let's see if it's wrong we might have to check something okay we got the first one let me check yeah the it's like a slight slight like down there right at least in my headphones yeah this is very I had this fixed right and then I turned off the thing for my for a visit and then yeah alright I say so we let's finish part two and then we take a break and then meanwhile I will fix the audio because this is yeah okay alright next you should verify the live support rating which can be multiplying out again generator scrub rating values I can be finding a diagnostic report finding them is the tricky part both values I look at using simple process involves filtering out values until only one remains before searching for either rating value start with a full list of binary numbers from the diagnostic board I check the first bit so bit criteria keep only numbers selected by the big criteria for the type of rating value which you are searching discard numbers which do not match the big criteria you only have one number left stop this is okay so we we're not doing the first just the first bit oh okay so we okay I'm not this it seems like very needlessly complicated okay so I think we okay so we're so we look we take the 12 numbers so we consider the first finish number one more bits and seven zero so keep only seven with the one with the first procedure then consider the second bit of seven remaining numbers there are more zero bits and first bit so keep only the four numbers okay actually I'm gonna take a break now like I have to try and fix the audio this is too bad okay yeah I'll be plus let me just give me five minutes and I'm gonna mute the audio okay so I just turned it off and on again let's see if it like slowly builds up or not because now there's no hiss at all right all right let's hope this works for for a few minutes at least and I'm like super regarded yeah there's some something we are going on with the power okay so we're looking at the criteria of the numbers let's start with all 12 on the first bit and we have one with the first bit in the first position okay then because of the second bit of the center name under there are four more bits and one bit so keep on the four numbers with the zero bit in the second position as there's only one number okay so find the oxygen okay so we consider the one second bit of the seven remaining means there are more zero bits and one bits to keep only the four numbers with a zero bit in the second position in the third position three of the four numbers are one so keep those three in the fourth and one so give those two in the fifth are equal number zero bits and one bits one each okay hmm okay we can't like yeah okay let's do it let's just let's just do it so what we can do is we can so we can say task two let's list of ints to int okay so we have the input okay and we're gonna recursively check the the bit positions okay yeah this is like this will be very easy we had like indexes and we could just use those but we don't it's a bit messy to do okay we can kind of use task one but let's let's do the let's just encode it right so the this is the gamma of digit right and the eps of digits so we're gonna use those because they they figure out like which one is the most common right except we have to have this like larger and then little larger than equal to because now we don't have an odd number of things okay the task two of input right okay so we're just actually gonna say int is gonna consist of the one and and then the rest okay and and then we're gonna say where ints equals zip zero to so the indexes are just gonna be zero to length and minus one right okay this is gonna be the indices of the so we're looking at currently right okay and then we are going to say but like I don't think we need to keep the numbers around right we can just kind of figure out that the for the first one is one and then we find all the most common bits okay like it says yeah the most common bit in the first one is one right and then in the second one the most common one is zero and then the most common one is one but we need to yeah we need to filter them out okay this seems a bit messy okay but let's let's go just do it okay now let's just do a task to prime and now we're just gonna iterate over the current and we have the we're gonna map over the ins so we're gonna so we don't have any if we have we don't have any if we have one left I it's gonna be I one let me say the one left last one it's gonna be last one okay we shouldn't we shouldn't end up with no no okay now this is these are the ins we're just gonna return the current okay and now if we have an I and then the rest of the eyes we are going to say so where X I is equal to so yeah so extract extracting the eyes bit X extract I is going to be map bang bang I over the current okay so we are going to so curve bits now most common is going to equal most common is going to equal the sum of curve bits so the sum of the current bits is larger than the length of curve bits to do then it's one right and it's true right otherwise it is false or at least common I think it's like this okay so we have the most common and the least common okay and then new in will be equal to filter on the current we're gonna filter the current in on the fact that bang bang I okay so we're gonna so we're filtering the current in again this is just gonna be X so that it's it's in and so it's elements right LLM L a so if the EL okay so let's say it just fall to a B2 int is equal to a B2 int of true is equal to 1 B2 int false is equal to 0 so the element at the Y I position is equal to the B2 int of the most common a current and that's the new in we're gonna do this for all the things was task to prime of the new in eyes now let's actually trace show ID over this right just see how it how it works all right so task to my task to prime in in's let's see and this is not okay because yeah we want but we want to return less of it's our list of it's okay let's just see what happens right we just want to write this is task one but task two so it gives us a one zero one one zero okay let's say a trace show in where are the curb it's here we need to load so the current base is zero one one one zero zero one one one zero okay so that those were the current bits one yes okay so it's okay so that was those were the ones okay and then the next ones are going to be we're supposed to see a one zero zero zero one zero zero zero one zero one okay and then we consider the third bit and then we get so we're supposed to see one one one zero yeah okay when we did this card that was supposed to see one one zero yes and then we're supposed to see zero and one and we see that okay so we but we why do we end up with the okay I think we mixed up the less than or equals to so would be like this yeah exactly yeah okay I think this is okay so we get the then we get to the one zero one one zero and one zero one one one and then we have zero and one and then what is the most common let's always draw a trace show idea of that and let's see reload the most common then there is true and the most common is false and the most common is true and the most common is supposed to prefer false keep the number with a one okay yeah okay so if zero and one are equally common keep values with one one in the position being considered okay so no why so now that okay so it keeps again then we see the one one one zero and now but it now is keeping the other some other ones okay I think we have like a okay at least where we're iterating over them correctly right it's just that this to keep okay let's say not most common let's just say let's just count the ones right for the num zero because of the num num one it's gonna be the sum of Kerr right the num zero is going to be length of Kerr it's minus sum of Kerr it's minus the number of ones right now so the most common is if num one larger than equal to num zero then one else zero what's wrong with this right and then we are doing like b2 into it so we don't need it okay least common is equal to okay let's just wait with this least common you don't need to know okay now we end up with the right number right okay so most common we end up with the one otherwise yeah okay so let's actually have another kind of another case here task two prime of last one but there's no one left then we just return the last one otherwise we're not gonna have that case okay so we're just gonna say like this and okay so that's the oxygen generator rating and then we keep the least common number and if zero one or equal to give the last zero in it so let's just call this one task to MC ask to MC this too and it's gonna be task to MC task to LC prime in task to MC okay there's no prime here MC and then we're gonna have LC hello we're having another audio glitch let's hope it doesn't last okay we don't need to print these anymore and we're not gonna print the new input anymore and now this is this should be fine we don't even need this function anymore let's just copy this we say LC here LC and we some and we say common and let me say the least common and then we say so if the number of ones is larger than equals the number of zeros then we should keep the zero so let's keep the ones you reload run it so we get the one zero one one one one and zero zero one one one is that the one we're supposed to get okay now this is the the number of zeros is less than or equal to number one I mean this should be the same result right okay what what's going on here now okay let's map the current inputs again trace show ID because now we kind of made it into like as simple as possible right this one is not good oh yeah no sorry we were just doing we weren't recurring correctly zero one zero one zero yeah right let's remove the trace show ID here and we load and run it so now we get the two right numbers and then this is running on the input and I guess we're supposed to multiply them together as per usual this supposed to be we get an internal this and this one gives so we say one equals zero equals so we go map into it into bull have into bull and we take the product this list and this one doesn't work because okay so we get 230 for the example now what use a binary ambient diagnosis to calculate the octane generator and memos but again that's the last support okay let's run from the input 587 895 all right we got it and the audio seems to be holding up but I really need to make sure that it does that all right we completed day three I don't think we're gonna look into the core now I mean like we did it also by I don't know it's not like we did it in a cool way it's like we just we just road forced it but I think you know for days one two and three right it's like you know you can just solve them pretty fast right you don't really need to dig into it and find a super nice way to do it right and I think like the way we did it now was that we you know it's like it's pretty clear that I was doing the right thing like when we just swapped to this way right the other one was kind of a bit murky and you could probably change these into like maps and remove some of the intermediate switch yeah I think this solution is right I would accept this if someone handed it all right let's take a one minute break or five minute break and oh no not five and two minute break I'm just gonna stand up shake my legs and and then we'll continue with day four all right see you in two minutes all right let me all right we're back and doesn't sound like there are any audio issues but we'll be on the guard all right let's look at day four let's see how we do me I open up a new file we're just gonna do it in the same directory because it all happened on the same day now maybe this one is gonna be hard we don't know all right you're almost 1.5 kilometers below the surface are you so deep that you can't see any sunlight but you can see however a row a giant squid that has attached itself to the outside of your submarine maybe you want to play bingo okay a bit of an assumption but I guess bingo is placed on a set of board each consisting of 5x5 grade of numbers numbers are chosen random and the chosen number is marked on all boards and which it appears numbers may not appear on all of our okay if all numbers in any row or any column of a board or mark that board wins okay this is gonna be interesting the submarine has a bingo sub system okay that's good good for submarine it automatically generates a random order in which to draw numbers in a random set of boards for example okay we get bingo numbers and then after the first five numbers are drawn there are no winners but the boards are marked as follows okay after after the next six numbers are drawn yeah because we mark the board on the fourth is drawn and the third board wins because it has at least one complete row or column of marked numbers in this case the entire top row is marked 14 yet bingo the score of the winning board can be now be calculated start by finding the sum of all unmarked numbers unmarked numbers in that one this case the sum is one way to eat then multiply that in the sum that sum by the wow okay we're playing bingo and then we're gonna those just called when the board won 24 to get the final score to guarantee victory against a giant squid figure out which board will win first okay so we don't need to keep the touch it's just diagonals don't count right so we just need to check these and these four set membership okay so how do we do this let's let's first we generate the sets right okay but first we have to parse this right so let's let's put this into example all right now I have to say example day for okay and this is gonna be this one I think this one's gonna be fun okay so we're gonna we're gonna parse the so let's say data input so it's gonna be the input it's gonna be the nums call so the input is just gonna be in and it's gonna have the numbers called and it's gonna have the list of all the boards right which is gonna be a list of lists lists right now we don't actually this okay so let's just write here a great input file path goes to a top couple of these okay and we're gonna say here let's say let's just say you know type or is equal to list of things and then this is a list of board read input let's import the parsec so let's say data input it's going to be yeah it's going to be an input of the nums of int and then it's gonna be a list of boards and now we're gonna say it is gonna be just to input and we're gonna find a reader so we're gonna say instant read read input where read s reads crack whatever is equal to so we're gonna import text as parsec compromise or import text parsec no text to parse let's just write like a read p to s to press yeah and then we import that right and then read input is just equal to read right string and then this is gonna be read input over read file fmap right so it's like this but what is wrong in this one couldn't match expected type read s p read reads preck right so read input I know so parse input is gonna be a read p input it's gonna be parse input right right and then parse input like this okay and now read input is gonna be what's wrong with that yeah this is gonna be IO input exactly okay yeah I mean the parsing is hard for this one right hello level migrants and welcome to the stream hope you're enjoying the Haskell now we're actually doing now we're doing a fun part right the parsing wow thanks for the follow it's always nice to get some follows right okay so we're gonna read the first line and then skip one line and then read five lines and then skip a line okay let's may I ask why Haskell because it is the best language it's got the type system and it's got a very mature ecosystem right you can have your packages for almost everything and it's functional so you can do a lot of stuff that's why I don't really have a better reason let's see data nums called it's gonna be nums called the list of things and then we're gonna say yeah instance read nums called where reads preck underscore equals read p to s of so we can actually put this here right and here we're gonna say pars here where pars that repeat nums called so it's gonna be the initial list so pars is gonna be do and then we're gonna go to the page for the text parser yeah thanks it's actually it's very nice it's from our Milo and it's the Icelandic flag which is nice like right text parser combinators read p okay so we are going to say so sep so yeah so sep buys parses zero more occurrences of p separated by sep so right so we are going to say here is a little this is gonna be the end so this is gonna be sep by you know I'm just gonna import everything from this library I don't need the I don't need this so it's gonna be sep by so is it gonna be nums this is gonna be actually it's just gonna be nums called mapped over sep by so which is it sep by p sep parses zero more occurrences of p separated by sep and it's gonna be reads preck and then we just say n at int separated by why is it combining now right so we need to say read p to s no read s to p right and then this is gonna be reads what's complaining about here it kind of apply read as invisible preck and and it's gonna see you separated by and it's gonna be separated by the the char comma now this is gonna be undefined so we're just gonna be able to load this right now load day four let's actually quit this and just say day four dot hs now we're gonna say read at nums called oh we're gonna actually have to set x type applications and we're gonna read at nums called and then what does it say it says seven four nine five right seven comma four comma nine comma five right reload right so it works for the yeah exactly so then we f map directly over whatever we get right and so because we we're just gonna read a list right i don't know we're just gonna make it into our nums called and this is just to make it to nums called all right so first here so the input is gonna be nums called right and then a list of words okay so we're gonna say here two so we are going to what we are going to uh we're gonna we are going to read a nums called right so parse nums called and we're gonna use this parsing function again so we actually want it to be global instead of to read p to s to p something parse nums called okay so what do we do here we say do uh nums is gonna be parse nums called so that's the first one and then we say and we return input nums undefined and then we derive in show here right let's let's just return an empty list for now okay yes we say we do like this and like this and we're never gonna have presidents here so it doesn't matter okay uh then we reload and let's see we read nums call still but now we're gonna read that input seven four nine four five and then slash n uh how do I set m right because it's like a way to gsi multiline something like that multiline input um we just have to set plus m okay set plus m so read add input and we're gonna say seven five four a space oh okay return by four then uh oh no okay I don't think this works actually uh so let's just say example day four okay let's just parse example day four right away actually uh we roll this gz and a four and let's say read add input over read file example day four set x type application so they allow us to do it read no parse a it's probably because we have more stuff but if we remove all this it should work right yeah so then we read the nums called okay now what we will have is that we we say okay now we say skip spaces and then we should be able to parse this file nice okay now we have we're gonna put in the board back and we are going to say um we're gonna say set by right because a parse board so how do we parse a board we don't actually need to read instance for nums called here uh hurry sorry how do you say parse board repeat board parse board is going to be do we're gonna we're gonna have a parsing the lines where parse line is undefined but we are going to say set by char slash end uh parse line right I think that should be okay no it's uh it's actually let's wait right parse line and uh yeah and board is just like literally this right so and parse line is just gonna be repeat of int no it's actually it's gonna be a p of int and this is gonna be data board deriving show now parse line how do we parse a line well it is set by uh read s to p uh of uh ten highest presidents uh set by and then what are they separated by they are separated by spaces I think this one is good okay and then then we say b is parse board let's just go with one board for now okay we parse the first board sorry it's pretty nice right you just kind of parse and then you assume okay and this is our board okay now we have to set all the boards so we say boards set by we parse a board and they are going to be separated by a char slash end or no string like there's gonna be a slash end and then space and then slash end right I think this should work let's see ambiguous parse I don't know how to deal with that um set by one so what if I do just be no wait I can do set by parse board skip spaces that should be possible wait it's not uh okay it loops set by one in parse board maybe yeah that is a good idea I think I think the skip spaces here is too much string slash end space slash end ambiguous parse again uh what about separated and ended by set okay we're almost we're almost there right we got we managed to I guess we know the amount of boards we're fine and we can't step right so what if I just write a loop is that too much yeah probably are gonna be as fast maybe it's separated by so what if I change is to end by because they are ended by one let's write so and then we have this slash end no parse okay but what if we go back to this one let me just see we're still good be parse board now okay then this is too bad okay what if I do um parse board skip spaces one returns what yeah okay like this and be let's be skip spaces uh skip spaces a return because that's allowed ambiguous parse a p1b is equal to this p1 so we're gonna say these is many p1b because it doesn't it doesn't tell you like why it's ambiguous right which is a bit annoying okay and then what if we say many okay I'm gonna try again by saying this and then and then you have and then return boards maybe that will like maybe that will be enough to make it no maybe I maybe it doesn't realize yeah that that it's good it has to be exactly a five line so let's change this this is count this is count five right and then parse line there is like a way to do this without with some combiners but not a skip spaces return l okay and now we're gonna say count five and then now we're not allowed doing this right now let's go back to our testing board b is a then it should know that should be should be five numbers okay this one works so parse board is count five parsed line okay now the parsed line that's exactly going to be count five and then this into uh and and skip spaces return and okay this one works now what about this right this is return n okay now it at least managed to get the one board now let's undo this no parsed damn it okay and many parsed board b b or two skip spaces all right we parsed all the boards by this pattern here which means like do it and then skip spaces and then return fun so he's kind of specifically specified the numbers move brackets and let's encapsulate this pattern right with skip is equal to p it's is equal to p into r like res and then skip spaces return p so we can just say many with with oh wait this should be so parsed board and then result and then skip spaces and then return all right return r right and then just many with skip parsed board and i'm sure this combinator is called something right i just can't remember now with skip parsed line and we just say with skip line 31 did it quite nicely right do i need the you have here no okay and then we can also say input nums over this we can probably do some applicative stuff here as well but this is fine right uh right this is actually like this okay it's quite uh quite smooth isn't there like a nice there's a nice pattern here right i think it's like uh input over with like with skip and then like the applicative thing and then this see it's all applicative completely unreadable though but very nice okay this is Haskell making things wine liners after everything else we kind of screwed up okay we don't need the nums called anymore right with it's just actually it's just going to be okay and the board yeah we're gonna have the board still okay and if we can move this as well yeah i think this is like getting very unreadable right okay but now we are getting okay now now we have the numbers called and the boards right okay that was the parsing which Haskell is super good at right so now we now we have to do the actual task all right let me see okay this is the previous one database we don't need that we don't need the parser anymore after five there are no winners but the board's a marked of swallows okay okay so let's say import data dot set import data dot set now we want to say board sets is equal to takes a board and returns a list of set or actually a set of set in board sets and it's map to to set i think it's let's say google data dot set now we're getting into some hardcore stuff uh from distinct so we can just say from list yeah okay map so this is going to be a board and uh else right and so it's going to be map a from list to else a plus plus um map from list to transpose else so then we have like the lines and the columns and we're gonna have from list what you're complaining about now uh right now it's complaining about uh import data set set and then import qualified data dot set as set as set dot from list and then we have the same here as set from list and set dot from list and what the rock is the word we're on the bracket okay and right then we need this from data list okay so let's read the input so we have in in per okay and let's do it differently let's see input called and boards now we say boards uh let's say uh let's like get the first board right board boards or no let's actually have all the boards boards and then we have one board okay this is a board and we have board to set oh we haven't reloaded uh board board board to set board sets it's called a board okay so this is like the set of numbers it has right so we uh we closed the actual challenge i think yeah okay so this is like the first so 11 13 17 22 so 11 13 17 22 and zero so these are all the sets and then we have the 1 6 8 21 22 which is this set right 8 okay and so basically we have bingo once every element and so once uh once this set is contained in the set of elements that have been called so far so okay so what we we will do is we will we will write uh so okay so has bingo we go to board to uh set of set of int actually we don't need so the board don't that doesn't need to be a list of list of ints it can be a set of set of int and then we when we parse a board we actually say we count five over uh so this is going to be board dot board sets and has a bingo board to pull and bingo equals uh false that's just uh has bingo so this one is uh cannot match or it be actually will be right and so this is going to be board a proper board and enough so board is the set takes a set of the board sets right so this one takes uh list of list of ints to add right and then we can see a board and it's just these sets right because we don't actually need to know the structure we just need the sets so has bingo uh is going to take a board board and it's going to take a set of ints that has been called and uh maybe it should just be a list of yeah maybe you can just avoid this we can just that list this is a list of sets of ints so uh this is going to be the uh list of set of ints and then this is also I mean it is a set of set of ints but we're going to iterate through it like a list so we might as well just be a list okay and this is not needed okay and so we're going to say has a board so okay board sets and then so far so what we compute is we say any uh all called sets right we're all called uh so so any takes a a to bool and a list of a's and uh so it's going to be one of the sets so all called uh set is going to be so here we check that the set minus so far right so if we remove everything in so far from the set uh then it should do yeah so this should be set difference I think that maybe it's like this set dot minus what is it called set difference and let's see yeah backslash backslash set dot okay any pretty much uh any uh yeah okay so we check is empty right let's see what is happening right now two two two two all right nothing important okay um okay so let's just do proper is proper subset of exactly so that's why we want to check so is proper subset of a a no okay we just want check is subset of yeah so null s1 difference s2 exactly so is so s1 is a subset of s2 so it's going to be a it's going to be flip set dot is subset of now it's still complaining because all called uh flip is says oh what what do you yeah okay like this okay so has bingo right so was the third one that had the bingo so let's just get the get all the boards right so it's going to be b1 b2 b3 of b3 was the one with the bingo when a 74 9 5 11 17 23 21 so 24 okay so yeah so it's these numbers uh so n equals these numbers now ends okay we check a has bingo let's check just be one right set dot from list ns is a lot of two but it's type board oh yeah i didn't i didn't reload sorry okay and then we rerun the board and when you rerun the ns now we say has bingo b1 okay b1 no b2 no b3 true exactly but if we said no we remove the right four then this is false okay so we got the has bingo function so okay so after okay so in this case the entire drop off score the ending board can be satisfying the sum of all unmarked numbers on that board uh so what is the sum of all unmarked numbers on that board okay so uh let's try turn this into like maybe uh int so it's gonna be the mb win okay maybe win bingo uh we're gonna say okay if any alcohol sets then okay and now we're gonna take the union the set okay the the set dot unions of sets okay and then we are going to remove set dot remove so far okay and then we should have a set of the numbers that have not been called and let's calculate the sum of that and just turn it to a list and let me do the sum of the list let's say reload this and we define that we want b2 b3 and we say has bingo b3 would okay maybe win bingo b3 set so that's just 188 and then we multiply it by the last number 24 okay so now i think we have our our game plan right we're gonna like iterate through it and the sets and then we are going to so we're gonna have like the the set of numbers that we have currently been called and we're always gonna like add one number to it we are going to um check if any of the boards have a maybe win if it has a maybe win then we return it okay so task one it takes in yeah file path and returns an end okay so task one okay so first where input nums uh boards is equal to uh what did we say read add input this is an io in so uh do input nums boards read add input uh fmapped over read file uh okay and then we are going to so uh it's a task one prime it's gonna take in okay so it's gonna have a couple of things right it's gonna have the so far it's gonna have the boards and it's going to have like the so if it's if it's done then we return error no okay but task one so nums so far boards and ns okay so then we are going to say uh so this is where so nsf num so far prime is equal to uh we're gonna insert the new one into the set right uh set dot insert and num so far okay and then we are going to map so this is a list of boards so we're gonna map we're gonna flip these arguments just to make it a bit easier to map it okay so we map uh oh thank you mat 314 seems like you're a big pie fan should probably watch those anyway pies are good and pie is good let me see ooh okay so we're gonna I think it was like a map map maybe let's just map maybe isn't there like a function that's like a hugo you know you have like an a and you get a maybe b and then you get a list of a's and you get a maybe b out first just did a list extra we're just gonna map maybe you see all okay and res equals map maybe and we're gonna map an mb win bingo and nsf prime over the boards okay and now we're actually we're just gonna do this case statement uh and also teaching has to let uni yeah yeah and these are fun uh exercises for if you're teaching right case map maybe mb waking boards of now if we have a winner we return winner times and otherwise we are going to go task one prime with nsf prime and the boards and ns and now we're just gonna call task one prime return task one prime on a yeah we're just gonna grab the first number actually because it's it's never gonna be you know you can't win a bingo with just one number so it's gonna be fine uh set dot singleton okay we can actually just we don't need to worry about it so just let's just say uh this is a so so far it's gonna be set dot empty the boards are gonna be the boards and the numbers is gonna be nums now notice that that is their nums so far and i think we need to import data dot maybe now let's see task one on example uh exception period no pars oh no but we've been parsing it right all right it's example day four sorry example day four four five one two which is exactly the answer to guarantee victory against the giant skid figure out which board will win first what will be your final score if you choose that board yeah so this is just we calculated and we you know we find the fairly first one and so we should be able to do this puzzle at this point okay now i hope this is just a long it's okay input input day four now because this is it like a bunch of set manipulations i'm gonna say main i o and then main equals task one input day four into print and i'm gonna actually gt o three on day four dot it just all right because it's not called module main sorry we do it and then we run it three five six seven zero in 25 milliseconds let's see if it's correct we got it so we had a lot of fun parsing music complaining about this one yeah okay we're not gonna use a new type because i don't think we can all right we we're not actually defining an instance here new type okay uh that's fine so we did part one so it's all about parsing we ended up with a nice applicative parser and we did this set list union thing 25 millisecond this is pretty nice right and i would like to point out that in other languages i think this whole parsing business takes a long time and like these just set manipulation things i i mean we this is this is not a lot of code right i think haskell has no in here but i don't know we could also do this like somehow differently right um like we don't need this if than else all right but let's check out task two okay so on the other hand it might be wise to try a different strategy let this giant squid win okay so you aren't sure how many bingo boards have giant quids applied one time so rather than waste the time counting it's ours the same thing to do is to figure out which word will win the last and choose that one in the above example the second board is the last to win which happens after 13 is eventually called and its middle column is completely marked if you were to keep playing um till this point the second board would have a sum of unworked numbers equals 148 for a final score of 149 1924 figure out which board will win last once it wins what would its final score be okay yeah so now instead of instead of um in yeah sorry instead of instead of just stopping we should keep going so just copy paste task two i mean the inputs are the same okay task two prime but now we want to kind of keep track of the boards that have one and the ones that have not one uh done one and then the rest of the boards one okay um right so if there's no winner ever that's one case right but probably not gonna end up with that case so we're just gonna kind of ignore it okay so uh if we have the last one right so i think we we know we now we need to we need to check the case for the last one at the end right so we can't do it here because because um yeah okay because we need the end right we need the number for the final number that's called so heater num so far okay okay so we we calculate the new num so far and we calculate new boards is going to be um filter so newly one so like multiple might win at the same time right we see this and we go sometimes so the filter is just we actually we want to let's i think it's called span like the function that you split you split things into things that where it works but it's not span right it's because span is the returns the first element um what is it called again a to bool uh list phase a comma a partition nice so uh newly one uh not yet it's going to be a partition partition no we don't actually have to do this right because we will have yes yeah we need to do this but we were sorry so we can have here task two prime so far one and then like the last board and then we have the num so far this will be like okay so we're gonna actually we're gonna use this one again so then we're gonna we gotta keep playing the game until it's done so we're gonna do like this yeah task one prime so we have only one board we have uh bees and board nums right so this is going to be task one prime of so far a bs nums right because then we kind of want to keep playing and we know it will be the board that wins but we just keep playing and i mean we're using map maybe i love it yeah i fuse is what we're hoping like it'll be list fusion and it'll be super fast anyway okay so newly one not yet is partition is just daughter mb win bingo nsf prime map nsf prime over a boards now we need to import is just from data dot maybe we need to import partition from g data dot list and it doesn't like this because partition apply with too few arguments is just a yeah okay we're not yeah okay we're doing mapping like this is just mb win bingo over boards and okay this one is going to be a task to prime nsf prime a one plus plus newly we don't have to keep track of the ones that win they don't actually matter so this is just filter ns prime a num so far not yet the ones that don't want so far don't matter let's uh let's run task two on example day four and see what happens in 1924 it returns which is the expected output for the example so let's check what happens if we say input day four boom 36 milliseconds isn't the right answer though we did it we did both days double feature sure in two hours that's nice i think yeah like you know the like a two solve a two push of i don't know how to pronounce it eh said right most of the work was like parsing and like figuring out how to make it and no i like yeah most of the work went into a flyhand use fewer import okay most of the work went to into writing the parser because we got like these weird parsing ambiguous parsing right and they they're hard to fix because like we're not using parsec right or mega parser for any of those uh so it like it doesn't do backtracking i think i think that's the thing so it doesn't it doesn't actually tell you right it doesn't tell you i don't know which one to pick here it just says ambiguous parser right so it's just like it's it's as informative as saying you know segmentation fault core dropped right doesn't tell you anything unless you already know what's wrong kind anyway uh we didn't actually use input let's do get status and let's go back get get and let's move day three two day three and four get add day three and four right and now i have to say you have to open this one in code because uh yeah i changed the directory no matter it don't matter to me uh let's see i added a marked field so alex added a marked field to the table bull int so that made figuring out the winning board very easy so you like you you added you added a truer false for every every time in every board that anything had been called is that right but like how long did it take right because here we like we just run a bunch of set differences right and the trick is that like we're not actually like i think set differences can be computed super efficiently right like a m plus you know it's at like m times log and m blah blah right so it could do all the set differences right away would kind of end up being super fast i mean you could do this with like a bit mask or whatever you know 35 millisecond is that's pretty decent right i don't think that's uh yeah i think um i think we should be happy with it is what i'm trying to say um let's see how long both take because like there's a boot up time yeah 255 milliseconds for both yes i i think we should be happy with uh without one today i mean yeah apart from like stream issues like the audio in the beginning and that was a very annoying but it seems to be working now without yeah i just like turn it off and on again a couple of times which which makes sense so let's look it over a bit right so yeah here we have the filter i mean i don't i don't really see any like i don't really see any like oh this is something we could improve right there's not no really there's not there's no like there's no place where like oh yeah this is gonna take a long time right it's all just very straightforward and i like that you know i like that with haskell especially right you can just write code and it's that's straightforward and kind of it it does it does what you want right and it's pretty clear what you're doing um i think often in imperative code and there is like there's so much overhead um not in the execution but in the like like things you have to be doing that are not really related to the actual problem right where i can i guess yeah because i i mean i like i like rust i don't really program in rust but i it's a nice language but a lot of a lot of the code like the character like the literal characters you're writing are about memory management right you're always telling the computer how to allocate memory and who can borrow what right which is uh you know and that's of course i mean it's important right if you want to execute fast that it that's all the memory is all correct right but like in you know like filling a bingo table is not about allocating memory right here we're just talking about sets and like yeah yeah i mean so we need it we we need it to parse right and that's like yeah okay just need to get it into an in format that the computer can understand right but after that we're just talking about like sets which are like mathematical objects right you're not you know you don't have to allocate memory for the set you don't have to say who can borrow this set right you're just using them and then you allow the runtime system to decide if if it's borrowable or not i don't anyway enough ranting about rust i should just learn rust and and then i'll be so first i have to learn rust and then i have to contribute to the compiler right become a rust person rust station and then i can complain about rust that's how you do it uh yeah exactly so here we like built a bunch of small things right and then we just use task one again and uh we're always just like everything we do is just about like this small thing we've built it up and then we just use it we're always just building up these pieces and puzzling them together in rust you can't make a set of sets because sets don't implement hash right and that's like that's like one of the things right it's like you know it's not a part of the problem like obviously you can't have a set of sets right mathematically that makes sense right you can't have the set of all sets or set of sets that don't contain themselves but you can have a set that contains a few sets right it's not related to the problem of sets whether you can compute a hash or not i mean it's it's related to how we describe the computation right the computational problem that's true but it's not related to solving the problem right um and that's how i like to do it right i want libraries and stuff like that that kind of they take care of you know how to describe uh how to describe how to compute with the objects right and then you you just kind of compose those and it has cool that's like that's a lot of what you do like you define types you define how they interact with each other and all that jazz right where and there's i mean like there's nothing here saying how sets work right we just take set difference we don't have to yeah anyway a and we're just composing functions and yeah so i i like i really like haskell it's uh i think it's at the nice point in uh in the abstraction cube or whatever like you have to pick point right where where it's not too abstract um so you can actually get things done um fast right and it's not too low level so you can actually so you so you don't actually uh spend all your time spending how to manipulate pointers right because pointers is not a pointer is not a thing in bingo right and you can view uh bingo as a you know figuring out the subset of a set of sets blah blah like we did right and that's like a mathematical description of bingo right you would never describe bingo mathematically as a pointer to pointers i think that's that's nice about askel right but for sure uh as these challenges get harder and harder they usually uh they also become very imperative right because uh the author uh he he came by actually last year it was uh he's cool but uh he's an imperative programmer right so all the kind of the some of sometimes the problems are kind of written with a certain solution in mind and it's not a functional solution right so you end up having to do very imperative things to make it fast enough um which is also and that's the thing about haskell right you can also do that right you can have the like state transformers and her vector arrays um and you can even like describe how to do it concurrently and then just run it all in parallel without having to worry about allocating memory but uh yeah so we'll see and yeah and that's it's a lot of fun but like yeah then like now we did two things in like one hour and a half right or two hours and a half uh but like yeah then you know you you spend two three hours on one task because you're manipulating safety but anyway uh thank you for stopping by today uh yeah so and what i'm like i'm saying now uh thank you for talking by today uh i'll be here tomorrow like around this time uh meaning a i'm gonna stream at seven o'clock uh european time central european time and gothenberg time which is like six o'clock utc in iceland and um and then yeah we'll see we're gonna we might have to get out into like proper mutation haskell right uh and you can describe it in really nice ways right when you and that's the thing about haskell right you can just grab you can just go back to imperative stuff if you need to um but like another language is it's very hard usually to go to the into the functional direction right all right see you tomorrow sorry for uh yesterday but uh yeah i mean better to just do a double feature than miss out on nice things and uh i'll make sure to test the sound better before tomorrow i mean it's working okay now and it was working okay fine but yeah make sure it works right before the stream all right uh catch you all tomorrow and yeah all right