require "advent" struct Tuple(*T) def reduce_fraction gcd = (self[0].gcd self[1]).abs return self if gcd == 0 {self[0] // gcd, self[1]//gcd} end end struct Tuple(*T) def -(other) {self[0]-other[0], self[1] - other[1]} end end input = input(2019, 10) asteroids = Set({Int32, Int32}).new input.lines.each_with_index do |l, y| l.chars.each_with_index do |c, x| next unless c == '#' asteroids << {x, y} end end p1 = asteroids.max_of do |a| angles = Set({Int32, Int32}).new asteroids.each do |b| next if a == b angles << (b-a).reduce_fraction end angles.size end puts p1 p2s = asteroids.max_by do |a| angles = Set({Int32, Int32}).new asteroids.each do |b| next if a == b angles << (b-a).reduce_fraction end angles.size end angle_groups = asteroids.group_by do |a| (a - p2s).reduce_fraction end angle_groups.delete({0,0}) angle_groups.each do |k, v| v.sort! do |a| (a - p2s).sum end end angles = angle_groups.keys.sort_by do |k| -Math.atan2(k[0].to_f32, k[1].to_f32) end i = 1 angles.cycle do |angle| next if angle_groups[angle].empty? asteroid = angle_groups[angle].delete_at(0) if i == 200 puts asteroid[0] * 100 + asteroid[1] break end i += 1 end