קישור לחידה המקורית:
https://adventofcode.com/2018/day/10
פיתרון בשפת רובי:
class Point
attr_accessor :x, :y, :vx, :vy
def initialize(line)
@x, @y, @vx, @vy =
line.
scan(/position=<\s*([-\d]+),\s*([-\d]+)>\s*velocity=<\s*([-\d]+),\s*([-\d]+)>/).
flatten.
map(&:to_i)
end
def to_s
"position=< #{x}, #{y}> velocity=< #{vx}, #{vy}>"
end
def move
@x += @vx
@y += @vy
end
end
class Canvas
attr_reader :part2
def initialize
@points = []
@index = nil
@part2 = 0
end
def top
@points.min_by {|point| point.y }.y
end
def left
@points.min_by {|point| point.x }.x
end
def <<(point)
@index = nil
@points << point
self
end
def looks_like_letter?
top, bottom = @points.minmax {|p1, p2| p1.y <=> p2.y }
return false unless (top.y - bottom.y).abs < 10
# left, right = @points.minmax {|p1, p2| p1.x <=> p2.x }
# return false unless (right.x - left.x).abs < 50
@points.any? do |point|
index.key?([point.x, point.y + 1]) &&
index.key?([point.x, point.y + 2]) &&
index.key?([point.x, point.y + 3]) &&
index.key?([point.x, point.y + 4])
end
end
def move
@index = nil
@points.each(&:move)
@part2 += 1
end
def index
@index ||= @points.reduce({}) do |acc, val|
acc.update({ [val.x, val.y] => true })
end
end
def paint(x, y, width, height)
y.upto(y + height) do |row|
x.upto(x + width) do |col|
# print " [#{col}, #{row}] "
print index[[col, row]] ? '#' : '.'
end
puts
end
end
end
canvas = ARGF.reduce(Canvas.new) do |state, line|
state << Point.new(line)
end
while !canvas.looks_like_letter?
canvas.move
end
top = canvas.top
left = canvas.left
canvas.paint(left, top, 60, 20)
puts canvas.part2
הטריק היה גובה וברגע שהבנתי את זה שאר הקוד רץ.
ומי שעוקבים אחרי הקטגוריה הזאת שמתם לב שדילגתי על החידה של אתמול… הסיבה היא חופשת חנוכה בגן אבל אל דאגה עוד נחזור אליו. מוזמנים להקדים אותי ולפרסם את הפיתרון שלכם ליום 9 או לחכות