Ho, ho, ho! It’s almost Christmas time and I don’t know about you, but I can’t wait for it! And what can be a better way of killing the waiting time (advent!) than participating in excellent Advent od Code. Big thanks to Colin Fay for telling me about it! It’s a series of coding riddles, one published every day between 1st and 25th of December. The riddles increase in difficulty level over time and they can be solved in any programming language, including R. After you’ve solved the first riddle of the day, the second one – a more difficult one – will be unlocked.
This post starts a (rather short) series of posts with my R take on Advent of Code. I present only the first riddle of a day and only those riddles that I managed to solve. I present the final solution and not a journey of how I got there. If I was to give you one piece of advice on how to solve the puzzles it would be:
ALWAYS start developing your solution using examples provided in the puzzle descriptions before you move on to applying it to the final puzzle sample.
These examples give you a very good – even if simplified – idea of what the challenge is really about and the chances are that if your solution works on the example data, so it will on the final dataset.
Finally, feel free to leave comments on other (faster? more elegant?) ways of solving it. Thanks!
Day 1 Puzzle
Here’s the original text of the riddle:
After feeling like you’ve been falling for a few minutes, you look at the device’s tiny screen. “Error: Device must be calibrated before first use. Frequency drift detected. Cannot maintain destination lock.” Below the message, the device shows a sequence of changes in frequency (your puzzle input). A value like +6 means the current frequency increases by 6; a value like -3 means the current frequency decreases by 3.
For example, if the device displays frequency changes of +1, -2, +3, +1, then starting from a frequency of zero, the following changes would occur:
Current frequency 0, change of +1; resulting frequency 1.
Current frequency 1, change of -2; resulting frequency -1.
Current frequency -1, change of +3; resulting frequency 2.
Current frequency 2, change of +1; resulting frequency 3.
In this example, the resulting frequency is 3. Starting with a frequency of zero, what is the resulting frequency after all of the changes in frequency have been applied?
So what is it really saying? That basically we need to add all of the numbers from the sample together to get the solution. Sounds easy! But is it…?
Let’s load the packages we’ll need:
library(stringr) library(dplyr) library(tibble)
And let’s have a look at the puzzle input, what does it look like?
## chr "\n +11\n +14\n +10\n -8\n -13\n -2\n +8\n +14\n -11\n -4\n +2\n -17\n -15\n -12\n -15\n -16\n "| __truncated__
OK, not too clean. It’s a character vector of positive and negative integers separated tabs and new lines. Something I learnt during The Advent of Code is: there’s nothing that
strsplit() wouldn’t solve… 🙂 Just keep in mind that this function always returns a list, so we have to deal with it accordingly (i.e. use good old
unlist()). In the following step I split the values by tabs and remove new lines, trim trolling spaces and bring the result to the vector format again.
# separate a character string into a vector of character numbers with + or - base <- strsplit(changes, '\t') %>% # splt by Tab str_replace_all('\n', '') %>% # remove all new lines stringr::str_trim() %>% # trim edges strsplit(' ') %>% # split by spaces unlist() # get to vector format # check if it is a vector glimpse(base)
## chr [1:2071] "+11" "" "+14" "" "+10" "" "-8" "" "-13" "" "-2" "" "+8" ...
We still see that there are some empty strings left, but once we get rid of them, we can turn the input to numeric and simply add it all up:
# generate a solution base[nchar(base)>0] %>% # remove empty character strings as.numeric() %>% # turn into numeric sum() # add it up
##  402
And that’s it! First challenge done and you already can see how addictive it can become.. 🙂