[2024][ruby][15.2]
change komvvqvwokkmokvosspzvswomvwnkkrn
commit d1eb09c8e766bbe513428ff6ebc727764f672b70
author Alpha Chen <alpha@kejadlen.dev>
date
parent zxyupmlr
diff --git a/2024/ruby/day_15.rb b/2024/ruby/day_15.rb
index 10e2d53..0c2e5e3 100644
--- a/2024/ruby/day_15.rb
+++ b/2024/ruby/day_15.rb
@@ -1,4 +1,6 @@
-input = DATA.read.split("\n\n")
+input = DATA.read.gsub(
+  /[#O\.@]/, %w[ # ## O [] . .. @ @. ].each_slice(2).to_h
+).split("\n\n")
 
 map = {}
 input.shift.split("\n").each.with_index do |row, y|
@@ -29,8 +31,21 @@ def push(map, pos, move)
   case map.fetch(pospos, nil)
   when ?#
     raise Nope
-  when ?O
-    push(map, pospos, move)
+  when ?[, ?]
+    case move
+    when ?<, ?>
+      push(map, pospos, move)
+    when ?^, ?v
+      a = pospos
+      dx = {?[ => 1, ?] => -1}.fetch(map.fetch(pospos))
+      b = a.zip([0, dx]).map { _1 + _2 }
+      push_two(map, a, b, move).reverse.uniq.each do |pos, pospos|
+        map[pospos] = map.fetch(pos)
+        map.delete(pos)
+      end
+    else
+      fail
+    end
   when nil
   else
     fail
@@ -42,6 +57,28 @@ def push(map, pos, move)
   pospos
 end
 
+def push_two(map, a, b, move)
+  delta = DELTAS.fetch(move)
+  aa = a.zip(delta).map { _1 + _2 }
+  bb = b.zip(delta).map { _1 + _2 }
+
+  [[a, aa], [b, bb]].flat_map {|pos, pospos|
+    case map.fetch(pospos, nil)
+    when ?#
+      raise Nope
+    when ?[, ?]
+      a_ = pospos
+      dx = {?[ => 1, ?] => -1}.fetch(map.fetch(pospos))
+      b_ = a_.zip([0, dx]).map { _1 + _2 }
+      [[pos, pospos]] + push_two(map, a_, b_, move)
+    when nil
+      [[pos, pospos]]
+    else
+      fail
+    end
+  }
+end
+
 DELTAS = %w[ ^ v < > ].zip([[-1,0], [1,0], [0,-1], [0, 1]]).to_h
 movements = input.shift.gsub("\n", "").chars
 
@@ -52,6 +89,7 @@ movements.each do |move|
   end
 end
 
-pp map.select { _2 == ?O }.sum {|(y,x),_| 100 * y + x }
+# pp map.select { _2 == ?O }.sum {|(y,x),_| 100 * y + x }
+pp map.select { _2 == ?[ }.sum {|(y,x),_| 100 * y + x }
 
 __END__