(def wall 9999)
(def GOAL 0)
(def height 60)
(def width 60)
(def dstr (str
"############################################################"
"#########......###...##........####...####.....#############"
"####............................##.....##............#######"
"###................###.....##..........................#####"
"###...............#####...####..........................####"
"###...............#####....####............#............####"
"####...###.........####.......##.................G.....#####"
"##########..........###........##.....................######"
"##########...........#..........##...................#######"
"#########.......................#####..............#########"
"######.........................#######...#......############"
"#####..........................############....#############"
"####...........................###########......######..####"
"###..........##.................#########................###"
"##.......#######........#..........######...###.........####"
"##......########.......##............###...######.....######"
"###.....#######...............#####........########..#######"
"###......#####...##...........######........################"
"###......#####..####...........#####.........###############"
"#######..#####..####............###...........#######....###"
"########..###...#####......###.................#####......##"
"########.......######......####.................###.......##"
"########.......######.......##....##..................##..##"
"#######.......######....##..G....####.........##.....####..#"
"#####........#######....###......####........#####..#####..#"
"####........#######.....######...#####.......############..#"
"####.......######..........####..#########..#############..#"
"###........#####............###..########################.##"
"##.........####.............###..################.######..##"
"#....###...####......####....#...######..#######...#####..##"
"#.....#.....##......######.......#####..G.#####....#####..##"
"#...................######........####....###.....#####...##"
"#....................#####........#####..###......##......##"
"#....G...............######........########................#"
"##......#............########.......#######................#"
"##......##...........#########......#######...............##"
"###.....#..G.........####...##.....#######..##...........###"
"###..........#......####...........######..####..........###"
"##..........####....####...........#####..######.........###"
"##...........####..#####............##....######.........###"
"##............###..######......#...........####..........###"
"##............###..#######.....##........................###"
"##.......###...#....#######....#..........................##"
"###......###.........######.........................##.....#"
"###.......#..........######........#####...........####....#"
"###............###...######......########.........#####....#"
"###...........#####..######.....#########.........####.....#"
"###...........#####.#######.....########...........###.....#"
"###...........####..########...#########......##...###....##"
"###...........####...##################......####..###....##"
"###...........####......##############.......####..###....##"
"###...........####..........##########........##...###....##"
"###............####..........#########.............####..###"
"###...........#####...........#######..............#########"
"###.....##########............######.......##......#########"
"##.....###########.....###.....####.......####......########"
"##.....############....###......##.......#####........######"
"###...##############..#####.............#######.......######"
"################################...##..#####################"
"############################################################"))
(def dungeon (vec (replace {\# wall \. floor \G GOAL} dstr)))
(defn find-goals [m]
(into {} (for [x (keep-indexed #(if (= %2 0) %1) dungeon)] [x 0])))
(defn find-walls [m]
(into {} (for [x (keep-indexed #(if (= %2 wall) %1) dungeon)] [x wall])))
(defn find-floors [m]
(into {} (for [x (keep-indexed #(if (= %2 floor) %1) dungeon)] [x floor])))
(defn step-value [d x]
d
(if (> (dec d) (val x))
(inc (val x)))))
(defn step [m x]
(if (= (val x) wall)
[{(key x) wall}]
(let [n (m (- (key x) width))
s (m (+ (key x) width))
w (m (- (key x) 1 ))
e (m (+ (key x) 1 ))
rv
(filter #(distinct? (val (first %)) wall nil)
[{(- (key x) width) (step-value n x)}
{(+ (key x) width) (step-value s x)}
{(- (key x) 1 ) (step-value w x)}
{(+ (key x) 1 ) (step-value e x)}])]
rv)))
(defn merge-maps [a b]
(merge-with min a b))
(defn dijkstra
([m]
(dijkstra m (find-walls m) (find-goals m)))
([m closed open]
(if (empty? open)
(merge-with min closed (find-floors m))
(recur
m
(merge-with min closed open)
(let [ms (flatten (map #(step (fn [index] (or (closed index) (m index))) %) open))]
(reduce merge-maps {} ms))))))
(defn -main
[& args]
(time (do ;(println
(str
(into
(sorted
-map
) (dijkstra dungeon
)))) (println (clojure.string/replace (reduce #(str %1 (condp = (val %2) wall "█" floor "ʔ" (char (+ (int \A) -1 (val %2) )))) "" (into (sorted-map) (dijkstra dungeon))) #"(.{60})" "$1\n"))
)))
(-main)