Something went wrong. Try again.
Code for the Advent of Code event
aoc advent-of-code
Something went wrong. Try again.
2.3 kB · 95 lines
Ruby
at rust
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596#!/usr/bin/env ruby# frozen_string_literal: true
input = $stdin.readline
moves = input.scan(/([RL])(\d+)/).map { |d, a| [d.downcase.to_sym, a.to_i] }
class Point MOVEMENT = { north: ->(steps) { [0, steps] }, east: ->(steps) { [steps, 0] }, south: ->(steps) { [0, -1 * steps] }, west: ->(steps) { [-1 * steps, 0] } }.freeze
attr_reader :x, :y, :twice
def initialize @x = 0 @y = 0 @orientation = 0 @visited = [] end
def orientation MOVEMENT.keys[@orientation] end
def turn(direction) @orientation += direction == :r ? 1 : MOVEMENT.keys.size - 1 @orientation %= MOVEMENT.keys.size end
def move(steps) dx, dy = MOVEMENT[orientation].call(steps) # puts "#{dx}, #{dy}" current = [@x, @y] target = [@x + dx, @y + dy]
iterate_horizontal current[0], target[0] if current[1] == target[1] iterate_vertical current[1], target[1] if current[0] == target[0]
@x, @y = target end
def iterate_horizontal(current, target) # Exclude our current position from checks current += (current < target ? 1 : -1) # Swap values to make range work if we're walking to the left current, target = target, current if current > target (current..target).each do |x| if @visited.include? [x, @y] @twice ||= [x, @y] else @visited << [x, @y] end end end
def iterate_vertical(current, target) # Exclude our current position from checks current += (current < target ? 1 : -1) # Swap values to make range work if we're walking down current, target = target, current if current > target (current..target).each do |y| if @visited.include? [@x, y] @twice ||= [@x, y] else @visited << [@x, y] end end end
def shortest_path @x.abs + @y.abs end
def real_shortest @twice.map(&:abs).inject(&:+) endend
destination = Point.new
moves.each do |move| # puts "Move: #{move[0]} then #{move[1]} steps" destination.turn move[0] destination.move move[1]end
puts "Target position: (#{destination.x}, #{destination.y})"
puts "(1) Shortest path is #{destination.shortest_path} steps long"
puts "(2) The REAL shortest path is #{destination.real_shortest} steps long"