[2024][ruby][15.1]
change zxyupmlrztqzmktkmsusukxwszqozmmp
commit f9871ec48a0e1566a8f261976c2133164856c16b
author Alpha Chen <alpha@kejadlen.dev>
date
parent rqzzzmzn
diff --git a/2024/ruby/day_15.rb b/2024/ruby/day_15.rb
new file mode 100644
index 0000000..10e2d53
--- /dev/null
+++ b/2024/ruby/day_15.rb
@@ -0,0 +1,57 @@
+input = DATA.read.split("\n\n")
+
+map = {}
+input.shift.split("\n").each.with_index do |row, y|
+  row.chars.each.with_index do |pos, x|
+    map[[y,x]] = pos unless pos == ?.
+  end
+end
+robot = map.find { _2 == ?@ }.first
+
+bounds = [
+  (0..map.keys.map(&:first).max),
+  (0..map.keys.map(&:last).max),
+]
+map_s = ->() {
+  bounds[0].map { |y|
+    bounds[1].map { |x|
+      map.fetch([y,x], ?.)
+    }.join
+  }.join("\n")
+}
+
+Nope = Class.new(Exception)
+
+def push(map, pos, move)
+  delta = DELTAS.fetch(move)
+  pospos = pos.zip(delta).map { _1 + _2 }
+
+  case map.fetch(pospos, nil)
+  when ?#
+    raise Nope
+  when ?O
+    push(map, pospos, move)
+  when nil
+  else
+    fail
+  end
+
+  map[pospos] = map.fetch(pos)
+  map.delete(pos)
+
+  pospos
+end
+
+DELTAS = %w[ ^ v < > ].zip([[-1,0], [1,0], [0,-1], [0, 1]]).to_h
+movements = input.shift.gsub("\n", "").chars
+
+movements.each do |move|
+  begin
+    robot = push(map, robot, move)
+  rescue Nope
+  end
+end
+
+pp map.select { _2 == ?O }.sum {|(y,x),_| 100 * y + x }
+
+__END__