66 lines
1.4 KiB
Crystal
66 lines
1.4 KiB
Crystal
require "./common.cr"
|
|
|
|
lines = File.read("day6_input").split("\n")
|
|
lines.pop
|
|
|
|
REGEX = /(\d+), (\d+)/
|
|
coords = lines.map(&.match(REGEX))
|
|
.select { |it| it != nil }
|
|
.map { |match| { match.not_nil![1].to_i32, match.not_nil![2].to_i32 } }
|
|
|
|
def distance(a, b)
|
|
(a[0] - b[0]).abs + (a[1] - b[1]).abs
|
|
end
|
|
|
|
def compute_area(coords, coord)
|
|
visited = Set(Tuple(Int32, Int32)).new
|
|
total = 0
|
|
|
|
coord_queue = Set(Tuple(Int32, Int32)).new
|
|
coord_queue << coord
|
|
|
|
while !coord_queue.empty?
|
|
new_coord = coord_queue.first
|
|
coord_queue.delete new_coord
|
|
|
|
next if visited.includes? new_coord
|
|
visited << new_coord
|
|
|
|
distances = coords.group_by do |coord|
|
|
distance(coord, new_coord)
|
|
end
|
|
min_distance = distances.keys.min
|
|
|
|
next if distances[min_distance].size != 1
|
|
next if distances[min_distance][0] != coord
|
|
|
|
total += 1
|
|
x, y = new_coord
|
|
coord_queue << { x + 1, y }
|
|
coord_queue << { x - 1, y }
|
|
coord_queue << { x, y + 1 }
|
|
coord_queue << { x, y - 1 }
|
|
|
|
if total > 10000
|
|
return 0
|
|
end
|
|
end
|
|
|
|
return total
|
|
end
|
|
|
|
def find_region(coords)
|
|
total = 0
|
|
(-11000/2..11000/2).each do |x|
|
|
(-11000/2..11000/2).each do |y|
|
|
coord = {x, y}
|
|
total += 1 if coords.sum { |it| distance(it, coord) } < 10000
|
|
end
|
|
end
|
|
|
|
return total
|
|
end
|
|
|
|
puts coords.max_of { |it| compute_area(coords, it) }
|
|
puts find_region(coords)
|