Als Neophyt Clojurian, war es recommended to me, dass ich durch die Project Euler Probleme als eine Möglichkeit, die Sprache zu lernen gehen. Es ist definitiv ein guter Weg, um Ihre Fähigkeiten zu verbessern und Selbstvertrauen zu gewinnen. Ich habe gerade meine Antwort auf problem #14 beendet. Es funktioniert gut, aber um es effizient laufen zu lassen, musste ich einige Memoization implementieren. Ich konnte die vordefinierte memoize
Funktion nicht verwenden, weil mein Code strukturiert war, und ich denke, es war eine gute Erfahrung, meine eigenen sowieso zu rollen. Meine Frage ist, ob es eine gute Möglichkeit gibt, meinen Cache innerhalb der Funktion selbst einzukapseln, oder ob ich einen externen Cache definieren muss, wie ich es getan habe. Außerdem würden alle Tipps, die meinen Code idiomatischer machen, geschätzt.Projekt Euler # 14 und Memoisierung in Clojure
(use 'clojure.test)
(def mem (atom {}))
(with-test
(defn chain-length
([x] (chain-length x x 0))
([start-val x c]
(if-let [e (last(find @mem x))]
(let [ret (+ c e)]
(swap! mem assoc start-val ret)
ret)
(if (<= x 1)
(let [ret (+ c 1)]
(swap! mem assoc start-val ret)
ret)
(if (even? x)
(recur start-val (/ x 2) (+ c 1))
(recur start-val (+ 1 (* x 3)) (+ c 1)))))))
(is (= 10 (chain-length 13))))
(with-test
(defn longest-chain
([] (longest-chain 2 0 0))
([c max start-num]
(if (>= c 1000000)
start-num
(let [l (chain-length c)]
(if (> l max)
(recur (+ 1 c) l c)
(recur (+ 1 c) max start-num))))))
(is (= 837799 (longest-chain))))
Ich wollte Ihnen nur danken, dass Sie mich dem Projekt euler aussetzen. Ich versuche auch clojure zu lernen. –
Extrem kleiner Punkt, aber (inc c) ist wahrscheinlich idiomatischer als (+ 1 c). –