library(tidyverse)
input <- read_lines(file = "inputs/2016/01.txt")Day 1: No Time for a Taxicab
Part One
# extract direction and length from input (first entry NA)
move <- c(NA, str_split_1(string = input, pattern = ", "))
turn <- str_extract(string = move, pattern = "L|R")
length <- str_extract(string = move, pattern = "[0-9]+") |> as.integer()
# pre-allocate vectors for x/y-positions and x/y-direction
position_x <- integer(length = length(move))
position_y <- integer(length = length(move))
direction_x <- integer(length = length(move))
direction_y <- integer(length = length(move))
# initialize position and direction (everything is pre-populated as 0)
# position_x[1] <- 0
# position_y[1] <- 0
#
# direction_x[1] <- 0
direction_y[1] <- 1L
change_direction <- function(current_direction, turn) {
if (turn == "R") new_direction <- rev(current_direction) * c(1L, -1L)
if (turn == "L") new_direction <- rev(current_direction) * c(-1L, 1L)
return(new_direction)
}
# calculate directions and positions
for (i in 2:length(move)) {
# get current x/y-direction
current_direction <- c(direction_x[i-1], direction_y[i-1])
# calculate new direction
new_direction <- change_direction(current_direction, turn[i])
# update values
direction_x[i] <- new_direction[1]
direction_y[i] <- new_direction[2]
# get current x/y-position
current_position <- c(position_x[i-1], position_y[i-1])
# calculate new position
new_position <- current_position + new_direction * length[i]
# update values
position_x[i] <- new_position[1]
position_y[i] <- new_position[2]
}
# collect all vectors in a table
moves <- tibble(move, turn, length,
direction_x, direction_y,
position_x, position_y) |>
mutate(distance = abs(position_x) + abs(position_y))
# result
moves |>
select(distance) |>
tail(1) |>
pull() |>
cat()
## 288unit_vectors <- list(up = c(0,1),
right = c(1,0),
down = c(0,-1),
left = c(-1, 0))
# right turn
map(.x = unit_vectors, .f = \(vector) change_direction(vector, "R"))
## $up
## [1] 1 0
##
## $right
## [1] 0 -1
##
## $down
## [1] -1 0
##
## $left
## [1] 0 1
# left turn
map(.x = unit_vectors, .f = \(vector) change_direction(vector, "L"))
## $up
## [1] -1 0
##
## $right
## [1] 0 1
##
## $down
## [1] 1 0
##
## $left
## [1] 0 -1Part Two
# change_direction() allows no change in direction
change_direction <- function(current_direction, turn) {
if (turn == "R") new_direction <- rev(current_direction) * c(1L, -1L)
if (turn == "L") new_direction <- rev(current_direction) * c(-1L, 1L)
if (turn == "N") new_direction <- current_direction
return(new_direction)
}
# initialize new turn vector (first entry is NA as before)
turn_unit <- c(NA)
# populate the vector: each turn + No turn for length - 1 times
for(i in seq_along(length)[-1]) {
turn_unit <- c(turn_unit, turn[i], rep("N", times = length[i]-1))
}
# length vector: NA + unit steps
length_unit <- c(NA, rep(1L, times = length(turn_unit) - 1))
# REPEAT WHAT'S DONE IN PART ONE
position_x <- integer(length = length(turn_unit))
position_y <- integer(length = length(turn_unit))
direction_x <- integer(length = length(turn_unit))
direction_y <- integer(length = length(turn_unit))
# initialize position and direction (everything is pre-populated as 0)
# position_x[1] <- 0
# position_y[1] <- 0
#
# direction_x[1] <- 0
direction_y[1] <- 1L
# calculate directions and positions
for (i in 2:length(turn_unit)) {
# get current x/y-direction
current_direction <- c(direction_x[i-1], direction_y[i-1])
# calculate new direction
new_direction <- change_direction(current_direction, turn_unit[i])
# update values
direction_x[i] <- new_direction[1]
direction_y[i] <- new_direction[2]
# get current x/y-position
current_position <- c(position_x[i-1], position_y[i-1])
# calculate new position
new_position <- current_position + new_direction * length_unit[i]
# update values
position_x[i] <- new_position[1]
position_y[i] <- new_position[2]
}
# collect all vectors in a table
moves_unit <- tibble(turn_unit, length_unit,
direction_x, direction_y,
position_x, position_y) |>
mutate(distance = abs(position_x) + abs(position_y))
# results
moves_unit |>
rowid_to_column("time") |>
group_by(position_x, position_y, distance) |>
summarise(count = n(), second_time = nth(time, 2)) |>
filter(count > 1) |>
arrange(second_time) |>
select(distance) |>
head(1) |>
pull() |>
cat()
## 111moves_unit |>
rowid_to_column("time") |>
group_by(position_x, position_y, distance) |>
summarise(count = n(), second_time = nth(time, 2)) |>
filter(count > 1) |>
arrange(second_time)Plot
moves |>
ggplot(mapping = aes(x = position_x, y = position_y)) +
geom_path() +
theme_minimal()