From 4c72a5dbf6583f0c77917ab46346717c8fd383f5 Mon Sep 17 00:00:00 2001 From: Jeremy Kaplan Date: Fri, 6 Dec 2019 09:34:39 -0800 Subject: [PATCH] 2019: Day 6 Part 2 --- 2019/day6/part2.rb | 90 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 2019/day6/part2.rb diff --git a/2019/day6/part2.rb b/2019/day6/part2.rb new file mode 100644 index 0000000..8571a15 --- /dev/null +++ b/2019/day6/part2.rb @@ -0,0 +1,90 @@ +# frozen_string_literal: true + +require 'set' + +class Body + attr_reader :name, :satellites + attr_accessor :parent + + def initialize(name) + @name = name + @satellites = [] + end + + def <<(satellite) + @satellites << satellite + satellite.parent = self + end + + def inspect + "" + end + + def to_s + name + end + + def direct_orbits + @direct_orbits ||= @satellites.length + @satellites.sum(&:direct_orbits) + end + + def indirect_orbits(depth = 0) + @indirect_orbits ||= @satellites.sum do |sat| + depth + sat.indirect_orbits(depth + 1) + end + end + + @@registry = {} + + def self.get_or_create(name) + if @@registry.key? name + @@registry[name] + else + body = new(name) + @@registry[name] = body + end + end + + def self.get(name) + @@registry[name] + end +end + +def parse(input) + input.lines.map do |line| + center_name, satellite_name = line.strip.split(')') + center = Body.get_or_create center_name + satellite = Body.get_or_create satellite_name + center << satellite + end +end + +input = File.read(File.join(__dir__, 'input')) + +parse(input) + +def find_path(start, goal) + queue = [[start.parent]] + visited = Set.new + visited << start + until queue.empty? + path = queue.shift + state = path[-1] + next if visited.include? state + + visited << state + return path if state.satellites.include? goal + + children = state.satellites + children << state.parent if state.parent + children.each do |child| + queue << path + [child] + end + end + nil +end + +you = Body.get 'YOU' +santa = Body.get 'SAN' +path = find_path(you, santa) +puts path.length - 1