2009-10-19 77 views
7

什麼是以下Python代碼的Clojure等效(對於確切的算法)?Clojure素數懶惰序列

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

僅供參考Python中的精確算法是弱快得多。尋找Alex Martelli的高效無限素材生成器。 – 2010-09-21 00:18:54

+0

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

回答

10

這是因爲Pythonish,我可以把它:

(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不考慮整數0是布爾值false。我花了幾分鐘才弄清楚你的Python代碼正在利用這一點。

Here是Clojure中的一些其他素數算法。 clojure.contrib.lazy-seqs還有一個素數實現。

+0

它不需要是Pitonish :)如果有對於相同的算法更常用的clojure解決方案,請發送它。 – Roskoto 2009-10-19 20:51:35

+2

您應該點擊鏈接。那裏有很多例子和答案。還有http://clj-me.cgrand.net/2009/07/30/everybody-loves-the-sieve-of-eratosthenes/#comments。 – dnolen 2009-10-19 21:10:49

+1

呃,除了變異'atom'外,並不是所有的非Clojurish。儘管避免使用「原子」,但它需要一些扭曲。一些算法需要副作用和非函數式編程風格(特別是像現場排序,混洗,特定數學函數等),在這種情況下切換到使用可變數據結構是可以的。這就是Clojure使它們可用的原因。你甚至可以下潛並使用原生Java數據結構來處理這些事情。 – 2009-10-19 21:15:51

0

這個版本與@布賴恩·卡珀的

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