Como clojurian neófito, fue recommended to me que pasé por los problemas Project Euler como una forma de aprender el idioma. Definitivamente es una gran manera de mejorar tus habilidades y ganar confianza. Acabo de terminar mi respuesta al problem #14. Funciona bien, pero para que funcione de manera eficiente tuve que implementar algunas memorias. No pude usar la función preempaquetada memoize
debido a la forma en que estaba estructurado mi código, y creo que fue una buena experiencia para mí. Mi pregunta es si hay una buena manera de encapsular mi caché dentro de la función en sí, o si tengo que definir un caché externo como lo he hecho. Además, cualquier consejo para hacer que mi código sea más idiomático sería apreciado.Proyecto Euler # 14 y memorización en 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))))
Solo quería agradecerle por exponerme al proyecto euler. Yo también estoy tratando de aprender clojure. –
Punto extremadamente menor, pero (inc c) es probablemente más idiomático que (+ 1 c). –