קישור לחידה המקורית:
https://adventofcode.com/2018/day/6
פיתרון בשפת רובי:
class Item
attr_accessor :owner, :x, :y
def distance(ax, ay)
(x - ax).abs + (y - ay).abs
end
def initialize(x, y, owner)
self.x, self.y, self.owner = x, y, owner
end
def to_s
"#{x}, #{y} [#{owner}]"
end
end
class Matrix
attr_accessor :top, :left, :bottom, :right, :data
def initialize
@bottom = -1
@right = -1
@left = Float::INFINITY
@top = Float::INFINITY
@phase = 0
end
def xy_in_game
Enumerator.new do |yielder|
(@right - @left).times do |x|
(@bottom - @top).times do |y|
yielder.yield x + @left, y + @top
end
end
end
end
end
$id = 'A'
matrix = Matrix.new
base = []
ARGF.each_line do |line|
x, y = line.scan(/\d+/).map(&:to_i)
base << Item.new(x, y, $id.dup)
matrix.bottom = y if y > matrix.bottom
matrix.right = x if x > matrix.right
matrix.left = x if x < matrix.left
matrix.top = y if y < matrix.top
$id.next!
end
part1 = {}
part1.default = 0
matrix.xy_in_game.each do |x, y|
closest_to = base.min_by(2) {|b| b.distance(x, y)}
if closest_to[0].distance(x, y) != closest_to[1].distance(x, y)
part1[closest_to[0].owner] += 1
end
end
print "Part 1: ", part1.values.max, "\n"
part2 = 0
matrix.xy_in_game.each do |x, y|
total_distance = base.map {|b| b.distance(x, y)}.sum
if total_distance < 10_000
part2 += 1
end
end
print "Part 2: ", part2, "\n"
הפעם הקוד יצא ארוך, וזה גם התרגיל הראשון השנה שנתקעתי עליו. הבעיה כמובן היתה אני ולא התרגיל - וניסיונות שלי להיות חכם מדי בחלק הראשון במקום לחפש את הדרך הקלה. למרות שבסופו של דבר יצא ארוך יותר מהקודמים אני מרוצה מהפיתרון. אשמח לשמוע מה אתם עשיתם.