add memoizing utils

This commit is contained in:
Adam Jeniski 2023-12-15 22:55:05 -05:00
parent 1f82ebfc52
commit 31348da8d4
2 changed files with 56 additions and 36 deletions

View File

@ -46,6 +46,29 @@
([f] #(reduce f %)) ([f] #(reduce f %))
([f init] #(reduce f init %))) ([f init] #(reduce f init %)))
(defmacro mfn
"like fn but memoizes return values, including recursive calls"
[name arglist & body]
`(let [dp# (atom {})
f# (fn ~name ~arglist
(or (@dp# [~@arglist])
(let [res# ~@body]
(swap! dp# assoc [~@arglist] res#)
res#)))]
f#))
(defmacro defmfn
"like defn but for a memoized fn, see ajet.core/mfn"
[name & args]
`(def ~name (mfn ~name ~@args)))
(comment (comment
(map (static-fn Long/parseLong) ["123" "456"]) (map (static-fn Long/parseLong) ["123" "456"])
input-cache) input-cache
(defmfn fib [x]
(if (< x 2)
x
(+ (fib (dec x))
(fib (- x 2)))))
(fib 200N))

View File

@ -1,50 +1,47 @@
(ns day12 (ns day12
(:require (:require
[clojure.string :as str] [clojure.string :as str]
[core :refer [get-puzzle-input]])) [core :refer [get-puzzle-input mfn]]))
(defn parse-line [line] (-> (str/split line #" ") (defn parse-line [line] (-> (str/split line #" ")
(update 1 #(->> (str/split % #",") (update 1 #(->> (str/split % #",")
(mapv parse-long))))) (mapv parse-long)))))
(defn ans [dots blocks] (defn ans [dots blocks]
(let [dp (atom {}) (let
f [len-blocks (count blocks)
(fn f [dots blocks i bi current] f
(or (@dp [i bi current]) (mfn f [i bi current]
(let [len-blocks (count blocks) (let [dot-i (when (< i (count dots)) (get dots i))]
dot_i (when (< i (count dots)) (get dots i)) (if (= i (count dots))
v (if (= i (count dots)) (cond (and (= bi len-blocks)
(cond (and (= bi len-blocks) (= current 0))
(= current 0)) 1
1 (and (= bi (dec len-blocks))
(and (= bi (dec len-blocks)) (= current (get blocks bi)))
(= current (get blocks bi))) 1
1 :else
:else 0)
0) (->> [\. \#]
(->> [\. \#] (map #(if (or (= dot-i %)
(map #(if (or (= dot_i %) (= dot-i \?))
(= dot_i \?)) (cond (and (= % \.)
(cond (and (= % \.) (= current 0))
(= current 0)) (f (inc i) bi 0)
(f dots blocks (inc i) bi 0)
(and (= % \.) (and (= % \.)
(> current 0) (> current 0)
(< bi len-blocks) (< bi len-blocks)
(= (get blocks bi) current)) (= (get blocks bi) current))
(f dots blocks (inc i) (inc bi) 0) (f (inc i) (inc bi) 0)
(= % \#) (= % \#)
(f dots blocks (inc i) bi (inc current)) (f (inc i) bi (inc current))
:else 0) :else 0)
0)) 0))
(reduce +)))] (reduce +)))))]
(swap! dp assoc [i bi current] v) (f 0 0 0)))
v)))]
(f dots blocks 0 0 0)))
;; part 1 ;; part 1
(->> (get-puzzle-input 12) (->> (get-puzzle-input 12)