heredocs, select with index, paper folding - Advent of Code 2021 - Day 13 with Ruby

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey what's up welcome back you're watching day 13 of the advent of code this is called transparent origami the idea is that we have some sort of transparent paper that has dots on it and we're gonna like fold it and keep folding it and then ultimately you should be able to see the dots at the new locations after it's all folded up so the input that you receive is all of the dots and then also some instructions for how to fold and this is kind of what you can think about in terms of where the dots are so like these pound signs octathorp whatever are where the where the dots are on the grid and then the periods are just the empty spaces on the grid and so what we're going to do is try to take in the list of all the dots put them on a grid and then we're going to look at those fold instructions and fold the paper so what we need to do is like have a two by two array and then when we're given a fold instruction along some line we want to take all of these dots and like move them up to their related spot up above so like this bottom corner ends up being in the top corner the almost bottom corner becomes almost the top corner etc etc and so you'll fold several different times and ultimately end up with something like this so for part one we want to just look at one fold instruction and then see what's on our transparent paper so that's what we're going to do so let's start off here by adding day 13 day 13 and we're going to add paper.rb and class paper and then we'll add our spec day 13 spec on our b and we're going to say require relative day 13 paper.rb and we're going to um describe paper and we're going to say that it like correctly parses the points um and the fold instructions and um so we're just going to give it some raw input so we'll say that input here looks like this this is called a here doc it looks like this like a here dock i think and it's basically like a way to make an an inline or like a multi-line string in ruby it's also a convenient way to drop in a bunch of instructions so in our case we don't need all of these instructions we just need some of them and so what i'm going to do is grab some of the points that are pretty close to zero so that we can have our like test grid be pretty small so this should give us some decent number of of results so now we'll say like paper is equal to paper.parse input and then we'll pass that we'll pass that in and we're going to expect that paper dot grid to equal something like this where we're gonna have um well we we need to figure out what the max number is here so it looks like four is the max number of uh rows and columns so we actually need five rows and five columns so then we're going to have i think a bunch of zeros at least to start and then at 0 3 we're going to have a 1 and then at 4 1 we will have a one and that three four two three uh four that's going to be a one and then at three zero we're gonna have a one and then we're also gonna expect that um paper dot fold instructions to equal and i guess let's just try to have the fold instruction be like the string and then the value so we'll just expect that it's an array of like y seven or something like that and um then x uh x5 so that's what we're going to kind of try to end up with when we parse so let's go try to parse this out so we're going to say self.parse input and we want to return a new paper paper dot new and that's going to have the grid and the fold instructions okay and it's failing no method undefined method input for the spec um [Music] oh this is okay you have to use the equal sign okay so yep let's see okay undefined local variable or method grid so there is no grid here right so we have to figure out the grid based on the input so the first thing we want to do is say input is going to we want to split it on i think we want to split it on like two new lines or something um in the instructions here there's like a new line after this row and then another new line here and so what i think that's gonna work and then we'll have like dots and instructions um at least like the raw versions of those so let's p dots and we'll p instructions um puts we'll just put like a line between them and then see what we get okay yep so that looks right so we've got our dots and then we've got our fold instructions now we need to properly parse the dots so dots.split on new line that should give us back each kind of like comma separated pair and then we want to map that onto a dot dot split on comma dot map uh to i and i think that should give us like nice nice dots um okay so we'll just say dots is this or grid no dots yes dots and then for our fold instructions we want to say like instructions is equal to instructions.split on newline dot map and then for this one what we want to do is just remove fold along space so we're going to say g sub like fold along space we want to replace that with nothing and then we want to split on equals and then we want to uh i guess we technically want the last element to be an integer so yeah then we can like map all of that onto um like it's gonna be like a string and then a number so x and n or something and then we want to say x n dot 2 i oh that's a long one okay so these this is like one of the beauties of ruby is you can just really chain on a lot of different uh stuff here but this hopefully this is not too hard to read and i actually think this is too hard to read um and so i'm gonna make this a little clearer by saying line and then line.g sub that thing and then split on equals um technically what we could do is have it map map map and then have like each instruction on a different line and that sometimes can make it a little clearer but um for now this is this is fine whatever okay so now we've got good all right so we've got y7 and x5 that looks right and then we want to pass in this we'll just call it instructions now and we don't need to print anything anymore we're still going to have an error because we don't have an initialize method and grid oh right so grid is going to be like dots dot we need to find the maximum first dot and the maximum second dot right so dots dot map um first dot max and this is going to be like max x and then max y will be last and then what we want to do is create a new grid that is an array of max x and inside of that array we want another array and that is going to be max y and we're going to just fill the entire thing with zeros for now and then what we can do is say dots dot each do dot actually we can we can destructure in the block argument here with x and y and then we can say grid at x and y is equal to the 1 right okay now if we run it we have a grid variable but uh undefined method square bracket equals four nil class okay so um oh right this should be plus one i think um i think that's right no oh yeah this is right now this is the next error that we have the initialize method doesn't actually take greater instructions yet so we have to say deafneu or no def def initialize and we're going to have grid and instructions at grid is equal to grid and at instructions is equal to instructions and we'll just make a reader for grid and for instructions and then we want to change this to be instructions instead of fold instructions and we'll run our test hey we've got a passing test nice we can remove our put statement so hopefully this makes sense basically it's just taking the input and doing a bunch of stuff to get what we need out of um out of that thing and into our class okay so now that we have our grid we kind of need to figure out like how this thing actually works so um one thing we want to do is print it out so let's add a let's add a method here um 2s that will that will print this thing out so we can add another test for this too it like prints as expected we can use another here doc here for testing this part out so this can be kind of handy so let's actually just use our same input in the paper and all that in fact let's use a let block again let paper be um do and this whole thing there's a couple other rspec features too that i'm excited to share in future episodes all right so we've got our this should still pass let's just make sure it does okay cool and then we don't need all of this and what we can do is we can say we expect that paper.2s to equal and here we can use another here doc um so um this the like the the all caps thing that you use at the start and end can actually be whatever you want and in some editors if you put like sql then it'll like syntax highlight for you so that can be super handy here i'm just putting whatever in for input um but what i wanted to show was that like when you're using a here doc as an argument to a method it gets super freaky because like the close paren for the method call is like at the end of this line but like the content for the string goes below so uh yeah it's it can get it can get kind of funky so i guess like we're basically building rebuilding this grid but we're gonna build it with three dots and then a pound and then a dot and then five dots and then five dots and then uh pound sign dot dot dot pound sign and then pound sign dot pound sign pounds or no dot pound sign dot dot okay so let's see what we get uh we got nothing because it's not implemented yet so what we want to do is we want to say at grid i each do row row.each do cell and um here we want to actually let's map it map map and we want to say we basically we want a pound sign if the cell is 1 and we want a period otherwise so if the cell is equal to 1 then put a pound sign otherwise put a dot and then i guess we can join this with new lines i don't know let's see all right so we got very close this one is just missing an extra new line so what we can do is um i'm going to just cheat and say plus new line at the end because that's whatever it's fine okay uh all right so that totally works so now we have a method to print it out and we have a method to generate it now let's let's uh figure out how we're actually going to fold so we have to use those fold instructions x7 and y5 to know sort of like which line we're folding on are we folding left are we folding up um so basically the way this works is we are always either going to fold everything left or we're going to fold everything from the bottom up and i think what makes the most sense is to first just move all the dots up to the upper part of the array the upper part of the grid and then instead of like having to figure out how to like make a new array and move it over and everything what we can do is create a new array by selecting only the rows that are above a certain mark or selecting only the columns that are above a certain mark that way we can kind of just like cut the cut the grid in half by using filter or select so it i don't know let's say like it folds up as expected so um let's say we're going to take our same paper and we're going to say like paper dot fold up and we're going to expect that paper to grid to equal something and i guess we also like in our instructions here in the fold instructions they give us like which axis we're going to fold along so here when when we see y equals 7 we're going to fold along the seventh like row or the seventh column i can't remember which but let's say okay so here in this case let's fold up on call on row two so this is row two right here so if we were to fold up row two then we should just end up with these two rows and let's see so i'm actually just going to copy all of the rows and paste them in here so we can we have reference so i'm going to move this one up here so that's a 1 and then i'm going to move this one all the way to the top and then i'm going to move this one up here and we're just kind of like making it symmetrical and then we're going to remove those bottom rows undefined method fold up yep we haven't made it yet def fold up some number and here is where the magic actually happens i think we can make this a little clearer let's call it crease i think um and then the idea is that we want to iterate over all of we want to iterate over the entire grid so at grid each with index do row and i and then um row.each with index do cell and j and we want to say something like if the cell is equal to 1 then we want to like copy it up but i guess we we want to skip over we want to skip over any rows that are smaller than the cr then that are like above the crease right and so we want to say like next if i is less than crease okay and then if the cell is one then what is the position um on the top right so like um here we moved this one at what is this um zero one two three we moved it from three to one so from three to one so we need to move things from three to one when folding at two and we also need to move things from five to zero um from five to zero when folding at two okay so this is where like sometimes it can be helpful to just write out a couple of those use cases so that you can sort of get the math right and so in order to get like we have crease crease is the number two so we have the number two and then i try to think about like what is three relative to one and what is five relative to zero and then we also have these inputs i and j so when we um when we get to three zero so when we get to 3 comma 0 i will equal 3 and j is going to equal 0 and what we want our and i guess like crease is going to equal 2 and what we want is we want to set 1 1 comma 0 equal to 1 okay and so how do we get 1 how do we get this one value and i think it's something like it's going to be something like crease minus [Music] i minus crease or something okay so this is two minus three minus two so that's one so two is two is the crease value so that's two so we get uh two minus and then i again is three so three minus two so we get two minus two okay so then let's just double check to make sure this works for the other case so we're moving from five to zero so this should be zero and um so the crease in that case is two um i in that case is four and then minus two so four minus two is is 2 2 minus 2 is 0. okay i think this works so then we want to set like at grid at crease minus i minus crease to or and then like j j is actually not gonna change in this case right when we're folding up the column doesn't change so j stays the same we'll set that equal to one and i think that's actually all we need to do okay so then what we need to do is like our i guess like that should bring us or like get us pretty close to this i think let's take a look all right so yeah okay so the first two rows are good now the next step is to just like filter out the rest of those those those rows so now we need to say something like at grid dot select with index this is kind of cool so like um both map and select don't have like an each with index like array does but you can add on dot with index and that will make it so that it sort of like wraps or decorates the block so that you get an index with it so we'll get row and i here and then we want to return rows if yeah so like if i is less than crease or maybe we just say i less than crease let's see no um oh i guess we also want to like update grid at grid equals hey it worked cool all right so now we need to fold left so let's fold left and it's going to be basically the same thing but just a little different so fold left is this time we're going to work with j so i is going to stay the same and we're going to change j actually before we do that let's write a test and here it's going to say folds left as expected and we're gonna say fold left at two we'll copy our um our stuff here okay so when we fold left this one is gonna come over here and this one oh this one is already it's already got a spot and that's okay the the numbers can overlap we don't need to increase it we just need to like make sure there is a dot there so we'll set it and uh it won't matter and then we're going to delete the rest of this array and we should end up with this so there is no fold left method so let's uh let's implement it and this part is not going to be the same okay so if this uh yeah so now we want to skip the rows that are less than the crease or i'm sorry the we want to skip the cells that are less than the crease and then if there is a cell then we want maybe it's the same is it the same crease minus j minus crease i don't know that can't be it that might be it maybe i don't know let's see so then what we want to do is we want to filter out the um yeah so now we need to say like row grid.select or grid.map yeah grid.map and then row.select with index do cell and j and here we want to just return j is less than crease i think holy moly okay awesome that's exciting okay so let's uh let's see um all right there's a fold instruction blah blah blah so why don't we try yeah let's take this let's take this input oh you know what we haven't actually figured out how to make a fold instruction do its thing so let's make a method on here called step and step is going to take instructions.pop so we'll just pop off an instruction and we're going to get back the like direction and the crease or something and then we want to say like if der is equal to y then fold up crease um else fold left crease and okay so then we've gotta do our file thing so file dot read lines or actually just file that read arg v dot input or dot first and we're gonna depend on paper to parse this all so paper is paper.parse and then what we want to do is say paper.step and then we want to say what is it what does it actually want here so after the first fold in the example above 17 dots are visible so we also i guess need to count how many dots there are dots um and this can just be at grid.flatten.count the ones what's paper dot dots not dogs dots okay so then what we want to do is add um example input and we're going to grab all of this and we're going to paste it in here and we're also going to want input and that is going to be our puzzle input which is here and then we can run this ruby day 13. uh all right 10 dots 10 dots that's wrong there should have been 17 dots so what happened so puts paper maybe we folded the wrong way 17 okay so we must have folded the wrong way and then if we fold again paper dot step do we get oh there's our zero cool all right it's like on its side but whatever um relative to this i think that's okay so part two finish folding the transparent paper according to the instructions the manual says the code is always eight capital letters so what we need oh right also we've got to go with our input and we got back eleven [Music] no we need to do all the fold instructions so how does that work i guess like um run or something and we'll just say like while instructions dot empty while the instructions are not empty step and then down here we're going to say paper dot run and zero let's see put self zero how are there no all right so what's super odd is that there's only six dots here but it's super tall and so i feel like we're we're folding at the wrong spot for some reason so let's take a look at our logic here and see if we can figure out what's going on um okay so the very first instruction in our input is fold along 665 so when we call step step this is pulling off the instruction and then folding it somewhere and then giving us let's just print out crease and see what that gives us um okay that didn't work as expected puts paper dot step we don't actually need to print that um okay uh six creases six huh oh that's the last instruction okay hold on a sec um instructions dot pop oh that's gonna pull off the last one we want shift shift and now we want to puts paper dot dots boom 669 and if we did it with the example example input we get 17. okay all right so 17 was the example 669 was hours awesome so part two finish folding the transparent paper according to the instructions the manual says the code is always eight capital letters so um this one is a little interesting it's basically just like print out print out the ultimate grid and then hopefully you can read it so let's try to do that here and then instead of step i guess we want to like run it uh run and then put up okay so that is the example input and then for our input we get this uh c m f something uh okay so like u e f so yeah u e okay so it's backwards f z c u c j okay it's backwards in in like all wonky let's see if we can transpose boom here we go u e f z c u cj awesome and that is the answer for the puzzle right here um and that's just the answer for my input thanks so much for watching this has been day 13 of the advent of code for 2021 in ruby hope you enjoyed that and yeah i guess we'll see you next time [Music]
Info
Channel: CJ Avilla
Views: 52
Rating: undefined out of 5
Keywords: cjav_dev, web development tutorials, web development for beginners, vim, ruby, rails, select.with_index, heredocs, advent of code, aoc, advent of code 2021, folding
Id: AaePCMNgyMY
Channel Id: undefined
Length: 31min 39sec (1899 seconds)
Published: Fri Dec 17 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.