|
|
@ -1,41 +1,37 @@
|
|
|
|
reactions = ARGF.read.lines.map {|line|
|
|
|
|
reactions = ARGF.read.strip.lines.each.with_object({}) {|line, h|
|
|
|
|
input, output = line.split(" => ")
|
|
|
|
reactands = line.scan(/(\d+) (\w+)/).map {|q,c| [c,q.to_i] }
|
|
|
|
inputs = input.split(", ").map(&:split).each.with_object({}) {|(q,c),h| h[c] = q.to_i }
|
|
|
|
c, q = reactands.pop
|
|
|
|
q, c = output.split
|
|
|
|
h[c] = { quantity: q, inputs: reactands }
|
|
|
|
[c, { quantity: q.to_i, inputs: inputs }]
|
|
|
|
|
|
|
|
}.to_h
|
|
|
|
}.to_h
|
|
|
|
|
|
|
|
|
|
|
|
class Factory
|
|
|
|
Factory = Struct.new(:reactions, :supply, :ores_used) do
|
|
|
|
attr_reader :ore_consumed
|
|
|
|
def produce(chemical)
|
|
|
|
|
|
|
|
self.ores_used ||= 0
|
|
|
|
|
|
|
|
|
|
|
|
def initialize(reactions)
|
|
|
|
case reaction = reactions[chemical]
|
|
|
|
@reactions = reactions
|
|
|
|
|
|
|
|
@supply = Hash.new(0)
|
|
|
|
|
|
|
|
@supply["ORE"] = Float::INFINITY
|
|
|
|
|
|
|
|
@ore_consumed = 0
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def produce(want)
|
|
|
|
|
|
|
|
case @reactions.fetch(want)
|
|
|
|
|
|
|
|
in { quantity: quantity, inputs: inputs }
|
|
|
|
in { quantity: quantity, inputs: inputs }
|
|
|
|
until inputs.all? {|c,q| @supply[c] >= q }
|
|
|
|
until inputs.all? {|c,q| supply[c] >= q }
|
|
|
|
inputs
|
|
|
|
inputs
|
|
|
|
.select {|c,q| @supply[c] < q }
|
|
|
|
.select {|c,q| supply[c] < q }
|
|
|
|
.each do |c,q|
|
|
|
|
.each do |c,_|
|
|
|
|
produce(c)
|
|
|
|
produce(c)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
inputs.each do |c,q|
|
|
|
|
inputs.each do |c,q|
|
|
|
|
@supply[c] -= q
|
|
|
|
self.ores_used += q if c == "ORE"
|
|
|
|
|
|
|
|
supply[c] -= q
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
@ore_consumed += inputs.fetch("ORE") { 0 }
|
|
|
|
supply[chemical] += quantity
|
|
|
|
@supply[want] += quantity
|
|
|
|
else
|
|
|
|
|
|
|
|
fail "unexpected reaction: #{reaction}"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
factory = Factory.new(reactions)
|
|
|
|
supply = Hash.new(0)
|
|
|
|
|
|
|
|
supply["ORE"] = Float::INFINITY
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
factory = Factory.new(reactions, supply)
|
|
|
|
factory.produce("FUEL")
|
|
|
|
factory.produce("FUEL")
|
|
|
|
puts factory.ore_consumed
|
|
|
|
|
|
|
|