[2020][ruby][17.x] refactor
change slmymxkzxxkvquymsortvxoopwvsxvzs
commit 168ac0eef68e50b8d7b829ad28b9554b67097249
author Alpha Chen <alpha@kejadlen.dev>
date
parent wkwwsqqv
diff --git a/2020/ruby/day_17.rb b/2020/ruby/day_17.rb
index a60de7b..72a1f90 100644
--- a/2020/ruby/day_17.rb
+++ b/2020/ruby/day_17.rb
@@ -1,24 +1,28 @@
-state = ARGF.read.split("\n").flat_map.with_index {|line,y|
-  line.chars.map.with_index {|c,x| [[0,0,y,x], c == "#"] }
+DIMENSIONS = 4
+state = ARGF.read.strip.split("\n").flat_map.with_index {|line,y|
+  line.chars.map.with_index {|c,x|
+    [[x,y].fill(0, 2, DIMENSIONS-2), c == "#"]
+  }
 }.to_h
 
-NEIGHBORS = (0...3**4).map {|n| n.digits(3) }.map {|n| (0..3).map {|x| n.fetch(x, 0) - 1 }} - [[0,0,0,0]]
+NEIGHBORS = (0...3**DIMENSIONS)
+  .reject {|n| n == 3**DIMENSIONS / 2 }
+  .map {|n| n.digits(3) }
+  .map {|n| (0...DIMENSIONS).map {|x| n.fetch(x, 0) - 1 }}
 
 def tick(state)
   actives = state.select {|_,c| c }.keys
-  ww, zz, yy, xx = actives.transpose.map(&:minmax).map {|min,max| [min-1, max+1] }
-  Range.new(*ww).flat_map {|w|
-    Range.new(*zz).flat_map {|z|
-      Range.new(*yy).flat_map {|y|
-        Range.new(*xx).map {|x|
-          active_neighbors = NEIGHBORS.map {|dw,dz,dy,dx| state[[w+dw,z+dz,y+dy, x+dx]] }.count(&:itself)
-          wzyx = [w,z,y,x]
-          [ wzyx,
-            state[wzyx] ? (2..3).cover?(active_neighbors) : active_neighbors == 3
-          ]
-        }
-      }
-    }
+  minmaxes = actives
+    .transpose.map(&:minmax)
+    .map {|min,max| (min-1..max+1).to_a }
+  coords = minmaxes.inject {|n,x|
+    n.flat_map {|nn| x.map {|xx| [nn, xx] }}
+  }.map(&:flatten)
+  coords.map {|coord|
+    active_neighbors = NEIGHBORS.count {|delta| state[coord.zip(delta).map {|a,b| a + b }] }
+    [ coord,
+      state[coord] ? (2..3).cover?(active_neighbors) : active_neighbors == 3
+    ]
   }.to_h
 end