day12: document part2, make part1 more concise

master
Clyne 3 years ago
parent c026fd3f3e
commit c507675805

@ -7,21 +7,13 @@
(#(concat % (map reverse %))) (#(concat % (map reverse %)))
)) ))
(def search-caves
(memoize (fn [id]
(filter #(= (first %) id) caves))))
(defn get-caves-forward [klst] (defn get-caves-forward [klst]
(let [end (first klst)]
(if (str/starts-with? end "end")
[klst]
(map #(cons (second %) klst) (map #(cons (second %) klst)
(filter (filter
(fn [cv] #(or (< (int (first (second %))) 96)
(or (< (int (first (second cv))) 96) (not-any? (partial = (second %)) klst))
(not-any? #(= % (second cv)) klst))) (filter #(= (first %) (first klst)) caves)
(search-caves end) )))
)))))
(loop [lst (get-caves-forward ["start"]) ms '()] (loop [lst (get-caves-forward ["start"]) ms '()]
(let [nxt (->> lst (let [nxt (->> lst

@ -1,5 +1,6 @@
(require '[clojure.string :as str]) (require '[clojure.string :as str])
; Build list of cave connections:
(def caves (->> (slurp "./in") (def caves (->> (slurp "./in")
(str/split-lines) (str/split-lines)
(map #(str/split % #"-")) (map #(str/split % #"-"))
@ -7,37 +8,41 @@
(#(concat % (map reverse %))) (#(concat % (map reverse %)))
)) ))
; Try to help execution speed by memoizing cave searches:
(def search-caves (def search-caves
(memoize (fn [id] (memoize (fn [id]
(filter #(= (first %) id) caves)))) (filter #(= (first %) id) caves))))
(defn get-caves-forward [klst] ; Given current path 'path', return a list of valid paths that branch
(let [end (first klst)] ; from 'path'. Note, paths are stored in reverse order.
(if (str/starts-with? end "end") (defn get-caves-forward [path]
[klst] (map #(cons (second %) path)
(map #(cons (second %) klst)
(filter (filter
(fn [cv] (fn [cv]
(and (and
; Do not return to start
(not (str/starts-with? (second cv) "start")) (not (str/starts-with? (second cv) "start"))
(or (or
; Always allow uppercase paths
(< (int (first (second cv))) 96) (< (int (first (second cv))) 96)
(let [rv (count (filter #(= % (second cv)) klst)) (let [lw (filter #(= (str/lower-case %) %) path)]
lw (filter #(= (str/lower-case %) %) klst)] (or
(or (= 0 rv) (< (- (count lw) (count (distinct lw))) 1))) ; Allow lowercase paths that have never been visited
) (= 0 (count (filter #(= % (second cv)) path)))
)) ; Allow one duplicate if there are none yet
(search-caves end) (= 0 (- (count lw) (count (distinct lw)))))))))
))))) ; Only work with paths that we connect to
(search-caves (first path))
)))
(loop [lst (get-caves-forward ["start"]) ms []] (loop [paths (get-caves-forward ["start"]) complete-paths []]
(println (count ms)) (let [branches (->> paths
(let [nxt (->> lst
(map get-caves-forward) (map get-caves-forward)
(apply concat)) (apply concat))
mtchs (concat ms (filter #(= (first %) "end") nxt)) complete-branches (concat complete-paths
nxtlst (filter #(not= (first %) "end") nxt)] (filter #(= (first %) "end") branches))
(if (empty? nxtlst) next-paths (filter #(not= (first %) "end") branches)]
(println (count mtchs)) (if (empty? next-paths)
(recur nxtlst mtchs)))) (println (count complete-branches))
(recur next-paths complete-branches))))

Loading…
Cancel
Save