2022-11-26 — 2 min read

Advent of Code 2015, Day 4 – In Ruby

Let’s solve the fourth puzzle of 2015!

The first half of the puzzle

Santa needs help mining some AdventCoins (very similar to bitcoins) to use as gifts for all the economically forward-thinking little girls and boys.

To do this, he needs to find MD5 hashes which, in hexadecimal, start with at least five zeroes. The input to the MD5 hash is some secret key (your puzzle input, given below) followed by a number in decimal. To mine AdventCoins, you must find Santa the lowest positive number (no leading zeroes: 1, 2, 3, …) that produces such a hash.

For example:

  • If your secret key is abcdef, the answer is 609043, because the MD5 hash of abcdef609043 starts with five zeroes (000001dbbfa…), and it is the lowest such number to do so.
  • If your secret key is pqrstuv, the lowest number it combines with to make an MD5 hash starting with five zeroes is 1048970; that is, the MD5 hash of pqrstuv1048970 looks like 000006136ef….

It seems easy: since we need the lowest positive number, we need to iterate over the range, starting with 1, and check each one whether it satisfies the condition. We can’t skip any number: from the point of view of the input, the MD5 hash is random, we can’t guess what it will be, unless we calculate it.

The solution:

#!/usr/bin/env ruby

require 'digest'

secret = ARGV.first
num = 0

num += 1 until Digest::MD5.hexdigest(secret + num.to_s).start_with? "00000"

puts "Lowest number to produce the required hash: #{num}"
puts "Hash: #{Digest::MD5.hexdigest(secret + num.to_s)}"

I’m using Ruby’s handy Digest::MD5 class to calculate the MD5 hashes, then use the returned String’s start_with? method to check whether it starts with five zeroes.

The second half of the puzzle

Now find one that starts with six zeroes.

The solution:

#!/usr/bin/env ruby

require 'digest'

secret = ARGV.first
num = 0

num += 1 until Digest::MD5.hexdigest(secret + num.to_s).start_with? "000000"

puts "Lowest number to produce the required hash: #{num}"
puts "Hash: #{Digest::MD5.hexdigest(secret + num.to_s)}"

It’ll take a lot more time to find this one, but the only change is an additional zero in the string that’s checked against the hash.

The code is available in the GitHub repo.

Thanks for reading! If you have any comments, additions, or corrections, feel free to reach me via e-mail.

Copyright © 2023 csm.hu
Contact