Day 2
R
Author

Liam D. Bailey

Published

December 4, 2021

See my solution for Day 1 here.

## The Data

See the explanation for today’s challenge here.

For day 2, our data are a set of directions that we can use to explore the ocean floor that we mapped out on Day 1. Each row of data contains two pieces of information: the direction to move (e.g. ‘forward’, ‘up’) and the distance (an integer). We’ll load the data in and then separate the direction and distance information.

``````library(readr)

col_names = c("direction", "distance"), show_col_types = FALSE)

``````# A tibble: 6 × 2
direction distance
<chr>        <dbl>
1 forward          8
2 forward          3
3 forward          8
4 down             6
5 forward          3
6 up               6``````

## The Challenges

### Challenge 1

Starting from (0,0) we need to follow each of the directions included in the data and determine our final location. We could simply do this using a for loop (probably the simpler solution), but I wanted to take this opportunity to practice writing recursive functions.

Let’s build a function that runs through the data row by row and recalls itself each time until there is not data left. Unlike in a for loop, we don’t need to define the number of iterations at the beginning, we simply define the conditions under which the function will continue. Of course…we also need to be careful not to create an infinite loop. Our function will take a data input, a vector of start coordinates c(0,0), and three functions that will be applied to the start coordinates (this will be important for challenge 2).

``````move <- function(data, start,
forward_func,
up_func,
down_func){

#Separate the first line of data and the remaining data
input  <- data[1, ]
remain <- data[-1, ]

#Depending on the directions, apply a difference function
new_coord <- switch(input\$direction,
forward = forward_func(start = start, distance = input\$distance),
down = down_func(start = start, distance = input\$distance),
up = up_func(start = start, distance = input\$distance))

#If there are still rows of data remaining, recall the function
if (nrow(remain) > 0) {

Recall(data = remain, start = new_coord,
forward_func = forward_func,
up_func = up_func,
down_func = down_func)

} else {

#If we've gone through all rows of data, return the coordinate
return(new_coord)

}

}``````

We’ll create some very simply input functions that we can feed into our `move()` function.

``````#Write funcs to do each process
#Forward moves on the x axis
forward <- function(start, distance){
start <- start + distance
return(start)
}

#Up will *decrease* depth
up <- function(start, distance){
start <- start - distance
return(start)
}

#Down will *increase* depth
down <- function(start, distance){
start <- start + distance
return(start)
}``````

Now we can run our recursive function.

``````final_position <- move(data = day2_data, start = c(0, 0),
forward_func = forward,
up_func = up,
down_func = down)

#Return the product, which is our answer
prod(final_position, final_position)``````
`` 1383564``

### Challenge 2

For the second challenge, the function used for each direction type has changed. We now also need to deal with an ‘aim’ value that affects our forward movement. This aim value can be the third value in our start vector. Luckily, we’ve already written our recursive function, so this is as simple as substituting in new functions for forward, up, and down.

``````forward_new <- function(start, distance){
start <- start + distance
start <- start + distance*start
return(start)
}

up_new <- function(start, distance){
start <- start - distance
return(start)
}

down_new <- function(start, distance){
start <- start + distance
return(start)
}``````
``````final_position <- move(data = day2_data, start = c(0, 0, 0),
forward_func = forward_new, up_func = up_new, down_func = down_new)

#Return the product, which is our answer
prod(final_position, final_position)``````
`` 1488311643``

By putting in a bit of effort to make a robust function at the beginning we were able to solve both challenges. It’s a good example of how writing good functions can save you a lot of time and effort later on.