Skip to content

Instantly share code, notes, and snippets.

@SleeplessByte
Created December 7, 2020 11:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SleeplessByte/31aea85a5699cd1429edc5094bb2fdee to your computer and use it in GitHub Desktop.
Save SleeplessByte/31aea85a5699cd1429edc5094bb2fdee to your computer and use it in GitHub Desktop.
Advent of Code 2020: Day 7 - Handy Haversacks
require 'benchmark'
class BagsContent
def initialize(name, count:)
self.name = name
self.count = Integer(count)
end
def to_s
name
end
def to_i
count
end
def inspect
"#{name} (#{count})"
end
private
attr_accessor :name, :count
end
class BagsBabushka
def self.from_rules(lines)
parsed = lines.each_with_object({}) do |line, rules|
subject, contents = line.split(' contain ')
subject = subject.gsub(/bags?/, '').strip
next rules[subject] = [] if contents == 'no other bags.'
rules[subject] = contents.split(', ').map do |bag|
match = /^([0-9]+) (.*?) bags?\.?$/.match(bag)
BagsContent.new(match[2], count: match[1])
end
end
new(parsed)
end
def initialize(rules)
self.rules = rules
end
def shiny(target = 'shiny gold')
potentials = [target]
targets = {}
while potentials.length > 0
matcher = potentials.shift
self.rules.each do |container, contents|
contents.each do |content|
color = content.to_s
if color == matcher
potentials.push(container) unless targets.key?(container)
targets[container] = true
end
end
end
end
targets.keys
end
def shiny_contents(target = 'shiny gold')
self.rules[target].inject(0) do |count, content|
count + content.to_i + content.to_i * shiny_contents(content.to_s)
end
end
private
attr_accessor :rules
end
rules = File
.read('input.txt')
.split(/\n/)
Benchmark.bmbm do |b|
b.report do
puts BagsBabushka.from_rules(rules).shiny_contents
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment