[2021][ruby][10.x] refactoring?
change qnwnuuzqluqmyyuzzrstwkwqswksxlty
commit 2e679369c5fdac003da6b7118866e9d8a05d3ae6
author Alpha Chen <alpha@kejadlen.dev>
date
parent oslrtrko
diff --git a/2021/ruby/day_10.rb b/2021/ruby/day_10.rb
index bd1e075..bd64e02 100644
--- a/2021/ruby/day_10.rb
+++ b/2021/ruby/day_10.rb
@@ -1,5 +1,3 @@
-require "strscan"
-
 input = ARGF.read.split("\n")
 
 class IllegalCharacter < StandardError
@@ -9,30 +7,19 @@ class IllegalCharacter < StandardError
   end
 end
 
+COMPLEMENTS = %w[ () [] {} <> ].map(&:chars).to_h
+OPENING_REGEXP = Regexp.new("[#{Regexp.escape(COMPLEMENTS.keys.join)}]")
+CLOSING_REGEXP = Regexp.new("[#{Regexp.escape(COMPLEMENTS.values.join)}]")
 def parse(line)
-  ss = StringScanner.new(line)
   stack = []
 
-  until ss.eos?
-    case
-    when ss.scan(/\(/)
-      stack << ?(
-    when ss.scan(/\[/)
-      stack << ?[
-    when ss.scan(/\{/)
-      stack << ?{
-    when ss.scan(/</)
-      stack << ?<
-    when ss.scan(/\)/)
-      raise IllegalCharacter.new(?)) unless stack.pop == ?(
-    when ss.scan(/\]/)
-      raise IllegalCharacter.new(?]) unless stack.pop == ?[
-    when ss.scan(/\}/)
-      raise IllegalCharacter.new(?}) unless stack.pop == ?{
-    when ss.scan(/>/)
-      raise IllegalCharacter.new(?>) unless stack.pop == ?<
-    else
-      fail
+  s = line.chars
+  until s.empty?
+    case char = s.shift
+    when OPENING_REGEXP
+      stack << char
+    when CLOSING_REGEXP
+      raise IllegalCharacter.new(char) unless stack.pop == COMPLEMENTS.invert.fetch(char)
     end
   end
 
@@ -55,20 +42,12 @@ end
 #   end
 # }
 
-POINTS = ")]}>".chars.map.with_index.to_h.transform_values { _1 + 1 }
-def score(closing)
-  total = 0
-  closing.each do |char|
-    total *= 5
-    total += POINTS.fetch(char)
-  end
-  total
-end
+def score(closing) = closing
+  .map { COMPLEMENTS.values.index(_1) + 1 }
+  .inject(0) {|n,i| n*5 + i }
 
-complements = "() [] {} <>".split(" ").map(&:chars).to_h
 scores = input
-  .map { parse(_1) rescue [] }
-  .reject(&:empty?)
-  .map {|remaining| remaining.reverse.map { complements.fetch(_1) }}
+  .filter_map { parse(_1) rescue nil }
+  .map {|remaining| remaining.reverse.map { COMPLEMENTS.fetch(_1) }}
   .map { score(_1) }
 p scores.sort.fetch(scores.length / 2)