array destructuring, operator overload, vents - Advent of Code - Day 5 with Ruby

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey what's up welcome back in this episode we're doing day five of the advent of code for 2021 where uh we're gonna build out the floor of the ocean and there are some thermal events we got to look out for so we're going to get as input a bunch of lines where on the left side here that is like the starting point for the line on the right side we have the ending point for the line and for part one we are only going to consider horizontal and vertical lines and in this list there are some diagonal lines but we're just going to only consider those that are horizontal and vertical and so you can kind of think of it like this where the ocean floor is just a bunch of basically the all of these dots are really like zeros or there's no line there and then we want to use this input so from zero nine to five nine so we basically wanna like fill in from zero nine to five nine and because there's one line there we wanna increment that from zero up to one and there is also another line that starts at zero nine and goes to two nine and because there is a zero nine to two nine there are twos there so that has more than one line they're overlapping and our goal is to look for anywhere that the lines are overlapping or crossing so we're going to sort of like use our lines to mark the ocean floor and then anywhere that they cross we will consider that sort of like a dangerous point where there's a vent or something in the floor so this is kind of the input um yeah let's let's jump into it and try to solve this that is bingo let's see day five uh and then we'll add day five spec.rb and in here our spec.describe and what do we wanna call this floor or something like that ocean floor do end so we're gonna describe um uh i guess like the very first thing that i'm noticing is that these are coming in as like it's these are all to be string values right and so we need to parse out like this line here that has the arrow and everything in into like a line where we have point a and point b and we're going to go from point a to point b and so what i think we want to do is um define parse uh and so it'll be something like it i don't know parses the input into um lines or something so we want to say something like ocean or like described class dot parse and the input is going to be something like um [Music] i guess we can just use this right and those are going to be strings and we want to get back an ocean floor so this will be a class method on ocean floor and it's going to be a factory method meaning that its return value is an instance of ocean floor so we're going to give it a bunch or an array of these string values and we're going to expect back an ocean floor that has a bunch of lines where the point values are or are arrays with with numbers so we're going to expect that floor.lines to equal a bunch of points and the points are going to be a 2d array where it's like 0 comma 9 that's like point a and point b is going to be 5 comma 9 and we want uh let's see eight zero two zero eight so that's kind of what we are expecting this parse method to do there is no parse method in fact there's no ocean floor method ocean uh florida rb i guess we need to require relative day five ocean floor dot rb and here we're gonna have class ocean floor and this is going to say self.parse and we're going to get as input like raw lines or something and we are going to return an ocean floor dot new with these lines that we've parsed so lines is going to equal lines it's going to equal these raw lines dot split on that arrow thing dot map uh yeah dot map do pair and then we need to do pair dot split on comma dot map uh 2i i think i don't know that's kind of we're just taking a guess here all right so let's see if this works okay no method split for array oh right because this is coming in as um so this is already like the lines line dot split wrong number of arguments one given zero expected so that's for the initialize method so we're getting all these lines in from the input which will be just like a file right and we're going to do read lines so def initialize lines at lines is lines uh yeah or like lines um okay so that's that's working um hopefully that makes sense we're just kind of like parsing this this input here into those lines all right the next step is that we want this to um to initialize and set up our grid and our grid is going to be um i guess the ocean floor like the dimensions of the ocean floor are somewhat arbitrary like i think what we can do is actually say like um max is lines dot flatten dot max or something and just add one to it because it doesn't actually matter how like the bounds of the ocean floor what matters is that we're drawing lines in the right places and so we want to figure out what is the maximum value in terms of an end point whether that is like in the x direction or in the y direction and we're going to use that to construct a new array that represents the ocean floor bottom so we'll just say like at grid is array dot new max and then for each element inside that array we want another array um that is also max elements and we're going to populate it with zeros so we're just going to get like a max by max grid with 0s in it so array.flatten recall that this takes a 2d array and flattens it down into a 1d array so we get all the elements dot max will give us the maximum value in that array we're just going to add one to it just so that we have a buffer on the edge there and that should be good so this is like this should all just continue passing i guess we would also expect that floor dot grid to equal something like um array.new10 array.new10 00 or something let's see uh undefined method grid we didn't expose that also as i'm going through all of these exercises this is we're now going through day five we've gone through four other days what i'm uh what i hope you're taking away is like the sort of the approach of just quickly solving um solving a problem it doesn't have to be perfect and oftentimes i'll write tests for like the first half of the time like the first half of the session and then when i know that we're pretty close to getting to the answer i just kind of stop writing tests and then like try to find an answer but like that's because once we have the answer we can just move on and we don't actually care about the next steps if this is going to be something that lives on in production and you know you're going to continue maintaining it you'll want to write tests that continue like adding coverage as you go all right let's let's write another method called like draw uh lines um and this is going to like like uh increments the grid across the line or something right and so um in this case what we want to do is say floor is equal to describedclass.parse um uh i guess instead of instead of doing it that way we can just say like described class dot new and we can give it lines explicitly we can just like pass in exactly what we want so let's do that okay so the first line is going to be 0 to [Music] 2 and it's gonna end at or maybe we go zero zero to zero two and we'll keep it very simple to start with and then we wanna say something like um uh floor dot draw lines expect floor dot grid to equal and then after we draw a line where this is we want it so we want it to have incremented from zero to one right and so this is going to be we expect that our grid is going to look something like this it's going to be a 2x2 grid or 3x3 because 2 is the max and from 0 0 we should get something like 1 0 or no one one one and then zero zero zero zero zero zero i think that's what we expect okay so let's let's add draw lines draw lines so uh lines that each do line and each line again is going to have like a point a and a point b right um p uh p or we can say like puts a puts b no p uh and then let's just see what what it prints out okay so printed out zero zero and zero two so point a and point b are being passed in here but what i wanted to do is extract this even further to like x1 and x2 and y or x1 y1 and x to y2 and now we can print out like p x1 y1 x2 y2 and that should give us like our actual values um i think oh you know what i missed a paren yeah this is weird because we're doing like array destructuring of destructuring so let's see what we get yeah zero zero zero zero okay so cool so then what we want to do is what i think we want to do is we want to check and make sure that we are only working with horizontal or vertical lines for this first part and it will be like um horizontal or vertical i don't know what we want to call that they're like non-diagonal we'll call them maybe like normal lines so like if x1 equals x2 or y1 equals y2 then draw like normal line from uh then we want like x1 y1 2 uh x2 y2 okay so then we'll have like this other method that's like def draw normal line and we'll have like point a to point b and then we can destructure it if we want and in fact yeah i wish there was a way to sort of like name these as you're destructuring because it would be cool to say like um yeah a point a and point b whatever all right so draw a normal line so when we're drawing a line from a to b yeah in fact like i do think we want these to be extracted out back again to like x1 y1 and x2 y2 and the reason is that here we want to say like we want to find the minimum of x1 or x2 and the minimum of y1 or y2 and then like work our way across so i think we want something like x1 x2 dot min dot up to um x1 x2 dot max i each do uh x uh all right let's print that out uh okay and what do we get we get nothing what all right so oh we just said p x that makes sense all right so we got zero ah right because for the x's we are we are already um for the x's the x's are the same for our example so we need to change all these to y's and now we're going to p y and we should get something interesting this time zero we should see zero one two and we do zero one two okay so then what we wanna do is something like we wanna draw or we wanna increment the value on the grid at that point and so what i want to do is um i'm going to make i'm going to use the square bracket operator to do some operator overloading we're going to define a new method here with the square bracket and it's going to take in x and y and this is going to return grid at x and grid at y and what this is going to allow us to do is say something like self at x comma y that will give us the value at the current location so is this a 0 is it a 1 is it a 2 is it whatever and then what we want to do is we want to um increment this one so we're going to add 1 to it and then we want to store that back inside of self with like x y equals okay and as soon as we write the equals sign here that means that we need another operator overload so we want to we want the square bracket equals operator so x y and the value that we want to store in x y so at grid x y equals value so this is going to be like our this is our reader and this is our writer and uh because we have the reader and the writer this is actually becomes just plus equals so we're able to use the plus equals as long as we have both the reader and the writer because under the hood it's kind of doing this this thing where it's like you know equals the thing on the right with the getter which yeah you get the point you get the point all right so draw a normal line let's see if that is working as expected and it totally is so we've got a passing test so increments the grid across the horizontal line and then if we wanted to make one across a vertical line then we might do something like zero one two two zero and then this should be something like uh one and one and oh that also works cool so um all right so we are drawing lines now what we want to do is um what else do we need to do actually uh okay why don't we yeah why don't we read in the file and just like try to draw the lines and see what happens so if file is equal to dollar zero we say file.readlines of r v dot first dot uh yeah i guess we can just like parse that so ocean floor dot parse that thing and we should get the floor and then if we say floor.draw lines p florida grid maybe i don't know and then we need um example input so we're going to add our example input there which is all of these lines okay and then we'll say uh ruby day was this day six day five i can't remember ocean floor day five example input and this is the output all right cool so we've got twos in the top left corner-ish hard to tell what that looks like all right so why don't we try to make it print out like this so let's try to mess around with that so let's make a new method uh 2s so this will be like the string representation of the floor and we should be able to just say puts floor and um in order to make this work i guess we want to like iterate over the grid and iterate over yeah let's iterate over the grid uh at grid each do row row.each do cell um if cell is zero uh put a period i guess yeah let's do this as a um ternary okay so um if the cell's value is zero put out a period otherwise put the cell value and let's see what happens that didn't work floor uh puts floor uh i don't know i thought this would call 2s on it no okay p oh wait what oh you know what we're not returning anything um hmm i thought uh wait yeah um i guess this needs to be map map yeah because we want to map out to the values okay let's see all right so we've got a bunch of periods uh okay so then we maybe we should join this together um all right we're getting closer we're getting closer but uh you'll notice that it's like tilted on the side so like if we look at this one the two two two one one one is on the bottom left and here two two two one one is on the top right so what if we just call like transpose trans pose.map and see what happens boom look at that okay amazing that looks exactly like this am i right so one two three four five twos okay so then the answer is we have to find to determine the points where at least two lines overlap in the example this is anywhere in the diagram total of five points consider the uh okay cool so we have to figure out how many values in this list are greater than one so the way that we do that is we'll just call like def score i don't know why maybe like overlaps overlaps we'll call it overlaps and what we want to do is we want to say like at grid dot um this is after we've drawn the lines we want to flatten again and then count where the value is greater than 1. i think that should give us the answer what's floor dot overlaps let's see five boom that's the answer all right let's try it with uh real input which is our puzzle input here and these numbers are massive 724 000 holy guacamole all right boom drop it in come back over to ocean floor run this again on input and you can't really see the grid because it's so huge but we get 6283 overlaps was that my answer 600 yeah 6283 is the answer the number of overlaps in my example input again your example input is going to be different when you go over and solve the advent of code all right now we are on to part two unfortunately considering only horizontal and vertical doesn't give you the full picture also consider diagonal lines so same deal but this time we have to like start considering diagonal lines which is it turns out a little bit trickier so when we draw a normal when we're drawing a normal line we are just sort of like incrementing in one direction or like kind of going in one direction and filling that out but when we draw a horizontal line which is going to have like the same sort of signature here uh oh so a method signature gosh that's like what the method looks like in terms of its name and what arguments it takes and the return types i don't think i hear that very much in ruby land but i remember it getting drilled into us in computer science um in college was like you have to know what method signature means and so uh yeah i just remember like uh grilling or like drilling on it and then being tested on it for some reason so yeah all right so for drawing a horizontal line what we want to do is we can't we can't use the same we cannot use the same logic here or otherwise we're going to end up covering like a whole square right with like lots of different points so in order to go in just the horizontal line we need to like go in a certain direction um right does that make sense so like otherwise so here we're gonna have like if x is equal to okay else draw horizontal horizontal line with like the same stuff okay so what we want to do is we need to figure out the direction we're going which i think we can do so for the x direction right so if if x1 if if the first point is on like the right side of the grid or whatever um then x 1 might be bigger than x 2. in which case like when we're traversing in the x direction we want to be going backwards or we want to go like down right if x1 is is on the left side then we of x2 then we want to traverse to the right so we want to go up so i think what we want to do here is say something like x direction is like if x one is less than x two then we want this to be one otherwise we want it to be negative one and we wanna do the same thing for y um and then uh what we want to do is we can just use either x1 or x2 or y1 or y2 and use that as kind of like our pointer and we want to say like while x 1 does not equal x2 and y1 does not equal y2 and what we're going to do is we're going to like take the direction that we need to go and we're just going to like increment x1 or y1 until we get to y2 x2 and y2 let me see let me just show you what i'm talking about all right so we're going to say something like x1 plus equals x der and y1 plus equals wider and at each point we need to increment so that we're like actually drawing the line and incrementing or like yeah marking the line so i think we want to do something like uh self at x one y one is equal to or like plus equals one and then we need to do the same thing after we increment i think i don't know let's write a test so let's comment this whole thing out uh and then we will write a test here because this yeah i'm like less confident that this is gonna actually work uh as expected so um let's try it yeah so increments the grid across a um diagonal line and so we're going to go from 0 0 to 2 2 which means that we should end up with uh one one zero zero all right so we'll run the test draw horizontal line isn't a thing that's true because it's not a thing draw all right so draw a horizontal line okay all right we got that okay so it didn't draw anything that's right okay so let's just try commenting it in and just hope that i got it right the first time uh wrong number of uh arguments given one expected two expected two what uh oh okay so somewhere self uh somewhere where we're drawing lines probably here or something oh you know what this is expecting this format yep yep okay all right tests are all passing fantastic all right now this is where it gets interesting draw a horizon a diagonal line um down or something and we'll put 2 2 first or maybe let's go the other direction and we'll draw it um let's draw it from like this corner back to this corner so this is like zero two to two zero and that should fail because it should be one one zero and it totally works okay so now we should be ready to draw all of our lines and yeah so let's try with example input first and i think that is what our output looks like here for part two so that's looking pretty good and our answer was 12 and the answer here was 12. all right let's try it with our actual input and eighteen thousand eight sixty four eighteen thousand eight sixty four all right so that's it that is how we draw lines across the ocean floor to find hydrothermal vents uh this has been uh day five of the advent of code thanks a ton for watching i guess like the yeah a couple of the couple of interesting things that we learned here is is what so we went over splitting and i guess yeah like the a factory method which is like a class method on a class which returns an instance of that same class sometimes referred to as a factory method um also something interesting that i i don't know if you if you all do this but i put my class methods above my sort of macros or adder reader stuff and then my initialize method and then some yeah my overloaded operators i guess that was another thing we talked about here is overloaded operator square bracket operator and then this up to method is kind of fun up two is like you can start at any lower number and count up to some other number that's pretty neat did some ternary operations um array destructuring destructuring that's part of a block argument so this is a block that takes something like a 2d array and we're breaking it down into all the different subcomponents so that's kind of cool yeah all right thanks so much for watching and we'll see in the next one [Music]
Info
Channel: CJ Avilla
Views: 74
Rating: undefined out of 5
Keywords: cjav_dev, web development tutorials, web development for beginners, vim, ruby, rails, array destructuring, advent of code, advent of code 2021, operator overloading
Id: pZC0Bgf-UNc
Channel Id: undefined
Length: 31min 1sec (1861 seconds)
Published: Fri Dec 10 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.