library(tidyverse)
2020: Day 5
Setup
Part 1
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)
<- boarding %>%
seat_IDs 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:
<- boarding %>%
seat_IDs 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
──────────────────────────────────────────────────────────────────────────────