Pernicious numbers: Difference between revisions
(→{{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
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
- Sequence A052294 pernicious numbers on The On-Line Encyclopedia of Integer Sequences.
- Wiki entry Pernicious number.
- Rosetta Code entry population count, evil numbers, odious numbers.
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.*/
- =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   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