]> code.bitgloo.com Git - clyne/advent-of-code.git/commitdiff
day15: success, part2 ~88min; trying to improve
authorClyne Sullivan <clyne@bitgloo.com>
Thu, 16 Dec 2021 00:31:47 +0000 (19:31 -0500)
committerClyne Sullivan <clyne@bitgloo.com>
Thu, 16 Dec 2021 00:31:47 +0000 (19:31 -0500)
day15/part1.clj
day15/part2.clj

index 48dab23ce8e24932a9578015f18adc9292157b35..caf4e2c21089c1c630f18c0577fbff1117a7262d 100644 (file)
@@ -1,3 +1,5 @@
+(require '[clojure.core.reducers :as r])
+
 (def input (->> (slurp "./in")
                 (clojure.string/split-lines)
                 (mapv (partial mapv (comp read-string str)))
@@ -6,13 +8,16 @@
                 (into {})))
 
 (defn min-distance [dist Q]
-  (reduce
-    #(if (and (not= (dist %2) :inf)
-           (or (= :inf (first %1))
-               (< (dist %2) (first %1))))
-         [(dist %2) %2]
-         %1)
-    [:inf []] 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))))
 
 (defn find-neighbors [Q u]
   (filter #(contains? Q %) [(update u 0 inc)
                             (update u 1 dec)]))
 
 (let [dim (apply max (map first (keys input)))]
-  (loop [Q (set (keys input))
-         dist (-> (zipmap Q (repeat :inf)) (update [0 0] #(do % 0)))]
+  (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)
-          (loop [d dist f (find-neighbors Q vu)]
-            (if (empty? f)
-              d
-              (recur
-                (let [v (first f) alt (+ u (input v))]
-                  (if (or (= :inf (dist v)) (< alt (dist v)))
-                    (assoc d v alt)
-                    d
-                    ))
-                (rest f)
-                ))))))))
+          (reduce
+            #(let [alt (+ u (input %2))]
+               (cond-> %1
+                 (or (not (contains? dist %2)) (< alt (dist %2)))
+                 (assoc %2 alt)))
+            dist
+            (find-neighbors Q vu)))))))
 
index d48ba927cc2a163c1503fb664e7de11ab4a0fefe..1b2b409afc99a7255b4965bdd00993f529158efd 100644 (file)
@@ -1,3 +1,5 @@
+(require '[clojure.core.reducers :as r])
+
 (def input (->> (slurp "./in")
                 (clojure.string/split-lines)
                 (mapv (partial mapv (comp read-string str)))
                 ))
 
 (defn min-distance [dist Q]
-  (reduce
-    #(if (and (not= (dist %2) :inf)
-           (or (= :inf (first %1))
-               (< (dist %2) (first %1))))
-         [(dist %2) %2]
-         %1)
-    [:inf []]
-    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))))
 
 (defn find-neighbors [Q u]
   (filter #(contains? Q %) [(update u 0 inc)
                             (update u 1 inc)
                             (update u 1 dec)]))
 
-(loop [Q (set (keys input))
-       dist (-> (zipmap Q (repeat :inf)) (update [0 0] #(do % 0)))]
-  (if (empty? Q)
-    (println (dist [499 499]))
-    (let [[u vu] (min-distance dist Q)]
-      (recur
-        (disj Q vu)
-        (loop [d dist f (find-neighbors Q vu)]
-          (if (empty? f)
-            d
-            (recur
-              (let [v (first f) alt (+ u (input v))]
-                (if (or (= :inf (dist v)) (< alt (dist v)))
-                  (assoc d v alt)
-                  d
-                  ))
-              (rest f)
-              )))))))
-
+(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)))))))