2021 Day 25

Author

Nathan Moore

— Day 25: Sea Cucumber —

The floor is just there, but it is covered in sea cucumbers.

Find somewhere safe to land your submarine. What is the first step on which no sea cucumbers move?

library(tidyverse)

my_file <- here::here("2021", "data-2021-25.txt")
x <- readLines(my_file)

Loop a little to make sure we are moving properly, and then let the cucumbers move.

# prepare an array
cuc_width = nchar(x[[1]])
cuc_length = length(x)

cuc = stringr::str_split_fixed(x, "", cuc_width)

Test and move

counter = 0

while (counter < 1) {
    movement = 0
    counter = counter + 1
    
    # test the easterly cucumbers: >
    for (i in seq(1,cuc_length)) {
        for (j in seq(1,cuc_width)) {
            if (cuc[i,j] == ">") {
                if (j == cuc_width) {
                    # if we're at the end of the row, check back
                    if (cuc[i,1] == ".") {
                        cuc[i,j] = "."
                        cuc[i,1] = ">"
                        movement = movement + 1      
                        
                    }
                } else {
                    # check the next cell
                    if (cuc[i,j+1] == ".") {
                        cuc[i,j] = "."
                        cuc[i,j+1] = ">"
                        movement = movement + 1                        
                    }                      
                }
             
            }
        }
    }        

    # test the southerly cucumbers: v 
    for (j in seq(1,cuc_width)) {
        for (i in seq(1,cuc_length)) {
#    for (i in seq(1,cuc_length)) {
#        for (j in seq(1,cuc_width)) {
            if (cuc[i,j] == "v") {
                if (i == cuc_length) {
                    # we're at the bottom, check the top
                    if (cuc[1,j] == ".") {
                        cuc[i,j] = "."
                        cuc[1,j] = "v"
                        movement = movement + 1                        
                    }
                } else {
                    # test for space
                    if (cuc[i+1,j] == ".") {
                        cuc[i,j] = "."
                        cuc[i+1,j] = "v"
                        movement = movement + 1                        
                    }                    
                }
            }

        }
    }   
    
    if (movement == 0) { 
        break
    }
    # print(movement)
}
    
# 462 too high
# 448 too high 

The above catches the cucumbers that have already moved and I don’t think there’s an iteration schema that can move without collecting them, unless I iterate backwards? But that let’s them move if they should be blocked.

So, which for an efficient loop of where they are, collecting possible moves.

counter = 0

while (counter < 1000) {

    # Easterly Cucumbers
    east = which(cuc == ">", arr.ind = TRUE)
    east = cbind(east, FALSE)
    # print(nrow(east))
        
    for (e in seq_len(nrow(east))) {
        if (east[e,2] == cuc_width) {
            # check the start of the row
            if (cuc[east[e,1], 1] == ".") {
                east[e,3] = TRUE
            }
        } else if (cuc[east[e,1], east[e,2]+1] == ".") {
            # if we can move, add it to moves
            east[e,3] = TRUE
        }
    }
    
    # move only the ones that we think can move
    east = subset(east, east[,3] == TRUE)
    
    # do moves
    for (m in seq_len(nrow(east))) {
        # do the moves
        if (east[m,2] == cuc_width) {
            cuc[east[m,1], 1] = ">"
            cuc[east[m,1], east[m,2]] = "."
        } else {
            cuc[east[m,1], east[m,2]+1] = ">"
            cuc[east[m,1], east[m,2]] = "."
        }
    }
    
    # Southerly Cucumbers
    south = which(cuc == "v", arr.ind = TRUE)
    south = cbind(south, FALSE)
    # print(nrow(south))
    
    for (s in seq_len(nrow(south))) {
        if (south[s,1] == cuc_length) {
            # check the top of the column
            if (cuc[1, south[s,2]] == ".") {
                south[s,3] = TRUE
            }
        } else if (cuc[south[s,1] + 1, south[s,2]] == ".") {
            # check for moves
            south[s,3] = TRUE
        }
    }
    
    # moves the ones we want to move  
    south = subset(south, south[,3] == TRUE)
    
    for (m in seq_len(nrow(south))) {
        # do the moves
        if (south[m,1] == cuc_length) {
            cuc[1, south[m,2]] = "v"
            cuc[south[m,1], south[m,2]] = "."
        } else {
            cuc[south[m,1] + 1, south[m,2]] = "v"
            cuc[south[m,1], south[m,2]] = "."
        }
    }
    
    if (nrow(east) + nrow(south) == 0) {
        break
    } else {
        # print(nrow(east) + nrow(south))
        counter = counter + 1
    }
    
}

# 360 someone else's anwer
# 361 incorrect
# 362 incorrect

# we don't move on that last run through - one less