2016 Update

This commit is contained in:
Tina Müller 2016-12-05 22:15:40 +01:00
parent 948b86eafa
commit dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions

View file

@ -2,13 +2,19 @@ A   ''[[wp:Pernicious number|pernicious number]]''   is a positive int
The &nbsp; ''population count'' &nbsp; (also known as ''pop count'') &nbsp; is the number of <big>1</big>'s &nbsp;(ones) in the binary representation of a non-negative integer.
For example: &nbsp; &nbsp; <big>22</big> &nbsp; (which is &nbsp; <big>10110</big> &nbsp; in binary) &nbsp; has a population count of &nbsp; <big>3</big> &nbsp; (which is prime), and therefore &nbsp; <big>22</big> &nbsp; is a pernicious number.
;Example:
'''22''' &nbsp; (which is &nbsp; '''10110''' &nbsp; in binary) &nbsp; has a population count of &nbsp; '''3''' &nbsp; (which is prime), &nbsp; and therefore
<br>'''22''' &nbsp; is a pernicious number.
'''Task requirements'''
:* display the first &nbsp; 25 &nbsp; pernicious numbers.
:* display all pernicious numbers between &nbsp; 888,888,877 &nbsp; and &nbsp; 888,888,888 &nbsp; (inclusive).
:* display each list of integers on one line (which may or may not include a title). <br>
;See also
* Sequence &nbsp; [[oeis:A052294|A052294 pernicious numbers]] on The On-Line Encyclopedia of Integer Sequences.
* Rosetta Code entry &nbsp; [[Population_count|population count, evil numbers, odious numbers]].
<br><br>

View file

@ -0,0 +1,126 @@
* Pernicious numbers 04/05/2016
PERNIC CSECT
USING PERNIC,R13 base register and savearea pointer
SAVEAREA B STM-SAVEAREA(R15)
DC 17F'0'
STM STM R14,R12,12(R13) save registers
ST R13,4(R15) link backward SA
ST R15,8(R13) link forward SA
LR R13,R15 establish addressability
SR R7,R7 n=0
MVC PG,=CL80' ' clear buffer
LA R10,PG pgi
LA R6,1 i=1
LOOPI1 C R7,=F'25' do i=1 while(n<25)
BNL ELOOPI1
LR R1,R6 i
BAL R14,POPCOUNT
LR R1,R0 popcount(i)
BAL R14,ISPRIME
C R0,=F'1' if isprime(popcount(i))=1
BNE NOTPRIM1
XDECO R6,XDEC edit i
MVC 0(3,R10),XDEC+9 output i format I3
LA R10,3(R10) pgi=pgi+3
LA R7,1(R7) n=n+1
NOTPRIM1 LA R6,1(R6) i=i+1
B LOOPI1
ELOOPI1 XPRNT PG,80 print buffer
MVC PG,=CL80' ' clear buffer
LA R10,PG pgi
L R6,=F'888888877' i=888888877
LOOPI2 C R6,=F'888888888' do i to 888888888
BH ELOOPI2
LR R1,R6 i
BAL R14,POPCOUNT
LR R1,R0 popcount(i)
BAL R14,ISPRIME
C R0,=F'1' if isprime(popcount(i))=1
BNE NOTPRIM2
XDECO R6,XDEC edit i
MVC 0(10,R10),XDEC+2 output i format I10
LA R10,10(R10) pgi=pgi+10
NOTPRIM2 LA R6,1(R6) i=i+1
B LOOPI2
ELOOPI2 XPRNT PG,80 print buffer
L R13,4(0,R13) restore savearea pointer
LM R14,R12,12(R13) restore registers
XR R15,R15 return code = 0
BR R14 -------------- end main
POPCOUNT CNOP 0,4 -------------- popcount(xx) [R8,R11]
ST R14,POPCOUSA save return address
ST R1,XX store argument
SR R11,R11 rr=0
SR R8,R8 ii=0
LOOPII C R8,=F'31' do ii=0 to 31
BH ELOOPII
L R1,XX xx
LR R2,R8 ii
BAL R14,BTEST
C R0,=F'1' if btest(xx,ii)=1
BNE NOTBTEST
LA R11,1(R11) rr=rr+1
NOTBTEST LA R8,1(R8) ii=ii+1
B LOOPII
ELOOPII LR R0,R11 return(rr)
L R14,POPCOUSA
BR R14 -------------- end popcount
ISPRIME CNOP 0,4 -------------- isprime(number) [R9]
ST R14,ISPRIMSA save return address
ST R1,NUMBER store argument
C R1,=F'2' if number=2
BNE ELSE1
MVC ISPRIMEX,=F'1' isprimex=1
B ELOOPJJ
ELSE1 L R1,NUMBER
C R1,=F'2' if number<2
BL EVEN
L R4,NUMBER
SRDA R4,32
D R4,=F'2' mod(number,2)
C R4,=F'0' if mod(number,2)=0
BNE ELSE2
EVEN MVC ISPRIMEX,=F'0' isprimex=0
B ELOOPJJ
ELSE2 MVC ISPRIMEX,=F'1' isprimex=1
LA R9,3 jj=3
LOOPJJ LR R5,R9 jj
MR R4,R9 jj*jj
C R5,NUMBER do jj=3 by 1 while jj*jj<=number
BH ELOOPJJ
L R4,NUMBER
SRDA R4,32
DR R4,R9 mod(number,jj)
LTR R4,R4 if mod(number,jj)=0
BNZ ITERJJ
MVC ISPRIMEX,=F'0' isprimex=0
L R0,ISPRIMEX return(isprimex)
B ISPRIMRT
ITERJJ LA R9,1(R9) jj=jj+1
B LOOPJJ
ELOOPJJ L R0,ISPRIMEX return(isprimex)
ISPRIMRT L R14,ISPRIMSA
BR R14 -------------- end isprime
BTEST CNOP 0,4 -------------- btest(word,n) [R0:R3]
LA R0,1 ok=1; return(1) if word(n)='1'b
LR R3,R2 i=n
LOOPB LTR R3,R3 if i=0
BZ ELOOPB
SRL R1,1 Shift Right Logical
BCTR R3,0 i=i-1
B LOOPB
ELOOPB STC R1,BTESTX x=word
TM BTESTX,B'00000001' if bit(word,n)='1'b
BO BTESTRET
LA R0,0 ok=0; return(0) if word(n)='0'b
BTESTRET BR R14 -------------- end btest
XX DS F paramter of popcount
NUMBER DS F paramter of isprime
ISPRIMEX DS F return value of isprime
BTESTX DS X byte to see in btest
POPCOUSA DS A return address of popcount
ISPRIMSA DS A return address of isprime
PG DS CL80 buffer
XDEC DS CL12 edit zone
YREGS
END PERNIC

View file

@ -0,0 +1,47 @@
# calculate various pernicious numbers #
# returns the population (number of bits on) of the non-negative integer n #
PROC population = ( INT n )INT:
BEGIN
INT number := n;
INT result := 0;
WHILE number > 0 DO
IF ODD number THEN result +:= 1 FI;
number OVERAB 2
OD;
result
END # population # ;
# as we are dealing with 32 bit numbers, the maximum possible population is 32 #
# so we only need a table of whether the integers 0 : 32 are prime or not #
# we use the sieve of Eratosthenes... #
INT max number = 32;
[ 0 : max number ]BOOL is prime;
is prime[ 0 ] := FALSE;
is prime[ 1 ] := FALSE;
FOR i FROM 2 TO max number DO is prime[ i ] := TRUE OD;
FOR i FROM 2 TO ENTIER sqrt( max number ) DO
IF is prime[ i ] THEN FOR p FROM i * i BY i TO max number DO is prime[ p ] := FALSE OD FI
OD;
# returns TRUE if n is pernicious, FALSE otherwise #
PROC is pernicious = ( INT n )BOOL: is prime[ population( n ) ];
# find the first 25 pernicious numbers, 0 and 1 are not pernicious #
INT pernicious count := 0;
FOR i FROM 2 WHILE pernicious count < 25 DO
IF is pernicious( i ) THEN
# found a pernicious number #
print( ( whole( i, 0 ), " " ) );
pernicious count +:= 1
FI
OD;
print( ( newline ) );
# find the pernicious numbers between 888 888 877 and 888 888 888 #
FOR i FROM 888 888 877 TO 888 888 888 DO
IF is pernicious( i ) THEN
print( ( whole( i, 0 ), " " ) )
FI
OD;
print( ( newline ) )

View file

@ -0,0 +1,9 @@
(defn counting-numbers
([] (counting-numbers 1))
([n] (lazy-seq (cons n (counting-numbers (inc n))))))
(defn divisors [n] (filter #(zero? (mod n %)) (range 1 (inc n))))
(defn prime? [n] (= (divisors n) (list 1 n)))
(defn pernicious? [n]
(prime? (count (filter #(= % \1) (Integer/toString n 2)))))
(println (take 25 (filter pernicious? (counting-numbers))))
(println (filter pernicious? (range 888888877 888888889)))

View file

@ -1,3 +1 @@
ispernicious=: 1 p: +/"1@#:
thru=: <./ + i.@(+*)@-~

View file

@ -1,4 +1,6 @@
25{.I.ispernicious i.100
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
thru=: <. + i.@(+*)@-~
888888877 + I. ispernicious 888888877 thru 888888888
888888877 888888878 888888880 888888883 888888885 888888886

View file

@ -0,0 +1,53 @@
-- Test primality by trial division
function isPrime (x)
if x < 2 then return false end
if x < 4 then return true end
if x % 2 == 0 then return false end
for d = 3, math.sqrt(x), 2 do
if x % d == 0 then return false end
end
return true
end
-- Take decimal number, return binary string
function dec2bin (n)
local bin, bit = ""
while n > 0 do
bit = n % 2
n = math.floor(n / 2)
bin = bit .. bin
end
return bin
end
-- Take decimal number, return population count as number
function popCount (n)
local bin, count = dec2bin(n), 0
for pos = 1, bin:len() do
if bin:sub(pos, pos) == "1" then count = count + 1 end
end
return count
end
-- Print pernicious numbers in range if two arguments provided, or
function pernicious (x, y) -- the first 'x' if only one argument.
if y then
for n = x, y do
if isPrime(popCount(n)) then io.write(n .. " ") end
end
else
local n, count = 0, 0
while count < x do
if isPrime(popCount(n)) then
io.write(n .. " ")
count = count + 1
end
n = n + 1
end
end
print()
end
-- Main procedure
pernicious(25)
pernicious(888888877, 888888888)

View file

@ -19,6 +19,20 @@ const
1,0,0,0,0,0, 1,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,
1,0,0,0);
function n_beyond_k(n,k: NativeInt):Uint64;
var
i : NativeInt;
Begin
result := 1;
IF 2*k>= n then
k := n-k;
For i := 1 to k do
Begin
result := result *n DIV i;
dec(n);
end;
end;
function popcnt32(n:Uint32):NativeUint;
//https://en.wikipedia.org/wiki/Hamming_weight#Efficient_implementation
const
@ -35,31 +49,36 @@ begin
end;
var
t : TDAteTime;
i,
bit1cnt,
k : LongWord;
PernCnt : Uint64;
Begin
writeln('the 25 first pernicious numbers');
I:=1;k:=0;
k:=1;
PernCnt:=0;
repeat
IF PrimeTil64[popCnt32(i)] <> 0 then Begin
inc(k); write(i,' ');end;
inc(i);
until k >= 25;
IF PrimeTil64[popCnt32(k)] <> 0 then Begin
inc(PernCnt); write(k,' ');end;
inc(k);
until PernCnt >= 25;
writeln;
writeln('pernicious numbers in [888888877..888888888]');
For i := 888888877 to 888888888 do
IF PrimeTil64[popCnt32(i)] <> 0 then
write(i,' ');
writeln;
For k := 888888877 to 888888888 do
IF PrimeTil64[popCnt32(k)] <> 0 then
write(k,' ');
writeln(#13#10);
//speedtest of popcount
t:= time;
k := 0;
For i := High(i) downto 0 do
k := k+PrimeTil64[popCnt32(i)];
t := time-t;
writeln(k,' pernicious numbers in [0..2^32-1] takes ',t*86400:0:3,' seconds');
end.
k := 8;
repeat
PernCnt := 0;
For bit1cnt := 0 to k do
Begin
//i == number of Bits set,n_beyond_k(k,i) == number of arrangements
IF PrimeTil64[bit1cnt] <> 0 then
inc(PernCnt,n_beyond_k(k,bit1cnt));
end;
writeln(PernCnt,' pernicious numbers in [0..2^',k,'-1]');
inc(k,k);
until k>64;
end.

View file

@ -0,0 +1,2 @@
(de pernicious? (N)
(prime? (cnt = (chop (bin N)) '("1" .))) )

View file

@ -0,0 +1,8 @@
: (let N 0
(do 25
(until (pernicious? (inc 'N)))
(printsp N) ) )
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 -> 36
: (filter pernicious? (range 888888877 888888888))
-> (888888877 888888878 888888880 888888883 888888885 888888886)

View file

@ -0,0 +1,28 @@
function pop-count($n) {
(([Convert]::ToString($n, 2)).toCharArray() | where {$_ -eq '1'}).count
}
function isPrime ($n) {
if ($n -eq 1) {$false}
elseif ($n -eq 2) {$true}
elseif ($n -eq 3) {$true}
else{
$m = [Math]::Floor([Math]::Sqrt($n))
(@(2..$m | where {($_ -lt $n) -and ($n % $_ -eq 0) }).Count -eq 0)
}
}
$i = 0
$num = 1
$arr = while($i -lt 25) {
if((isPrime (pop-count $num))) {
$i++
$num
}
$num++
}
"first 25 pernicious numbers"
"$arr"
""
"pernicious numbers between 888,888,877 and 888,888,888"
"$(888888877..888888888 | where{isprime(pop-count $_)})"

View file

@ -0,0 +1,61 @@
EnableExplicit
Procedure.i SumBinaryDigits(Number)
If Number < 0 : number = -number : EndIf; convert negative numbers to positive
Protected sum = 0
While Number > 0
sum + Number % 2
Number / 2
Wend
ProcedureReturn sum
EndProcedure
Procedure.i IsPrime(Number)
If Number <= 1
ProcedureReturn #False
ElseIf Number <= 3
ProcedureReturn #True
ElseIf Number % 2 = 0 Or Number % 3 = 0
ProcedureReturn #False
EndIf
Protected i = 5
While i * i <= Number
If Number % i = 0 Or Number % (i + 2) = 0
ProcedureReturn #False
EndIf
i + 6
Wend
ProcedureReturn #True
EndProcedure
Procedure.i IsPernicious(Number)
Protected popCount = SumBinaryDigits(Number)
ProcedureReturn Bool(IsPrime(popCount))
EndProcedure
Define n = 1, count = 0
If OpenConsole()
PrintN("The following are the first 25 pernicious numbers :")
PrintN("")
Repeat
If IsPernicious(n)
Print(RSet(Str(n), 3))
count + 1
EndIf
n + 1
Until count = 25
PrintN("")
PrintN("")
PrintN("The pernicious numbers between 888,888,877 and 888,888,888 inclusive are : ")
PrintN("")
For n = 888888877 To 888888888
If IsPernicious(n)
Print(RSet(Str(n), 10))
EndIf
Next
PrintN("")
PrintN("")
PrintN("Press any key to close the console")
Repeat: Delay(10) : Until Inkey() <> ""
CloseConsole()
EndIf

View file

@ -1,31 +1,32 @@
/*REXX program displays a number of pernicious numbers and also a range.*/
numeric digits 30 /*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 " ? " " " " */
if H=='' | H==',' then H=888888888 /*H " ? " " " " */
say 'The 1st ' N " pernicious numbers are:" /*display a nice title.*/
say pernicious(1,,N) /*get all pernicious # from 1──►N*/
say /*display a blank line for a sep.*/
say 'Pernicious numbers between ' L " and " H ' (inclusive) are:'
say pernicious(L,H) /*get all pernicious # from L──►H*/
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*/
/*──────────────────────────────────PERNICIOUS subroutine───────────────*/
pernicious: procedure; parse arg bot,top,m /*get the bot & top #s, limit*/
_ = 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
!.=0; do k=1 until p=''; p=word(_,k); !.p=1; end /*gen low prime array*/
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.*/
pc=popCount(j) /*obtain population count for J.*/
if \!.pc then iterate /*if popCount ¬ in !.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.*/
/*REXX program computes and displays a number (and also a range) of pernicious numbers.*/
numeric digits 100 /*be able to handle large numbers. */
parse arg N L H . /*obtain optional arguments from the CL*/
if N=='' | N==',' then N=25 /*N not given? Then use the default. */
if L=='' | L==',' then L=888888877 /*L " " " " " " */
if H=='' | H==',' then H=888888888 /*H " " " " " " */
say 'The 1st ' N " pernicious numbers are:" /*display a nice title for the numbers.*/
say pernicious(1,,N) /*get all pernicious # from 1 ─~─► N. */
say /*display a blank line for a separator.*/
say 'Pernicious numbers between ' L " and " H ' (inclusive) are:'
say pernicious(L,H) /*get all pernicious # from L ───► H. */
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
pernicious: procedure; parse arg bot,top,lim /*obtain the bot and top numbers, limit*/
p='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 101'
@.=0
do k=1 until _=='' /*examine the list of some low primes.*/
_=word(p, k); @._=1 /*generate an array " " " " */
end /*k*/
$= /*list of pernicious numbers (so far). */
if m=='' then m=999999999 /*Not given? Then use a gihugic limit.*/
if top=='' then top=999999999 /* " " " " " " " */
#=0 /*number of pernicious numbers (so far)*/
do j=bot to top until #==lim /*generate pernicious #s 'til satisfied*/
pc=popCount(j) /*obtain the population count for J. */
if \@.pc then iterate /*if popCount not in @.prime, skip it.*/
$=$ j /*append a pernicious number to list. */
#=#+1 /*bump the pernicious number count. */
end /*j*/
return substr($, 2) /*return the results, sans 1st blank. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
popCount: return length( space( translate( x2b( d2x(arg(1))) +0,, 0), 0)) /*count 1's.*/