uses heap; fn main [ var lines := list_break_to_lines(read_lazy(h[0])); lines := list_flatten(lines); const x := len(lines[0]); const y := len(lines); var a := list_to_array([x, y], list_join(lines, "")); a := array_flatten(a); var xp, yp, xe, ye := -1, -1, -1, -1; for j := 0 to y do [ for i := 0 to x do [ if a[i, j] = 'S' then [ xp, yp := i, j; a[i, j] := '.'; ] if a[i, j] = 'E' then [ xe, ye := i, j; a[i, j] := '.'; ] ] ] var min_hl := array_fill(-1, [x, y, 3, 3]); var pending := heap_from_list([ mktuple5(0, xp, yp, 1, 0) ]); while true do [ var s : tuple5(int, int, int, int, int); pending, s := heap_extract(pending); if min_hl[s.v2, s.v3, s.v4 + 1, s.v5 + 1] <> -1 then continue; min_hl[s.v2, s.v3, s.v4 + 1, s.v5 + 1] := s.v1; if s.v2 = xe, s.v3 = ye then [ write(h[1], ntos(s.v1) + nl); break; ] var xn, yn := s.v2 + s.v4, s.v3 + s.v5; if a[xn, yn] = '.' then pending := heap_insert(pending, mktuple5(s.v1 + 1, xn, yn, s.v4, s.v5)); pending := heap_insert(pending, mktuple5(s.v1 + 1000, s.v2, s.v3, s.v5, -s.v4)); pending := heap_insert(pending, mktuple5(s.v1 + 1000, s.v2, s.v3, -s.v5, s.v4)); ] ]