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__