2009-10-19 47 views
7

Cuál es el equivalente Clojure (para el algoritmo exacto) del siguiente código Python?Clojure números primos secuencia perezosa

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 el algoritmo exacto en Python es débil. Busque el eficiente generador infinito de Alex Martelli. –

+0

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

Respuesta

10

Esto es tan Pythonish que puedo hacerlo:

(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 no tiene en cuenta el número entero 0 es falso booleano. Me tomó unos minutos darme cuenta de que su código Python se estaba aprovechando de esto.

Here son algunos otros algoritmos de números primos en Clojure. También hay una implementación de número principal en clojure.contrib.lazy-seqs.

+0

No tiene por qué ser Pitonish :) Si hay una solución clojure más idiomática para el mismo algoritmo, por favor envíela también. – Roskoto

+2

Debe seguir el enlace. Hay muchos ejemplos y respuestas allí. También http://clj-me.cgrand.net/2009/07/30/everybody-loves-the-sieve-of-eratosthenes/#comments. – dnolen

+1

Bueno, no es todo lo que un-Clojurish distinta de la mutación de un 'atom'. Sin embargo, tomaría algunas contorsiones evitar el uso de un 'átomo '. Algunos algoritmos demandan efectos secundarios y un estilo de programación no funcional (especialmente cosas como clasificación en el lugar, barajado, funciones matemáticas específicas, etc.) y está bien cambiar a utilizar estructuras de datos mutables en esos casos. Es por eso que Clojure los pone a disposición. Incluso podría sumergirse y utilizar estructuras de datos Java nativas para este tipo de cosas. –

0

Esta versión es mucho más rápido que @ Brian Carper de

(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)))) 
Cuestiones relacionadas