%%% -*- mode: erlang -*-
%%% $Id: sieve.erlang,v 1.12 2000/10/07 08:41:44 doug Exp $
%%% http://www.bagley.org/~doug/shootout/

-module(sieve).
-export([main/0, main/1]).
-import(io, [fwrite/2]).
-import(lists, [seq/2]).
-import(math, [sqrt/1]).

%% get the program argument, which is how many test iterations
%% to run
main() -> main(['1']).
main(Arg) ->
    [Tmp] = Arg,
    Num = list_to_integer(atom_to_list(Tmp)),
    test(Num),
    halt(0).

test(N) ->
    Primes = primes(8192),
    Count = length(Primes),
    case N > 1 of
    true  -> test(N-1);
    false -> fwrite("Count: ~w\n", [Count])
    end.

primes(Size) ->
    era(sqrt(Size), seq(2,Size)).


%% modified from Maurice Castro's original (below), sped it up 
%% a fraction by reordering clauses and args, but if it's less
%% clear now, that's my fault.
%% -Doug

era(Max, [H|T]) when H =< Max ->
    [H | era(Max, sieve([H|T], H))];
era(Max, L) -> 
    L.

sieve([H|T], N) when H rem N =/= 0 ->
    [H | sieve(T, N)];
sieve([H|T], N) ->
    sieve(T, N);
sieve([], N) ->
    [].


%%% eratosthenes algorithm from Maurice Castro, with permission, 
%%% from his book, _Erlang in Real Time_, ISBN: 0864447434
%%% http://www.serc.rmit.edu.au/~maurice/erlbk/eg/choice/erasto.erl
%
%era(Max, L) when hd(L) =< Max ->
%    Prime = hd(L),
%    [Prime | era(Max, sieve(Prime, L))];
%era(Max, L) -> 
%    L.
%
%sieve(N, []) ->
%    [];
%sieve(N, [H|T]) when H rem N == 0 ->
%    sieve(N, T);
%sieve(N, [H|T]) ->
%    [H | sieve(N, T)].