2020-12-07 17:06:30 -08:00

#### 69 lines 1.2 KiB Crystal Raw Permalink Blame History

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