69 lines
1.2 KiB
Crystal
69 lines
1.2 KiB
Crystal
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
|