2019: Day 14 Part 1
This commit is contained in:
parent
03f0ac49d9
commit
f58d42e04a
1 changed files with 80 additions and 0 deletions
80
2019/day14/part1.rb
Normal file
80
2019/day14/part1.rb
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
Chemical = Struct.new(:amount, :name) do
|
||||
def pretty_print(pp)
|
||||
pp.text to_s
|
||||
end
|
||||
|
||||
def to_s
|
||||
"#{amount} #{name}"
|
||||
end
|
||||
end
|
||||
|
||||
Formula = Struct.new(:product, :reactants) do
|
||||
def produces?(name)
|
||||
product.name == name
|
||||
end
|
||||
|
||||
def pretty_print(pp)
|
||||
pp.text to_s
|
||||
end
|
||||
|
||||
def to_s
|
||||
"#{product} <= #{reactants.join(', ')}"
|
||||
end
|
||||
end
|
||||
|
||||
def parse_chemical(text)
|
||||
parts = text.split(' ')
|
||||
amount = parts[0].to_i
|
||||
name = parts[1].strip
|
||||
Chemical.new(amount, name)
|
||||
end
|
||||
|
||||
def parse(input)
|
||||
input.lines.map do |line|
|
||||
left, right = line.split('=>')
|
||||
|
||||
product = parse_chemical(right)
|
||||
reactants = left.split(',').map { |text| parse_chemical(text) }
|
||||
Formula.new(product, reactants)
|
||||
end
|
||||
end
|
||||
|
||||
input = File.read(File.join(__dir__, 'input'))
|
||||
formulas = parse(input)
|
||||
|
||||
have = Hash.new { |hash, key| hash[key] = 0 }
|
||||
need = Hash.new { |hash, key| hash[key] = 0 }
|
||||
need['FUEL'] = 1
|
||||
ore = 0
|
||||
|
||||
until need.empty?
|
||||
product, amount = need.shift
|
||||
next if amount.zero?
|
||||
|
||||
formula = formulas.find { |f| f.produces? product }
|
||||
|
||||
needed = (amount - have[product])
|
||||
|
||||
runs = (needed.fdiv formula.product.amount).ceil
|
||||
|
||||
formula.reactants.each do |r|
|
||||
wanted = runs * r.amount
|
||||
already_have = have[r.name]
|
||||
can_use = [already_have, wanted].min
|
||||
more = wanted - can_use
|
||||
|
||||
have[r.name] -= can_use
|
||||
if r.name == 'ORE'
|
||||
ore += more
|
||||
else
|
||||
need[r.name] += more
|
||||
end
|
||||
end
|
||||
|
||||
yielded = runs * formula.product.amount
|
||||
extra = yielded - needed
|
||||
have[product] += extra
|
||||
end
|
||||
puts ore
|
||||
Loading…
Reference in a new issue