J'ai cette mise en œuvre du tamis d'Eratosthène en Clojure:Clojure - tamis récursive queue de Eratosthène
(defn sieve [n]
(loop [last-tried 2 sift (range 2 (inc n))]
(if
(or (nil? last-tried) (> last-tried n))
sift
(let [filtered (filter #(or (= % last-tried) (< 0 (rem % last-tried))) sift)]
(let [next-to-try (first (filter #(> % last-tried) filtered))]
(recur next-to-try filtered))))))
Pour plus n
(comme 20000), il se termine par un débordement de pile. Pourquoi n'effectue-t-on pas un travail d'élimination de queue ici? Comment le réparer?
En note, mais ce n'est pas le tamis de Eratosthenes. SoE n'effectue pas d'opérations restantes, juste l'addition et le "barrage". Voir http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf pour une discussion prolongée (c'est une excellente lecture!); pour une belle mise en œuvre "incrémentale" de SoE dans Clojure par Christophe Grand, voir http://clj-me.cgrand.net/2009/07/30/everybody-loves-the-sieve-of-eratosthenes/ (c'est aussi le plus rapide version que j'ai vu jusqu'ici). –
@ Michał Marczyk merci. Je dirais que "rayer" est équivalent à "filtrage", et "addition" dans cet algorithme est équivalent à "multiplication" et par conséquent "reste". –
Pas vraiment. Le résultat est, bien sûr, le même, mais la complexité algorithmique est très différente. –