2009-10-19 13 views
7

Co to jest odpowiednik Clojure (dla dokładnego algorytmu) następującego kodu Pythona?Clojure liczby pierwsze leniwa sekwencja

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 dokładny algorytm w Pythonie jest słaby. Poszukaj wydajnego generatora nieskończonego prime Alexa Martellego. –

+0

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

Odpowiedz

10

To jak Pythonish jak mogę to zrobić:

(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 nie bierze pod uwagę liczbę całkowitą 0 do być logiczna fałsz. Zajęło mi kilka minut, aby dowiedzieć się, że twój kod Pythona wykorzystywał to.

Here to niektóre inne algorytmy liczb pierwszych w Clojure. Istnieje również pierwsza implementacja numeru w clojure.contrib.lazy-seqs.

+0

To nie musi być Pitonish :) Jeśli jest bardziej idiomatyczne rozwiązanie clojure dla tego samego algorytmu, proszę również przesłać go. – Roskoto

+2

Powinieneś kliknąć link. Istnieje wiele przykładów i odpowiedzi. Również http://clj-me.cgrand.net/2009/07/30/everybody-loves-the-sieve-of-eratosthenes/#comments. – dnolen

+1

Cóż, to nie wszystko, co un-Clojurish poza mutowaniem "atomu". Aby uniknąć użycia "atomu", trzeba trochę skrzywienia. Niektóre algorytmy wymagają efektów ubocznych i niefunkcjonalnego stylu programowania (w szczególności takich rzeczy jak sortowanie na miejscu, tasowanie, określone funkcje matematyczne itp.) I można w takich przypadkach przełączyć się na używanie zmiennych struktur danych. Właśnie dlatego Clojure sprawia, że ​​są one dostępne. Można nawet zanurkować i używać natywnych struktur danych Java dla tego typu rzeczy. –

0

Ta wersja jest o wiele szybciej niż @Brian Carper na

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