2024

— R Day 1 Part 1 —

#' 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)
}
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

— R Day 1 Part 2 —

#' 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)
}
Run
aoc_source(day = 1, part = 2)

input = aoc_read(day = 1)

aoc_run(solve_day1_part2(input))
Elapsed: 0.008 seconds
Memory:  4067 KB

— Python Day 1 Part 1 —

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))
Run
aoc_source(day = 1, part = 1)

input = aoc_read(day = 1)

result = aoc_run("solve_day1_part1(input)")
Elapsed: 0.005 seconds
Memory:  377 KB

— Python Day 1 Part 2 —

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))
Run
aoc_source(day = 1, part = 2)

input = aoc_read(day = 1)

result = aoc_run("solve_day1_part2(input)")
Elapsed: 0.011 seconds
Memory:  357 KB
Back to top