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| 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 ?[, ?] 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 end map[pospos] = map.fetch(pos) map.delete(pos) 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 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 } pp map.select { _2 == ?[ }.sum {|(y,x),_| 100 * y + x } __END__ ########## #..O..O.O# #......O.# #.OO..O.O# #..O@..O.# #O#..O...# #O..O..O.# #.OO.O.OO# #....O...# ########## ^v>^vv^v>v<>v^v<<><>>v^v^>^<<<><^ vvv<<^>^v^^><<>>><>^<<><^vv^^<>vvv<>><^^v>^>vv<>v<<<^<^^>>>^<>vv>v^v^<>><>>>><^^>vv>v<^^^>>v^v^<^^>v^^>v^<^v>v<>>v^v^v^^<^^vv< <>^^^^>>>v^<>vvv^>^^^vv^^>v<^^^^v<>^>vvvv><>>v^<<^^^^^ ^><^><>>><>^^<<^^v>>><^^>v>>>^v><>^v><<<>vvvv>^<><<>^>< ^>><>^v<><^vvv<^^<><^v<<<><<<^^<^>>^<<<^>>^v^>>^v>vv>^<<^v<>><<><<>v<^vv<<<>^^v^>^^>>><<^v>>v^v><^^>>^<>vv^ <><^^>^^^<>^vv<<^><<><<><<<^^<<<^<<>><<><^^^>^^<>^>v<> ^^>vv<^v^v^<>^^^>>>^^vvv^>vvv<>>>^<^>>>>>^<<^v>^vvv<>^<>< v^^>>><<^^<>>^v^v^<<>^<^v^v><^<<<><<^vv>>v>v^<<^