Challenges: * Implement rudimentary SieveOfEratosthenes with no optimizations. * Implement a smarter sieve for PrimeNumber''''''s. * Animate the sieve. '''Remember: ConvertSpacesToTabsNotForCode''' ---- '''BasicLanguage''': The code at http://www.quitebasic.com/prj/math/eratosthenes/ marks composite numbers while STEPping through an array, not using MOD. ---- '''BefungeLanguage:''' 2>:3g" "-!v\ g30 < |!`"O":+1_:.:03p>03g+:"O"`| @ ^ p3\" ":< 2 234567890123456789012345678901234567890123456789012345678901234567890123456789 ---- '''CeeLanguage''': See the SieveOfEratosthenes page for an example in C. ---- '''CommonLisp:''' A version where a bit vector is marked and then its indices are listed: (defun sieve (n) (let ((bit-vector (make-array n :initial-element 1 :element-type 'bit))) (loop for i from 2 upto (isqrt n) do (loop for j from i for index = (* i j) until (>= index n) do (setf (sbit bit-vector index) 0))) (loop for i from 2 below (length bit-vector) unless (zerop (sbit bit-vector i)) collect i))) ---- The '''FalseLanguage''' page has a couple one-liner PrimeNumber finders. ---- '''ForthLanguage:''' Three fast (no MODs) versions here: http://wiki.forthfreak.net/index.cgi?SieveOfEratosthenes ---- '''GameOfLife''': http://www.radicaleye.com/lifepage/patterns/primes.html ---- '''HaskellLanguage''': combine op (i1:l1) (i2:l2) = (op i1 i2):(combine op l1 l2) ns n = n:(ns n) nmults n = n:(combine (+) (nmults n) (ns n)) diff (i1 : l1) (i2 : l2) | i1 < i2 = i1:(diff l1 (i2:l2)) | i1 == i2 = (diff l1 l2 ) | i1 > i2 = (diff (i1:l1) l2 ) filtermults (li:l) = li:(filtermults (diff l (nmults li))) primes = filtermults [2..] Main> take 10 primes [2,3,5,7,11,13,17,19,23,29] This solution uses no multiplication or division, only addition. For each prime, a stream containing all of its multiples is generated, and this stream is subtracted from the integers. The resulting stream contains only the primes. We must use custom-defined ''diff'' because the built-in ''notElem'' or the infix ''\\'' "remove" operator won't terminate on an infinite list. -- JonathanTang The above duplicates a lot of the Prelude functions. Changing variable names we get a one-liner, except for the ''diff'': sieve (p:ns) = p : sieve (diff ns [p, p+p..]) primes = sieve [2..] A true one-liner is DavidTurner's sieve (p:ns) = p : sieve [n | n <- ns, rem n p /= 0] where ''diff'' is replaced with the standard ListComprehension syntax and ''rem'' divisibility testing. But it is a TrialDivision algorithm i.e. its theoretical complexity is worse. It is essential for the Sieve of Eratosthenes that it ''doesn't test'' for composites but rather directly ''generates'' them through iterated addition. This is because the testing of each candidate number must go through all the primes up to its square root, whereas with direct generation each composite is generated only from its ''prime factors'' up to its square root. Both of the above versions start removing the multiples of each produced prime immediately, but actually need to do that only from the prime's square. Thus both of them create many superfluous removal streams. This makes them very slow and of quadratic time complexity, or worse, in ''n'' primes produced. The bounded formulation stops early and thus does not make any unneeded removal steps: primesTo m = sieve [2..] where sieve (p:ns) | p*p > m = p : takeWhile (<= m) ns -- all ns up to p*p are prime already | otherwise = p : sieve (diff ns [p*p, p*p+p..]) Ideally, each multiple should be removed in ''O(1)'' time, or equivalently, ''O(|b|)'' for the whole ''(diff a b)'' removal step. This is achievable on mutable RandomAccess arrays. Unfortunately, on SinglyLinkedLists it takes ''O(|union a b|)'' time. With BinaryTrees it would have been ''O(|b|*log(|a|))''. Still, the amount of removal steps is strictly limited to what is necessary. Even though each ''diff'' step starts prematurely (right after ''p'' instead of at ''p*p'') this code runs much faster than the first one and with EmpiricalOrdersOfGrowth of about '''''~ n^1.4''''' in ''n'' primes produced. The unbounded formulation is fixed by ''postponing'' the sieving, sieve ns (p:ps) | (h,t) <- span (< p*p) ns = h ++ sieve (diff t [p*p, p*p+p ..]) ps primes = 2 : sieve [3..] primes In Richard Bird's version, the above ''(...(((ns-a)-b)-c)-...)'' workflow is rearranged into ''(ns-(a+(b+(c+...))))'': primes = 2 : diff [3..] (foldr (\p r-> p*p : add [p*p+p, p*p+2*p..] r) [] primes) add (x:xs) (y:ys) | xy = y : add (x:xs) ys With tree-shaped folding and telescopic multistage recursive production of primes (to minimize memory usage) we get primes = 2 : _Y ((3:) . gaps 5 . _U . map (\p-> [p*p, p*p+2*p..])) _Y g = g (_Y g) -- non-sharing (recursive) fixpoint combinator _U ((x:xs):t) = x : (add xs . _U . pairs) t -- bigU == sort . concat pairs (a:b:t) = add a b : pairs t gaps x (y:ys) | x < y = x : gaps (x+2) (y:ys) -- gaps 5 == ([5,7..] \\) | otherwise = gaps (x+2) ys -- x==y This runs at about '''''~ n^1.2''''' EmpiricalOrdersOfGrowth, in ''n'' primes produced, and in practically constant space. WheelFactorization optimization can be further applied. More at http://haskell.org/haskellwiki/Prime_numbers. -- WillNess ---- '''JavaScript:''' function sieve(max) { var D = [], primes = []; for (var q=2; q factor and num % factor == 0: world.beepers[world.robot] = 0 pause(0.4) move() if num % 10 == 0: turnaround() zipTenSpaces() turnright() move() turnright() num += 1 turnright() zipTenSpaces() turnleft() def turnaround(): turnleft() turnleft() def zipTenSpaces(): for i in range(10): setDelayAmount(0.01) move() setDelayAmount(0.05) def turnright(): turnaround() turnleft() def spin(): turnaround() turnaround() def celebrate(): while 1: turnleft() main() ---- '''RubyLanguage:''' def sieve(upper) nums = (2..upper).to_a iend = nums.size - 1 sqrt = Math.sqrt(upper).to_i (0..(nums.index(sqrt))).each do |i| n = nums[i] # n is either prime or nil (i + n).step(iend, n) { |j| nums[j] = nil } unless n.nil? end nums.compact # eliminate nil entries end sieve(19) # returns [2, 3, 5, 7, 11, 13, 17, 19] ---- '''SchemeLanguage''': (Using SiCp style streams) ;;;; Stream Implementation (define (head s) (car s)) ;; _odd_ non-memoized streams, (define (tail s) ((cdr s))) ;; per SRFI-41 (define-syntax s-cons (syntax-rules () ((s-cons h t) (cons h (lambda () t))))) ;;;; Stream Utility Functions (define (from-By x s) (s-cons x (from-By (+ x s) s))) (define (take n s) (cond ((> n 1) (cons (head s) (take (- n 1) (tail s)))) ((= n 1) (list (head s))) ;; don't force it too soon (else ()))) ;; so (take 4 (s-map / (from-By 4 -1))) works (define (drop n s) (cond ((> n 0) (drop (- n 1) (tail s))) (else s))) (define (s-map f s) (s-cons (f (head s)) (s-map f (tail s)))) (define (s-diff s1 s2) (let ((h1 (head s1)) (h2 (head s2))) (cond ((< h1 h2) (s-cons h1 (s-diff (tail s1) s2 ))) ((< h2 h1) (s-diff s1 (tail s2))) (else (s-diff (tail s1) (tail s2)))))) (define (s-union s1 s2) (let ((h1 (head s1)) (h2 (head s2))) (cond ((< h1 h2) (s-cons h1 (s-union (tail s1) s2 ))) ((< h2 h1) (s-cons h2 (s-union s1 (tail s2)))) (else (s-cons h1 (s-union (tail s1) (tail s2))))))) ;;;; odd multiples of an odd prime (define (mults p) (from-By (* p p) (* 2 p))) ;;;; The Sieve itself, bounded, ~ O(n^1.4) in n primes produced ;;;; (unbounded version runs at ~ O(n^2.2), and growing worse) ;;;; **only valid up to m**, includes composites above it (define (primes-To m) (define (sieve s) (let ((p (head s))) (cond ((> (* p p) m) s) (else (s-cons p (sieve (s-diff (tail s) (mults p)))))))) (s-cons 2 (sieve (from-By 3 2)))) ;;;; all the primes' multiples, tree-merged, removed; ;;;; ~O(n^1.17..1.15) time in producing 100K .. 1M primes ;;;; ~O(1) space (O(pi(sqrt(m))) probably) (define (primes-TM) (define (no-mults-From from) (s-diff (from-By from 2) (s-tree-join (s-map mults odd-primes)))) (define odd-primes (s-cons 3 (no-mults-From 5))) (s-cons 2 (no-mults-From 3))) ;;;; join an ordered stream of streams (here, of primes' multiples) ;;;; into one ordered stream, via an infinite right-deepening tree (define (s-tree-join sts) ;; sts -> s (define (join-With of-Tail sts) ;; sts -> s (s-cons (head (head sts)) (s-union (tail (head sts)) (of-Tail (tail sts))))) (define (pairs sts) ;; sts -> sts (s-cons (join-With head sts) (pairs (tail (tail sts))))) (join-With (lambda (t) (s-tree-join (pairs t))) sts)) ;;;; Print 10 last primes from the first thousand primes (begin (display (take 10 (drop 990 (primes-To 7919)))) (newline) (display (take 10 (drop 990 (primes-TM)))) (newline)) ---- '''SmalltalkLanguage:''' Didn't realize it till afterwards, but I ended up with something pretty close to the Lisp solution above, but using nil instead of 0 and 1. -- RamonLeon Integer>>sieveOfEratosthenes | primes | primes := Array new: self. 2 to: self do: [:each | (primes at: each) ifNil: [each + each to: self by: each do: [:notPrime | primes at: notPrime put: notPrime]]]. ^(2 to: self) select: [:each | (primes at: each) isNil] 19 sieveOfEratosthenes -> (2 3 5 7 11 13 17 19) ---- MATLAB: function [ primes ] = sieveOfEratosthenes( N ) sieve=1:N; p=2; while p^2<=N sieve(p^2:p:N)=0; p=find(sieve>p,1); end primes = sieve(sieve>1); end ---- CategoryInManyProgrammingLanguages