Ho questa implementazione del crivello di Eratostene in Clojure:Clojure - coda setaccio ricorsiva di Eratostene
(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))))))
Per maggiore n
(come 20000) termina con overflow dello stack. Perché qui non funziona l'eliminazione chiamata coda? Come sistemarlo?
Come nota a margine, ma questo non è il setaccio di Eratostene. SoE non esegue operazioni di resto, solo aggiunte e "crossing out". Vedi http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf per una discussione estesa (è un'ottima lettura!); per una bella implementazione SoE "incrementale" in Clojure di Christophe Grand, vedi http://clj-me.cgrand.net/2009/07/30/everybody-loves-the-sieve-of-eratosthenes/ (è anche il più veloce versione che ho visto finora). –
@ Michał Marczyk ringrazia. Direi che "crossing out" equivale a "filtering" e "addizione" in questo algoritmo equivale a "moltiplicazione" e di conseguenza "resto". –
Non proprio. Il risultato è, ovviamente, lo stesso, ma la complessità algoritmica è molto diversa. –