Advent Of Code Day 3
Third day of Advent of Code. During undergrad, my favourite comment I got on an assignment was ‘This code should be taken out and be shot’1. I feel like my solution for Day 3 is another example of this.
I started out with good intentions. I wanted to create a list of tuples showing where the wires went, take the intersection, then calculate the distances. But I couldn’t work out how to generate a list of tuples. And then my OR background kicked in and I thought matrices, they are nice. Lets make matrices of the path.
A matrix was a solution. But they are very big, break if the path goes outside their bounds, slow and lots of wasted memory. This is one of the problems I would like to go back and resolve once I have a better handle on R funamentals.
In the meantime, I’m reading R for data science and properly understanding these R solution for day 3 - solution 1 and –(solution 2)[https://www.reddit.com/r/adventofcode/comments/e5bz2w/2019_day_3_solutions/?utm_source=share&utm_medium=web2x)__. My other big learning is to develop with the example as input: it is much quicker to debug if you don’t need to load up a 30,000x30,000 matrix.
ibrary(tidyr)
library(dplyr)
library(purrr)
define_directions <- function(direction, value)
{
if (direction == 'R'){
movement <- c(0, value)
}
else if (direction == 'L'){
movement <- c(0, -1*value)
}
else if (direction =='U'){
movement <- c(value, 0)
}
else if (direction == 'D'){
movement <- c(-1*value, 0)
}
else{
print('Unknown direction')
}
movement
}
manhatten <- function(pos1, pos2)
{
abs(pos1[1] - pos2[1]) + abs(pos1[2] - pos2[2])
}
# There is a warning message saying incomplete final line, but comparing the lengths it it fine
steps <- data.frame(t(read.table('day3.txt', sep=',',header=FALSE, row.name=c('wire1', 'wire2'))))
steps <- steps %>% separate(wire1,
into=c('wrire1_dir', 'wire1_steps'),
sep="(?<=[A-Z])(?=[0-9])",
convert=TRUE)
steps <- steps %>% separate(wire2,
into=c('wrire2_dir', 'wire2_steps'),
sep="(?<=[A-Z])(?=[0-9])",
convert=TRUE)
current_pos = c(0,0)
#steps <-
#cal <- purrr::map2(steps$wire1_dir, steps$wire1_steps, define_dire
matrix_size <- 30000
#matrix_size <-20
wire1_path <- matrix(0L, nrow = matrix_size, ncol = matrix_size)
wire2_path <- matrix(0L, nrow = matrix_size, ncol = matrix_size)
centre_point <- c(matrix_size/2, matrix_size/2)
wire1_last_position <- centre_point
wire2_last_position <- centre_point
wire1_path[wire1_last_position] <- -1
wire2_path[wire2_last_position] <- -1
wire1_steps <- 0
wire2_steps <- 0
for(row in 1:nrow(steps))
{
wire1_move <- wire1_last_position + define_directions(steps[row, 'wrire1_dir'], steps[row, 'wire1_steps'])
wire2_move <- wire2_last_position + define_directions(steps[row, 'wrire2_dir'], steps[row, 'wire2_steps'])
# Setting all the posisitions transversed in the last move to 1
wire1_path[wire1_last_position[1]:wire1_move[1], wire1_last_position[2]:wire1_move[2]] <- pmin(wire1_steps + 0:steps[row, 'wire1_steps'])
wire2_path[wire2_last_position[1]:wire2_move[1], wire2_last_position[2]:wire2_move[2]] <- pmin(wire2_steps + 0:steps[row, 'wire2_steps'])
print(wire1_steps + 0:steps[row, 'wire1_steps'])
wire1_steps <- wire1_steps + steps[row, 'wire1_steps']
wire2_steps <- wire2_steps + steps[row, 'wire2_steps']
wire1_last_position <- wire1_move
wire2_last_position <- wire2_move
}
#
min_dist_manhat = 10000000000
min_dist_steps = 10000000000
for(row in 1:matrix_size)
{
for(col in 1:matrix_size)
{
if(wire1_path[row, col]>0 & wire2_path[row, col] >0 & row != centre_point[1] & col != centre_point[2])
{
dist <- manhatten(centre_point, c(row, col))
min_dist_manhat <- min(c(dist, min_dist_manhat))
dist <- wire1_path[row, col] + wire2_path[row, col]
min_dist_steps <- min(c(dist, min_dist_steps))
}
}
}
# Part 1
print(min_dist_manhat)
# Part 2
print(min_dist_steps)
-
Don’t try to write your own shuffle algorithm. Fisher-Yates is your friend ↩