Come clojuriano neofita, è stato recommended to me che ho passato i problemi Project Euler come un modo per imparare la lingua. È sicuramente un ottimo modo per migliorare le tue abilità e acquisire sicurezza. Ho appena finito la mia risposta allo problem #14. Funziona bene, ma per farlo funzionare in modo efficiente ho dovuto implementare alcune memoization. Non ho potuto utilizzare la funzione memoize
preconfezionata a causa del modo in cui il mio codice era strutturato, e penso che sia stata una buona esperienza girare il mio comunque. La mia domanda è se c'è un buon modo per incapsulare la mia cache all'interno della funzione stessa, o se devo definire una cache esterna come ho fatto io. Inoltre, qualsiasi suggerimento per rendere il mio codice più idiomatico sarebbe apprezzato.Progetto Eulero # 14 e memoizzazione 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))))
Volevo solo ringraziarvi per avermi esposto al progetto euler. Anche io sto cercando di imparare il clojure. –
Punto estremamente minore, ma (inc c) è probabilmente più idiomatico di (+ 1 c). –