Pernicious numbers: Difference between revisions

From Rosetta Code
Content added Content deleted
(→‎{{header|C}}: adding comments in the code)
(→‎{{header|C}}: binary litteral + more comments)
Line 26: Line 26:
=={{header|C}}==
=={{header|C}}==
<lang c>#include <stdio.h>
<lang c>#include <stdio.h>

typedef unsigned uint;
typedef unsigned uint;
uint is_pern(uint n)
uint is_pern(uint n)
Line 33: Line 33:
// Turn c into 2**p where p is c's population count
// Turn c into 2**p where p is c's population count
for (c = 1; n; n >>= 1) c <<= 1 & n;
for (c = 1; n; n >>= 1) c <<= 1 & n;

// Use a binary encoding of prime numbers
// Use a binary encoding of prime numbers
// in order to find out if p is prime
// in order to find out if p is prime
// 3129 23 1917 1311 7 5 32
return c & 2693408940u;
return c & 0b10100000100010100010100010101100;
}
}

int main(void)
int main(void)
{
{
Line 46: Line 47:
printf("%u ", i), ++c;
printf("%u ", i), ++c;
putchar('\n');
putchar('\n');

for (i = 888888877u; i <= 888888888u; i++)
for (i = 888888877u; i <= 888888888u; i++)
if (is_pern(i))
if (is_pern(i))
printf("%u ", i);
printf("%u ", i);
putchar('\n');
putchar('\n');

return 0;
return 0;
}</lang>
}</lang>

Revision as of 15:10, 12 March 2014

Pernicious numbers is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

pernicious numbers

definition

A pernicious number is a positive integer whose population count is a prime.

The population count (also known as pop count)   is the number of 1's (ones) in the binary representation of an non-negative integer.

I.E.:     22   (which is   10110   in binary)   has a population count of   3   which is prime, so   22   is a pernicious number.

task requirements

  • display the 1st   25   pernicious numbers.
  • display all pernicious numbers between   888,888,877   and   888,888,888   (inclusive).
  • display each list of integers on one line   (which may or may not include a title).

See also



C

<lang c>#include <stdio.h>

typedef unsigned uint; uint is_pern(uint n) {

       uint c;
       // Turn c into 2**p where p is c's population count
       for (c = 1; n; n >>= 1) c <<= 1 & n;

       // Use a binary encoding of prime numbers
       // in order to find out if p is prime

// 3129 23 1917 1311 7 5 32

       return c & 0b10100000100010100010100010101100;

}

int main(void) {

       uint i, c;
       for (i = c = 0; c < 25; i++)
               if (is_pern(i))
                       printf("%u ", i), ++c;
       putchar('\n');

       for (i = 888888877u; i <= 888888888u; i++)
               if (is_pern(i))
                       printf("%u ", i);
       putchar('\n');

       return 0;

}</lang>

Output:
3 5 6 7 9 10 11 12 13 14 17 18 19 20 21 22 24 25 26 28 31 33 34 35 36
888888877 888888878 888888880 888888883 888888885 888888886

Perl 6

Straightforward implementation using Perl 6's is-prime built-in subroutine. <lang perl6>sub is-pernicious(Int $n --> Bool) {

   is-prime [+] $n.base(2).comb;

}

say (grep &is-pernicious, 0 .. *)[^25]; say grep &is-pernicious, 888_888_877 .. 888_888_888;</lang>

Output:
3 5 6 7 9 10 11 12 13 14 17 18 19 20 21 22 24 25 26 28 31 33 34 35 36
888888877 888888878 888888880 888888883 888888885 888888886

REXX

<lang rexx>/*REXX program displays a number of pernicious numbers and also a range.*/ numeric digits 100 /*be able to handle large numbers*/ parse arg N L H . /*get optional arguments: N, L, H*/ if N== | N==',' then N=25 /*N given? Then use the default.*/ if L== | L==',' then L=888888877 /*L given? Then use the default.*/ if H== | H==',' then H=888888888 /*H given? Then use the default.*/ _=pernicious(1,,N) /*get all pernicious # from 1──◄N*/ say 'The 1st ' N " pernicious numbers are:" /*display a title.*/ say _ /*display a list. */ say /*display a blank line for a sep.*/ _=pernicious(L,H) /*get all pernicious # from L──◄H*/ say 'Pernicious numbers between ' L " and " H ' (inclusive) are:' say _ /*display a list. */ exit /*stick a fork in it, we're done.*/ /*──────────────────────────────────D2B subroutine──────────────────────*/ d2b: return word(strip(x2b(d2x(arg(1))),'L',0) 0,1) /*convert dec──►bin*/ /*──────────────────────────────────ISPRIME subroutine──────────────────*/ isPrime: procedure; parse arg x; if x<2 then return 0 /*X is too low.*/

        if wordpos(x,'2 3 5 7')\==0 then return 1       /*X  is prime. */
        if x//2==0 then return 0;     if x//3==0  then return 0
            do j=5  by 6 until j*j>x; if x// j   ==0  then return 0
                                      if x//(j+2)==0  then return 0;  end

return 1 /*The X number is prime. */ /*──────────────────────────────────PERNICIOUS subroutine───────────────*/ pernicious: procedure; parse arg bot,top,m /*get the bot & top #s, limit*/ if m== then m=999999999 /*assume an "infinite" limit. */ if top== then top=999999999 /*assume an "infinite" top limit.*/

  1. =0 /*number of pernicious #s so far.*/

$=; do j=bot to top until #==m /*gen pernicious until satisfied.*/

    if \isPrime(popCount(j))  then iterate  /*if popCount ¬prime, skip.*/
    $=$ j                             /*append a pernicious #  to list.*/
    #=#+1                             /*bump the pernicious #  count.  */
    end   /*j*/                       /* [↑]  append popCount to a list*/

return substr($,2) /*return results, sans 1st blank.*/ /*──────────────────────────────────POPCOUNT subroutine─────────────────*/ popCount: procedure;_=d2b(abs(arg(1))) /*convert the # passed to binary.*/ return length(_)-length(space(translate(_,,1),0)) /*count the one bits.*/</lang> output &nbsp when the default input is used:

The 1st  25  pernicious numbers are:
3 5 6 7 9 10 11 12 13 14 17 18 19 20 21 22 24 25 26 28 31 33 34 35 36

Pernicious numbers between  888888877  and  888888888  (inclusive) are:
888888877 888888878 888888880 888888883 888888885 888888886