fn main [ var lines := list_break_to_lines(read_lazy(h[0])); var lines2 := list_break(lines, ""); var area := lines2[0]; area := list_flatten(area); var movements := list_join(lines2[1], ""); const x := len(area[0]) * 2; const y := len(area); var a := array_fill(byte, '.', [x, y]); var xp, yp := -1, -1; for j := 0 to y do [ for i := 0 to x shr 1 do [ if area[j][i] = '#' then [ a[i * 2, j] := '#'; a[i * 2 + 1, j] := '#'; ] else if area[j][i] = 'O' then [ a[i * 2, j] := '['; a[i * 2 + 1, j] := ']'; ] else if area[j][i] = '@' then [ xp, yp := i * 2, j; ] else if area[j][i] = '.' then [ ] else [ abort; ] ] ] for m in movements do [ var dx dy : int; if m = '>' then dx, dy := 1, 0; else if m = '<' then dx, dy := -1, 0; else if m = 'v' then dx, dy := 0, 1; else if m = '^' then dx, dy := 0, -1; else abort; var movements := empty(tuple2(int, int)); var next_pending := treeset_from_list([ mktuple2(xp, yp) ]); while treeset_is_nonempty(next_pending) do [ var pending := next_pending; next_pending := treeset_init(tuple2(int, int)); for p in pending do [ var xn, yn := p.v1 + dx, p.v2 + dy; var c := a[xn, yn]; if c = '#' then goto dont_move; if c = '.' then continue; next_pending := treeset_set(next_pending, mktuple2(xn, yn)); if dy <> 0 then [ if c = '[' then next_pending := treeset_set(next_pending, mktuple2(xn + 1, yn)); else next_pending := treeset_set(next_pending, mktuple2(xn - 1, yn)); ] ] for p in next_pending do movements +<= p; ] movements := list_reverse(movements); for m in movements do [ a[m.v1 + dx, m.v2 + dy] := a[m.v1, m.v2]; a[m.v1, m.v2] := '.'; ] xp += dx; yp += dy; dont_move: ] var sum := 0; for j := 0 to y do [ for i := 0 to x do [ if a[i, j] = '[' then [ sum += 100 * j + i; ] ] ] write(h[1], ntos(sum) + nl); ]