1 minute read

Parts 1 and 2

The result of part 1 and 2 are returned by the list.

I wasted quite a bit of time on this puzzle, as I was implementing the redistribution incorrectly at first. Once again this is not very elegant, I’m sure there are ways to improve the computing speed and clarity of the code.xs

puzzle_input <- c("4	10	4	1	8	4	9	14	5	1	14	15	0	15	3	5")
puzzle_input <- as.numeric(unlist(strsplit(puzzle_input, "\\t")))

## x: value to distribute
## n: number of elements to distribute it over
allocate <- function(x, n) {
    res <- integer(n)
    pos <- 1
    i <- 1
    while (i <= x && sum(res) < x) {
        res[pos] <- res[pos] + 1
        pos <- pos + 1
        if (pos == n + 1) pos <- 1
        i <- i + 1
    }
    res
}

count_cycles <- function(input) {
    
    step <- 0
    visited <- character(0)
    while (!paste(input, collapse = " ") %in% visited) {
        visited <- c(visited, paste(input, collapse = " "))
        
        max_i <- which.max(input)

        to_distribute <- allocate(input[max_i], length(input))

        ## reorder the distribution
        offset <- length(input) - max_i
        if (offset != 0) {
            to_distribute <- c(tail(to_distribute, -offset),
                               head(to_distribute, offset))
        }
        
        input[max_i] <- 0
        input <- input + to_distribute
        step <- step + 1
    }
    list(
        steps = step,
        loop_size = (step - which(paste(input, collapse = " ") == visited)) + 1
    )
    
}


count_cycles(c(0, 2, 7, 0))
## $steps
## [1] 5
## 
## $loop_size
## [1] 4
count_cycles(puzzle_input)
## $steps
## [1] 12841
## 
## $loop_size
## [1] 8038

Comments