You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
117 lines
2.7 KiB
117 lines
2.7 KiB
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...#
|
|
##########
|
|
|
|
<vv>^<v^>v>^vv^v>v<>v^v<v<^vv<<<^><<><>>v<vvv<>^v^>^<<<><<v<<<v^vv^v>^
|
|
vvv<<^>^v^^><<>>><>^<<><^vv^^<>vvv<>><^^v>^>vv<>v<<<<v<^v>^<^^>>>^<v<v
|
|
><>vv>v^v^<>><>>>><^^>vv>v<^^^>>v^v^<^^>v^^>v^<^v>v<>>v^v^<v>v^^<^^vv<
|
|
<<v<^>>^^^^>>>v^<>vvv^><v<<<>^^^vv^<vvv>^>v<^^^^v<>^>vvvv><>>v^<<^^^^^
|
|
^><^><>>><>^^<<^^v>>><^<v>^<vv>>v>>>^v><>^v><<<<v>>v<v<v>vvv>^<><<>^><
|
|
^>><>^v<><^vvv<^^<><v<<<<<><^v<<<><<<^^<v<^^^><^>>^<v^><<<^>>^v<v^v<v^
|
|
>^>>^v>vv>^<<^v<>><<><<v<<v><>v<^vv<<<>^^v^>^^>>><<^v>>v^v><^^>>^<>vv^
|
|
<><^^>^^^<><vvvvv^v<v<<>^v<v>v<<^><<><<><<<^^<<<^<<>><<><^^^>^^<>^>v<>
|
|
^^>vv<^v^v<vv>^<><v<^v>^^^>>>^^vvv^>vvv<>>>^<^>>>>>^<<^v>^vvv<>^<><<v>
|
|
v^^>>><<^^<>>^v^<v^vv<>v^<<>^<^v^v><^<<<><<^<v><v<>vv>>v><v^<vv<>v^<<^
|