2022-11-27 — 3 min read

Advent of Code 2015, Day 5 – In Ruby

This is day 5 of 2015.

The first half of the puzzle

Santa needs help figuring out which strings in his text file are naughty or nice.

A nice string is one with all of the following properties:

  • It contains at least three vowels (aeiou only), like aei, xazegov, or aeiouaeiouaeiou.
  • It contains at least one letter that appears twice in a row, like xx, abcdde (dd), or aabbccdd (aa, bb, cc, or dd).
  • It does not contain the strings ab, cd, pq, or xy, even if they are part of one of the other requirements.

For example:

  • ugknbfddgicrmopn is nice because it has at least three vowels (u…i…o…), a double letter (…dd…), and none of the disallowed substrings.
  • aaa is nice because it has at least three vowels and a double letter, even though the letters used by different rules overlap.
  • jchzalrnumimnmhp is naughty because it has no double letter.
  • haegwjzuvuyypxyu is naughty because it contains the string xy.
  • dvszwmarrgswjxmb is naughty because it contains only one vowel.

How many strings are nice?

The solution:

#!/usr/bin/env ruby

f = File.read(ARGV.first)
nice_strings = 0

f.each_line do |line|
  next unless line =~ /[aeiou].*[aeiou].*[aeiou]/
  next unless line =~ /(\w)\1/
  next if line =~ /ab|cd|pq|xy/
  nice_strings << line
end

puts "Number of nice strings: #{nice_strings}"

This puzzle calls for regular expressions. We’ll loop over the input line-by-line, check each of the three conditions in turn, and if either of the conditions isn’t met, we skip to the next input line. Once we find a line that satisfies every condition, we increase the nice_strings counter. At the end, we print the result.

A bit about the regular expressions:

The second half of the puzzle

Realizing the error of his ways, Santa has switched to a better model of determining whether a string is naughty or nice. None of the old rules apply, as they are all clearly ridiculous.

Now, a nice string is one with all of the following properties:

  • It contains a pair of any two letters that appears at least twice in the string without overlapping, like xyxy (xy) or aabcdefgaa (aa), but not like aaa (aa, but it overlaps).
  • It contains at least one letter which repeats with exactly one letter between them, like xyx, abcdefeghi (efe), or even aaa.

For example:

  • qjhvhtzxzqqjkmpb is nice because is has a pair that appears twice (qj) and a letter that repeats with exactly one letter between them (zxz).
  • xxyxx is nice because it has a pair that appears twice and a letter that repeats with one between, even though the letters used by each rule overlap.
  • uurcxstgmygtbstg is naughty because it has a pair (tg) but no repeat with a single letter between them.
  • ieodomkazucvgmuy is naughty because it has a repeating letter with one between (odo), but no pair that appears twice.

How many strings are nice under these new rules?

The solution:

#!/usr/bin/env ruby

f = File.read(ARGV.first)
nice_strings = 0

f.each_line do |line|
  next unless line =~ /(\w\w).*\1/
  next unless line =~ /(\w).\1/
  nice_strings += 1
end

puts "Number of nice strings: #{nice_strings}"

This part is also about regular expressions. For these new rules, we’ll use slight variations of the second regexp from the first part:

The code with my input text 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