2009-10-19 78 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))))