]> code.bitgloo.com Git - clyne/advent-of-code.git/commitdiff
day15: priority queue, <10 sec
authorClyne Sullivan <clyne@bitgloo.com>
Thu, 16 Dec 2021 02:48:23 +0000 (21:48 -0500)
committerClyne Sullivan <clyne@bitgloo.com>
Thu, 16 Dec 2021 02:48:23 +0000 (21:48 -0500)
day15/part1.clj
day15/part2.clj

index caf4e2c21089c1c630f18c0577fbff1117a7262d..7838e34234b2f0e9482baa0f5d40b7c004ffa3e5 100644 (file)
@@ -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 [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)))))))
 
index 1b2b409afc99a7255b4965bdd00993f529158efd..a422ed019777db13b27016ed0ac8ec63d87af15d 100644 (file)
@@ -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)))
                 (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)))))))