DEV Community

Caleb Weeks
Caleb Weeks

Posted on

Advent of Code #13 (in Crystal)

Similar to yesterday's puzzle, this one was fairly easy to visually inspect, but requires a bit more work to describe algorithmically. Not quite a bad as yesterday, though.

For part 1, I originally took the two halves on either side of each row, reversed one of them and then compared the two using the equality comparison (==). It was easy enough to swap out that equality comparison for a Levenshtein distance, which Crystal conveniently provides in the standard library.

There is still a fair amount of code duplication between parts 1 and 2, but I didn't feel like refactoring it much today.

Here's the code:

require "levenshtein"

input = File.read("input").strip

patterns = input.split("\n\n")

def find_mirror(rows, distance = 0)
  mirror = 0
  (1...rows.size).each do |i|
    edge = Math.min(i, rows.size - i)
    image = rows[i - edge...i].join
    reflection = rows[i...i + edge].reverse.join
    mirror = i if Levenshtein.distance(image, reflection) == distance
  end
  mirror
end

part1 = patterns.reduce(0) do |sum, pattern|
  rows = pattern.split("\n")
  cols = Array.new(rows[0].size, "")
  rows.each do |row|
    row.each_char.with_index do |char, col|
      cols[col] += char
    end
  end
  sum + find_mirror(rows) * 100 + find_mirror(cols)
end

puts part1

part2 = patterns.reduce(0) do |sum, pattern|
  rows = pattern.split("\n")
  cols = Array.new(rows[0].size, "")
  rows.each do |row|
    row.each_char.with_index do |char, col|
      cols[col] += char
    end
  end
  sum + find_mirror(rows, 1) * 100 + find_mirror(cols, 1)
end

puts part2
Enter fullscreen mode Exit fullscreen mode

Top comments (0)