Run
aoc_source(day = 1, part = 1)
input = aoc_read(day = 1)
aoc_run(solve_day1_part1(input))
Elapsed: 0.008 seconds
Memory: 71 KB
Day 1 Day 2 Day 3 Day 4 Day 5 Day 6 Day 7 Day 8 Day 9 Day 10 Day 11 Day 12 Day 13 Day 14 Day 15 Day 16
#' Compare the differences between 2 lists
#'
#' A friendly opener! We parse the input text as 2 lists of numbers and sort
#' them. Then we take the sum of the absolute differences between pairs.
#'
#' @param input
#' A character vector with 2 numbers per string
#'
#' @return
#' The sum of absolute differences between the sorted lists
solve_day1_part1 <- function(input) {
# extract to 2 vectors for ease of operations
lists <- strsplit(input, " +")
first_list <- lapply(lists, \(x) x[[1]])
second_list <- lapply(lists, \(x) x[[2]])
# sort so that we pair up the smallest number in the left list with the
# smallest number in the right list etc.
first_list <- sort(as.numeric(first_list))
second_list <- sort(as.numeric(second_list))
# we want the absolute distance
# it doesn't matter which list has the larger number
distances <- abs(second_list - first_list)
sum(distances)
}
aoc_source(day = 1, part = 1)
input = aoc_read(day = 1)
aoc_run(solve_day1_part1(input))
Elapsed: 0.008 seconds
Memory: 71 KB
#' Score the similarities between 2 lists
#'
#' Parse the input text as 2 lists of numbers. Count the number of occurrences
#' of each item in the first list in the second list. Multiply each number by
#' its count to get the similarity score. Finally sum the score.
#'
#' To count I used the sum of equality between each number in the second
#' list and the number being counted from the first list.
#'
#' @param input
#' A character vector with 2 numbers per string
#'
#' @return
#' The sum of absolute differences between the sorted lists
solve_day1_part2 <- function(input) {
# extract to 2 vectors for ease of operations
lists <- strsplit(input, " +")
first_list <- lapply(lists, \(x) x[[1]])
second_list <- lapply(lists, \(x) x[[2]])
first_list <- as.numeric(first_list)
second_list <- as.numeric(second_list)
# This time we need to count how many times a number in the first list
# occurs in the second list. We can do that as the sum of logical equality
# between each number in the second list and the number being counted from
# the first list.
counts <- vapply(first_list, \(num) sum(second_list == num), numeric(1))
similarity_scores <- first_list * counts
sum(similarity_scores)
}
aoc_source(day = 1, part = 2)
input = aoc_read(day = 1)
aoc_run(solve_day1_part2(input))
Elapsed: 0.008 seconds
Memory: 4067 KB
def solve_day1_part1(text):
"""
Compare the differences between 2 lists
Parse the input text as 2 lists of numbers and sort
them. Then take the sum of the absolute differences between pairs.
I imagine it's not too 'pythonic' even for such a simple puzzle. In porting
my R solution with the limited Python that I know, lapply has become list
comprehensions and I've used a for loop to iterate over the 2 lists instead
of a vectorised comparison. Perhaps NumPy could help out there?
Parameters
----------
text : list of str
Where each string contains a number in the first list and a the second
list.
Returns
-------
int
The sum of absolute differences between the sorted lists
"""
# extract to 2 lists of integers for ease of operations
lines = [line.split() for line in text]
first_list = [int(line[0]) for line in lines]
second_list = [int(line[1]) for line in lines]
# sort so that we pair up the smallest number in the left list with the
# smallest number in the right list etc.
first_list.sort()
second_list.sort()
distances = [None] * len(first_list)
# we want the absolute distance
# it doesn't matter which list has the larger number
for i in range(len(first_list)):
distances[i] = abs(second_list[i] - first_list[i])
return(sum(distances))
def solve_day1_part2(text):
"""
Score the similarities between 2 lists
Parse the input text as 2 lists of numbers. Count the number of occurrences
of each item in the first list in the second list. Multiply each number by
its count to get the similarity score. Finally sum the score.
The list count method made this one fairly easy. Again I imagine there is a
slightly slicker way then using a for loop, but not bad to have the basics!
Parameters
----------
text : list of str
Where each string contains a number in the first list and a the second
list.
Returns
-------
int
The sum of absolute differences between the sorted lists
"""
# extract to 2 lists of integers for ease of operations
lines = [line.split() for line in text]
first_list = [int(line[0]) for line in lines]
second_list = [int(line[1]) for line in lines]
counts = [second_list.count(num) for num in first_list]
similarity_scores = [None] * len(first_list)
for i in range(len(first_list)):
similarity_scores[i] = first_list[i] * counts[i]
return(sum(similarity_scores))