Last updated: 2017-12-02

Code version: 038d1ad

See more puzzles

Advent of Code

Session information

sessionInfo()
R version 3.4.2 (2017-09-28)
Platform: x86_64-apple-darwin15.6.0 (64-bit)
Running under: macOS Sierra 10.12.6

Matrix products: default
BLAS: /Library/Frameworks/R.framework/Versions/3.4/Resources/lib/libRblas.0.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/3.4/Resources/lib/libRlapack.dylib

locale:
[1] en_GB.UTF-8/en_GB.UTF-8/en_GB.UTF-8/C/en_GB.UTF-8/en_GB.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

loaded via a namespace (and not attached):
 [1] compiler_3.4.2  backports_1.1.0 magrittr_1.5    rprojroot_1.2  
 [5] tools_3.4.2     htmltools_0.3.6 yaml_2.1.14     Rcpp_0.12.13   
 [9] stringi_1.1.5   rmarkdown_1.8   knitr_1.17      git2r_0.19.0   
[13] stringr_1.2.0   digest_0.6.12   evaluate_0.10.1

Brief

As you walk through the door, a glowing humanoid shape yells in your direction. “You there! Your state appears to be idle. Come help us repair the corruption in this spreadsheet - if we take another millisecond, we’ll have to display an hourglass cursor!”

The spreadsheet consists of rows of apparently-random numbers. To make sure the recovery process is on the right track, they need you to calculate the spreadsheet’s checksum. For each row, determine the difference between the largest value and the smallest value; the checksum is the sum of all of these differences.

For example, given the following spreadsheet:

5 1 9 5
7 5 3
2 4 6 8

The first row’s largest and smallest values are 9 and 1, and their difference is 8. The second row’s largest and smallest values are 7 and 3, and their difference is 4. The third row’s difference is 6. In this example, the spreadsheet’s checksum would be 8 + 4 + 6 = 18.

What is the checksum for the spreadsheet in your puzzle input?

Let’s go

Packages & functions

library(tidyverse)
library(testthat)
library(aocodeR)
library(httr)

Input

I get my input directly from the AoC server using aocodeR function aoc_get_input.

input <- aoc_get_input(day = 2, cookie_path = paste0(rprojroot::find_rstudio_root_file(),
                                                 "/secrets/session_cookie.txt"))
input
[1] "409\t194\t207\t470\t178\t454\t235\t333\t511\t103\t474\t293\t525\t372\t408\t428\n4321\t2786\t6683\t3921\t265\t262\t6206\t2207\t5712\t214\t6750\t2742\t777\t5297\t3764\t167\n3536\t2675\t1298\t1069\t175\t145\t706\t2614\t4067\t4377\t146\t134\t1930\t3850\t213\t4151\n2169\t1050\t3705\t2424\t614\t3253\t222\t3287\t3340\t2637\t61\t216\t2894\t247\t3905\t214\n99\t797\t80\t683\t789\t92\t736\t318\t103\t153\t749\t631\t626\t367\t110\t805\n2922\t1764\t178\t3420\t3246\t3456\t73\t2668\t3518\t1524\t273\t2237\t228\t1826\t182\t2312\n2304\t2058\t286\t2258\t1607\t2492\t2479\t164\t171\t663\t62\t144\t1195\t116\t2172\t1839\n114\t170\t82\t50\t158\t111\t165\t164\t106\t70\t178\t87\t182\t101\t86\t168\n121\t110\t51\t122\t92\t146\t13\t53\t34\t112\t44\t160\t56\t93\t82\t98\n4682\t642\t397\t5208\t136\t4766\t180\t1673\t1263\t4757\t4680\t141\t4430\t1098\t188\t1451\n158\t712\t1382\t170\t550\t913\t191\t163\t459\t1197\t1488\t1337\t900\t1182\t1018\t337\n4232\t236\t3835\t3847\t3881\t4180\t4204\t4030\t220\t1268\t251\t4739\t246\t3798\t1885\t3244\n169\t1928\t3305\t167\t194\t3080\t2164\t192\t3073\t1848\t426\t2270\t3572\t3456\t217\t3269\n140\t1005\t2063\t3048\t3742\t3361\t117\t93\t2695\t1529\t120\t3480\t3061\t150\t3383\t190\n489\t732\t57\t75\t61\t797\t266\t593\t324\t475\t733\t737\t113\t68\t267\t141\n3858\t202\t1141\t3458\t2507\t239\t199\t4400\t3713\t3980\t4170\t227\t3968\t1688\t4352\t4168"

Functions

The input from the server is a string encoding a table through delimiters \n for newline and \t for tab (or newcell). So I’ll write a function to convert it to a matrix. Might be useful for future puzzles too.

string_to_matrix <- function(input) {
    split_input <- input %>% strsplit(split = "\n") %>% unlist() %>% strsplit(split = "\t")
    ncol <- split_input  %>% map(length) %>% unlist %>% unique
    if(ncol %>% length > 1){stop("tabs per line unequal")}
    split_input %>% do.call("c", .) %>% as.numeric() %>% matrix(ncol = ncol, byrow = T)    
}

Then I’ve made a couple of function to help me address both part of the challenge


  • get_row_div()

Takes a row and returns the result of the division of the only two evenly divisibles in the row.

get_row_div <- function(row){
    row_div <- map(row, function(x){ x/row }) %>% unlist %>% 
        magrittr::extract(.>1 & . == as.integer(.))
    if(length(row_div) == 0){ 1 }else{ row_div }
}
  • get_checksum()

Applies whatever computation metric is required on each row and returns the sum

get_checksum <- function(mat, compute_mode = "diffs") {
  mat %>% apply(1, FUN = switch(compute_mode,
                                "diffs" = function(x){x %>% na.omit %>% range %>% diff},
                                "divs" = get_row_div)) %>% sum
}

Test

# create the example matrix to test
test_matrix <- matrix(c(5, 1, 9, 5, 7, 5, 3, NA, 2, 4, 6, 8), ncol = 4, byrow = T)
expect_equal(get_checksum(test_matrix, compute_mode = "diffs"), 18)

deploy

matrix <- string_to_matrix(input)
get_checksum(matrix)
[1] 44887

Success!



—- Part 2 —-

Brief

“Great work; looks like we’re on the right track after all. Here’s a star for your effort.” However, the program seems a little worried. Can programs be worried?

“Based on what we’re seeing, it looks like all the User wanted is some information about the evenly divisible values in the spreadsheet. Unfortunately, none of us are equipped for that kind of calculation - most of us specialize in bitwise operations.”

It sounds like the goal is to find the only two numbers in each row where one evenly divides the other - that is, where the result of the division operation is a whole number. They would like you to find those numbers on each line, divide them, and add up each line’s result.

For example, given the following spreadsheet:

5 9 2 8
9 4 7 3
3 8 6 5

In the first row, the only two numbers that evenly divide are 8 and 2; the result of this division is 4. In the second row, the two numbers are 9 and 3; the result is 3. In the third row, the result is 2. In this example, the sum of the results would be 4 + 3 + 2 = 9.

What is the sum of each row’s result in your puzzle input?

Let’s go

Functions

Test

test_matrix2 <- matrix(c(5, 9, 2, 8, 9, 4, 7, 3, 3, 8, 6, 5), ncol = 4, byrow = T)
expect_equal(get_checksum(test_matrix2, compute_mode = "divs"), 9)

Test the case when the only divisibles result from duplicates

test_matrix3 <- matrix(c(5, 9, 8, 8, 9, 4, 7, 3, 3, 8, 6, 5), ncol = 4, byrow = T)
expect_equal(get_checksum(test_matrix3, compute_mode = "divs"), 6)

deploy

get_checksum(matrix, compute_mode = "divs")
[1] 242

Success!



template based on the workflowr standalone template