92 lines
1.5 KiB
Ruby
92 lines
1.5 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require 'pp'
|
|
|
|
input = File.read(File.join(__dir__, 'input'))
|
|
|
|
def wires(input)
|
|
input.lines.map do |line|
|
|
wire_points(line.strip.split(','))
|
|
end
|
|
end
|
|
|
|
class Point
|
|
attr_reader :x, :y
|
|
def initialize(x, y)
|
|
@x = x
|
|
@y = y
|
|
end
|
|
|
|
def inspect
|
|
"Point(#{x}, #{y})"
|
|
end
|
|
|
|
def hash
|
|
[x, y].hash
|
|
end
|
|
|
|
def eql?(other)
|
|
x == other.x && y == other.y
|
|
end
|
|
|
|
def right(dy)
|
|
Point.new(x, y + dy)
|
|
end
|
|
|
|
def left(dy)
|
|
Point.new(x, y - dy)
|
|
end
|
|
|
|
def down(dx)
|
|
Point.new(x - dx, y)
|
|
end
|
|
|
|
def up(dx)
|
|
Point.new(x + dx, y)
|
|
end
|
|
|
|
def move(direction, delta)
|
|
case direction
|
|
when 'U'
|
|
up(delta)
|
|
when 'D'
|
|
down(delta)
|
|
when 'L'
|
|
left(delta)
|
|
when 'R'
|
|
right(delta)
|
|
else
|
|
raise StandardError, "Unexpected move direction: #{direction}"
|
|
end
|
|
end
|
|
|
|
def manhattan_distance_to(other)
|
|
(x - other.x).abs + (y - other.y).abs
|
|
end
|
|
end
|
|
|
|
def wire_points(moves)
|
|
pos = Point.new(0, 0)
|
|
# NOTE: We don't include the origin in the list of points because that's not
|
|
# considered a valid intersection.
|
|
points = []
|
|
moves.each do |move|
|
|
direction = move[0]
|
|
delta = move[1..].to_i
|
|
delta.times do
|
|
pos = pos.move(direction, 1)
|
|
points << pos
|
|
end
|
|
end
|
|
points
|
|
end
|
|
|
|
wire1, wire2 = wires(input)
|
|
origin = Point.new(0, 0)
|
|
intersections = (wire1 & wire2).sort do |p1, p2|
|
|
d1 = p1.manhattan_distance_to origin
|
|
d2 = p2.manhattan_distance_to origin
|
|
d1 - d2
|
|
end
|
|
|
|
pp intersections.first.manhattan_distance_to origin
|