2009-10-19 4 views
7

Qual è l'equivalente Clojure (per l'algoritmo esatto) del seguente codice Python?Clojure numeri primi di sequenza pigro

from itertools import count 
from math import sqrt 

def prime_gen(): 
    primes = [] 
    for n in count(2): 
     if all(n%p for p in primes if p <= sqrt(n)): 
      primes.append(n) 
      yield n 
+0

FYI l'algoritmo esatto in Python è debole. Cerca l'efficiente generatore di prime infinite di Alex Martelli. –

+0

http://stackoverflow.com/questions/2211990/how-to-implement-an-efficient-infinite-generator-of-prime-numbers-in-python –

risposta

10

Questo è come Pythonish come posso farlo:

(def prime-gen 
    (let [primes (atom [])] 
     (for [n (iterate inc 2) 
      :when (not-any? #(zero? (rem n %)) 
          (filter #(<= % (Math/sqrt n)) 
            @primes))] 
     (do (swap! primes conj n) 
      n)))) 

(take 10 prime-gen) ; => (2 3 5 7 11 13 17 19 23 29) 

Clojure non prende in considerazione il numero intero da 0 a essere falso booleano. Mi ci sono voluti alcuni minuti per capire che il tuo codice Python stava approfittando di questo.

Here sono alcuni altri algoritmi numerici primo in Clojure. C'è anche un numero primo implementazione in clojure.contrib.lazy-seqs.

+0

Non ha bisogno di essere Pitonish :) Se non c'è una soluzione clojure più idiomatico per lo stesso algoritmo, si prega di inviare troppo. – Roskoto

+2

Dovresti seguire il link. Ci sono molti esempi e risposte lì. http://clj-me.cgrand.net/2009/07/30/everybody-loves-the-sieve-of-eratosthenes/#comments anche. – dnolen

+1

Bene, non è tutto ciò che non è Clojurish oltre a mutare un 'atomo'. Ci vorranno alcune contorsioni per evitare di usare un 'atomo' però. Alcuni algoritmi richiedono effetti collaterali e uno stile di programmazione non funzionale (in particolare cose come l'ordinamento in loco, lo shuffling, funzioni matematiche specifiche ecc.) Ed è OK passare a utilizzare strutture di dati mutabili in questi casi. Ecco perché Clojure li mette a disposizione. Potresti anche immergerti e usare strutture dati native Java per questo genere di cose. –

0

questa versione è molto più veloce di @ Brian Carper del

(def prime-gen 
    (let [primes (atom [2N])] 
    (iterate 
     #(let [ps @primes] 
     (loop [n (inc %)] 
      (if (loop [i 0] 
       (let [p (nth ps i)] 
        (cond 
        (< n (* p p)) true 
        (zero? (mod n p)) false 
        :else (recur (inc i))))) 
      (do (swap! primes conj n) n) 
      (recur (inc n))))) 
     (first @primes))))