2020: Day 5

tidyverse
binary
base R
Author

Ella Kaye

Published

December 5, 2020

Setup

The original challenge

My data

Part 1

library(tidyverse)

The code below sets starts by setting each row number to 127 and each column number to 7, the maximum they can be, then, working along the string, lowering the maximum (or leaving it as is) one letter at a time:

boarding <- 
  read_tsv(here::here("2020", "day", "5", "input"),
           col_names = FALSE) %>%
  rename(binary = X1)

seat_IDs <- boarding %>%
  mutate(row = 127) %>%
  mutate(col = 7) %>%
  mutate(row = if_else(str_sub(binary, 1, 1) == "F", row - 64, row)) %>%
  mutate(row = if_else(str_sub(binary, 2, 2) == "F", row - 32, row)) %>%
  mutate(row = if_else(str_sub(binary, 3, 3) == "F", row - 16, row)) %>%
  mutate(row = if_else(str_sub(binary, 4, 4) == "F", row - 8, row)) %>%
  mutate(row = if_else(str_sub(binary, 5, 5) == "F", row - 4, row)) %>%
  mutate(row = if_else(str_sub(binary, 6, 6) == "F", row - 2, row)) %>%
  mutate(row = if_else(str_sub(binary, 7, 7) == "F", row - 1, row)) %>%
  mutate(col = if_else(str_sub(binary, 8, 8) == "L", col - 4, col)) %>%
  mutate(col = if_else(str_sub(binary, 9, 9) == "L", col - 2, col)) %>%  
  mutate(col = if_else(str_sub(binary, 10, 10) == "L", col - 1, col)) %>%  
  mutate(ID = row * 8 + col) 

seat_IDs %>%
  summarise(max = max(ID)) %>%
  pull(max)
[1] 963

OK, I know I said in the introduction to this post that I would go with the first solution I think of that gets the right answer, and the above does work, but I’m deeply unhappy with the code. There’s too much repetition, I don’t like the use of subtraction when diving by 2 feels more appropriate in a binary context, and it doesn’t feel like I’ve taken full advantage of the mathematical structure of the problem. So, on further reflection, I realise that the way that ID is defined is essentially turning a binary number into a decimal, where we get the binary number as a string by replacing “B” and “R” by “1” and L” and “F” by “0”. Then, I just found, there is a base R function strtoi() that takes a string of digits in a given base and converts it to a base 10 integer, just what we need:

seat_IDs <- boarding %>%
  mutate(binary = str_replace_all(binary, "L|F", "0")) %>%
  mutate(binary = str_replace_all(binary, "B|R", "1")) %>%
  mutate(ID = strtoi(binary, base = 2)) %>%
  arrange(desc(ID))

seat_IDs %>%
  slice(1) %>%
  pull(ID)
[1] 963

That’s better!

Part 2

We need to find the missing number, so we arrange the IDs in ascending order and look at the gap between each ID and the preceding one. In most cases, that should be one. Where we have a gap of 2, we must have skipped the integer below:

seat_IDs %>%
  arrange(ID) %>%
  mutate(diff = lag(ID)) %>%
  mutate(gap = ID - diff) %>% 
  filter(gap == 2) %>%
  summarise(my_seat = ID - 1) %>%
  pull(my_seat)
[1] 592

Session info

Toggle
─ Session info ───────────────────────────────────────────────────────────────
 setting  value
 version  R version 4.3.1 (2023-06-16)
 os       macOS Sonoma 14.0
 system   aarch64, darwin20
 ui       X11
 language (EN)
 collate  en_US.UTF-8
 ctype    en_US.UTF-8
 tz       Europe/London
 date     2023-11-06
 pandoc   3.1.1 @ /Applications/RStudio.app/Contents/Resources/app/quarto/bin/tools/ (via rmarkdown)
 quarto   1.4.466 @ /usr/local/bin/quarto

─ Packages ───────────────────────────────────────────────────────────────────
 package     * version date (UTC) lib source
 dplyr       * 1.1.2   2023-04-20 [1] CRAN (R 4.3.0)
 forcats     * 1.0.0   2023-01-29 [1] CRAN (R 4.3.0)
 ggplot2     * 3.4.2   2023-04-03 [1] CRAN (R 4.3.0)
 lubridate   * 1.9.2   2023-02-10 [1] CRAN (R 4.3.0)
 purrr       * 1.0.1   2023-01-10 [1] CRAN (R 4.3.0)
 readr       * 2.1.4   2023-02-10 [1] CRAN (R 4.3.0)
 sessioninfo * 1.2.2   2021-12-06 [1] CRAN (R 4.3.0)
 stringr     * 1.5.0   2022-12-02 [1] CRAN (R 4.3.0)
 tibble      * 3.2.1   2023-03-20 [1] CRAN (R 4.3.0)
 tidyr       * 1.3.0   2023-01-24 [1] CRAN (R 4.3.0)
 tidyverse   * 2.0.0   2023-02-22 [1] CRAN (R 4.3.0)

 [1] /Users/ellakaye/Library/R/arm64/4.3/library
 [2] /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/library

──────────────────────────────────────────────────────────────────────────────