-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathesieve.clj
74 lines (63 loc) · 2.78 KB
/
esieve.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
;; This source code is released under MIT License
;; Copyright (c) 2016 Peter Cerman (https://github.com/pcerman)
;;----------------------------------------------------------------------
;; Pairing heap (https://en.wikipedia.org/wiki/Pairing_heap)
(defn ph:merge [h1 h2]
(cond (empty? h1) h2
(empty? h2) h1
:else (let [k1 ((first h1) 0)
k2 ((first h2) 0)]
(if (< k1 k2)
(list* (first h1) h2 (rest h1))
(list* (first h2) h1 (rest h2))))))
(defn ph:insert [ph k v]
(ph:merge (list (vector k v)) ph))
(defn ph:first [ph]
(if (empty? ph) nil
(first ph)))
(defn ph:merge-pairs [ls]
(loop [ls ls ph nil]
(cond (empty? ls) ph
(empty? (rest ls)) (ph:merge ph (first ls))
:else (recur (rest (rest ls))
(ph:merge (ph:merge (first ls) (second ls))
ph)))))
(defn ph:remove-min [ph]
(if (empty? ph) nil
(ph:merge-pairs (rest ph))))
;;----------------------------------------------------------------------
;; Infinite lazy sequence of the prime numbers
;; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;; This is implementation of the Sieve of Eratosthenes by using
;; functional programming principles.
(defn esieve []
(letfn [(sieve-seq [pn wh mp]
(let [kv (ph:first mp)
kn (if kv (kv 0) (inc pn))]
(cond (< kn pn) (recur pn wh (ph:insert (ph:remove-min mp)
(+ kn (kv 1))
(kv 1)))
(= kn pn) (recur (+ pn (first wh))
(next wh)
(ph:insert (ph:remove-min mp)
(+ kn (kv 1))
(kv 1)))
:else (cons pn
(lazy-seq
(sieve-seq (+ pn (first wh))
(next wh)
(ph:insert mp (* pn pn)
(+ pn pn))))))))]
(let [wheel2357 (cycle [2 4 2 4 6 2 6 4 2 4 6 6 2 6 4 2
6 4 6 8 4 2 4 2 4 8 6 4 6 2 4 6
2 6 6 4 2 4 6 2 6 4 2 4 2 10 2 10])]
(concat
(lazy-seq '(2 3 5 7))
(sieve-seq 11 wheel2357 nil)))))
(def primes (esieve))
;;----------------------------------------------------------------------
;; Example:
;; function esieve-example returns lazy-seq of first 25 primes:
;; (2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97)
(defn esieve-example []
(take 25 primes))