2024: Day 01 Historian Hysteria

loop
grepl
vectors
Published

December 2, 2024

Setup

The original challenge

Chief historian is lost, gotta try to find him. Searched his office, found several lists of places (ID’s) we should look, but the lists don’t align. Need to find out how close they are.

Toggle the code
library(aochelpers)
library(dplyr)
# other options: aoc_input_data_frame(), aoc_input_matrix()
input <- aoc_input_vector(01, 2024)
head(input)
[1] "23238   26034" "94370   90190" "15509   72666" "48816   23909"
[5] "31300   40420" "14729   97519"

TLDR; Solutions

Part 1 ⭐

❓ What is the total distance between your lists?

Toggle the code
p1 <- input |> lines_to_matrix(split = "   ")
c1 <- sort(as.numeric(p1[,1]))
c2 <- sort(as.numeric(p1[,2]))
sum(abs(c1-c2))
[1] 2769675

Part 2 ⭐⭐

❓ Calculate a total similarity score by adding up each number in the left list after multiplying it by the number of times that number appears in the right list.

Toggle the code
multiplier <- rep(0, NROW(p1))
for(i in 1:NROW(p1)){
    multiplier[i] <- grepl(c1[i], c2) |> sum()
}
sum(c1*multiplier)
[1] 24643097

Walkthrough / Explainer

Part 1

Example Data

Data comes in as space separated lists, so I used the lines_to_matrix function from aochelpers

Toggle the code
(exa <- c("3   4", "4   3", "2   5", "1   3", "3   9", "3   3")  |> lines_to_matrix())
     [,1] [,2] [,3] [,4] [,5]
[1,] "3"  " "  " "  " "  "4" 
[2,] "4"  " "  " "  " "  "3" 
[3,] "2"  " "  " "  " "  "5" 
[4,] "1"  " "  " "  " "  "3" 
[5,] "3"  " "  " "  " "  "9" 
[6,] "3"  " "  " "  " "  "3" 

Pair up the smallest number in the left list with the smallest number in the right list, then the second-smallest left number with the second-smallest right number, and so on.

So, take the separation even further and detach the lists into separate vectors, sorted ascendingly.

Toggle the code
ex1 <- sort(as.numeric(exa[,1]))
ex2 <- sort(as.numeric(exa[,5]))

Within each pair, figure out how far apart the two numbers are; you’ll need to add up all of those distances.

Sum the absolute differences

Toggle the code
sum(abs(ex1-ex2))
[1] 11

Matches the example solution.

Part 2

The two lists are pretty different. The Historians can’t agree on where the problem is at, but noticed that some of the ID”s are duplicated. So let’s calculate a similarity score.

_ Calculate a total similarity score by adding up each number in the left list after multiplying it by the number of times that number appears in the right list._

So, use grepl to identify the number of times each element in the first vector appears in the second vector. Since it returns a TRUE/FALSE for ever element, add up the trues using sum. Then loop over all rows, add that as a third vector.

Toggle the code
mult <- rep(0, NROW(exa))
for(i in 1:NROW(exa)){
    mult[i] <- grepl(ex1[i], ex2) |> sum()
}

Now take the first column, and multiply it by the multiplier, then add the result

Toggle the code
sum(ex1*mult)
[1] 31

Matches example.

Session info

Toggle
─ Session info ───────────────────────────────────────────────────────────────
 setting  value
 version  R version 4.4.1 (2024-06-14)
 os       macOS Sonoma 14.6.1
 system   aarch64, darwin20
 ui       X11
 language (EN)
 collate  en_US.UTF-8
 ctype    en_US.UTF-8
 tz       America/Los_Angeles
 date     2024-12-02
 pandoc   3.1.11 @ /Applications/RStudio.app/Contents/Resources/app/quarto/bin/tools/aarch64/ (via rmarkdown)

─ Packages ───────────────────────────────────────────────────────────────────
 package    * version    date (UTC) lib source
 aochelpers * 0.1.0.9000 2024-12-02 [1] Github (EllaKaye/aochelpers@d4ccd91)
 dplyr      * 1.1.4      2023-11-17 [1] CRAN (R 4.4.0)

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

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