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
``````