[2020][ruby][18] playing around
change ltvurvtvtpwkyukqryoxtkkzrvsrrkpm
commit 91aae48ff7768c165e7375b5ef2546ddb4d8dd74
author Alpha Chen <alpha@kejadlen.dev>
date
parent klqlymry
diff --git a/2020/ruby/day_18.rb b/2020/ruby/day_18.rb
index 50bf8ec..daf50a7 100644
--- a/2020/ruby/day_18.rb
+++ b/2020/ruby/day_18.rb
@@ -1,32 +1,58 @@
 require "strscan"
 
-def evaluate(input)
-  while input.include?(?()
-    input = input.gsub(/\((?~[()])+\)/) {|m| evaluate(m[1..-2]) }
-  end
+# def evaluate(input)
+#   while input.include?(?()
+#     input = input.gsub(/\((?~[()])+\)/) {|m| evaluate(m[1..-2]) }
+#   end
 
-  # ss = StringScanner.new(input)
-  # n = ss.scan(/\d+/).to_i
-  # until ss.eos?
-  #   case
-  #   when ss.scan(/\s*\+\s*(\d+)/)
-  #     n += ss.captures[0].to_i
-  #   when ss.scan(/\s*\*\s*(\d+)/)
-  #     n *= ss.captures[0].to_i
-  #   else
-  #     fail
-  #   end
-  # end
-  # n
+#   # part one
+#   # ss = StringScanner.new(input)
+#   # n = ss.scan(/\d+/).to_i
+#   # until ss.eos?
+#   #   case
+#   #   when ss.scan(/\s*\+\s*(\d+)/)
+#   #     n += ss.captures[0].to_i
+#   #   when ss.scan(/\s*\*\s*(\d+)/)
+#   #     n *= ss.captures[0].to_i
+#   #   else
+#   #     fail
+#   #   end
+#   # end
+#   # n
 
-  while input.include?(?+)
-    input = input.gsub(/\d+\s*\+\s*\d+/) {|m| eval(m) }
-  end
-  while input.include?(?*)
-    input = input.gsub(/\d+\s*\*\s*\d+/) {|m| eval(m) }
+#   while input.include?(?+)
+#     input = input.gsub(/\d+\s*\+\s*\d+/) {|m| eval(m) }
+#   end
+#   while input.include?(?*)
+#     input = input.gsub(/\d+\s*\*\s*\d+/) {|m| eval(m) }
+#   end
+#   input.to_i
+# end
+
+def evaluate(input)
+  stack = [->(x) { x }]
+
+  ss = StringScanner.new(input)
+  until ss.eos?
+    ss.scan(/\s*/)
+    case
+    when n = ss.scan(/\d+/)
+      stack << stack.pop[n.to_i]
+    when ss.scan(/\+/)
+      stack << ->(x) { stack.pop + x }
+    when ss.scan(/\*/)
+      stack << ->(x) { stack.pop * x }
+    when ss.scan(/\(/)
+      stack << ->(x) { x }
+    when ss.scan(/\)/)
+      n = stack.pop
+      stack << stack.pop[n]
+    else
+      fail
+    end
   end
-  input.to_i
+
+  stack.pop
 end
 
 p ARGF.read.split("\n").map {|line| evaluate(line) }.sum
-