AdventOfCode-2019/day10.cr

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