|
|
@ -1,3 +1,5 @@
|
|
|
|
|
|
|
|
(require '[clojure.core.reducers :as r])
|
|
|
|
|
|
|
|
|
|
|
|
(def input (->> (slurp "./in")
|
|
|
|
(def input (->> (slurp "./in")
|
|
|
|
(clojure.string/split-lines)
|
|
|
|
(clojure.string/split-lines)
|
|
|
|
(mapv (partial mapv (comp read-string str)))
|
|
|
|
(mapv (partial mapv (comp read-string str)))
|
|
|
@ -6,13 +8,16 @@
|
|
|
|
(into {})))
|
|
|
|
(into {})))
|
|
|
|
|
|
|
|
|
|
|
|
(defn min-distance [dist Q]
|
|
|
|
(defn min-distance [dist Q]
|
|
|
|
(reduce
|
|
|
|
(r/fold
|
|
|
|
#(if (and (not= (dist %2) :inf)
|
|
|
|
(r/monoid
|
|
|
|
(or (= :inf (first %1))
|
|
|
|
#(if (< (first %1) (first %2)) %1 %2)
|
|
|
|
(< (dist %2) (first %1))))
|
|
|
|
(constantly [##Inf []]))
|
|
|
|
[(dist %2) %2]
|
|
|
|
(r/monoid
|
|
|
|
%1)
|
|
|
|
#(if (< (first %1) (dist %2)) %1 [(dist %2) %2])
|
|
|
|
[:inf []] Q))
|
|
|
|
(constantly [##Inf []]))
|
|
|
|
|
|
|
|
(r/filter
|
|
|
|
|
|
|
|
(partial contains? dist)
|
|
|
|
|
|
|
|
(apply vector Q))))
|
|
|
|
|
|
|
|
|
|
|
|
(defn find-neighbors [Q u]
|
|
|
|
(defn find-neighbors [Q u]
|
|
|
|
(filter #(contains? Q %) [(update u 0 inc)
|
|
|
|
(filter #(contains? Q %) [(update u 0 inc)
|
|
|
@ -21,22 +26,19 @@
|
|
|
|
(update u 1 dec)]))
|
|
|
|
(update u 1 dec)]))
|
|
|
|
|
|
|
|
|
|
|
|
(let [dim (apply max (map first (keys input)))]
|
|
|
|
(let [dim (apply max (map first (keys input)))]
|
|
|
|
(loop [Q (set (keys input))
|
|
|
|
(loop [Q (apply sorted-set (keys input))
|
|
|
|
dist (-> (zipmap Q (repeat :inf)) (update [0 0] #(do % 0)))]
|
|
|
|
dist (assoc (hash-map) [0 0] 0)]
|
|
|
|
|
|
|
|
(when (= 0 (rem (count Q) 500)) (println (count Q)))
|
|
|
|
(if (empty? Q)
|
|
|
|
(if (empty? Q)
|
|
|
|
(println (dist [dim dim]))
|
|
|
|
(println (dist [dim dim]))
|
|
|
|
(let [[u vu] (min-distance dist Q)]
|
|
|
|
(let [[u vu] (min-distance dist Q)]
|
|
|
|
(recur
|
|
|
|
(recur
|
|
|
|
(disj Q vu)
|
|
|
|
(disj Q vu)
|
|
|
|
(loop [d dist f (find-neighbors Q vu)]
|
|
|
|
(reduce
|
|
|
|
(if (empty? f)
|
|
|
|
#(let [alt (+ u (input %2))]
|
|
|
|
d
|
|
|
|
(cond-> %1
|
|
|
|
(recur
|
|
|
|
(or (not (contains? dist %2)) (< alt (dist %2)))
|
|
|
|
(let [v (first f) alt (+ u (input v))]
|
|
|
|
(assoc %2 alt)))
|
|
|
|
(if (or (= :inf (dist v)) (< alt (dist v)))
|
|
|
|
dist
|
|
|
|
(assoc d v alt)
|
|
|
|
(find-neighbors Q vu)))))))
|
|
|
|
d
|
|
|
|
|
|
|
|
))
|
|
|
|
|
|
|
|
(rest f)
|
|
|
|
|
|
|
|
))))))))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|