יום 10 - The Stars Align

קישור לחידה המקורית:
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 או לחכות