 all right good evening everyone and uh welcome to day eight of the advent of code um today i'm gonna be streaming for at least nine minutes and then i'll have had enough time to become a twitch affiliate so i become a pro streamer let's say it's not something i thought would happen in 2020 but here we are i also want to find out um see this shirt here yeah so these these here things they are actually green so my green screen thing is cutting them off so if i go to a white web page like google you'll see that they become white i hope you enjoy this uh word world world crisis i don't even know what to call it anyway let's look at today's problem i hope it's not too long too like two like two guys like two hours a day that was a lot uh but you know we had a lot of fun along the way it's not about the destination is about the journey oh right remember when i was talking about yesterday about that virtual machine we had to implement now we finally have a virtual machine that's cool all right flight to the major airline hub reaches cruising altitude without incident when you consider checking okay so here's a handheld game console i think you all know what that is um the can't turn on there's a strange infinite loop in the boot code of the device you should be able to fix it but first you need to be able to run the code in isolation the boot code is presented in as a text file one instruction per line of text each instruction consists of an operation act jump or not and an argument assigned number like plus four or minus 20 act increases of three increases of global volume called a cumulative by the value given the character all right thank you oxython for the follow and uh so so act plus seven for the increased accumulated by seven the camera starts at zero after exact instruction it's actually immediately below it is executed next jump jumps to a new instructional data to itself the next instruction to execute a fund using the argument as an offset from the jump instruction jump plus two would skip the next instruction jump once one was continued to the instruction immediately below it that jump kind of would cause the instruction 20 lines above to be executed okay knob stands for no operation does nothing so here we have the program and then the here we have the trace I guess so the first one is this and second third jumps to here then it goes to five jump minus four goes to six six jumps goes here to jump and then it goes to eight bang okay the camera is from one after it sets why so why okay so it goes back into the jump I guess so jump so we'll go here so this is the infinite loop right program that tries to run any instruction in a second time you'll the moment the program tries to run any instructions a second time you know it will never terminate okay that is a that is a very harsh condition on on a program right that you can't run any instruction twice that's like why are you you can't use functions right you can't run it right loops okay so immediately before that okay what is in the web page okay that's right okay take the input here make a new directory day eight change into day eight uh touch input touch no this is going to be test input right touch into eight dot HS then we just open them all here let's write the test input okay and now we are going to module main where main IO get input test input into print like we usually start and let's see so get input is going to be a file path it's just a classic one IO to list the strings get input fb equals fmap lines over a read file right oh yeah so this will just print the input so we won't compile it and we will write I always time it but so far we haven't had any like super long run times so it's been quite good compiling linking all right we got the instructions now so far in these challenges I've actually been just using string manipulation to parse stuff but uh google soon pointed out that uh google soon 78 uh pointed out that there are actually nice parsers in standard library classical so let's look at those so I found one here called text parser combinators i read b and then we use these operations here to kind of write a parser right so let's let's let's try it I got a I got a tweet reply right now that says don't forget to smash the like and subscribe button below so yeah that's what pro streamers say right but I've only been streaming for six minutes a day so I am three minutes away from being a pro streamer so you will see the moment I ascend to the glorious position of a pro streamer so choice so here okay so here we're gonna be we're gonna write this clean so now we're defining this handheld game thing I assume we are going to be using that a lot in the next couple couple days so let's let's write a data instruction it's going to be so what are the instructions so far it's gonna be not but they all have an integer value right this will be a knob int or it will be a a hack int or a jump int uh deriving show so and now we will write so pars instruction uh it's going to be a choice right so let's write here pars instruction read p in a read it's read read p for this one let's write it import text dot parser combinator dot we have parsec here does this compile well we have base let's just see what's in base like I should I thought parsec was not in base so here we have text well we have this read p and read prep we do not have parsec so it's just I think I just like globally installed it at some point and then I haven't reused it that's okay read prep let me see who will yeah per year king the quickest of questions but you're wondering uh if anyone can help should I be using pycharm or visual studio so I use visual studio um I've been using that for like a year and a half now and I use it because all the Haskell stuff works really great so I tried pycharm and the thing with the thing that we as code is that it also works on linux not quite well I I just haven't used pycharm so I can't say but like for my purposes you know it has nice color schemes it has a bunch of plugins so here I'm like working on a uh so this is like actually like a virtual linux machine like vsl2 machine running on my like the hyper v on my windows computer um and then this is just like I just I literally I literally write code here like I started on the linux machine it starts the internal server and opens this window on my windows machine so I get to use all the GUI stuff from windows which is so I'm so for my part like because it it just works you know I've tried SSHing Vim it it's just so it's annoying I mean it doesn't quite I mean I've never gotten it quite to work like I've gotten it to work but not like as nice as I wanted to use um and uh I think so I mean but I usually I use Vim too like if I'm just editing one file I just open Vim the thing is it also has pretty good Vim emulation like there are a couple of cases where it doesn't do what I want it to do that I've encountered um I I'll show you I'll show you all so if I copy lines like this I copy three lines down and then I paste them it pastes them like this in Vim it would paste the T after all of them so there's like a slight difference from Vim that I'm used to but you know I would recommend VS go that's what I'm I'm I'm using um that's when I found so far at least for doing development on windows but it it's it's very much depends on if you like it or not so just I that's what I would recommend you don't just try the editor you don't have to dedicate yourself to a side in the editor wars just pick one um and get used to it you know and as long as it's so like vs code py charm you know Vim emacs they all have so many plugins so that's that's the main thing that you want from an editor you want it to have plugins because then you can change how it works if it if you don't like it but uh yeah so I would look into that uh but let's let's keep going uh read Prec so I want to so the the the read s read s that's the one we use for reading in the prelude and uh I think there is like a read read p to read s reads Prec yeah no this read spec here is read s let's just use read spec so and now after because we're going to be using this again and again and again it's a nice to write like a proper parser for it because then we can we can reuse that um we can reuse it as much as we want all right uh let's see so to parse so to so to parse a uh so to so to pause or parse an instruction let's actually let's actually not take the lines here okay we're gonna have lines again we don't need to worry about lines that's fine um so parse an instruction it's gonna be a read p of instruction parse instruction it's going to be a choice so this is going to be read p so to read parse an instruction we're gonna have a choice of parse not okay let's not write it like that so so this parses and returns a specified string so so we we're always going to be parsing an int right so read s to read p and so parsing an instruction so here we're gonna have instruction parse instruction code so it's gonna be so this is gonna be so choice separated by uh so set by parses zero more cursors of p separated by sep uh in terms of list of values yeah so set by so so set by these are gonna be oh no yeah okay no that's that's not what we want um parses open followed by p and followed by close only the value of p is return okay we don't want that um yeah i haven't written a parser in so long uh so it's like where do i set put the skip spaces let's see anyway so these are gonna be so so let's say it's gonna be undefined let's just write that so let's say where so this is gonna be where parse code equals this is gonna be the choice right choice of pars parts anyone here written a parser like recently i mean i think it's like it's not a we i mean you have to do it for every language but like i'm just wondering if if it's wait so okay oh yeah i it's not parse string it's just string it's gonna be a string not or string okay so here we actually want the entire code mm-hmm it's parse string not parse string act and then it's gonna be a string jump so i think here so we're gonna take in parse instruction we're gonna take in the stream right so stir it's going to be so first we're going to say do code it's gonna be parse code parse code has hybrid p string right okay so i think it's is it complaining that it's not a monad yeah okay now so and then we say we have to return something right not zero okay um so we parse the code and then we we will say so here's where we wish i could use reflection i wish i could just say look up the code so i let's say uh so you know i want choice yeah so i wish i could like attach to the choices something so um a code to so this is gonna give me a function from string to a function that accepts the string and sets an integer and returns an instruction so code to insert stir stir so code to insert okay if it's not then it's going to be not you see what i mean this would be very nice if i could like just reflect it somehow and i think you can like if you had the arriving we could reflect it but we don't so jump is gonna be a jump so and we don't have anything else so we say code to insert s equals error and defined in direction also my wishlist for haskell is format string so i should just say format here and then say s but i think it's i think it's harder to define than i think you need like a nice parser to define it and the haskell parser is a bit outdated actually so uh we will parse the code and then we will we will skip a space or skip white space so skip spaces skip spaces and then we will parse an integer but i think i think there's a read s to p yeah so i think you know i think there's a read s to p i think it's like an already defined parser for numbers uh let me see yes okay we have here reads i think we have the function that's just called we're not gonna use the presidents yet so reads yeah so let's say here language we okay we don't actually need it so so here i will say okay we want to be i want to be explicit about it what i'm trying to read so here we will say so this would be val is going to be reads at it so it's going to be going to be a read s so i'm going to have to say uh why haskell well i uh so i'm doing a phd in programming languages or programming languages and security and i have contributed to the haskell compiler so it's like my favorite favorite language my favorite compiler and i feel feel part of it you know from having contributed so uh i'll show you so if i do like this if you want to see what i added uh this will compile into a typed home well it should anyway let's see oh i have incorrect indentation somewhere let me see oh i forgot to do like this okay see typed holes in haskell you can just write a typed hole and it says uh it says you know you you get a typed hole you compile this and it says found hole read s int to read p a zero for a is an ambiguous type variable and valid hole fits include read s to p which is exactly the function that we want right so i added this valid hole fits thing here i so this is like super naive code synthesis that you know based on this type here just finds everything in scope that can work so now you know instead of saying instead of like writing read and hoping that okay it is in the list right we can also just say okay based on the type we do control period replace hole width boom how's that for efficiency huh type directed code completion cool stuff uh so here we say here we say return code to insta of val right a oh yeah so we want to say code to insta code of val are you into the crypto space uh i hats i met like i i i know oh no i met a bunch of the cardano guys um at conferences and they they're pretty cool people actually and you know after i finished my phd i probably it's definitely one of the places i would look at for work i had some add for a while um and i you know pending on like based on the lectures they were you know i really like i really like the idea behind cardano like they seem to be i mean like it's also like people i respect in the academia so it's like i think they know what they're doing and that helps me in the crypto space rich how about parse code oh that is clever to me he is one of like 10 people in iceland at no that no uh no functional programming he's also a cool guy give it up for to me yeah so that's that's good so instead of sparsing string here we he wants us to parse into instruction um so this is gonna be a choice so we are going to instruction now these return um so yeah so here we parse string knob and then we say pure knob exactly that is so much nicer thank you timmy uh pure act pure jump this is good stuff so and then we say say parse code and then we apply code to the value nice that is good stuff and then we don't even need this here it will just give us a parser which is exactly what we want but like again i wish i could reflect i wish i didn't have to say string knob and then act and then pure knob i wish i could just say reflect this symbol i think there is a way to do it but it involves so many language extensions that you know we wouldn't be we wouldn't quite be writing haskell anymore right okay we written the parser so we're we're banking on here is we are banking on the fact we're banking on the fact that um what am i trying to say we're banking on the fact that we're going to be using this machine later so that's why we're writing this way that's actually you know encapsulate this pattern so uh so that's gonna be this code to inster that's going to be read p into instruction no in structure so that's gonna take in a string and it's going to take in a like this bio med engineering that is hardcore stuff you know i always have such big respects for engineers um i i was i did my p i did my bachelor's in it's called computational engineering there's a joke about it it says what does a computational engineer say when he's rounding he says log log log log log because all the algorithms have log complications it's not such a good joke uh let's say but yeah yeah this is haskell boss finder x i had a i had a joke but it's like slightly i don't want to was about my boss but i like my boss i'm not gonna tell it but it was terrible let me see thanks for the follow boss finder yeah this is haskell this is greatest programming language uh according to me but i also i i really just i like all the types i really like types they're the best um let's call this from string so we kind of encapsulate this pattern here if we had reflection we could drop this but this this is quite this is quite understandable you know i like it so i want to ask you twitchy what well language do you guys use in or gals use in biomed engineering like is it like math lab or like how do you do your modeling we say instance read instruction where read preck i think to define a read instance we have to we have to say uh read preck read as preck yeah so i never know what to do with the pre so i'm not so i never know what to do with the presidents here when i'm defining read instances i mean like i could figure it out but it's too much work uh read p's s to s a par's instruction all right so now we have a read instance for instructions which means that we can say here print and then so the test input reads as it leads the rest of the string so we just say map read add instruction prelude dot read no parse okay which one can't we parse a here is one of my other favorite taskful functions do you like that trace we use commercial software abacus for finite element analysis we use for trend yeah for certain matlab and python for automation data post processing yeah for trend for trend is hard core um but like python and matlab like they i think they are essentially just interfaces for for trend i think like actually like all the array manipulation code is written in for trend and then like numpy calls into for trend and and and matlab also all the arrays serve to call into for trend because like intel just has a bunch of special paths for for trend instructions because they know that's that's what people are going to be running their code with finite element analysis let me actually i'm curious element analysis because i did i did some of this my math bachelor's uh yeah that is really i mean that's a lot of work it's really hard to work but it's uh you know you gotta play the respects you know i just make the language i never i don't well i'm writing code now but you know i'm not i'm not doing the hardcore array manipulation stuff all right but we're looking at deback doc trace which is one of my favorite modules in Haskell because it it just allows you to trace show id you know it just what what it does is that that so i can just add here just before you read the instruction trace it just write it out so it's trying to parse oh wait i think it's the plus zero yeah yeah yeah that is good point okay so we're gonna skip spaces then we are going to read a character so so we are going yeah plus zero that is to me hit it i think i was right about there but so we are going to say c gonna be choice of char plus or it's gonna be char char minus so we're gonna say parse instruction hint it's going to give us a read p part insta do so we're either we're gonna say option right we're gonna say option x p we'll either parse p or return an x without consuming any input let's see so then it's then we're gonna say what so we have these also symmetric choice so we're let's say let's see so okay so how do we how do we use option again i know i forget uh well i forget i don't i haven't really done this right i think we just say do optional char plus and and then a and then we say reads add int yeah now we need this and then we say here parse insert so we have an optional plus there and then so we you know we remove the plus if it's there but if the minus there it will parse into an int right all right it worked good work to me uh this is what pair programming is all about right so that's actually we don't need this so we parse the instruction int okay now we parse the instruction that is the first part so we are actually you know this here is a programming language right it's just a very simple programming language so now we are writing the parser and next up we have to write the virtual machine that it's going to be running on so the this the vm state so let's say let's say here right data vm state equals vm it's going to be our virtual machine call it virtual machine we are going to have the program so we're gonna have the global act which is this accumulator here let's call it accumulator then we are going to have the instruction counter classic right so uh initial state the initial vm state is going to be vm i wish i knew how to make it so i can click on this and make it work but oh no it's not even the type we want so let's go to be a vm with the accumulator set to zero and instruction set to zero right that's the initial state let's see global value the accumulator starts at zero yes and then the instruction counter i mean here it starts at one but we're gonna have it start at zero okay now we are going to have the program itself which is just going to be which is going to be easy yeah let's click it okay let's let's have the so now we have a program and the the type of program is going to be a list of instructions okay now find infinite infinite loop it's gonna take program and it's going to uh it's going to return it's going to return the what the value of the accumulator at the end right so right like this find infinite loop okay so okay okay we're actually gonna be jumping around in this with it with the instruction with the instruction so let's uh let's let's use state arrays i think it's like st u array we might be we might be we might be going something we might be doing something too much right now but that is okay so here we're going to be diving into mutable arrays in haskell and they are they're a bit harder to do than in regular regular dynamic languages because you know we actually have to care about the memory we're using so um should i just yeah okay no i think that's okay mutable array with unboxed elements so this is unboxed elements so but we can't have unboxed elements in them so we're gonna be i'm wondering you know if we should just have integers and then compile the code to like int codes because that would allow us to do it even faster okay let's we're doing premature optimization here we don't actually need st arrays just yet uh well okay we're gonna need them later so hugo run st so here we're gonna say this is gonna be a state monad how do we how do we write states again we turn the value computed by state thread so okay it's gonna be to run st but i for run st i don't i i should i should like have it i i need to provide the initial state right dc fanatic yeah so now we got the icelandic viewers coming in um um he's asking which just means uh he accidentally got into the stream but he's wondering what i'm writing uh what i'm programming is this advent of code puzzle um it's day eight and we are we are working with a handheld console but we have to we have and there's an infinite loop in the booting of that console so we have to find the infinite loop and we're doing it all in haskell so run st just that runs a state computation but like there was a isn't there a run st with initial state oh no maybe i maybe i state i maybe i write state t yeah so here's a new war okay let's let's look so now we're gonna be looking into all the things that are gonna be going into this machine so because we're gonna i don't write it properly in the beginning so here we have st arrays and it's all using these m array interface so we're gonna say new list array um then we can map array and get a source and then we can freeze them and then can thaw them do run st um i was the for all uh okay so let's say so find a loop yeah that is why yeah i definitely think this would be a feature in the next thing that's why i'm trying to do it properly now so i won't have to like rewrite the whole thing later so this is going to be s equal st this is going to be i'm going to have st and then it's going to have this so the state is going to be a virtual machine and it returns an input right find a loop this equals do is this type check now i need to import data.st right uh control.mono.st so and this is return zero will not be okay because i here i haven't looked at the program yeah so a hascaling through the puzzles i mean i'm using hascaling it's not sad not hascaling it's not okay to use that as a verb but who are you the language police but uh yeah no i might might be might not be the the way to go but might not be the way to go but i don't know so so here we're gonna have some visited that's gonna be a that's gonna be a data.set so we're gonna create a new set set so this is going to be a new var this is coming from and this is a new st var and it's going to be populated with an st now in front of a set dot from set set dot empty return length this is return zero now it's complaining about new var and it's because i haven't i haven't i haven't taken any i don't have st refs so the st monad is it's kind of like the io monad except it prevents you from i mean you can't do io in it right so but you can write these you can write these hyper you can write this kind of because like yeah and that's also one of the issues well one of the issues one of the fun things about admin of code is that they are very imperative you know they kind of assume that you have a lot of mutable memory and or like at least like sometimes in the late like in the first phase is then we could do all it in a very functional way but here they've kind of started to say you know here's a virtual machine right it's an imperative machine you have to you have to actually run the code to get your answer so so we just kind of have to go back to the imperative world in haskell and what i like about haskell is that you can just do that you know it's functional programming by default and yeah you have to jump through a few hoops to do imperative programming but it works yeah who cool is the best you can just you know look for anything and it looks it up uh this will not find anything i think um const 2 great it's a bit funny because it actually it uses it uses text based search so it doesn't actually look up the type it just looks at something that looks like the type text wise so it's super fast but it doesn't actually do any type checking that's why i added the valid whole fits to do it like type checking wise all right anyway visit it is set dot empty so here so i'm going to create the empty set and now i'm going to run the program until i've until i'm the instruction is a value that is in the empty set so this should actually be let's see here let's create the curse date let's let's call these state ref right this is going to be new st ref of initial vm state it's going to be visited ref and it's going to be it's not going to be empty initially actually because they want the they want the the one that's like the value of the calculator right before you execute it so i so it could either be empty or it could be one so i think we want so if we were to be if you were about to execute instruction one again i think that's when we would want the we want the thing right so let's say this is going to be set dot singleton containing the instar the instruction pointer of the initial vm state which is going to be zero so it's all going to work out okay now uh so now we will define what instructions do so run instar that takes in an instruction and the virtual machine and it returns a new virtual machine so run instar so not of anything vm that is the only thing that's going to do is going to update the instruction counter by one okay um i usually do it like this and but i require something called record type you cannot use in a record update parser oh right i usually do it like this i like using record while cards so a lot of the a lot of the language extensions i'm using here they are very likely going to be in it's not going to be haskel 2020 i think i don't know because i don't think they're going to make haskel 2020 but it's going to be in something called ghc 2020 but ghc is kind of the de facto haskel the haskel compiler so so you know ghc 2020 will be a language and i think record while cards is like there's not some there's not a reason i mean for my sake there's no reason to not have it and i use it a lot so i i like it so knobs update the instruction pointer actually all of them will update the instruction pointer uh hack will update the instruction pointer and it will update the accumulator now jumps how do how will jumps work is this in the same order knock act jump yeah okay so jumps no this is it's going to be adding the a here and this is the jump j that will only change the instruction pointer but okay so let's see so jump plus four so that says that the collector pointer so so this will be plus four three so the next instruction will be seven because what it could have been like it could have like said okay so i think jump zero will be an infinite loop is what i'm thinking you know it jumps to the next instruction at that the jump zero would be an infinite loop so that's how we're gonna we're gonna interpret it i think maybe it's wrong okay now we have the run instruction instruction okay now we are going to take the program and we're going to create an array from it now we're not going to be modifying that array this time but last year we had uh we had to modify arrays all the time and it was it was very annoying in Haskell but it all worked out so bounds of the array so list so i want the list array so okay so so let's say here this is gonna be data dot array right uh so the the the prog here our prog prog r equals the program array is going to be list array it's going to be from zero to length of the prog and it's going to take in the prog okay should be a function you know that does just this all right let's see prog array now now we initialized all the things now let's run the function so where run fun okay so so that is going to say okay that is going to be let run fun that is going to be do okay we are going to to curl state is going to be read st ref uh state ref yeah so like i said i could i could do this because we're not modifying the program and we're not modifying the state we could do this in a way that we just kind of pass this updated state along i think i'll actually i will do a version that does that after i've written this first but um but i i i i rather i like it this way okay so let's say so the current state we get the current state okay and then we say a care so we're gonna say let's just say state right visited is going to be the read st ref uh visited ref yeah i think i'm i'm think i'm over complicating this a lot because we're not going to be modifying the array we don't actually need all these references so let's let's comment this out let's just say so this is going to be run uh so we'll just say the run is going to be so okay so the we're going to have the program arrays we're going to have the program array like this run that's gonna so we're gonna say run it's gonna be a function that takes in you know a virtual machine takes you know virtual machine it takes in like the current state um it takes in the current state it takes in the set of states that we visited it and it returns an integer right and so run current state it's going to be initial vm state and then this is going to be the singleton set uh run and then you know because it's going to be so simple just this program maybe we'll have to go to the sc ref like that's when we started writing self modifying programs that we had to care about that that was annoying okay uh but it wasn't annoying but it was um it was it was more work than it should have been because we were doing it in a functional language but that's part of the fun right equal to do now okay here's this is not going to be do so here we're going to say cur a is going to be inster of state so we're going to say if if cur i so let's let's actually let's expand the state here so the v so the we're going to say vm and then visit it right so if the current instruction uh so if inster that's going to be instruction coming from this vm so what this essentially does is that it takes it says okay it essentially says you know inster equals inster and then it gives so it gives a name to all the parameters which are the same name as the name of the accessing function that we would either use this is a very nice way to work with records i feel set dot member visit it then we say then accumulator else uh zero let's see let's just see okay and now this is not going to be a an sd anymore or maybe in it so we don't need we don't need this stuff anymore let's keep around i i had maybe we have to use it in part two already i don't know okay so if the instruction is the member visited then we return the current accumulator otherwise uh otherwise we we we look up the the instruction equals so it's going to say program array so in data dot array so we just access it right program array bang uh inster else so otherwise so okay let's just write it like this let's say let cur i equals proc r bang inster and then and then in and then the next thing we want to do so and we say next state equals so it's going to be run inster of cur i not curry it's cur i no anyway run instruction cur i a vm let's just say here vm prime the updated vm wow you got featured on the scream cur i maybe maybe i was subconsciously influenced i don't know uh we access a value run instruction cur i then the current state it's going to be the prime state in uh run vm prime and then we so okay if it is a member and then visited prime is going to be a we just add right i usually i don't add so much to sets i just use let's see here uh let's just say visited and then i have the inster is going to be visited right right let's just apply type hole here okay it's not like that uh so it doesn't actually respect flips int set int so i think we need to give it more information here insert yeah so we i reported this already uh but see i can do like this this should be insert but actually yeah okay didn't even expect that here um it should be set that insert but they don't respect scope for queries all right let's say let's try and run it let's say here so prog it's going to be you want to you want to so let's just just do this in in in here in get input right so get input will not return a list of lines it will return a program and here we will say map read add instruction and that's gonna be wrong because we don't have a dot here okay now we got the input that's gonna be just a program and we're gonna print uh we're gonna print find loop and it ends up with five oh yeah because we added the initial instruction so this shouldn't be here this should be set up empty no we got five pretty neat huh let's actually let's actually dump the trace right trace show id so we'll say zero one two and then it jumps so that's this one two three so then it jumps to six zero one two and then it jumps here to six so this is gonna be so it's gonna be zero one two and then three four five six and then seven and then seven jumps to three so it's one two zero one two three yeah okay the trace seems to be correct also so i think i think this works okay i'm just gonna delete these things i uh we'll just we'll just add them back if we need them yeah i like this i like it okay let's uh let's run it on the the input okay this is wrong let's close these actually and let's uh let's not trace it 1200 in four milliseconds it's not bad is that the answer let's check it check it all right whoop whoop we got part one i wish i had a on a sound effect like whoo i need to i am at a sound board here you see garyax he's a distinguished fellow he does not follow unless they solve part one um he's got standards damage uh okay after some careful analysis you believe that exactly one i mean so i i don't like yeah that's the thing like the first couple of ones they took like half an hour and you're like okay this is nice and then well yesterday it took like two hours because i yeah at least for me i had like writer tries to do closure thing that's how i did it um but yeah i mean this is gonna be taking more and more and i think but like that's why i'm trying to spend the time now to make it so that i can reuse it you know that's why i wrote a parser and everything because i'm pretty sure that day nine he's a good streamer by the way but on day nine uh we will be getting more instructions more stuff to do with his machine that's you know that's what they did last year and i think i think uh i think yeah i think that's going to happen again so if you're just tuning in we just finished part one of the advent of code today and we're about to write part two what we're doing in haskell which is the best programming language uh for me i like it a lot because it is at the right point you got all the types you need but it also infers all the types if you don't want to specify them but like at least most of them without language extensions it can infer almost all the types you need so it's at that just right point of enough type series to help you as much as you can but not too much so you actually you don't have to yeah and if you're liking this content consider following because the more followers i have like which rewards me for having followers which is like like they want people to say follow me for some reason uh so that's what i do i'm just a sellout now has haskell changed a lot in the past few years thanks timmy couldn't have done this without you yes uh well no everything you still wrote is still valid uh there are uh a couple of new extensions or like new extensions i don't know like the the the haskell i've been writing hasn't changed it's just like cabal has gotten a lot better the package manager right it heck finally has it finally has uh like actual sandboxing so it just works which is pretty nice and uh and like the edit the tooling like you look at i mean look at this vs code thing you know i can i can say you know so i added these typed holes right but this is the tooling to make it work like when i wrote it you know it just dumps here right but then the ghc id i crowd they've actually made it into a code action like i think you know you can see it i'm like you can't right i can press control period and it suggests to me what i can replace it with right and it's type correct replacements and it's like oh my god this is such a nice developer experience i'm so glad that the ghc id did this because and this is like my research topic actually it's my research topic is you know in haskell and type languages we have so much type information right and what are we using it for well we use it for optimizations and we use it for like a bullion is it right or wrong and then we get a we get an error message um but you know we can use this there's so much more information in the type than just that right and that's what my research topic is about i want to take all the extra information we have in the types and try to squeeze as much juice out of it as we can and i think it's gonna be good stuff we'll see uh what terminal is that i mean it's bash but it is a bash with some movie magic let me see a bash rc i think it is power line the python version of power line and is it just like vs code and then the terminal emulator in vs code so i can just have one program running i do control a or this is like the this character it's control a on my keyboard and i can just jump to the terminal and it makes for such a nice developer experience right and then i can have i can have multiple terminals if i click click this button but you can't see that terminal so well um bash comma bash so i i really like this programming environment i really like vs code also like it just works right and it works on linux it works on windows and that like that's my main problem with emacs you know it's like it works great on linux but then when i try to use it on windows i just i never managed to get it working anyway let's let's keep going let's see so let's see what's with program here so somewhere in the loop uh somewhere in the program there is exactly one instruction that is corrupted either a jump is supposed to be a knob or a knob is supposed to be a jump no act instructions were harmed that's nice we don't want to harm those nice act instructions so they're trying to terminate by attempting to execute an instruction immediately after the last instruction in the file by by changing exactly one jump or knob you can repair the bloot code and make it terminate correctly for example consider the same program above you change the first instruction from driven up to jump zero it would create a single instruction infinite loop see that's what i thought would happen jump zero guys and gals this is wait i have to calculate this is eight years of computer science at work such totally worth it but no i i love computer science that's only worth it okay so we change that that's not good um we don't want to change to jump zero if you change the second to last instruction from jump zero to knob minus four the program terminates the instructions are visited in this order one two three jump four four five six oh yeah that was 2012 that was good times you know rihanna was still doing it big uh i could i could i could i could drink a lot more i you know or like i don't know i i had more fun at parties i think the parties are just wilder when you're like starting out yinny it was good times but now i'm so much wiser right and that is what we want okay if we change the second to last instruction from jump minus four to knob minus four the program terminates the instructions are visited in this order after the last instruction at plus six the program terminates by attempting to run the instructions below the last instruction in the file with this change after the program terminates accumulator contains a value eight takes the program so it terminates normally by changing exactly one jump to knob or one knob to jump what is the value of the accumulator after the program terminates okay now we are trying to figure out we're trying to figure out we want to reverse engineering so let's let's up doubt let's up doubt our our so this is going to be this is just going to be a run program because it just it just runs the program right um so if we're either visiting a thing something again then it's an infinite loop but we're also going to say if the instruction is a member of visited then accumulator um if instruction is in the visited or pinster is the same as the high bound of the array that is what it's trying to say it bounds uh s and d bounds of bragar so if we're oh yeah so my sister actually she's doing medicine and she's she's on her second year right and they you know they they put so much work into making those people feel good uh and like making them feel welcome because that's the thing you know education at least for me you know it's not it's not about the lectures and the things you're learning it's about the people you know you make a lot of connection you learn a stuff right but you make a lot of connections right and that's why you know like you know I didn't because I went to stanford for like a summer program um and like the education at stanford I mean it was good but it wasn't like mind-blowingly better than what I was used to at the University of Iceland you know I didn't feel like I learned so much more there than I did back home but the thing is like if you're going to stanford or harvard or Yale or any of those big names in the us especially you're going there with other people we're going to stanford or Yale or whatever so you know and when when one of them and then you know and then so it's like the social dimension you know and then one of them is going to be hey I'm founding a startup and my rich dad is willing to fund it or you know this other harvard graduate is willing to fund it and then you know that person right and then you you make those connections so I think I think like 60% of the value you get out of a really good school is going to be the connections you make there and you know that's what they're being cheated of right now you know they're paying 50 000 other dollars a year for education and they're not getting the they're not getting the connections that they should be getting so I feel I think that's a bit sad but you're also like you're paying for I read that somewhere in an article like you're paying for a title of nobility right you went you're harvard alumni right and you're somehow better than other people just because you went there I mean that's what you're kind of paying for also I don't know I didn't go there uh I know a lot of people or not not a lot of people but I know well very good people there but I think it's anyway they're they're missing out that's what I'm trying to say here I'm not gonna be out I don't want to be too controversial on this channel uh well I will be if you guys don't like it you can go watch someone else's program but that's the truth about computer science education is that it doesn't matter so much where you get it from tell about how much in love with it you are anyway uh so this is gonna be running our program and we are going to cancel it if it reaches like the end of the array because you know that makes sense we don't if we we can't we cannot execute it if it's out of bounds so we are even gonna say we're gonna say here um we're gonna say here let l high like lower bound higher bound equals bounds of prog are in and then we're gonna check that instruction is indeed greater or equal to l and insta is less than h that's what we want to be sure of right all right and uh and then we can actually you know check whether we're out of bounds I think either we just otherwise we just get an error and we are trying to figure out uh we're trying to figure out what instruction we have to change the knob or the jump that would make it go like so what instructions would give it uh the like what instructions would make the instruction counter be out of bounds and in this case it's gonna be what what instruction would make instruction counter be length of zero so we're trying to like create a trace a reverse trace to the start of the program that starts at eight or it starts at the last instruction and we want it we want to we want to recreate this trace here this is gonna be taking some work right so we could like we could just flip knobs to jumps at every single point but that would be a bit much right it's like the brute force way uh so selen this is gonna take a while okay uh let's see for the first one we want it to be what what is the um this is gonna be one two three four five six seven eight nine ten ten instructions set let's just get a prog length uh that's t prog it's going to be the get input test input and then we're gonna print the links of t prog okay and yeah it has 10 elements exactly so for the t prog let me check one thing am i so i should be affiliate by now actually let me see if if i am like can you guys see like a subscribe button at this point i mean there's still a follow button but yeah okay there's no subscribe button i probably have to restart the thing yeah um i think it's fun to start to stream haskell i mean we don't have i mean oh i want to say it's quality or quantity in haskell programmers in the sense that i mean i want to sound like i'm i'm being better but it's like i mean there's a lot of very good haskell programmers out there um and they get snatched up by like the big companies but it's like um and that's really the thing like you know you don't have any script kitties in haskell not to not like you know i have i have a lot of respect for script kitties but you know you you kind of have you know you have to be interested in programming languages in some sense to learn haskell you know it's not like you know if you don't like programming languages then you would just you know because javascript or something or python it's so much more useful you want to do interesting stuff you have to kind of be interested in the esotericism like it's never going to be like the default language you default to just because so uh so and then the programmers then you get are the ones who are like interested in the languages themselves and not just in what you can do with it so you get a different set of programmers so there's not too many but we have to spread the good word okay so now we want a something that reaches nine okay so so so how do we how do we say you want it to reach nine right so so that means uh to get to nine we need either uh so nine that is equal to that's either instruction plus one so either either you know uh so to get to the end then either eight is uh not or hack or there is a jump so so we so we want we want instruction to be to be you know instruction wants to be nine and that will happen if instruction plus one equals nine or if instruction plus j equals nine so we want to find if you know uh if instruction eight is not or hack or if instruction nine if there is an instruction nine minus nine plus j so i think we so this this should be so prog prog j should be so does there exist a program j such that this is nine plus j right so on jump or not we branch to where the branch function is flipped or not and see if the branch takes us to nine so that is one case right that's one thing we could do we could do what timis suggests right which is kind of like speculative execution so we run the instruction and then we kind of branch off into two worlds one in which we take the knob or we assume that it's a knob and one in which we assume it's a jump and then we split both paths and then at every single path we do this and then we run all of them and then we want to see if if you know which ones take us to the end of the program but you know that certainly worked for our example but i'm worried that you know in just this example you know there are uh one two three there's three branching instructions right so we would have to run that many programs that's not that's not that bad i could i but i kind of want to you only have to branch if you haven't modified an instruction oh yeah and we only have to modify one instruction that is true it's very true in certia i kind of want to to i kind of want to reverse engineer it though i want to see if i can just figure out by retracing the trace which ones to which ones to which ones to check so let me let me try that approach so let's say here okay so find and okay so so find and that takes in a program and returns a program okay find and it's gonna be find and prime of nine now of prog of length of the program where find and prime int program program so find and prime this is actually gonna take in yeah let's let's see let's see if we can make this work and where you spend like you know an hour on it or more that's that's gonna be and let's just do the other thing we know the other thing will work but i'm i want to see if we can kind of do this in the quickest possible way right uh so okay so find and and so then we so okay so so yeah so let me see so the instruction here uh in it's going to be we're going to look up so we're going to look up prog of n so to get to nine we have to check is there any spot in the program that will take us directly to nine like is there any is there any knob in the program we could modify so that it takes us no it but we don't have any guarantee that will and then we will like we'll change it to that and then we see if we can reach that but i think that is that is i think that is way too much work that's gonna be that's gonna be too much work actually let's do let's do to miss and essentially as suggestions i think they are they're cooler actually okay um so we have the run program uh let's actually say that they return maybe int if so and then okay if either of these hold then uh let's say here yeah okay so oh yeah that's right so if if we are reaching the the loop so if we're looping and it's gonna be nothing we didn't we didn't actually fix it if okay then how else if if we okay let's not do it this way let's just say if we okay this one that was actually the wrong thing anyway so if we if a length if insta equals length insta we want to actually we want to be executing the last one then just kill me later otherwise we're still running the program it's gonna be length second of the bounds of the prog array okay so here we will run it okay so run and fix uh program it's gonna return as an int run and fix prog run yeah so run initial vm state set dot empty okay so now we're gonna say we're gonna change the run function here so let's freeze or let's freeze the array again we're gonna be copy pasting this so okay run program a uh maybe okay so here we say run again this is gonna be the run instruction run it's gonna take the v virtual machine and it's gonna take the int and it's gonna take no it's gonna take a uh what does it take yeah it's gonna take the set of ints and int that's actually that's actually i want to keep this run program around right let me do this one simple trick i will copy this and then i won't undo all the changes and then i will just paste it here okay so this was gonna be so because we're gonna we want to run it with the we want to run it with the set the same set anyway okay uh visit it if instruction member visited then it is gonna be nothing if if we're at the end then we turn just the accumulator else so then we're gonna say okay case cur i of if cur the current instruction is not not n okay if it's an accumulator hack n if it's an accumulator then we are going to then we're just gonna continue right then we're just gonna run the instruction this is gonna be the vm prime okay so if it's an accumulator we just run the instruction now if it is jump and then what we want to do is we want to know now you want to say run the program maybe without modification right okay so let's let's let's maintain let's keep it let's keep transform program maybe let's keep it like a sorry it's a it's a bit i'm being a bit out here so now we want to run it and we want to get the result so this one runs it we'll get the result so here okay it's a run program it's gonna be run and fix so we have everything the same except we actually we never checked this okay we let's check it but so here we have just the accumulator so we're gonna say okay case the vm prime here it's going to be case cur i of so if it's hack then it's just run the instruction what is a cat jam so jump instructions if it's a jump instruction we want to update the array we want to change the we want to change the element of the array so let me say prog so okay so here we're gonna say let p a so this is gonna be modified one that's gonna be take the programming array okay so prog let me see so here we're gonna have the p a prime it's gonna be prog r and then we're gonna have this array modification thing and then we are going to update it with a this is gonna be instruction and this is gonna be mop and if it's jump and we're gonna change that to mop and in uh so if it's gonna be if if we have here you know okay this is actually gonna be this whole thing this whole thing is going to be let's we have to write and change this whole thing so case cur curry of so we we're always gonna have this be this one okay um then we're gonna move this one down here so if if it is if it's just hack then we want to then we just continue okay if it's if it's a jump then we say here in case run program maybe then we run the program maybe and this is gonna be run program maybe that is program to maybe int oh no yeah we then we don't want the initial state right so let's say the run program maybe takes in a program and it takes in a virtual machine and it's going to be like this initial machine IVM slightly better than IVM nope nobody okay prime IVM oh this is gonna be so this is gonna be vm uh run so so if we have a jump then we try changing that one and if it is just hack then we just say now we just return the effort uh what is the issue here pa prime proc r run program maybe okay yeah i have to let's let's have this be array int program and this is just proc r just taking that what is wrong with curry here okay this will be run into array like this no oh right this is gonna be instruction so if we if we run the program and we modified the instruction if we modified the instruction to be knob and it returned and accumulate or then that's great we return it if it's nothing then we we we keep going right then it's just so what we're gonna say here then continue is just gonna be like this so it's gonna be continue and this is gonna be continue and then we can copy this we're starting to replace the chimp here with an op the i think they should work and the question we have to answer is what is the value of the cumular character after the program term so we don't actually have to say which one we modified but let's actually let's trace it trace show inster so we want to show the instruction it's gonna be just trace show right so let's say we show the instruction and it's gonna be act so let's let's print out the instruction we modified it's okay so for test input i say we're gonna run and fix okay it says zero zero just eight that is indeed the result but what is it saying here is it what the the previous the run programs don't work anymore huh oh yeah i i said this earlier right if this is less than and this is greater than equal to so we broke the first parts okay it says just eight and we modified instruction seven which is exactly this instruction not four so things in search here i think we're actually we're just gonna fix it we're gonna fix it right now and let's see what happens and i think i'm obliged to say this if you're liking this stuff please follow and then we will get some more because we get we get a bunch of stuff like if i if i if i have more followers they give me like vip badges and stuff which is that's cool let's see run and fix boom so modifying instruction 327 gives us just one 10 23 let's see all right thanks insertia now this is way better right i think our because my idea of backtracking it that would have been very tricky because um well let me see i still want to try it out though because as you say we only have to modify one instruction so i just have to see like is there a jump instruction that i can change to knob or like can i change a knob to jump a jump to knob that is in the set of reachable states from the start but yeah that is it's a good function um i mean 20 lines and it's like a very ugly if then if then else right but we made it we made it happen let me see let me see what is this this is a advent of code day eight and we just finished actually uh we finished the solution insertia suggested and it returned the correct result but i want to see if i can reverse engineer it i really want to see if my my initial thought would have worked so what are we're trying to see so i want to see here um so we have this run program here which is currently correct but i want to change it so that instead of returning the accumulator i'm gonna say reachable and instead of returning the accumulator we turn visit it um and it's complaining this year doesn't actually return the reset yeah this is Haskell that is lazy functional programming language um a lot of expressions a lot of ifs a lot of case statements i think like the the base unit of computation in Haskell is actually i mean you cannot do a lot of you have a lot of primitive functions like plus and minus and you know multiplication and of course that gets compiled with the compiler instructions but like the primitive unit of computation is a pattern match you have a data type and you check you know it's like a big switch statement that's a big unit of computation you run case matches and then you the base unit of computation is can we do we match something here so like in this this case statement here and i think that's actually like program language is like agata they uh it's called elaboration right and they kind of they elaborate the source code to case statements as far as i've understood agata it's kind of a cool way to do computation in my opinion okay so here we have the visited states uh thanks for the follow kistina kistina kistina i never sure what kind of nicknames you should be giving people anyway let's see the reachable this computes the reachable set so i want to see if you know starting from the end is there is there so starting from all positions what are the reachable states starting from those so let's let's check that first uh so instead of saying here reachable let's let's have it take in an integer so let's have it take in an integer and then let's update so we start at start and we want to see starting at every instruction what is the set of reachable cast in on them all right is that too much probably it's probably too much right yeah let's see let's just let's just ask it for reachable let's not do this i just want to investigate this because i i i feel like that we should be able to reverse engineer it right get input this and we're gonna say print reachable oh no that's the input itself i'm gonna copy a function from day seven i had a nice function to oh no to pretty print sets uh i don't want to implement it again it's just just add some stuff but i i like it more than so let's see press test and put putster ellen and pp set pp sets for pretty print funny no okay um so these are the reachable reachable states starting from zero i think that's the first thing we can check right we don't have to look at all the jumps and hops we only have to modify one of the one of them right okay so if starting at starting at starting at the end uh reverse engineer okay so starting at hint and you're taking a program and then so reverse engineer engineer okay so here if i start at n let's just say let's just see uh like what instructions read me to n that's let's take in here an array of int instruction let me see here doing program i think we should just define program to be an array of instu instructions and then we change this to prog r this is going to be program and this is already prog r okay this is work is there like a type something wrong somewhere all right okay so we don't want to define it here let me just see prog r and this should be okay so here we'll just say we'll not do it like this we say do stir is gonna be read file fb and then we are going to get uh insturs that's gonna be map read instructions over the line dollar lines dollar string and then we're gonna return uh what did we just have list array right a list return the list array of zero comma length now length insturs insturs and this is complaining because this is not actually i'm sorry like this so line 106 we're still using it in this region okay it still works um let me see now here so yeah reverse engineer is going to take in and the program so reverse engineer of n so we want to see what are the instructions that can that can get to get to there um so at n so how can we get to n well we get to n if we can get to n if a set int so this is gonna be reachable from um uh wait so can come from okay can come from n so that is gonna be okay so if a so so this is gonna be let me see what we're trying what are we trying to write here uh so we're gonna say okay if it's gonna be prog okay uh where so let's just write something i'm defined here and that's just gonna say we're say um for prog of n minus one right so we're we're essentially checking like if this is ak right okay so yeah equals case prog one of if this is ak something then it's true okay so we check if the previous one is ak and then so if the previous one is ak then a we can write from there so we could change the previous one to not then we can reach it from there so we can we can always reach it from the last one right that's actually find all the instructions where which are jumps and let's just find all the instructions that are um jumps so uh now we want to actually use the as a list alums okay so uh let's see okay let's see here uh jumps and knobs it's going to be take a program and return jumps and knobs are going to be um they are going to be set the set of integers so we're gonna see here so we're gonna fold um so we're gonna take an integer and we're gonna say what am i trying to write here if let me let me look at it a bit more so okay zero one two three four five six seven seven are those are reachable states do we run the entire program okay from the start zero one two three four so five shouldn't be reachable right six and seven yeah five isn't reachable and then eight isn't reachable okay so to get from eight to eight we either we either need a seven yeah so get to get to n we either need n minus one to be reachable or we need a uh we need some jump somewhere or like a jump or a knob somewhere that goes to um that says you know the index of the jump plus the value of the jump should be equal to n okay so let's figure out uh can jump to is it gonna be a set of uh so the instructions add int can jump to int can jump to so we're gonna say here uh that's going to be can jump to prime of the ellums program this would be a way for me to get uh get associations yes okay of the assocks of grog okay and where it can jump to prime so this is going to be uh the index and then so if it's ac that's gonna be i comma i plus one can jump to i comma knob of n okay this is actually gonna be a set of ins so this is gonna be so it's gonna be the instructions add i can jump to no we don't know which one is which so let's just leave it like this uh is it gonna be i comma uh so the instructions that i can jump to i plus n right and this is wrong because we're gonna be mapping okay so how you guys have you all solved this i mean we solved it before but with like a uh with some help from from one of the from rdo viewer insertio and i wanted to try and reverse engineer it right instead of just executing the machine and seeing what happens i want to try and see what if we can actually if we can kind of actually you know kind of programmatically figure out the exact ones we want uh um you like figure out the one we want to change just like by starting at the end and seeing it okay can't jump to but this is the associations of program and it's saying undefined array element is that or is it earlier no i mean it is but i'm not using bang here so what does this suck use that is weird the list of association of an array in index order okay right maybe so from list so maybe this bounds here so this should not be length in the get program this even needs to be one minus length because we want to we wanted to start at zero okay so these are the associations so zero can jump to zero one can jump to two that's an accumulation um so let's actually do here map maybe we only want to look at the we actually only want to jump the only one we don't want to look at the x nothing is going to be just so okay zero can jump to zero two can jump to six four can jump to one and seven can jump to three okay so these are the ones we can change so zero jumps to zero so we don't want that so we are looking you know we want to get we want to get to nine so if any of these had nine in them and they were reachable then we could jump directly to them so we want to check if if there is an instruction they can jump to there let me let's let's try and say um let's just let's just see the jumps jumps uh prime it's going to be jumps prime that's only going to be for jumps and then we look at the knobs knob is it going to be a knob and here we actually just say you know if it's a jump look at that if it's anything else then it's going to be nothing same here delete this one okay and let's look at the the jumps and knobs jumps and so these are the jumps that we're already performing and the knobs that we're already have okay and then okay let's just complete the circle right x here which is going to be back this is going to be i plus one and it doesn't like this because this is not a gist okay print the jumps pretty yeah let's print the and the knobs how do you define here knob act jump right knob acts jump let's see here's all here all the okay so here we can see so okay let's actually let's actually turn this into sets so put stir lm period bb set period set not form list so we want to put change these into sets okay so we so we look at okay let's flip flip the pairs and turn them into a map flip pair takes in a pair a comma b and changes into a p of every made a pair equals a comma b equals a comma a okay and then it's like map for two lists right data dot map i think it's i think we can do i think you can do from list on data dot map from list right keys comma values okay so now we're gonna import we're gonna reuse this except we are going to change set for good stuff so let's let's not make it into a list let's say let's say here uh this is gonna be map flip pair uh who doesn't like this because yeah it's putting string ln print there's gonna be map doc from list so now we create these maps and then let's change set here let's not change set uh let's see this okay so from nine we can reach eight uh okay so now we want to see so okay we can reach nine with eight okay so now we want to we want to which editing mode extension is that um this is vs code and it's actually yeah the ghcid folks have made gs vs code like the best editor for editing haskell right now in my opinion at least uh because you can get all these fancy completions and things working quite well okay let's think here i don't i don't think we want to flip so we want to flip the pair for associations let's let's see what happens if we don't flip the jumps protstr ln protstr ln this is gonna be not this is gonna be this is gonna be yeah so this is kind of how a program right um i i i really like to look at the data and kind of get a good feeling for how it's working what it's doing so we have we can't we have a nine in the x which so and then from we can get from nine to eight okay so now then we need to check you know is is is there a jump at seven we can change it to a knob or is there a knob that we can change that would take us to eight right so let's see here let's see okay now let's see let's see what's happening okay so let me see here let's let's have all of these in a function reverse engineer program program reverse engineer equals it's gonna be something like this so if it's gonna prog where and we're gonna just connect we're gonna have all of these available to us and then we're gonna say here just delete all of this so it's gonna be equal okay so it's gonna be n and n prime uh yeah yeah these are i'm using the uh i'm using the vim mode of vs code and i you know i don't i don't even think about it anymore that's and this is just how i edit things um okay so let me see yeah let's see here reverse engineer prog okay so we want to see so okay so prog here is going to be so yeah so we want to get the bounds of the prog so this is gonna be zero and this is gonna be the the length that's gonna be the bounds of prog so we want to see we want to see okay so first of all let's figure out which one of them uh the length minus one is so end of program is going to be length minus one and then we are going to see okay let's just take it in here uh let's see here eop let's just let's have it at right okay and then we're gonna say okay case so if so the end of the program is going to be somewhere there right it's going to be in the knobs in the ax or in the jumps i think so okay no no so it's either it's so it's either gonna be so yeah let's let's figure it out so okay this is gonna be an int you can tell us which one to change okay case eop if it is a member of the a's so this was the yeah so if it is a member of the a primes and zero else two let's just this is going to be type incorrect right uh program and then it's going to be an int and then this member function won't work because we're gonna have like map document right and this doesn't work a prime is applied to too few argument maps are from list right we need to actually okay oh yeah the command doesn't work but uh this is a varmillo keyboard it's the va 69 special edition but then i got the eagan keys and i replaced so these were all red and it looked too danish for me i'm so sorry all the danes watching so i changed the colors to be the icelandic colors because that's where i'm from representing you got to represent if you're from a small country you know it's like like 360 000 now total uh you know and then you gotta you gotta represent your country you know you gotta you gotta be there for the rest of them okay let me see so if it is in the axe then we you know let's let's do this a bit so case eop a prime off so this will be this will look up of just i two so if if if the if the eop this is so all the way right replace these let's try it one more time space we don't want to play space like this okay um then it says right this is this needs to be a prime has eop that's gonna be correct and you find and then so okay so how are we reverse engineering it so if it is i so if it was in the ac e gang u gang yeah it's good i got i got the the nordic keys i i emailed them right you can get custom keyboards from them um and i emailed them to ask like can you get me the icelandic character set uh but they said no so and i don't want to buy a 100 custom keyboards i customized this myself but i'm still missing like the icelandic keys so i'm stuck with nordic keys which is you know close enough but it's not quite where i would want like to be so if if i if if the end of the program is in the axe then i need to find which one i need to modify uh thorn gang yeah so go man he knows where it's at these are the blue switches uh and here the click i like the blues when i'm programming but i also have another one a with the red switches and this is you know you can see i this is like what it looked like but then i didn't use these keys so i use them on this keyboard and it's just the exact same keyboard except listen it has like silent red switches and why do i have two keyboards well i've been asked this by various female members of my family and my excuse is that you know if someone's visiting me and i don't want to keep them awake at night i can switch to the silent red switches you know which is which is it's not too not too bad right uh and also like if i'm recording because i do some teaching and i do some like talks like actual talks and then i don't want them to have to listen to the super noisiness but in this stream i have the keyboard cam so you can like see when i push the button and because you can see me pressing it i think that makes it okay for you but it's like super annoying if you can't see it you just like wow it's so loud but because you can see me interact everything it works out yeah but you know i'd rather have two keyboards than use rtx voice also uh yeah that doesn't keep keep people sleeping you know someone wants to sit in the couch watch tv and i don't want them to be like also like if i go to the office i don't want to keep them they get mad you know they don't appreciate the clickiness but yeah definitely that would work for teaching i i did do that for a while i would like i would like fine tune the i didn't use rtx voice because it it's always this sorts me a bit much but i've like fine tuned the compressor settings on the microphone so that it would pick up my voice but it would like use a noise gate if i push the buttons and that worked but it was just not good enough all right so let's look at this is so if the position that i'm looking for is in the axe like if it's if i want to be coming from an accumulation instruction then i then i want then i want to find if i can come from eight like if i if i'm coming i'm trying to find if i can reach here from nine and then i'll see okay can i reach here from eight let's see reverse engineer program coming from i do i use haskell at work i mean yes i am a i'm doing i'm like i'm a i'm a phd student i'm doing a phd in programming languages and security and like synthesis and most of my work so far has been so i modified the ght compiler like the compiler i'm using here um and most of my work so far has been on that and ght is written in haskell and i'm like very interested in can we use haskell to its full potential um we'll see see if it works out oh my god i have 99 followers now so if i get one more we're gonna be that i will have a hundred not hundreds of followers but i will have a hundred followers it's quite a lot like two days ago i had 44 or something that's how it works on twitch because switch only sorts by number of current viewers so once you get a few viewers you get higher on the list and then more people click and then you get more so it's that's when you go where okay rocker simon our 100th view follower thanks so much rocker and banan banane okay if i found it in axe then i don't then i want to see if i can come from that one if i didn't find it there then then i want to see like is is there a current knob i could change into that case is there a current knob which i could change so that i would be coming from the knob that would say i'm nine prime uh uh how's adamant of code doing hey this is day eight i already solved it like an hour ago but i wanted to do it differently because uh i want to figure out like the exact one i need to change just by reverse engineering it instead of just executing the code and like speculative branching which is cool i mean i i like the other approach it is a more cool approach it's a cooler idea than mine but i still want to see if my idea works i'm curious like that okay so if there is a knob i could change to get to this position so let's actually see yeah i mean exactly this is a reachability question so i think a problem with this so i also need the visited set here i need the reachability set set int uh reachable because i can only change one thing and i need to make sure that that thing is reachable if i'm going to change it so here i will say um so if i'm change i mean so i'll only be changing one of them and it has to be reachable so let's check here so it's okay for it to not be reachable if it is uh if it's if it's a act because then i only need to check if like the that act that act is reachable now if it's a knob i'm changing then i need to make sure that that knob is reachable so case n map not up so if if if i am if i'm uh so if i if i if i found a knob that i can change so if i found a knob that i can change so okay so these are the these are the j's so so the j here the j here goes from seven this is a j seven and the seven goes to minus four so it goes to three right oh you're the creator of adamant of code wow uh yes that's what i'm trying to do so we had one solution where we just ran the program and fixed it but now i am trying to figure out can i change like so yeah so i'm so here's all the list of all the links you know so here's all the things that so here here all the jumps right so this is the jump in line like an instruction point seven and it jumps back to three so and then i'm essentially saying here like if i want so so if i change this yeah so if i change a knob right if i change a knob that says so if i yeah it doesn't work for this one right but if i change this knob and it said seven three then i could go from line seven to three now if i change all right but i have to follow the jumps yeah but uh person's already claiming they're following the jump from both ends and also doing some clever memorization they got another one solution yeah i think that's um that's essentially what i'm trying to do but i'm not following from both ends though i probably need to do that but let's keep keep at it i think it's uh yeah thanks a lot for making this um i don't know code like i really like these kind of tricky things where you really you really want to because you're like you know you can't just run it and kind of brute force it but you're like i yeah it's a graph like you say it's a graph low graph problem right so we should be able to do it in a nicer way and especially like we're doing this in a functional language right and these problems are very very um they're very imperative like especially this in code stuff it's very imperative um but that's also part of the fun right you're all like oh i want to make it so that it works in a functional language even if it's imperative right but yeah it's uh it's a lot of fun hold on i'm gonna i'm gonna reply to one message right now uh on a whatsapp sorry all you gotta give all you gotta give it yeah uh now you can have fun decoding decoding what i wrote on my keyboard by watching the recording over and over again you can find a recording on youtube and uh you know i'll just get views you do that so be my guest okay so so here we're saying okay if we change this map right let's say this was a map here and it said and it said um said seven three like then we could if we change this knob so i guess the knob said okay so we essentially looked up here okay we said okay is is there a knob such that that the the actually that could be an issue there could be there could be multiple values for the keys that is yeah let's see let's see uh so if there is a knob such that such that we could change it so that i think that's the issue right we have to pick the knob that is reachable so these are gonna be the knobs right uh but if we flip the pair this should actually be this is the we might there might be multiple there might be multiple jumps like multiple like you can you could have you know that this is a jump in line one that jumps to this position and there's a jump in line two that jumps to this position so we will flip the pairs okay let's let's see let me have to write this into a yeah that is the best best way to do it i think i i really like that right because you know i've always been trying to get like a nice algorithmic approach working but it's you know and then like i spent i spent so much time on it right and then i'm like oh i could have just bootforced it but then then it starts finally paying off all that hard work right that's fun i think i really like these problems so thanks again yeah good work i also i would just want to say i really like the story so far with the whole santa is traveling because you know none of us have been traveling this year so it's i appreciate it we get the full experience passport control customs we get you know luggage we get being bored on the plane i wonder what will happen next it's a very exciting story okay so so okay so this acts here it doesn't actually have to be that doesn't actually have to be a doesn't have to be that would only that only needs to be a set yeah no okay that that is okay but in the sense yeah i don't i don't really i don't need because i i can i can infer i can infer what it should be from from that the fact that it's an act but it's okay we can do it this way but i don't need these i think okay so if it is in the axe yeah it's a good thing we started at like six o'clock uh european time otherwise i would have been here all day but we still are and we're still working on it and so thanks for all of you who are still here where am i i am in gothenberg sweden so we're at it's like nine o'clock here um i'm guessing because like it's released at us time right so i'm guessing it's based in the us but i mean it's fine it's a you know i also i'm not in the super fast like i like him i'm enjoying and getting a nice solution i don't want to i don't want to worry too much about competing but that's it's still fun taking a train through there all right we're on the map it's kind of the same as being like you know i it's like it's more right it's like it's not just i've been to the airport there it's like oh i took a train through there we were on the ground and you saw the places that's good it's a nice cozy city um it's not super bustling but um okay so here let us let's actually this list here let's filter it by the set of reachable states uh okay and let's like let's not let's not all right cool in certia certia is completely overshadowing the stream but that's cool i mean if if in certia had a stream we would we could like rate it right now i don't even know if i can do that but that would be cool yeah i mean and it's also fine you know i i didn't get hit by the first you know like the the it was a blackout in the first couple of minutes or something like that so you know i just i i just log in when everything's working it's it's good um so okay so here we're also like we are computing these things again again again so let's take a let's take here data uh pre computed pc i mean they are pre computed so they are very pc and okay so n will be a map of inch to inch and prime will be a map and it's also it's fun that you eric get your eric muscle that you're like checking in other streams i like that that's like the best way to get feedback right let's literally look at people and see how they're let's pre compute all these we don't need to compute them all the time i actually think that ghc does this already for us in the sense that it will see that these things okay i mean they do depend on the argument right but the argument isn't changing that's the thing oh okay yeah the ghc does not do this so and let's see here then we say pre compute program to a pre computed this is gonna be pre compute it's gonna be this we're gonna say where and here's another record wildcard trek from haskell you just say pc period and it just it just grabs everything from scope and then we can say here pc pre compute it it just works so let's pre compute these things so okay and so here we are actually pre computing from the program but what i wanted to do is i want to check that the knob that i'm editing is actually reachable from the start of the program so we oh this will be an int also so we will just run this reachable thing on the program r equals reachable uh prog and then i so i i do the and s that's gonna be the knobs of the program and we also don't need to compute them twice okay so the so the as here will be the x of the prog okay but and then we will do map from list as and then we do as here and that's fine but for the the knobs and the progs what i want to do is i want to say filter i so i want to say that the i come out whatever so i want to say that the set dot member are first so i want to make sure that that the the ones i'm looking at and the ones i'm editing are actually accessible from the set from the start right and that way so that is essentially like what what eric was talking about is that you can like follow the jumps from the start um but uh but we don't need to do that if we have the reachable set this will be gs and this will be gs so let's say here deriving show let's say let's write here instance show pre-computed it's gonna be a where show so like the first couple ones took like 30 minutes um the last one took yesterday took like two hours or like it took like an hour and a half and then i spent like a 40 minutes trying to do it in a different way and then i that way didn't work um like this one yeah it took like an we were done at like 7 30 right but now we've been working for an hour and a half uh on like the the o of n version so yeah quite long at this point right uh let's just do deriving show yeah that is exactly what we do so if we were someone like not a uh polycarpova who's like a she's a synthesis researcher we would just like input this into set three and be like find it up and it would just okay here's the solution uh yeah pretty good at what she does now let's see here so these are the knobs let's see get input test input into print dot pre was it pre compute right now there's some error somewhere just i okay line line 173 yeah there's some issue here uh yeah so this is gonna be pc got a path pc in here and and then this is gonna be like this yeah set three let's just write it let's just do it what is the pre computation of this so we can reach the first state that's good we can reach uh yeah so they we can reach all the acts that's oh no we can't actually reach all the acts but that's okay because we just want because the acts don't really they don't really do any jumps the j's is that we can reach the two the four and the seven and we saw that again we can reach everything in this program we can't reach this here yeah i mean like like now you know we're like we know what we want to do we know the solution to the problem we're just taking super long to implement it right i mean that's the thing you know that's that's like what computer science education gives you like you know immediately how to solve it so you usually don't spend two like okay not immediately but like it gives you the breadth of knowledge that you need to like okay yeah this is a this kind of problem so we need something like a transit of closure or something like that right and then you started and then yeah this way we have a you know phc students and then phc advisors and the phc advisors like oh it's simple you just do z3 and then it works and you're like okay and then it takes you you know six months to implement z3 and he's like why did it take you so long and if you're just joining in we are solving part two of the admittive code day eight we've been at it for an hour and a half we solved it already so we know that the answer should be for my input it should be 10 23 but what we are trying to do now is that we're trying to reverse engineer it with like an open algorithm and if you like what you're watching please hit that follow button i would tell you to subscribe but i think i have to like start and stop the stream for my affiliate stages to update so and i don't want to do that okay now okay so all of them are reachable so that's that's fine it's only one of the acts that is not reachable what if i like what if i get like i don't have to change any of them that's actually that's actually that would actually be a funny thing right so let's say let's have r here to be set in and then we pre-compute the r and then that okay okay so a is in map okay so and then we're gonna say we're gonna say maybe and actually because i think you know if we're looking at something and we don't have to change it so and the idea here is you know if if there is an act in there and just i is there so and then we say you know if i is a set dot member of car then we return nothing else okay anyway so now we've we were only looking at reachable knobs and reachable jumps and it's gotta be one of those that we have to change uh let's see so case and prime map you'll be of so if there is a knob in the map that i should change then just i returns just i right so if there's a knob in there i should change that knob right then we're gonna say case j prime and like this you know we we've been writing exactly this for so long we've been writing exactly this for so long but we've been talking so much so it's i mean this doesn't take so long if i would just focused on it right but because i'm talking so much and trying to i'm trying to give you the full experience of what i'm thinking you know so let's see if it does a knob that we could change so that would make us jump there then we're done otherwise if there is a if there's a reachable jump that that jumps us to this location i think so i think that's that's like so we don't actually use this end map here oh this should be an s we don't use this end map and we don't use this a map so let's just remove it let's remove those two we don't need them we'll give them better names later so okay so if there's not a knob that we could change that would make us jump to the position that we want to be in then that is we shouldn't change that right so then the last question is okay is there a jump that we should change right and then that question is okay uh you know is is there an eop minus one that is a jump so then we don't need the j prime you get where i mean if there's a if there's a jump if there's a jump we could turn into a knob and then so that would say so instead of the jump going from so then there was to be a yeah so this should work well i will clean this code up okay so it was not an act and there was not so i think this is just nothing i actually think this is just our base case okay so we found out previously that we had to change instructions 327 now let's see here all right thanks for the follow jankron and kkkkksssdceven 5k3sdceven i have no idea i thought it was like is there like a wait let me see so we write 5k3sdceven skskess no 3 s like this would be an s that is skskessdceven i don't know skskessdceven could you explain could you explain how did you pick a nickname with so many so many letters in it should ask my parents that prog is going to be get input test input let pc equals pre compute of prog then let's print reverse engineer of the uh pre computation there's a prog and then pc right pc prog what should it be reverse pre-computed yeah pc and then the program and then whatever uh upper bound just gonna be the bounds of the program so the upper bound okay then we're gonna say you you plus one so it says here just three uh what does that mean oh right that's not the instructions you want to change so case jmap EOP 3 of just i then we want to change EOP this is just eight so then we want to change EOP minus one right so then we get the just seven right so so we looked up the lookups and if we have a seven here then that's the one we want to remove oh right yeah so i'm also i'm teaching uh i'm not teaching i'm a ta for a ascol class i think there's a lot you learn from ascol that uh you can take to other languages as well and you can just write things directly or you can just get a job at facebook and wear a task on there it all works so let's see it does this work for the actual input so we're gonna replace prog with prog 2 and then we're gonna replace this with the input well there it says nothing hmm okay yeah i thought it was like it's gonna be some profound reason why you had that the name but i guess not okay this is slightly sad we worked up very long on this right print you and it works for huh you here should not be prog this you here okay you know this should be this right pc two gonna be pc two and you two no not you 21 so is it you two okay then we get nothing what does that mean keyboard model yeah this is the varmillo va 69 special edition but i replaced uh so it came with all these red keys when i replaced those some of them with blue keys so it's customized and it's got blue switches uh and they're quite nice so is it because is it what when did i hit the thing that's right here trace show id trace show i nothing if i hit this is it because i hit what happened now i print the pre-compute and then it calculates to seven and then okay just calculates this one okay so trace i already also show i like this and but i think it's not this one that we're hitting we're hitting this so let's see here trace show trace a a op not found okay and what we were searching for we were searching that minus one right so we're searching for 643 let's see here let's see how do we get here trace show op donor so we start at 643 and then yeah so that's the length of the uh so i think that's the length here so that's the length of the list now 642 is the length of the list yes so 643 should be the last element let's look at the input what is the last element of the input here well the last element is jump plus one okay that should be okay also right okay so if it's not so then we do need the j prime here map flip pair j s a so then we need j prime okay so if the op this is not there then we need to check j prime map op of case of just i then we want to reverse engineer reverse engineer engineer pc prog i nothing it's gonna be the end of it and here we need j prime this should work oh no still nothing oh right this should be op minus no it should be op right what is j prime here we should not filter the reachable here right jumps prog still nothing okay but now we at least we found that one okay so now it's saying you can't find 465 um 445 yeah there's no 465 here right so what which was the instrument we're supposed to edit find 327 do we also need yeah i think we also need i think we also need the n prime here so the the ak this will be this map flip pair the ax of the prog plus the knobs of the prog right because like if we if there's already a knob there and we don't want to change it then we just keep going there right just 327 all right we did it so now we found the instruction that we want to change um so let's see here print 327 let i to r equal reverse engineer and we say prog 2 so let's print prog 2 of 327 it's only bang right let's jump minus 199 so let's say here flip prog uh that's gonna take a program and an int and it's gonna return a program and program a prog so it's gonna say yeah we'll need to we need to look at it yeah it worked we found it in reverse uh let's say here a where ker equals prog bang of bloke loke so it's gonna be uh okay so flip flip flip of jump n equals a flip of jump n equals knob n and flip of ak and equals ak and no flip of flip of the knob and equals jump n and flip of anything else is going to be an error crying wrong wrong flip and now we need to map over the index of function hugo let's look at your data array and x map no that's not what we want non-total programs oh no uh map array yeah we don't want to map over everything we want to map like over only one of them how do i do that this is like each of the elements so i want to like map with key and data.array f the qmap takes an array and a social listening list and accumulates repair from this one thank you but how do i update like only well how do i apply a function of only one point on the array yeah i don't want to install lens right that's that's too much bro bro okay let's say here a we're just gonna say we're gonna say prog okay this is gonna be loke prog it's gonna be updated by flip prog loke uh so then the new the new value of loke should be flip prog of loke right flip prog yeah i mean i i know lenses right but oh you mean like that i mean yeah i could define my own lens but i don't want to go into that i mean i don't want download lens you know and then or i could yeah i guess i could write my own function but this is a function right flip prog okay let's write modify r takes an int and a function so it takes a takes an array of uh i e and then it takes an i and then it takes some e to e and returns array i e and then modify r r equals r loke f equals r uh loke uh f r uh loke what is wrong with this ignore yeah i mean this is then this is a lens right this is the modify array lens and then flip prog is modify r r loke flip yeah no this is r so this is prog okay so we we want to say okay so n prog equals uh flip prog uh prog uh i to r did it oh let's just pattern match we know this is gonna right flip prog i to r okay we print prog we print prog i to r we print n prog at i to i to r and then we simply run program run program maybe run program a right uh index 327 out of range all right we flipped prog we're gonna flip prog to uh index 643 out of range so we flipped the prog uh and now it's saying that the index 643 is out of range what is it trying to say here so the advent of code is like this collection of programming problems and they publish one new problem every day and then you yeah so you kind of start you get you get a new problem to work on every day it makes for happy programmers right oh okay i think it's just because we don't have the correct yeah this used to be okay we we didn't we didn't update our run program to bail out on the right one so we said run program maybe end prog initial VM stage the other one doesn't bail out just 10 22 all right and that was exactly the one that we did before so let us remove all of these 22 milliseconds let's see here okay uh let's see if we like actually save any time here so okay we only run the one with run and fix on the input that takes 12 milliseconds notice 13 7 is there like a bash function that allows me to run a command multiple times and like gets stats from it time with time command multiple times the next time command multiple times no uh yeah multi-time perf perf stat r10 let's do this do i have perf which perf oh i don't have perf uh do i have python time it so let's see python 3 m time it import os system a day 8 65 6.5 to 2 milliseconds per loop that's uh let's see time it uh repeat setup but because i want to i want to this is best of 100 let's let's actually remove the what is the why is it printing something here print all right yeah i think i need to print otherwise it will not give me like it won't force evaluate the output uh run and fix takes 6.32 milliseconds our reverse engineer program takes 6.37 milliseconds no wait i didn't compile again 4.66 milliseconds that's the best time i want the average a can i get average from time it oh but here there i'm debug tracing right crucial thing i think we're not actually using that one but okay i think none of these actually happen so say this okay compile it again 4.43 milliseconds i mean it's not way better but uh i like i like it um i like it better why well it's my idea that's one thing and uh this is just like this this depends on us running the program right so this is just so this is this is something called dynamic program analysis where you like insert monitors and then you run the program and then you see what happens right so like and that's that's totally valid way to analyze programs right you just run it and see what happens right but this here is so called static program analysis note that we we figure out what we want only by looking at the instructions of the program but we never actually execute the instructions of the program right we generate a model of the we have a model of the behavior and then we we we use that information this is static program analysis right and you can imagine that if the program was super long and did like did a bunch of loops first and then returned this would be way faster because we don't actually have to run the program to see which instruction we have to modify so we have a tuple dot swap never in prelude no i don't think so i mean because you just write up write the function right away to lock no yes it is swap the components of a pair so this is a dynamic program analysis here we have static analysis yeah and if we can imagine like if there was a bunch of IO here then this would this would be way faster right flip there we don't need that we need we can have swap oh okay import data dot tuple okay and yeah and so you know like okay we did a bit of bunch of pre computation but like these these functions here all do this exact same thing so i mean they're maybe not that interesting right we can probably unify them let's see here now we have to iterate over the program three times to get the jumps knobs and associations so let's just do that in a title loop right jumps a nops x equals go and we're gonna have three empty lists and we're gonna have s-hocs we're gonna apply to s-hocs of prog and go so this is gonna be this is gonna be so go so this is gonna be j's n's and a's equals so so an empty list that's gonna be reverse j's reverse knobs reverse n s reverse a s go of j s n s a s of i comma so just of of some tuple here i comma inster equals case inster of if it's jump so let's say in at jump whatever inns at jump whenever that's gonna be a go and then we're gonna add it to the jumps j inns jump it's gonna be a j if it's a j we add it to the j's j j s and then we just keep the a s's and then we say t okay this is gonna be the tuple and then rest okay and then we're gonna this the tuple is jump the instruction is jump inns so if this here is like this what partition yeah that's true but then i have to anyway write these case statements to branch on the to to branch on the type right so that is too much work okay let me add the inns to jumps and we're going to rest if it is a knob then we add it to the knob and then we add it to here then knobs if it is something else okay we add it to the back we add it to the a s okay and here we will just say map swap jumps and this is just gonna be do i use i use the a's right no i don't i don't actually use so now this won't work because the n prime here is all right still difficult yeah yeah exactly yeah which this will be what is it complaining about now it's missing so we have n prime we have a prime we have j and j prime and we have r this j s will be just exactly this right but it's complaining that the expected type is map instruction int and as saying that the n prime field is wrong this isn't actually what we're doing right we are taking we're just taking the tuples jump n jump knob n act whatever so this should be i so we're not just picking out the instructions we're actually doing the computation right so it's gonna be i comma i plus n this is gonna be i comma i plus n this is gonna be i comma i comma i this one if i'm not mistaken yeah delete all of this code let's see uh let's see if it still works yeah we still get this correct result it's good we can so here we're also doing like tail recursive optimization right so we like this is now this is gonna be super fast we we have these pp set we don't need that right we use a reachable one right so we have to run the program once but we don't have to run it so many times and this this thing is like this analysis saying here that would work even if we allowed infinite loops so we'd also avoid those right which is good so we don't have to talk about timeouts or or anything like that right yeah i i have to say i i kind of enjoy this solution also let's see do we gain any time on doing it this way like all in a tight loop oh i gotta keep keep forgetting to keep forgetting to compile again still 4.53 milliseconds okay one thing we can uh we're creating a map here but we don't actually need the actual map so we don't need to we don't need to reverse them so we can get to 4.24 with the analysis okay let's see this is quite fast right now because i because like the other one took six milliseconds right and i just i just kind of want to show that we can make the program analysis way faster because we don't have to execute anything uh so we need all these we don't need to check for membership in this set we know that it's always going to be there okay that didn't save us any time oh i didn't say okay but we don't need to we don't need to actually do that uh that was just kind of a safety while we were making sure that was correct we need to look up us in all these maps so right if you're just joining us we are solving advent of code day eight and now we have two solutions we have one that runs the program and checks what happens which is like a dynamic program analysis it's called where you kind of instrument your program and then you run it and then you look at what happens when you run it right but this we also we did this static program analysis way where uh we don't actually have to run the program we just look at the code which which is like the cleaner way that's what you do in real life right you don't i mean at least if you like you try to use the information you have just from looking at the program like you don't want to have to run it get to see what's happening um let me say can this be any faster we need all these computations right we're using j j prime we're using n prime we're using a prime and we need the do we need to check the reachability can we just say knobs here but now it's complaining that we don't use have r but we don't we never use r actually so that's okay oh that didn't work okay we need the reachability here but you saw that it it failed it wasn't actually that much quicker let me just see prog 2 print links prog 2 okay so two seconds are taking this print pre compute prog 2 yeah so most of the time is spent in the pre computation step right a print link n prime so most of the time is spent in the pre computation so that's exactly what we're trying to optimize so this one this one was super fast the reverse engineering itself like the action analysis is very fast it's just this one that's slow let's uh let's do some haskell perf criterion boze boze is a cool dude there's a lot of cool people in the haskell community that's what i like about i don't know what i like about it uh thread a haskell performance check heat map there's something like they call a heat map look it it shows you it like shows you what what it's spent time on let's see like we could download criterion but that's like a lot i want to see these cross centers right so let's see here gco day eight and then it says prof prof auto rts arts right photo f prof auto yeah then it links and then it says rts arts rts now it should be slower because it's been instrumented but not too much lower wait okay and then we run it plus rts p and then we say day eight dot prof uh is haskell used much in today's programming yes uh maybe not like you know it's not as widely as java script of course but like there's a bunch of stuff at facebook that uses like like facebook spam detection runs on haskell like it's a dsl that compiles into haskell code right and you know and you're wondering like oh spam on facebook i never seen spam on facebook well that's that's how good their system is right because and they reuse haskell to allow their uh spam engineers they call them to uh wow powers instructions take that takes 80 of the time wow okay so and then the reachable stuff takes a lot of time too you know haskell is not a scripting language i mean so it's a it's a compiled language but it's a functional programming language so it's all based on expressions but you can interpret it if you want um so yeah you can do you can do a lot with it if you want to see more haskell content you can follow me and you can just kind of get an idea for what it's doing so uh powers instruction powers instruction int what powers it's taking most of the time is here parsing the integer that is a lot right why is 80% of the time being spent at parsing the int is it because of this this read s to p reads thing because it does says when it isn't log back in or something bother does a possible inefficiency can i just say okay let's just our read bunch is digit is what i use but i haven't benched it the thing is that we kind of we know like it's okay we're not gonna get wrong stuff into it you know um that is the thing so what i want to do so so because yeah so we know that the the instructions are well formatted right so we don't actually need to know figure out when it happens so but i'm just surprised that it that it's so wrong okay so let's say here there's gonna be a choice of uh either either it's going to be you know optional char plus and and then we are going to do so it's going to be optional do okay uh if yeah so let's just get many characters right you said munch one okay yeah that's that's true so let's see import data.char munch munch a munch one and then it's going to be satisfied is digit so they're gonna satisfy we're gonna munch a bunch of oh no it's not gonna it's not gonna satisfy it's just this digit right uh yeah this is just hackage so you know i i usually just google something yeah so i say i go to google dot haskell dot org and here you can use search for anything haskell related like you can say munch one and it finds everything that's called that or you can like search by type right so i can say here char to bool to read the string and i can search for that and then it finds it also right and then i can just click it and it will take me to the documentation of that function which is pretty op actually so we munch is digits so this is going to be a stir let's write here par's num read p int par's num takes in a string is going to be string to int right string okay i'm not gonna do this right i think because like this should be fast like i you know i'm gonna do something and it's not gonna be as fast as yeah there are multiple implementations but yeah the ghc is the one that's everyone's using right now and it's quite good it's quite fast recommended did you go straight into it no yeah i code in uh i code a lot in i code a lot in python i've done a bunch of java script type script a little bit of c but now i try to use it mostly haskell because it's it speaks to me and i like it okay uh let's see so is it gonna be an optional char par's yeah so you know this read s to p reads int it should be fast right let's say hugel read p int anyway it's weird it's weird that spending 80 of its time there um but you can see that like almost all of the time here is being spent in this reachable function which is shared between the two um so yeah okay so i think that's going to be enough for today we've been at it for four hours now um happy to have so many of you here dropping in and uh if you want to see more you can follow i'll be here again tomorrow at uh six o'clock european time that's five o'clock uc i guess it's it's noon on the east coast i think so if you want to wake up early on a wednesday and see some haskell programming that's one uh we're gonna be using the same thing again and we had a we had a very nice stream today we got the creator of advent of code dropping in and looking at our attempts which is cool i really i like that he's dropping in and and seeing what's happening when should i learn category theory well you know whenever you feel like it don't don't let anyone pressure you into learning category theory you don't actually need it uh but you know if you know it you can get a bunch of papers from it by being like oh this is actually just a functor over the category which is which is what a lot of researchers are doing but like for just writing haskell you don't need you don't need categories you know and i think that's one of the things we have to be be careful about you know um you don't need you don't need to know complex things you can just like this there's no category theory or anything here this is just me case matching we are applying functions to lists we're using arrays looking up in arrays you know that's all we're doing we're not really doing anything you know there's no category theory in here i mean there's no functors from i mean yeah this parser is a monad but you know we don't we don't use that fact kind of but yeah exactly like insertia says i mean we have nice theorems about all of these things but we never i mean we you use them when you are designing you like if you're writing a library and you want it to be super fancy and your name is edward commit you know then you use all the categories here to be like you know we can use this function here in this way because we have proven guaranteed that it will never do this and that's why you can optimize it this way right so you can you use categories here you definitely do improve uh the code but it's not it's never actually going to it's never actually gonna matter i mean yeah unless you're trying to do something completely different it's not going to change so many things let's say here a git status a git add day 8.hs git status git add input and test input uh day eight and you can watch this i can like down below the channel there is like my github repository so you can you'd find all the code there you want to look at it yourself i'm glad we did the static analysis that's kind of my one of my subfields actually uh my advisor is a program static program analysis guy so he would he would enjoy this and um and yeah exactly like insertia says you could just use i or roughs uh you can just kind of yeah you can kind of use sort of inline yeah except like you have to you compile it and then you define like a foreign function interface for it and then you say you can call it uh from ghc and there is a library i think which is just like inline c ascol that that lets you literally write uh inline c code so you know if all you know is c and you want to be able to use all that stuff you can do that uh but i'm i'm not sure it's recommended i wouldn't recommend it i don't want to i don't want to be telling you to do things but uh but yeah you should try to write it in a hascol way but you can definitely still use see directly without too much trouble all right everyone i hope you enjoyed today and uh see you all tomorrow probably hopefully not for this long i think hopefully we won't be able to do the cool thing right away and uh yeah thanks for participating thanks a lot again insertia for your suggestion for the first one and um like for the dynamic program analysis way and yeah just being helpful on chat and yeah all right bye bye