]> code.bitgloo.com Git - clyne/advent-of-code.git/commitdiff
add day 15
authorClyne Sullivan <clyne@bitgloo.com>
Wed, 15 Dec 2021 17:03:41 +0000 (12:03 -0500)
committerClyne Sullivan <clyne@bitgloo.com>
Wed, 15 Dec 2021 17:03:41 +0000 (12:03 -0500)
day15/part1.clj [new file with mode: 0644]
day15/part2.clj [new file with mode: 0644]

diff --git a/day15/part1.clj b/day15/part1.clj
new file mode 100644 (file)
index 0000000..48dab23
--- /dev/null
@@ -0,0 +1,42 @@
+(def input (->> (slurp "./in")
+                (clojure.string/split-lines)
+                (mapv (partial mapv (comp read-string str)))
+                (#(for [y (range 0 (count %)) x (range 0 (count (first %)))]
+                    {[y x] (get-in % [y x])}))
+                (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))
+
+(defn find-neighbors [Q u]
+  (filter #(contains? Q %) [(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 (set (keys input))
+         dist (-> (zipmap Q (repeat :inf)) (update [0 0] #(do % 0)))]
+    (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)
+                ))))))))
+
diff --git a/day15/part2.clj b/day15/part2.clj
new file mode 100644 (file)
index 0000000..d48ba92
--- /dev/null
@@ -0,0 +1,54 @@
+(def input (->> (slurp "./in")
+                (clojure.string/split-lines)
+                (mapv (partial mapv (comp read-string str)))
+                (#(for [y (range 0 (count %)) x (range 0 (count (first %)))]
+                    {[y x] (get-in % [y x])}))
+                (into {})
+                ((fn [lst]
+                (reduce
+                  #(into %1
+                     (for [j (range 0 5) i (range 0 5)]
+                       {[(+ (first (key %2)) (* 100 j)) (+ (second (key %2)) (* 100 i))]
+                        (let [s (+ i j (val %2))] (if (> s 9) (- s 9) s))}))
+                  {}
+                  lst
+                  )))
+                (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
+    ))
+
+(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 [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)
+              )))))))
+