Day 6: Lanternfish

Click for Problem Statement

Back to 2021


library(tidyverse)
library(here)
path_data <- here("2021/inputs/06-input.txt")
input <- tibble(x = read_lines(path_data))
raw <- input %>% 
  mutate(x = str_split(x, ",")) %>% 
  pull(x)

fish <-  as.numeric(raw[[1]])

fish
##   [1] 2 5 2 3 5 3 5 5 4 2 1 5 5 5 5 1 2 5 1 1 1 1 1 5 5 1 5 4 3 3 1 2 4 2 4 5 4 5 5 5 4 4 1 3
##  [45] 5 1 2 2 4 2 1 1 2 1 1 4 2 1 2 1 2 1 3 3 3 5 1 1 1 3 4 4 1 3 1 5 5 1 5 3 1 5 2 2 2 2 1 1
##  [89] 1 1 3 3 3 1 4 3 5 3 5 5 1 4 4 2 5 1 5 5 4 5 5 1 5 4 4 1 3 4 1 2 3 2 5 1 3 1 5 5 2 2 2 1
## [133] 3 3 1 1 1 4 2 5 1 2 4 4 2 5 1 1 3 5 4 2 1 2 5 4 1 5 5 2 4 3 5 2 4 1 4 3 5 5 3 1 5 1 3 5
## [177] 1 1 1 4 2 4 4 1 1 1 1 1 3 4 5 2 3 4 5 1 4 1 2 3 4 2 1 4 4 2 1 5 3 4 1 1 2 2 1 5 5 2 5 1
## [221] 4 4 2 1 3 1 5 5 1 4 2 2 1 1 1 5 1 3 4 1 3 3 5 3 5 5 3 1 4 4 1 1 1 3 3 2 3 1 1 1 5 4 2 5
## [265] 3 5 4 4 5 2 3 2 5 2 1 1 1 2 1 5 3 5 1 4 1 2 1 5 3 5 2 1 3 1 2 4 5 3 4 3

Part 1

Do it by adding to a vector. Will come back to bite us later.

# decrement the fish
# check for negatives
# reset negatives and add that many new fish

one_day <- function(fish) {
  curr_fish <- fish - 1 # decrement fish by one
  total_negatives <- sum(curr_fish < 0) # count fish that will make new fish
  curr_fish <- replace(curr_fish, curr_fish < 0, 6) # reset fish
  curr_fish <- append(curr_fish, rep(8, total_negatives)) # add new fish
  
  return(curr_fish)
}

fish_status <- fish
for (i in seq(80)) {
  fish_status <- one_day(fish_status)
}

length(fish_status)
## [1] 350605

Part 2

Adding to a vector wont work here. Make a dictionary of sorts and update it.

# use dataframe as a dictionary
one_day_better <- function(df) {
  df %>% mutate(
    coming_soon = num_0,
    num_0 = num_1,
    num_1 = num_2,
    num_2 = num_3,
    num_3 = num_4,
    num_4 = num_5,
    num_5 = num_6,
    num_6 = num_7,
    num_7 = num_8,
    
    
    num_8 = coming_soon,
    num_6 = num_6 + coming_soon
  ) %>% 
    mutate(coming_soon = 0)
}

# make a blank dataframe to start
blank <- tibble(x = c(paste("num", seq(0, 8), sep = "_"), "coming_soon"), value = 0) %>% 
  pivot_wider(names_from = x, values_from = value)
# manually find out the starting values
tibble(fish) %>% 
  count(fish)
## # A tibble: 5 × 2
##    fish     n
##   <dbl> <int>
## 1     1    89
## 2     2    50
## 3     3    46
## 4     4    48
## 5     5    67
# update blank to starting conditions
start <- blank %>% 
  mutate(
    num_1 = 89,
    num_2 = 50,
    num_3 = 46,
    num_4 = 48,
    num_5 = 67
  )

# make bunches of lanternfish!
fish_status2 <- start
for (i in seq(256)) {
  fish_status2 <- one_day_better(fish_status2)
}

# add up the big lanternfish population!
fish_status2 %>% 
  pivot_longer(cols = everything()) %>% 
  summarise(total = sum(value))
## # A tibble: 1 × 1
##           total
##           <dbl>
## 1 1592778185024

All Done!

And we have made bunches of lanternfish. Hope you learned something!

How would you do it? What’s your shortcut? Please share!

Till next time!