% ---------------------------------------------------------------------------- %
% sieve.m
% Ralph Becket <rbeck@microsoft.com>
% Mon Jan 8 14:23:22 GMT 2001
% vim: ts=4 sw=4 et tw=0 wm=0 ff=unix
%
% Eratosthenes' Sieve - counts the number of primes in 2..8192
%
% ---------------------------------------------------------------------------- %
:- module mytest.
:- interface.
:- import_module io.
:- pred main(io__state, io__state).
:- mode main(di, uo) is cc_multi.
:- implementation.
:- import_module int, bool, array, string, list, require, benchmarking.
main -->
io__command_line_arguments(ArgV),
( { ArgV = [], Repeats = 1 }
; { ArgV = [Arg], Repeats = string__det_to_int(Arg) }
; { ArgV = [_,_|_], error("usage: sieve [NumIterations]") }
),
{ P = ( pred(Sz::in, N::out) is det :- N = count_primes(Sz) ) },
{ benchmarking__benchmark_det(P, 8192, Count, Repeats, Time) },
io__format("Count: %d\n", [i(Count)]).
:- func count_primes(int) = int.
count_primes(Size) = sieve_and_count(2, array__init(Size, yes), 0).
:- func sieve_and_count(int, array(bool), int) = int.
:- mode sieve_and_count(in, array_di, in) = out is det.
sieve_and_count(I, A, N) =
( if I > array__max(A) then N
else if array__lookup(A, I) = no then sieve_and_count(I + 1, A, N)
else sieve_and_count(I + 1, filter_multiples(I + I, I, A), N + 1)
).
:- func filter_multiples(int, int, array(bool)) = array(bool).
:- mode filter_multiples(in, in, array_di) = array_uo is det.
filter_multiples(I, P, A) =
( if I > array__max(A)
then A
else filter_multiples(I + P, P, array__set(A, I, no))
).