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