2015-04-17 5 views
0

Вот код:Как сделать эту функцию решета ленивой?

;; Helper function for marking mutiples of a number as 0 
(defn mark 
    ([xs k m] (mark xs k m [])) 
    ([xs k m mark-vec] 
    (loop [[x & rest-xs] xs 
      k k 
      mark-vec mark-vec 
      ] 
    (cond 
     (and (nil? x) (nil? rest-xs)) mark-vec 
     (= k m) (recur rest-xs 1  (conj mark-vec 0)) 
     :else (recur rest-xs (inc k) (conj mark-vec x)) 
     )))) 

;; Sieve of Eratosthenes 
(defn sieve 
    ([xs] (sieve xs [])) 
    ([xs sieve-res] 
    (loop [[x & rest-xs] xs 
      sieve-res sieve-res] 
    (cond 
     (and (nil? x) (nil? rest-xs)) sieve-res 
     (= x 0) (recur rest-xs sieve-res) 
     :else (recur (mark rest-xs 1 x) (conj sieve-res x)))))) 

(take 10 (sieve (range 2 100))) 

Я хочу, чтобы это получить что-то вроде (iterate inc 2) и порождает бесконечную последовательность простых чисел.

+0

http://stackoverflow.com/a/29705514/2472391 – galdre

ответ

2

Наилучшим подходом было бы создать надлежащее функциональное инкрементное сито, такое как описано в статье The Genuine Sieve of Eratosthenes Мелиссы Э. О'Нейл.

Christophe Grand опубликовал несколько действительно красивых инкрементных ситовых реализаций here.

+0

Является ли ссылка Christophe Grand мертвой? Не могу открыть его здесь. – qed

+0

Кэшированная версия: https://webcache.googleusercontent.com/search?q=cache:http%3A%2F%2Fclj-me.cgrand.net%2F2009%2F07%2F30%2Feverybody-loves-the-sieve-of- Эратосфен% 2F –

Смежные вопросы