[2019][ruby][14.1]

master
Alpha Chen 5 years ago
parent f0c024d28f
commit 61afcde94e

@ -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

Loading…
Cancel
Save