Day 17 Conway Cubes
This is my attempt to solve Day 17.
read_lines("samples/day_17_sample.txt")
sample <- read_lines("inputs/day_17_input.txt") actual <-
17.1 Part 1
We can use the R “array” data type for today’s problem: these are n-dimensional vectors. First, let’s create a function to convert our input into a 3 dimensional array.
function(input, dimensions) {
to_array <-if (dimensions < 3) {
stop("dimensions must be at least 3")
}
c("." = 0, "#" = 1)
replacement <-
input %>%
m <- str_extract_all(".", simplify = TRUE) %>%
apply(c(1,2), function(.x) replacement[[.x]])
array(m, dim = c(nrow(m), ncol(m), rep(1, dimensions - 2)))
}
to_array(sample, 3)
## , , 1
##
## [,1] [,2] [,3]
## [1,] 0 1 0
## [2,] 0 0 1
## [3,] 1 1 1
At each iteration we need to increase the size of the state by 1 on every side.
function(state) {
grow_state_3d <- dim(state)
ds <-
array(0, dim = ds + 2)
next_state <-
for (x in 1:ds[[1]]) {
for (y in 1:ds[[2]]) {
for (z in 1:ds[[3]]) {
+ 1, y + 1, z + 1] <- state[x, y, z]
next_state[x
}
}
}
next_state }
We need a function to iterate the states according to the rules.
function(state) {
iterate_state_3d <- grow_state_3d(state)
state <- dim(state)
ds <- state
next_state <-
# helper function to find the bounds of the array in a given dimension:
# make sure we start no lower than 1, and no higher than the size of that dim
function(a, i) max(1, a - 1):min(ds[[i]], a + 1)
gs <-
for (x in 1:ds[[1]]) {
for (y in 1:ds[[2]]) {
for (z in 1:ds[[3]]) {
# get the bounds of the array for the dimensions
gs(x, 1)
xs <- gs(y, 2)
ys <- gs(z, 3)
zs <-# sum the neighbours, subtract the current cell
sum(state[xs, ys, zs]) - state[x, y, z]
e <-# apply rules
if (state[x, y, z] == 1) {
if (e != 2 & e != 3) {
0
next_state[x, y, z] <-
}else {
} if (e == 3) {
1
next_state[x, y, z] <-
}
}
}
}
}# return the iterated state
next_state }
We can build a helper function to run as many iterations as requested:
function(input, n) {
run_n_iterations_3d <-reduce(1:n, ~iterate_state_3d(.x), .init = to_array(input, 3))
}
Now we can check our function runs as expected
%>%
sample run_n_iterations_3d(6) %>%
sum() == 112
## [1] TRUE
And we can run with our actual data
%>%
actual run_n_iterations_3d(6) %>%
sum()
## [1] 368
17.2 Part 2
For part 2 we just need to extend our functions to include a 4th dimension.
function(state) {
grow_state_4d <- dim(state)
ds <-
array(0, dim = ds + 2)
next_state <-
for (x in 1:ds[[1]]) {
for (y in 1:ds[[2]]) {
for (z in 1:ds[[3]]) {
for (w in 1:ds[[4]]) {
+ 1, y + 1, z + 1, w + 1] <- state[x, y, z, w]
next_state[x
}
}
}
}
next_state
}
function(state) {
iterate_state_4d <- grow_state_4d(state)
state <- dim(state)
ds <- state
next_state <-
function(a, i) max(1, a - 1):min(ds[[i]], a + 1)
gs <-
for (x in 1:ds[[1]]) {
for (y in 1:ds[[2]]) {
for (z in 1:ds[[3]]) {
for (w in 1:ds[[4]]) {
gs(x, 1)
xs <- gs(y, 2)
ys <- gs(z, 3)
zs <- gs(w, 4)
ws <-
sum(state[xs, ys, zs, ws]) - state[x, y, z, w]
e <-
if (state[x, y, z, w] == 1) {
if (e != 2 & e != 3) {
0
next_state[x, y, z, w] <-
}else {
} if (e == 3) {
1
next_state[x, y, z, w] <-
}
}
}
}
}
}
next_state
}
function(input, n) {
run_n_iterations_4d <-reduce(1:n, ~iterate_state_4d(.x), .init = to_array(input, 4))
}
We can run with our sample data to test:
%>%
sample run_n_iterations_4d(6) %>%
sum() == 848
## [1] TRUE
And we can run with our actual data:
%>%
actual run_n_iterations_4d(6) %>%
sum()
## [1] 2696
Elapsed Time: 3.306s