> 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>