Ruby universal orbit map
This commit is contained in:
parent
d30e3f9600
commit
7708169e56
9
ruby/2019/6/bin/problem
Normal file
9
ruby/2019/6/bin/problem
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
|
require "universal_orbit_map"
|
||||||
|
|
||||||
|
map = UniversalOrbitMap.for STDIN.read.chomp
|
||||||
|
|
||||||
|
puts "Part 1: #{map.bodies.values.map(&:orbit_chain).map(&:length).sum}"
|
||||||
|
|
||||||
|
puts "Part 2: #{map.path_between("YOU", "SAN").length}"
|
||||||
55
ruby/2019/6/lib/universal_orbit_map.rb
Normal file
55
ruby/2019/6/lib/universal_orbit_map.rb
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
class UniversalOrbitMap
|
||||||
|
attr_reader :orbits, :bodies
|
||||||
|
def initialize(orbits)
|
||||||
|
@orbits = orbits
|
||||||
|
body_names = orbits.map(&:orbitee) | orbits.map(&:orbiter)
|
||||||
|
@bodies = body_names.to_h { |name| [name, Body.new(name)] }
|
||||||
|
orbits.each do |orbit|
|
||||||
|
bodies[orbit.orbitee].orbiters << orbit.orbiter
|
||||||
|
bodies[orbit.orbiter].orbiting = bodies[orbit.orbitee]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.for(input)
|
||||||
|
new input.split("\n").map { |line| Orbit.for line }
|
||||||
|
end
|
||||||
|
|
||||||
|
def path_between(to, from)
|
||||||
|
to_chain = bodies[to].orbit_chain.map(&:name)
|
||||||
|
from_chain = bodies[from].orbit_chain.map(&:name)
|
||||||
|
common_chain = to_chain & from_chain
|
||||||
|
(from_chain - common_chain) + (to_chain - common_chain).reverse
|
||||||
|
end
|
||||||
|
|
||||||
|
class Body
|
||||||
|
attr_reader :name, :orbiters
|
||||||
|
attr_accessor :orbiting
|
||||||
|
def initialize(name)
|
||||||
|
@name = name
|
||||||
|
@orbiting = nil
|
||||||
|
@orbiters = []
|
||||||
|
end
|
||||||
|
|
||||||
|
def orbit_chain
|
||||||
|
chain = [orbiting]
|
||||||
|
while chain.last
|
||||||
|
chain << chain.last.orbiting
|
||||||
|
end
|
||||||
|
chain[..-2]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Orbit
|
||||||
|
attr_accessor :orbitee, :orbiter, :orbitee_name, :orbiter_name
|
||||||
|
def initialize(orbitee, orbiter)
|
||||||
|
@orbiter = orbiter
|
||||||
|
@orbiter_name = orbiter
|
||||||
|
@orbitee = orbitee
|
||||||
|
@orbitee_name = orbitee
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.for(line)
|
||||||
|
new *line.split(")")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
Loading…
Reference in New Issue
Block a user