AdventOfCode-2018/day10.cr

58 lines
1.4 KiB
Crystal

require "./common.cr"
lines = File.read("day10_input").split "\n"
lines.pop
points = [] of Tuple(Int64, Int64, Int64, Int64)
REGEX = /position=<\s*(-?\d+),\s*(-?\d+)> velocity=<\s*(-?\d+), \s*(-?\d+)>/
lines.map(&.match(REGEX)).each do |match|
match = match.not_nil!
points << { match[1].to_i64, match[2].to_i64, match[3].to_i64, match[4].to_i64 }
end
def max_distance(points)
points.product(points).max_of do |left, right|
(left[0] - right[0]).abs + (left[1] - right[1]).abs
end
end
def simulate(points, multiplier = 1)
points.size.times do |index|
old = points[index]
points[index] = { old[0] + multiplier * old[2], old[1] + multiplier * old[3], old[2], old[3] }
end
end
def print_message(points)
max_x = points.max_of &.[0]
min_x = points.min_of &.[0]
max_y = points.max_of &.[1]
min_y = points.min_of &.[1]
(max_y - min_y + 2).times do |yoff|
(max_x - min_x + 2).times do |xoff|
x = min_x + xoff - 1
y = min_y + yoff - 1
if points.any? { |point| (point[0] == x) && (point[1] == y) }
STDOUT << '▩'
else
STDOUT << '.'
end
end
puts
end
end
d1 = max_distance(points)
simulate(points)
d2 = max_distance(points)
times = (d2 / (d2 - d1)).abs - 10
simulate(points, times)
20.times do |i|
simulate(points, multiplier = 1)
print_message(points)
puts "^ #{times + 1 + i + 1}"
end