methods with block arguments - Advent of Code 2021 - Day 11 with Ruby

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey what's up welcome back this is day 11 of the advent of code and this is called dumbo octopuses we're going to be solving this with ruby this is 2021 and uh the process or like the the idea here is that you have 10 or 100 octopuses arranged in a 10 by 10 grid and it's one of these dumbo octopuses which are pretty interesting looking um they've got these like dumbo looking ears um and they look like elephants they totally look like elephants so um yeah we've got a hundred bioluminescent dumbo octopuses arranged in a grid and each uh element in the grid represents the energy level of the octopus and when the octopus reaches 10 or whatever when it like crosses from a 9 up to a 10 it flashes and what happens when it flashes is it also increases the energy level of the neighbors of that octopus so in this case we if we started off with a grid of octopuses that looked like this is octopi i don't know some sort of plural and we had a bunch of ones and then some nines arranged in like a square inside as we tick or go to like the next step then each of these nines are going to flash and when it flashes that means that we're gonna like switch it to a zero representing that it flashed and we will also increase the power of all of the elements around it so step one of a tick is that we're gonna increase the energy level of all the octopuses by one step two is that uh any octopus that flashed will also cause its neighbors to increase so if we look at this top left corner right the number three first we increased it from one to two naturally as part of a tick and then we increased it from two to three because its neighbor its direct neighbor was an octopus that flashed this four increased from one to four because first increased from one to two as part of the normal tick and then it increased from two to three because this octopus flashed then it increased from three to four because this octopus flashed and so on and so forth so the idea is that we want to sort of track how many times we flash and the first part here is going to be trying to figure out um after 100 steps how many total flashes are there and so my answer was six 16 15 1600 and so we are going to go through and try to implement this and yeah so let's let's uh let's jump in and get started um so we're going to add a new day 11 and this is going to be like i don't know octopus.rb sure uh uh and then we want to add a spec uh day 11 spec that rb and this will be require relative and it's really kind of like a grid of octopuses but whatever we're just gonna call it that class um i've been needing buy bug in every single episode so might as well drop it in there uh class octopus i don't know if it's actually like an octopus but yeah it's whatever it's it's fine it's a grid of octopuses i don't know what the plural of octopus is but um so these are all of the energy levels so i think we can safely start off with a um 10 by 10 grid so we're going to say like energy or like levels or something is going to be array dot actually we'll we'll take in levels as an argument levels and we'll just say like we'll add a lead a reader for levels and i guess we also want to say like it flashes as expected based on the example my its statements are getting uh lazier and lazier depending on how late it is in the day so all right so before any steps let's assume that we're passing this in as our argument so this is going to be like our grid of octopuses um uh let's see octopus is octopus dot new and here's all the energy levels and we will just start off with these in an array of arrays and then what we want to do is we want to say like octopus dot step and then after it steps we want to expect that octopus grid or something or levels to equal this new state which is going to be after step one so this is kind of we're basically just copying and pasting um from the example here and this should help us really get started all right no method step for octopus so let's go implement that now so we're going to have uh step and what is step can actually do okay so we expected this new state and we got the old state and so what step is going to do is going to say something like um first actually yeah i guess we can kind of just do exactly this so we want to sort of just like um uh first the energy level of all the octopuses increases by one so at levels dot each with index do row and i i guess we're going to iterate over all of these the same way and say at levels at i j plus equals one um okay so let's let's extract this and make it a like this the square bracket thing again so let's say something like um self or like def uh square bracket at a point i j is going to be levels at i and j and then here we'll just say self self at i j plus equals one and then what i want to do is uh okay so then let's just keep going but i think i want to extract out this thing that iterates over because i think we're gonna have to do that several times so then any octopus with an energy level greater than nine flashes so now what we want to do is like this same iteration but if the value is greater than nine then we want to flash so something like if self at i j is greater than nine flash like i j or something um and we'll have to write some method here that does that uh but for now we can run our test um and we need oh we also need a setter method that looks something like this um and this will have like some value uh equals value run the test undefined method flash okay we're going to have a flash that's going to take in a point i j and this is going to what is this going to do so this is going to say go through the neighbors that is including those that are uh diagonally adjacent and increases theirs and then if it also flashes that process continues as long as new octopuses keep having their energy level increased beyond 9. so what we want to do here is we want to say something like go through all the neighbors and increase their um energy so something like i guess we also want a neighbors uh we want some neighbors method so let's describe that um it and we did this for a previous exercise right where we had like some sort of neighbors um but let's see so we expect the neighbors are like octopus dot neighbors of some point so let's say like zero zero um zero zero we expect those neighbors to contain exactly um some numbers so if we're at zero zero um so if we're right here we should expect zero one um we should expect one one and we should expect one zero and let's see what we get oh we got nothing back because neighbors doesn't exist so let's write a method neighbors that takes in a point i j and this is going to again return something that's pretty simple so we just have to go through all of the adjacent points i think there's like six of them so this will be like i minus or like i and j minus one i and j plus one okay i don't know why that was so confusing all right but this this i think should be all of the different diagonal directions right one two three four five six seven eight and there's three across the top three across the bottom one on each side okay dot select there was also a question on one of the youtube videos in the comments about filter versus select filter and select or filter is an alias for select so we can use filter or select here it doesn't really matter and then we have to say like a and b and we want a dot between 0 and at levels dot length minus one and b dot between zero and levels dot first up length minus one and let's see if that passes our test boom all right so let's add another expectation here we will test out this top right corner so this is going to be 0 one two three four three um then it's gonna have two one 2 2 is itself 2 3 is to the right and then below it is gonna be the same but all of these have threes and we're still good okay so we got our neighbors we got our neighbors figured out um all right so what we want to do now is we want to go through all the neighbors neighbors of i j dot each do um and this is going to be a neighbor coordinate so like x and y or something and for all x and y we want to say self at actually now we can use point yeah let's just do point self at point plus equals one if uh self at point is greater than nine then we want to flash point because if if flashing ourselves causes us to um flash a neighbor then we want them to also kick off and like trickle down to their to their neighbors and so we're going to call flash here but this is going to cause a like recursive loop that is going to probably have like an infinite loop situation so if we run this yeah so this is like a classic sign that we have an infinite loop right we're just like getting all this feedback and we don't have a way to stop so what we need to do is we need to keep track of what we have flashed so at flashed is going to be it's going to include this new point let's actually just call this point um and now we can add the point to flash and we can return if at flash dot includes uh point i think that should stop us early include oh i guess like we got to say well where do we want to initialize this i think we want to initialize it right before we step at flashed equals empty not sure okay so we expected three four five three four five okay and we got oh we got this number okay so uh here some of these instead of being zeros are way bigger than zeros right they're 15 10 15 whatever and so what we want to do is the last step here is any octopus that flashed during this step has its energy levels set to zero as it used all of its energy to flash okay so now what we need to do is after we have flash we want to again iterate through all the stuff and say um if uh if self at i j is greater than nine then set it to uh zero and let's run our tests again all right now we've got a passing test so we are flashing we're flashing as expected so i do want to come back and refactor this but let's just keep let's keep driving on um all right an octopus is highlighted when it's flashed when it flashes given the step uh here's a larger example of how it progresses blah blah blah after step 10 there have been a total of 204 flashes fast forwarding here's the same configuration um every 10 steps all right what do we need to know after 100 steps there have been a total of 1656 flashes given the starting energy level of dumbo octopuses in your cavern simulate 100 steps how many total flashes are there after 100 steps so what i think we want to do is make some method here called like um uh i don't know pass or like tick or something i don't know uh that'll take in some n and we'll do like n times step that way we can actually like run some certain number of steps and then how we keep track of how many flashes there were is going to be interesting because like after each step i guess we need to count how many flashes there were right so like uh yeah so after at the end i think we might want to just like count how many flashes after every single step and then we'll just count them up all right so the way we're gonna do that is i'm just gonna like keep track of a new instance variable called like flash count and we'll just set it to zero and after we actually start ticking it's game over after that like once we start ticking all right so at levels dot flatten dot count zero count all the zeros and add that to our flash count and that should give us that should give us the answer i think um so let's add a little test here so we want to expect that octopus dot flash count to equal nine because this one flashed nine times right so let's run it undefined method flash count run it again boom all right so that works i think i don't know i mean we only flashed one time so we'll have to just roll with it and see how it goes okay so what we want to do now is we want to check if it's file input and if so we're going to read in from the file our uh actually no let's just use data again let's use data so we'll use um data.each line.map chomp this is a cool trick so if you put underscore underscore end at the bottom you can drop in your own data so i'm gonna use the example data first before we put our own and we'll say um split each line and then grab its characters or no i guess like dot map um so that's going to give us the lines and we want to map over all of those and get the characters um that seems too easy but let's see uh octopus okay so um octopus equals octopus.new and we want to say octopus dot what is it tick and we want it to tick a hundred times i think and then we want to put out octopus dot flash count and just see how it goes so day 15 octopus wait what no day 11 day 11. uh day 11 octopus okay boom cannot convert integer into string okay so then this needs to be mapped again uh huh oh we need to map that to lines and then we want to map the lines each to so that gives us a line and then line.map 2i uh unexpected local variable [Music] something oh octopus.new that's where that parent was for 1656 1656 okay cool so that's the end of part one for day 11 of the advent of code actually no hold on jump in the gun hold on get your puzzle come over here grab this thing and then what was mine mine was 6 000 or 1 615 1615 so that is totally working okay it seems like the individual flashes aren't bright enough to navigate so you might have a better option if uh the black the flashes seem to be synchronizing so in the above example the first time all the octopuses flash simultaneously is step 195. if you can calculate the exact moments when the octopuses will all flash simultaneously you should be able to navigate through the cavern what is the first step during which all octopuses flash okay so what i think we want to do now is make a method um called something like all flash or something like that it knows when all octopuses are flashing or something and then we want to uh i guess we actually want to like use the input the example input so that we can use the exact numbers that they used so we know that like 195 is is the number here okay okay so then we want to say something like um octopus.tick 195. and then we'll p octopus dot levels and just see what happens here so we did get all zeros so that's cool so then we want to say expect octopus dot all flashing or something like to be all flashing and then we have to make a method all flashing um so then we'll we'll write a method here all flashing and this will just be like at levels dot flatten dot um actually we have a count already somewhere don't we uh levels.count oh i guess yeah whatever um levels.flatten.com 0 equals 100. that should give us like whether they're all flashing or not okay and um actually you know what we should probably make it a little bit more durable so that we're not depending on the size of the grid so let's do at levels like dot flatten dot count so all the like the count of zeros should match the count of all elements and that's true so then i guess let's make it um 194 and that should not be all flashing and 195 should be all flashing and not to be all flashing oh we don't want to yeah okay so we want to just tick one more yep cool so we were ticking 194 and then 195 more instead of just one more to get us to 195. all right so that seems like it's working now what we want to do is we want to like find the tick at which we know that they're all flashing so now we know how to find if they're all flashing we know how to tick what we don't know how to do is figure out how many steps it takes so def um like i don't know full flash count or something and then we'll just go like um zero to a thousand dot each do x or something and that doesn't even actually yeah we just need like a thousand times do um i and then we want to say step and if or like return i if all flashing something like that and that should that should return the number of the step that resulted in them all flashing so let's see if it works oh wait what is it again what was the thing we just created uh full flash count all right uh octopus dot full flash count and we don't want to tick at all we just want to run it so 248 was oh my answer was 249. so why are we off by one um hmm [Music] yeah oh you know what uh oh yeah this should be i plus one because we're going to start at zero here um times or i is going to be yeah i is going to be 0 indexed so that is going to return 249. that's right and then if we did it for the example input we should get 195. so we'll just grab this again and drop it in here and we get 195. cool all right so again we did this operator overloading i'm not super pumped about having to do all of these sort of like uh each with each with index each with index and it kind of like always yields a point we're always just working directly with the point object we're not working with anything other than like anything fancy other than the point object so what i wanted to do was just kind of like add one more method in here and call it like each i don't know coordinate or something like that and this is just going to be a helper that takes in a block and it calls the block with a point i j because we don't actually need the value at that position um but we technically i guess we technically could we could pass the the value also um so let's do that so then we can then we should be able to refactor this and say like each coordinate do like chord or point or something and then now we should be able to just like replace it with that actually let's comment it um so that you can see the old stuff and then instead of passing this array around we can pass around the point so each coordinate do point and then we're going to increment by one and then down here we're going to say each coordinate actually let's just let's see if our stuff still works and it does okay each coordinate do point um and then we can pull this up here comment this out um what this is what's cool about this is that we're writing our own method that takes in a block so this is a nice use case for when you might write your own method that takes a block and notice that like by default here if i'm only passing one argument or i'm only like accepting one argument in the block then only the first argument that i'm calling the block with is actually receiving that argument so then point here is just going to be i j if i said point like comma value or something then i would also get the value in that position and so we're going to see that in in just a sec here so first we're going to iterate through all of them and increment by one actually yeah let's just remove this and then we're going to iterate through each of them and we have the point again and if we wanted to we can say self at pt give me this thing flash pt that really simplifies it run all of our tests again and those are still passing there is a little bit of a cost when you are passing blocks around like this but whatever cares but what i wanted to show here is that this is actually simplified because we can say value and now instead of having to reach into self at pt we can just say value if value is greater than nine then flash and we can actually make this a one liner flash the pt if the value is greater than nine so that's kind of cute i like that a lot all right what else we got down here so this one is another example where we will probably want the value right and so 3y boom so here we can say self at point is set to zero and then um this becomes value and then we comment this out the nice thing about these tests is it lets you refactor like super super quickly right so now we can actually just remove this and we can remove this and it makes it so much easier to read right like self at pt equals zero if that thing um and now our step totally follows exactly what um the instructions say and it's super tight yeah i don't know i really like it um so that is a way that you can sort of like implement a method that accepts a block and then calls that block with one or many arguments and then you don't actually have to use them all you can just use some of them and so yeah i kind of picked a thousand here arbitrarily but i yeah had a sense that it's probably going to be less than a thousand flashes so um that's where we're at i guess is there any other uh no this was already sort of cleaned up we have point that comes into flash and then for each neighbor we call the neighbor pt but maybe this can be like neighbor point or something but um this is this is pretty good i'm happy with this so let's call it there and uh yeah hopefully this was useful um and if you are doing the advent of code i would love to see your solutions please drop them down in the comments section below so we can all take a look um i do plan on going back to all these exercises and backfilling with links to github i just haven't done it so it'll be up soon so thanks so much for watching and we'll see in the next one [Music]
Info
Channel: CJ Avilla
Views: 88
Rating: undefined out of 5
Keywords: cjav_dev, web development tutorials, web development for beginners, vim, ruby, rails, javascript
Id: o_9uhOhMKtQ
Channel Id: undefined
Length: 30min 28sec (1828 seconds)
Published: Wed Dec 15 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.