Erastothenes
Chris Nicholson-Sauls
ibisbasenji at gmail.com
Thu Jun 14 14:50:18 PDT 2007
davidb wrote:
> Dave Colling wrote:
>> Has anyone confirmed that the example showing how to find primes
>> by the sieve of Erastothenes actuall works?
>> It certainly counts something, but they are not primes!
>
> You're right, definitely not (includes 0, 1, 4, 8, 10, 14, 20, 22, 25, ...)
> It still features printf instead of writef and is in my opinion
> rather confusing for someone starting to learn by example.
> So here's a cleaned up version, placed in the public domain (hint)
>
> David
>
[... code snipped ...]
And here's one I wrote a little while back just to play around with,
using Tango. Its bound to be sub-optimal, as it was just a toy. An
experiment on the efficiency of associative-arrays. With a limit of
1,000,000 it clocks at a consistant 0.87s for me on a 2GHz Athlon. At
10,000,000 it jumps to ~25s or so. Cough.
You can run it with 'eratos ### report' to confirm the results. And,
yes, it is public domain for whatever it may be worth.
<code>
module eratos ;
import tango .io .Stdout ;
import tango .util .time .StopWatch ;
static import Integer = tango .text .convert .Integer ;
ulong[] sieve (ulong max) {
ulong[] result = [2_UL] ;
bool[ulong] list ;
for (
ulong step = 3_UL;
step <= max;
step += 2
) {
if (step in list) {
list.remove(step);
}
else {
result ~= step;
for (
ulong number = step * step;
number <= max;
number += step
) {
if (number % 2) {
list[number] = false;
}
}
}
}
return result;
}
char[] prettyNumber (ulong number) {
char[] tmp ,
result ;
size_t i ,
j ;
while (number > 0) {
j = cast(size_t) (number % 10);
tmp ~= "0123456789"[j];
number /= 10;
}
for (i = 0, j = 3; i < tmp.length; i += 3, j += 3) {
if (j >= tmp.length) {
result ~= tmp[i .. $];
}
else {
result ~= tmp[i .. j] ~ ',';
}
}
result.reverse;
return result;
}
const DEFAULT_LIMIT = 10_000_UL ;
void main (char[][] args) {
ulong limit = DEFAULT_LIMIT ;
ulong[] primes ;
Interval elapse ;
StopWatch timer ;
if (args.length > 1) {
limit = Integer.convert(args[1]);
}
timer.start;
primes = sieve(limit);
elapse = timer.stop;
Stdout.formatln(
"{} primes thru {} computed in {} seconds.",
prettyNumber(primes.length), prettyNumber(limit), elapse).flush;
if (args.length > 2) {
foreach (index, value; primes) {
Stdout.formatln(" [{,3:u}] {:u}", index, value).flush;
}
}
}
</code>
-- Chris Nicholson-Sauls
More information about the Digitalmars-d-learn
mailing list