> From: Stuart White [mailto:[EMAIL PROTECTED] 
> Sent: Tuesday, 2 March 2004 11:55 PM
> To: David le Blanc; [EMAIL PROTECTED]
> Subject: RE: listing prime numbers in a range (Beginning Perl 
> exercise)
> 
> 
> --- David le Blanc
> <[EMAIL PROTECTED]> wrote:
> > 
> > Just for the sake of it, and I apologise profusely
> > for the top posting..
> > 
> stuart>Hi David,
> 
> 
> > Here is a summary of the posted prime calculators
> > for testing your
> > results against.
> > 
> > >(1) Ohad
> 
> stuart>I saw his regexp soln.  I was attempting to
> stuart>solve it with arrays, loops and maybe hashes. 
> stuart>I figure that the exercise wouldn't be in the
> stuart>book before the regexp chapter if I couldn't do
> stuart>it easily (or without TOO much difficulty)
> stuart>without them.  That's all.
> 
> > >(2) Joseph
> stuart>I thought this one was a joke.  Partly because
> stuart>of the context it was sent in, partly because
> stuart>of what I saw it do.  I ran it, and it printed
> stuart>out a slew of numbers.  It didn't stop after a
> stuart>few minutes, so I ended the program.


You just have to realise that the script is printing the entire
array of primes EVERY time it finds a new one.  change the
'while (1)' to 'while( $#primes < 2000 )' to only find 1000
primes, and move the 'print' to after the loop.

> 
> 
> > >(3) me (Hey, it's a Mee Too!)
> >
> #-------------------------------------------------------
> > $max=shift||17393;
> > %notprime=();
> > @prime=();
> > 
> > for $n (2..$max){
> >     unless($notprime{$n}){
> >             push @prime,$n;
> >             $notprime{$_*$n}=1 for 2..$max/$n;
> >     }
> > }
> > 
> > print "Found $#prime prime numbers..".$/;
> > print "@prime\n";
> >
> #-------------------------------------------------------
> > 
> > Brief explanation..
> > (1) 
> sounds neat.
>  
> > (2) Joseph posted a calculator which uses the
> > feature of prime numbers
> > that the 
> >     largest number you need to divide it by is the
> > square root of itself
> > ($_**0.5)
> >     and that you only need to test if the number you
> > are examining is
> > divisible
> >     (ie mod==0) by another prime you have already
> > found.  Hence, very
> > quick and
> >     very cpu/memory cheap.  Why not test against
> > every number?  If you
> > test against
> >     a non-prime number, you are simply testing
> > against a multiple of a
> > prime of
> >     course.
See above.  It does work afaik.
> 
> stuart>Ahh, this makes sense, sortof.  I'm going to
> stuart>need to look at the code again and your
> stuart>explanation.  This was printing many, many,
> stuart>many numbers, some of which sure didn't look
> stuart>like they were primes.  The sheer number plus
> stuart>the proximity of them to each other in
> stuart>cardinal? order (2341  2347 2443 etc) (these
> stuart>numbers are used to illustrate my probably
> stuart>improper use of cardinal, I'm not implying that
> stuart>those numbers were outputted by the program)
> stuart>made me think that some weren't primes.
> 
> 
> > 
> > (3) A very simple implementation of an erogenous
> > sieve (iud? did I say
> > that wrong?)
> >     which keeps all primes in '@primes' and all
> > 'eliminated' entries in
> > '%notprime'.
> >     quick, but likely more memory intensive than
> > (2).
> 
> This one is a bit confusing. 
> $max=shift||17393;

> stuart>I thought shift was to remove an element from
> stuart>the beginning of an array, but it's being used
> stuart>in scalar context here.  Why?  And what is it
> stuart>doing?

When 'shift' has no argument, it shifts '@_' which is parameter
arguments in a function, and command line arguments elsewhere.

$max = shift will grab the first command line argument. If 
there isn't one, shift == undef, so perl will complete the 'x||y'
expression by evaluating 'y'.  If 'shift' returns a number, the 'x||y'
expression is shortcut.

Hence, $max = first argument OR 17393 if there isn't one.

> 
>  %notprime=();
> > @prime=();
> > 
> > for $n (2..$max){
> stuart>this makes me think that you were somehow
> stuart>assigning a number to $max above.  But where
> stuart>does 17393 come in?  Why not 17394, or 18000?

17393 is a completely magic number it just so happens where are
exactly 2000 prime numbers between 2 and 17393 inclusive.

> 
> 
> >     unless($notprime{$n}){
> >             push @prime,$n;
> >             $notprime{$_*$n}=1 for 2..$max/$n;
> stuart>I'm not sure I understand this line directly
> stuart>above.  What I think it says is that it is
> stuart>accessing the value within the %notprime hash
> stuart>where the key equals the last inputted number
> stuart>which I suppose is $n and $_ if $n was pushed
> stuart>onto @prime, but just $_ if $n was not pushed
> stuart>onto @prime.  I don't get the "=1" part
> stuart>though.  What is that doing?  I'm assuming that
> stuart>is a for loop there that is working like a
> stuart>foreach loop?  but I'm not quite sure what it's
> stuart>doing.
> 

How about:
for($i= $n*2; $i<$max; $i = $i+$n) {
        $notprime{$i} = 1
}

In order to set an entry in the 'notprime' hash for every
multple of '$n' from $n*2 to $max, I iterate from 2 to $max/$n
and set '$notprime{ <current iteration>*$n } = true'.
Hence, when $n is 2,
$notprime{ 2*2 } = 1;
$notprime{ 2*3 } = 1;
$notprime{ 2*4 } = 1;
$notprime{ 2*5 } = 1;
$notprime{ 2*6 } = 1;
... until $notprime{ 2*($max / 2) } = 1 


> > Cheers.
> > David
> > 
> >
> 
> __________________________________
> Do you Yahoo!?
> Yahoo! Search - Find what you're looking for faster
> http://search.yahoo.com
> 

--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
<http://learn.perl.org/> <http://learn.perl.org/first-response>


Reply via email to