From fa34a065eee5c6a519c046429b7375ae74ac1591 Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Wed, 15 Dec 2021 21:48:23 -0500 Subject: [PATCH] day15: priority queue, <10 sec --- day15/part1.clj | 54 ++++++++++++++++++------------------------------ day15/part2.clj | 55 +++++++++++++++++++------------------------------ 2 files changed, 41 insertions(+), 68 deletions(-) diff --git a/day15/part1.clj b/day15/part1.clj index caf4e2c..7838e34 100644 --- a/day15/part1.clj +++ b/day15/part1.clj @@ -1,5 +1,3 @@ -(require '[clojure.core.reducers :as r]) - (def input (->> (slurp "./in") (clojure.string/split-lines) (mapv (partial mapv (comp read-string str))) @@ -7,38 +5,26 @@ {[y x] (get-in % [y x])})) (into {}))) -(defn min-distance [dist Q] - (r/fold - (r/monoid - #(if (< (first %1) (first %2)) %1 %2) - (constantly [##Inf []])) - (r/monoid - #(if (< (first %1) (dist %2)) %1 [(dist %2) %2]) - (constantly [##Inf []])) - (r/filter - (partial contains? dist) - (apply vector Q)))) +(def dim (apply max (map first (keys input)))) -(defn find-neighbors [Q u] - (filter #(contains? Q %) [(update u 0 inc) - (update u 0 dec) - (update u 1 inc) - (update u 1 dec)])) +(defn find-neighbors [u] + (filter #(contains? input %) [(update u 0 inc) + (update u 0 dec) + (update u 1 inc) + (update u 1 dec)])) -(let [dim (apply max (map first (keys input)))] - (loop [Q (apply sorted-set (keys input)) - dist (assoc (hash-map) [0 0] 0)] - (when (= 0 (rem (count Q) 500)) (println (count Q))) - (if (empty? Q) - (println (dist [dim dim])) - (let [[u vu] (min-distance dist Q)] - (recur - (disj Q vu) - (reduce - #(let [alt (+ u (input %2))] - (cond-> %1 - (or (not (contains? dist %2)) (< alt (dist %2))) - (assoc %2 alt))) - dist - (find-neighbors Q vu))))))) +(loop [dist (zipmap (keys input) (repeat ##Inf)) + Q {[0 0] 0}] + (if (empty? Q) + (println (dist [dim dim])) + (let [[u distu] (first Q) + NN (reduce + #(let [dv (+ distu (input %2))] + (cond-> %1 + (> ((first %1) %2) dv) + (-> (update 0 assoc %2 dv) + (update 1 assoc %2 dv)))) + [dist {}] + (find-neighbors u))] + (recur (first NN) (sort-by val < (into (rest Q) (second NN))))))) diff --git a/day15/part2.clj b/day15/part2.clj index 1b2b409..a422ed0 100644 --- a/day15/part2.clj +++ b/day15/part2.clj @@ -1,5 +1,3 @@ -(require '[clojure.core.reducers :as r]) - (def input (->> (slurp "./in") (clojure.string/split-lines) (mapv (partial mapv (comp read-string str))) @@ -18,37 +16,26 @@ (into {}) )) -(defn min-distance [dist Q] - (r/fold - (r/monoid - #(if (< (first %1) (first %2)) %1 %2) - (constantly [##Inf []])) - (r/monoid - #(if (< (first %1) (dist %2)) %1 [(dist %2) %2]) - (constantly [##Inf []])) - (r/filter - (partial contains? dist) - (apply vector Q)))) +(def dim (apply max (map first (keys input)))) + +(defn find-neighbors [u] + (filter #(contains? input %) [(update u 0 inc) + (update u 0 dec) + (update u 1 inc) + (update u 1 dec)])) -(defn find-neighbors [Q u] - (filter #(contains? Q %) [(update u 0 inc) - (update u 0 dec) - (update u 1 inc) - (update u 1 dec)])) +(loop [dist (zipmap (keys input) (repeat ##Inf)) + Q {[0 0] 0}] + (if (empty? Q) + (println (dist [dim dim])) + (let [[u distu] (first Q) + NN (reduce + #(let [dv (+ distu (input %2))] + (cond-> %1 + (> ((first %1) %2) dv) + (-> (update 0 assoc %2 dv) + (update 1 assoc %2 dv)))) + [dist {}] + (find-neighbors u))] + (recur (first NN) (sort-by val < (into (rest Q) (second NN))))))) -(let [dim (apply max (map first (keys input)))] - (loop [Q (apply sorted-set (keys input)) - dist (assoc (hash-map) [0 0] 0)] - (when (= 0 (rem (count Q) 500)) (println (count Q))) - (if (empty? Q) - (println (dist [dim dim])) - (let [[u vu] (min-distance dist Q)] - (recur - (disj Q vu) - (reduce - #(let [alt (+ u (input %2))] - (cond-> %1 - (or (not (contains? dist %2)) (< alt (dist %2))) - (assoc %2 alt))) - dist - (find-neighbors Q vu)))))))