Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Easy way to list prime numbers 1 to 100

by l.frankline (Hermit)
on May 22, 2006 at 10:23 UTC ( [id://550896]=perlquestion: print w/replies, xml ) Need Help??

l.frankline has asked for the wisdom of the Perl Monks concerning the following question:

This node falls below the community's threshold of quality. You may see it by logging in.

Replies are listed 'Best First'.
Re: Easy way to list prime numbers 1 to 100
by davorg (Chancellor) on May 22, 2006 at 10:42 UTC

    You might want to check the definition of a prime number. After running your code, @primes includes a lot of numbers that aren't prime (9, 15 and 21 for example). In fact you seem to be calculating all of the odd numbers rather than the prime numbers.

      In fact you seem to be calculating all of the odd numbers rather than the prime numbers.

      Indeed, and in a very clumsy way, including the deprecated use of a map in void context...

      Update: at the moment of this update this node has gained a reputation of -4. So far so fine. However this should imply that at least four persons did disagree with my claim. I must deduce that those persons think that

      @prime = (1,2); map { push(@prime,$_) if (($_ % 2) != 0) } (2 .. 100);
      is a very nice, clean and elegant way to obtain the list of "primes" (in l.frankline's arithmetic) as opposed to, say,
      my @prime=(1,2,grep $_%2, 2..100);

      PS: from perldoc perlstyle:

      Avoid using grep() (or map()) or `backticks` in a void context, that is, when you just throw away their return values. Those functions all have return values, so use them. Otherwise use a foreach() loop or the system() function instead.
        including the deprecated use of a map in void context

        Is map in a void context deprecated?

        I thought that the main concern with using map in a void context was the inefficiency of building a results list that is then discarded--but that was corrected in 5.8.1 (from the delta):

        map in void context is no longer expensive. map is now context aware, and will not construct a list if called in void context.

        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Easy way to list prime numbers 1 to 100
by Zaxo (Archbishop) on May 22, 2006 at 22:03 UTC

    The truly easy way:

    use Math::Pari; my $primes = PARI 'primes(25)'; print "@{$primes}\n";
    The argument of Pari's primes() function is how many primes you want, not a limit.

    The hard part is installing Math::Pari.

    After Compline,
    Zaxo

Re: Easy way to list prime numbers 1 to 100
by blazar (Canon) on May 22, 2006 at 11:02 UTC
    my $MAX=100; my(@comp,@prime); for my $i (2..$MAX) { next if $comp[$i]; $comp[$i*$_]++ for 1..$MAX/$i; push @prime, $i; }
Re: Easy way to list prime numbers 1 to 100
by blazar (Canon) on May 22, 2006 at 11:41 UTC
      ...with the actual calculation taking one single grep statement:
      That's rather misleading. There's a nested map as well, but you didn't count that.

      I've played with this idea quite a bit in the past, and never cared much for over-complexifying it. I'll post 2 ideas here, one from Abigail from CLPM, and one I dreamed up for my keystroke programmable TI-95 longer ago than I care to imagine.

      From Usenet, June '97:

      #!/usr/local/bin/perl -wl use strict; my ($prime, $max) = (2, shift || 50); # First prime, max numb +er. my @sieve = (0, 0, map {1;} ($prime .. $max)); # Init sieve. while ((my $product = $prime * $prime) <= $max) { do {$sieve [$product] = 0;} while (($product += $prime) <= $max); do {$prime ++;} while !$sieve [$prime]; } map {print if $sieve [$_];} (0 .. $max);
      I like this because it's easy to understand, and reasonably efficient. For instance, once the next $prime is found, all unmarked candidates less than the $prime**2 are also prime -- no need for trial division on them.

      Notice that this takes up some memory. On the TI-95, there was only a little memory, so computing the first million primes would be painful. And keeping a list of anything besides primes was even more limiting. With that in mind, here's another way:

      #!/your/perl/here use strict; use warnings; use integer; $|=1; my $stop = (shift or 50); print "2"; my @primes; TRIAL_PRIME: for (my $i=3;$i<$stop;$i+=2) { for my $p (@primes) { next TRIAL_PRIME unless ( $i % $p ); } push @primes, $i; print ", $i"; } print "\n"; exit;
      That's reasonably fast with a small memory footprint. For a slight speedup, and less memory, use a bit vector.

      Update: Can't spell Abigail (at least the link was correct?)

      -QM
      --
      Quantum Mechanics: The dreams stuff is made of

Re: Easy way to list prime numbers 1 to 100
by TedPride (Priest) on May 22, 2006 at 18:57 UTC
    All the primes up to 100:
    use strict; use warnings; my (@prime, $p, $limit) = 2; PRIME: for $p (3..100) { $limit = int sqrt($p); for (@prime) { last if $_ > $limit; next PRIME if $p % $_ == 0; } push @prime, $p; }
    Or alternately, the first 100 primes:
    use strict; use warnings; my ($max, $p, @prime, $limit) = (100, 2, 2); PRIME: while (1) { $limit = int sqrt(++$p); for (@prime) { last if $_ > $limit; next PRIME if $p % $_ == 0; } push @prime, $p; last if $max == $#prime + 1; }
Re: Easiest way to list prime numbers 1 to 100 (one-liner)
by Anonymous Monk on May 22, 2006 at 22:15 UTC
    print "2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,8 +3,89,97";

      It's good practice to seperate the input from the output. It makes it easy to change the output format in the future. For example,

      my @primes = qw( 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 ); local $, = ", "; local $\ = "\n"; print @primes;

      ;)

      As the claim was only to list primes below 100 easily, I found that solution actually quite O.K.

      No need to praise it as "innovative", but also no need to mock it.

      After all, the intend of the OP obviously dealt with small numbers and was not for example to show "a way to compute the 42th digit of the base 3 expansion of the 7th million prime number!"

      When dealing with small primes (say up to 1,000,000 or even beyond), using precomputed lists maybe covenient. Moreso if such lists are easily available, e.g. from this site.

      that's damn best solution i've seen. simple, effective, innovative.
    A reply falls below the community's threshold of quality. You may see it by logging in.
Re: Easy way to list prime numbers 1 to 100
by Akhasha (Scribe) on May 23, 2006 at 12:03 UTC
    Not so easy, not so nice, and possibly buggy, as a 1 liner:
    print "$_\n" for grep { $n=$_; $_==1 or ( $_%2 and ! grep { $n%$_==0 } + (2..int($n/2))) } (1..100);

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://550896]
Approved by GrandFather
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others taking refuge in the Monastery: (8)
As of 2024-04-18 06:03 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found