diff --git a/ruby/2019/3/bin/problem b/ruby/2019/3/bin/problem new file mode 100644 index 0000000..27bace1 --- /dev/null +++ b/ruby/2019/3/bin/problem @@ -0,0 +1,7 @@ +#!/usr/bin/env ruby + +require "crossed_wires" + +cw = CrossedWires.for STDIN.read.chomp +puts "Part 1: #{cw.closest_intersection.map(&:abs).sum}" +puts "Part 2: #{cw.intersection_distances.min}" \ No newline at end of file diff --git a/ruby/2019/3/lib/crossed_wires.rb b/ruby/2019/3/lib/crossed_wires.rb new file mode 100644 index 0000000..3acc749 --- /dev/null +++ b/ruby/2019/3/lib/crossed_wires.rb @@ -0,0 +1,76 @@ +require "set" + +class CrossedWires + attr_reader :wires + def initialize(wires) + @wires = wires + end + + def self.for(input) + new input.split("\n").map { |line| Wire.for line } + end + + def intersections + wires.map(&:positions).map(&:keys).reduce(&:&) + end + + def intersection_distances + intersections + .map { |intersection| wires.map { |wire| wire.positions[intersection] }.sum } + end + + def closest_intersection + intersections + .map{ |intersection| intersection.split(",").map(&:to_i) } + .sort_by { |x, y| x.abs + y.abs }.min + end + + class Wire + attr_reader :turns + def initialize(turns) + @turns = turns + end + + def self.for(line) + new line.split(",").map { |turn| Turn.for turn } + end + + def positions + @positions ||= begin + x = 0 + y = 0 + current_distance = 0 + p = {} + turns.each do |turn| + turn.length.times do + current_distance += 1 + case turn.dir + when "U" + y -= 1 + when "D" + y += 1 + when "L" + x -= 1 + when "R" + x += 1 + end + p["#{x},#{y}"] = current_distance unless p.key?("#{x},#{y}") + end + end + p + end + end + end + + class Turn + attr_reader :dir, :length + def initialize(dir, length) + @dir = dir + @length = length + end + + def self.for(string) + new string[0], string[1..].to_i + end + end +end