Skip to main content

Command Palette

Search for a command to run...

Advent of Code 2020: Day 15 (Ruby solution)

Published
1 min read

Today's puzzle is a kind of n-back game.

In this game, the players take turns saying numbers. They begin by taking turns reading from a list of starting numbers (the puzzle input). Then, each turn consists of considering the most recently spoken number:

  • If that was the first time the number has been spoken, the current player says 0.
  • Otherwise, the number had been spoken before; the current player announces how many turns apart the number is from when it was previously spoken.

In the first task, you are asked what would be the 2020th number spoken. Later, you are supposed to check the 30000000th one. If you choose an effective method using an associative array, you can solve both tasks with one function.

My Ruby solution:

def determine_number starting_numbers, nth
  i = starting_numbers.size - 1
  last = starting_numbers.last
  last_spoken = starting_numbers[0..-2].map.with_index { |v, index| {v => index} }.reduce(:merge)
  while i < nth - 1
    prev_last = last
    last = last_spoken.has_key?(prev_last) ? i - last_spoken[prev_last] : 0
    last_spoken[prev_last] = i
    i += 1
  end
  last
end

INPUT = [7, 12, 1, 0, 16, 2].freeze
puts "First task answer: #{determine_number INPUT, 2020}"
puts "Second task answer: #{determine_number INPUT, 30000000}"

More from this blog

R

Ruby Wizards blog

26 posts

I am a full-stack business developer from Poland with a strong interest in DDD. My leading technology is Ruby on Rails.

Contact me at: piotr.jurewicz(you-know-what)rubywizards.com

Advent of Code 2020: Day 15 (Ruby solution)