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