[2019][ruby][14.1]
change lruyrpyvsztnnpywspmouqpmvxoovusx
commit 084fee54b2448b5e7da9f5091fca6d6dd8820a1d
author Alpha Chen <alpha@kejadlen.dev>
date
parent notlxtsk
diff --git a/2019/ruby/day_14.rb b/2019/ruby/day_14.rb
index 453416e..d0a5048 100644
--- a/2019/ruby/day_14.rb
+++ b/2019/ruby/day_14.rb
@@ -1,41 +1,37 @@
-reactions = ARGF.read.lines.map {|line|
-  input, output = line.split(" => ")
-  inputs = input.split(", ").map(&:split).each.with_object({}) {|(q,c),h| h[c] = q.to_i }
-  q, c = output.split
-  [c, { quantity: q.to_i, inputs: inputs }]
+reactions = ARGF.read.strip.lines.each.with_object({}) {|line, h|
+  reactands = line.scan(/(\d+) (\w+)/).map {|q,c| [c,q.to_i] }
+  c, q = reactands.pop
+  h[c] = { quantity: q, inputs: reactands }
 }.to_h
 
-class Factory
-  attr_reader :ore_consumed
+Factory = Struct.new(:reactions, :supply, :ores_used) do
+  def produce(chemical)
+    self.ores_used ||= 0
 
-  def initialize(reactions)
-    @reactions = reactions
-    @supply = Hash.new(0)
-    @supply["ORE"] = Float::INFINITY
-    @ore_consumed = 0
-  end
-
-  def produce(want)
-    case @reactions.fetch(want)
+    case reaction = reactions[chemical]
     in { quantity: quantity, inputs: inputs }
-      until inputs.all? {|c,q| @supply[c] >= q }
+    until inputs.all? {|c,q| supply[c] >= q }
         inputs
-          .select {|c,q| @supply[c] < q }
-          .each do |c,q|
+          .select {|c,q| supply[c] < q }
+          .each do |c,_|
             produce(c)
           end
       end
 
       inputs.each do |c,q|
-        @supply[c] -= q
+        self.ores_used += q if c == "ORE"
+        supply[c] -= q
       end
 
-      @ore_consumed += inputs.fetch("ORE") { 0 }
-      @supply[want] += quantity
+      supply[chemical] += quantity
+    else
+      fail "unexpected reaction: #{reaction}"
     end
   end
 end
 
-factory = Factory.new(reactions)
+supply = Hash.new(0)
+supply["ORE"] = Float::INFINITY
+
+factory = Factory.new(reactions, supply)
 factory.produce("FUEL")
-puts factory.ore_consumed