Data update

This commit is contained in:
Ingy döt Net 2023-07-01 19:04:33 -04:00
parent 8f05c7136f
commit 0bf4da02c3
82 changed files with 2194 additions and 118 deletions

View file

@ -0,0 +1,27 @@
10 DEFINT A-Z: DIM B$(2): B$(0)="No": B$(1)="Yes"
20 PRINT " N Totient Prime"
30 FOR N=1 TO 25
40 GOSUB 200
50 P=-(T=N-1)
60 C=C+P
70 PRINT USING "## ####### \ \";N;T;B$(P)
80 NEXT N
90 F$="Number of primes up to ######: ####"
100 PRINT USING F$;25;C
110 FOR N=26 TO 10000
120 GOSUB 200
130 C=C-(T=N-1)
140 IF N=100 OR N=1000 OR N=10000 THEN PRINT USING F$;N;C
150 NEXT N
160 END
200 REM T = TOTIENT(N)
210 T=N: Z=N
220 I=2: GOSUB 270
230 I=3
240 IF I*I<=Z THEN GOSUB 270: I=I+2: GOTO 240
250 IF Z>1 THEN T=T-T\Z
260 RETURN
270 IF Z MOD I<>0 THEN RETURN
280 IF Z MOD I=0 THEN Z = Z\I: GOTO 280
290 T = T-T\I
300 RETURN

View file

@ -0,0 +1,31 @@
get "libhdr"
let totient(n) = valof
$( let tot = n and i = 2
while i*i <= n
$( if n rem i = 0
$( while n rem i = 0 do n := n / i
tot := tot - tot/i
$)
if i=2 then i:=1
i := i+2
$)
resultis n>1 -> tot-tot/n, tot
$)
let start() be
$( let count = 0
writes(" N Totient Prime*N")
for n = 1 to 25
$( let tot = totient(n)
let prime = n-1 = tot
if prime then count := count + 1
writef("%I2 %I7 %S*N", n, tot, prime -> " Yes", " No")
$)
writef("Number of primes up to %I6: %I4*N", 25, count)
for n = 26 to 10000
$( if totient(n) = n-1 then count := count + 1
if n = 100 | n = 1000 | n = 10000 then
writef("Number of primes up to %I6: %I4*N", n, count)
$)
$)

View file

@ -0,0 +1,50 @@
totient = proc (n: int) returns (int)
tot: int := n
i: int := 2
while i*i <= n do
if n//i = 0 then
while n//i = 0 do
n := n/i
end
tot := tot-tot/i
end
if i=2 then i:=1 end
i := i+2
end
if n>1 then
tot := tot-tot/n
end
return(tot)
end totient
start_up = proc ()
po: stream := stream$primary_output()
count: int := 0
stream$putl(po, " N Totient Prime")
for n: int in int$from_to(1, 25) do
tot: int := totient(n)
stream$putright(po, int$unparse(n), 2)
stream$putright(po, int$unparse(tot), 9)
if n-1 = tot then
stream$putright(po, "Yes", 7)
count := count + 1
else
stream$putright(po, "No", 7)
end
stream$putl(po, "")
end
stream$putl(po, "Number of primes up to 25:\t" || int$unparse(count))
for n: int in int$from_to(26, 100000) do
if totient(n) = n-1 then
count := count + 1
end
if n = 100 cor n = 1000 cor n // 10000 = 0 then
stream$putl(po, "Number of primes up to "
|| int$unparse(n) || ":\t"
|| int$unparse(count))
end
end
end start_up

View file

@ -0,0 +1,93 @@
IDENTIFICATION DIVISION.
PROGRAM-ID. TOTIENT-FUNCTION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 TOTIENT-CALCULATION.
03 N PIC 9(6).
03 TOTIENT PIC 9(6).
03 DIVISOR PIC 9(6).
03 DIV-SQUARE PIC 9(6).
03 MODULUS PIC 9(6).
01 LOOP-VARS.
03 PRIME-COUNT PIC 9(4).
03 CURRENT-N PIC 9(6).
03 PRIME-TOTIENT PIC 9(6).
01 OUTPUTFORMAT.
03 HEADER PIC X(20) VALUE " N Totient Prime?".
03 TOTIENT-ROW.
05 OUT-N PIC Z9.
05 FILLER PIC XX VALUE SPACES.
05 OUT-TOTIENT PIC Z(6)9.
05 FILLER PIC XX VALUE SPACES.
05 OUT-PRIME PIC X(5).
03 PRIME-COUNT-ROW.
05 FILLER PIC X(22) VALUE "Number of primes up to".
05 OUT-PRMTO PIC Z(5)9.
05 FILLER PIC XX VALUE ": ".
05 OUT-PRMCNT PIC ZZZ9.
PROCEDURE DIVISION.
BEGIN.
MOVE ZERO TO PRIME-COUNT.
DISPLAY HEADER.
PERFORM SHOW-SMALL-TOTIENT
VARYING CURRENT-N FROM 1 BY 1
UNTIL CURRENT-N IS GREATER THAN 25.
MOVE 25 TO OUT-PRMTO.
MOVE PRIME-COUNT TO OUT-PRMCNT.
DISPLAY PRIME-COUNT-ROW.
PERFORM COUNT-PRIMES
VARYING CURRENT-N FROM 26 BY 1
UNTIL CURRENT-N IS GREATER THAN 10000.
STOP RUN.
SHOW-SMALL-TOTIENT.
MOVE CURRENT-N TO N.
PERFORM CALCULATE-TOTIENT.
MOVE CURRENT-N TO OUT-N.
MOVE TOTIENT TO OUT-TOTIENT.
MOVE "No" TO OUT-PRIME.
SUBTRACT 1 FROM CURRENT-N GIVING PRIME-TOTIENT.
IF TOTIENT IS EQUAL TO PRIME-TOTIENT,
MOVE "Yes" TO OUT-PRIME,
ADD 1 TO PRIME-COUNT.
DISPLAY TOTIENT-ROW.
COUNT-PRIMES.
MOVE CURRENT-N TO N.
PERFORM CALCULATE-TOTIENT.
SUBTRACT 1 FROM CURRENT-N GIVING PRIME-TOTIENT.
IF TOTIENT IS EQUAL TO PRIME-TOTIENT, ADD 1 TO PRIME-COUNT.
IF CURRENT-N IS EQUAL TO 100 OR 1000 OR 10000,
MOVE CURRENT-N TO OUT-PRMTO,
MOVE PRIME-COUNT TO OUT-PRMCNT,
DISPLAY PRIME-COUNT-ROW.
CALCULATE-TOTIENT.
MOVE N TO TOTIENT.
MOVE 2 TO DIVISOR.
MOVE 4 TO DIV-SQUARE.
PERFORM DIVIDE-STEP.
PERFORM DIVIDE-STEP
VARYING DIVISOR FROM 3 BY 2
UNTIL DIV-SQUARE IS GREATER THAN N.
IF N IS GREATER THAN 1,
COMPUTE TOTIENT = TOTIENT - TOTIENT / N.
DIVIDE-STEP.
MULTIPLY DIVISOR BY DIVISOR GIVING DIV-SQUARE.
DIVIDE N BY DIVISOR GIVING MODULUS.
MULTIPLY DIVISOR BY MODULUS.
SUBTRACT MODULUS FROM N GIVING MODULUS.
IF MODULUS IS ZERO,
PERFORM DIVIDE-OUT UNTIL MODULUS IS NOT ZERO,
COMPUTE TOTIENT = TOTIENT - TOTIENT / DIVISOR.
DIVIDE-OUT.
DIVIDE DIVISOR INTO N.
DIVIDE N BY DIVISOR GIVING MODULUS.
MULTIPLY DIVISOR BY MODULUS.
SUBTRACT MODULUS FROM N GIVING MODULUS.

View file

@ -0,0 +1,61 @@
include "cowgol.coh";
sub totient(n: uint32): (tot: uint32) is
tot := n;
var i: uint32 := 2;
while i*i <= n loop
if n%i == 0 then
while n%i == 0 loop
n := n/i;
end loop;
tot := tot - tot/i;
end if;
if i == 2 then
i := 1;
end if;
i := i + 2;
end loop;
if n > 1 then
tot := tot - tot/n;
end if;
end sub;
var count: uint16 := 0;
print("N\tTotient\tPrime\n");
var n: uint32 := 1;
while n <= 25 loop
var tot := totient(n);
print_i32(n);
print_char('\t');
print_i32(tot);
print_char('\t');
if n-1 == tot then
count := count + 1;
print("Yes\n");
else
print("No\n");
end if;
n := n + 1;
end loop;
print("Number of primes up to 25:\t");
print_i16(count);
print_nl();
while n <= 100000 loop
tot := totient(n);
if n-1 == tot then
count := count + 1;
end if;
if n == 100 or n == 1000 or n % 10000 == 0 then
print("Number of primes up to ");
print_i32(n);
print(":\t");
print_i16(count);
print_nl();
end if;
n := n + 1;
end loop;

View file

@ -0,0 +1,39 @@
proc totient(word n) word:
word tot, i;
tot := n;
i := 2;
while i*i <= n do
if n%i = 0 then
while n%i = 0 do n := n/i od;
tot := tot - tot/i
fi;
if i=2 then i:=1 fi;
i := i+2
od;
if n>1 then
tot - tot/n
else
tot
fi
corp
proc main() void:
word count, n, tot;
bool prime;
count := 0;
writeln(" N Totient Prime");
for n from 1 upto 25 do
tot := totient(n);
prime := n-1 = tot;
if prime then count := count+1 fi;
writeln(n:2, " ", tot:7, " ", if prime then " Yes" else " No" fi)
od;
writeln("Number of primes up to ",25:6,": ",count:4);
for n from 25 upto 10000 do
if totient(n) = n-1 then count := count+1 fi;
if n=100 or n=1000 or n=10000 then
writeln("Number of primes up to ",n:6,": ",count:4)
fi
od
corp

View file

@ -0,0 +1,45 @@
NORMAL MODE IS INTEGER
BOOLEAN PRM
INTERNAL FUNCTION(A,B)
ENTRY TO REM.
FUNCTION RETURN A-A/B*B
END OF FUNCTION
INTERNAL FUNCTION(NN)
ENTRY TO TOTENT.
N = NN
TOT = N
THROUGH STEP, FOR I=2, 2, I*I.G.N
WHENEVER REM.(N,I).E.0
THROUGH DIV, FOR N=N, 0, REM.(N,I).NE.0
DIV N = N/I
TOT = TOT-TOT/I
END OF CONDITIONAL
WHENEVER I.E.2, I=1
STEP CONTINUE
WHENEVER N.G.1, TOT = TOT-TOT/N
FUNCTION RETURN TOT
END OF FUNCTION
COUNT = 0
PRINT FORMAT HEADER
THROUGH FRST25, FOR KN=1, 1, KN.G.25
KTOT = TOTENT.(KN)
PRM = KTOT.E.KN-1
WHENEVER PRM, COUNT = COUNT + 1
FRST25 PRINT FORMAT NUMTOT,KN,KTOT,PRM
PRINT FORMAT NUMPRM,25,COUNT
THROUGH CNTPRM, FOR KN=26, 1, KN.G.100000
KTOT = TOTENT.(KN)
WHENEVER KTOT.E.KN-1, COUNT = COUNT+1
WHENEVER KN.E.100 .OR. KN.E.1000 .OR. REM.(KN,10000).E.0,
0 PRINT FORMAT NUMPRM,KN,COUNT
CNTPRM CONTINUE
VECTOR VALUES HEADER = $19H N TOTIENT PRIME*$
VECTOR VALUES NUMTOT = $I2,S2,I7,S2,I5*$
VECTOR VALUES NUMPRM = $22HNUMBER OF PRIMES UP TO,I7,1H:,I6*$
END OF PROGRAM

View file

@ -0,0 +1,25 @@
main :: [sys_message]
main = [Stdout (lay (map showline [1..25])),
Stdout (lay (map countprimes (25:map (10^) [2..5])))]
countprimes :: num->[char]
countprimes n = "There are " ++ show amount ++ " primes up to " ++ show n
where amount = #filter prime [2..n]
showline :: num->[char]
showline n = "phi(" ++ show n ++ ") = " ++ show (totient n) ++ ", " ++ kind
where kind = "prime", if prime n
= "composite", otherwise
prime :: num->bool
prime n = totient n = n - 1
totient :: num->num
totient n = loop n n (2:[3, 5..])
where loop tot n (d:ds)
= tot, if n<=1
= tot - tot div n, if d*d > n
= loop tot n ds, if n mod d ~= 0
= loop (tot - tot div d) (remfac n d) ds, otherwise
remfac n d = n, if n mod d ~= 0
= remfac (n div d) d, otherwise

View file

@ -0,0 +1,62 @@
MODULE TotientFunction;
FROM InOut IMPORT WriteString, WriteCard, WriteLn;
VAR count, n, tot: CARDINAL;
PROCEDURE totient(n: CARDINAL): CARDINAL;
VAR tot, i: CARDINAL;
BEGIN
tot := n;
i := 2;
WHILE i*i <= n DO
IF n MOD i = 0 THEN
WHILE n MOD i = 0 DO
n := n DIV i
END;
DEC(tot, tot DIV i)
END;
IF i=2 THEN i := 1 END;
INC(i, 2)
END;
IF n>1 THEN
DEC(tot, tot DIV n)
END;
RETURN tot
END totient;
PROCEDURE ShowPrimeCount(n, count: CARDINAL);
BEGIN
WriteString("Number of primes up to");
WriteCard(n, 6);
WriteString(": ");
WriteCard(count, 4);
WriteLn
END ShowPrimeCount;
BEGIN
count := 0;
WriteString(" N Totient Prime");
WriteLn;
FOR n := 1 TO 25 DO
tot := totient(n);
WriteCard(n, 2);
WriteCard(tot, 9);
IF tot = n-1 THEN
WriteString(" Yes");
INC(count)
ELSE
WriteString(" No")
END;
WriteLn
END;
ShowPrimeCount(25, count);
FOR n := 26 TO 10000 DO
IF totient(n) = n-1 THEN INC(count) END;
IF (n=100) OR (n=1000) OR (n=10000) THEN
ShowPrimeCount(n, count)
END;
END
END TotientFunction.

View file

@ -0,0 +1,41 @@
totientFunction: procedure options(main);
totient: procedure(nn) returns(fixed);
declare (nn, n, i, tot) fixed;
n = nn;
tot = n;
do i=2 repeat(i+2) while(i*i <= n);
if mod(n,i) = 0 then do;
do while(mod(n,i) = 0);
n = n / i;
end;
tot = tot - tot / i;
end;
if i=2 then i=1;
end;
if n>1 then tot = tot - tot/n;
return(tot);
end totient;
showPrimeCount: procedure(n, primeCount);
declare (n, primeCount) fixed;
put skip edit('There are', primeCount, ' primes up to', n) (A,F(5),A,F(6));
end showPrimeCount;
declare (n, primeCount, tot) fixed;
do n = 1 to 25;
tot = totient(n);
put edit('phi(', n, ') = ', tot) (A,F(2),A,F(2));
if tot = n-1 then do;
put list('; prime');
primeCount = primeCount + 1;
end;
put skip;
end;
call showPrimeCount(25, primeCount);
do n = 26 to 10000;
if totient(n) = n-1 then primeCount = primeCount + 1;
if n=100 | n=1000 | n=10000 then
call showPrimeCount(n, primeCount);
end;
end totientFunction;

View file

@ -0,0 +1,66 @@
100H:
BDOS: PROCEDURE (F,A); DECLARE F BYTE, A ADDRESS; GO TO 5; END BDOS;
EXIT: PROCEDURE; GO TO 0; END EXIT;
PRINT: PROCEDURE (S); DECLARE S ADDRESS; CALL BDOS(9,S); END PRINT;
PRINT$NUM: PROCEDURE (N);
DECLARE (N, P) ADDRESS, CH BASED P BYTE;
DECLARE S (6) BYTE INITIAL ('.....$');
P = .S(5);
DIGIT:
P = P-1;
CH = '0' + N MOD 10;
IF (N := N/10) > 0 THEN GO TO DIGIT;
CALL PRINT(P);
END PRINT$NUM;
TOTIENT: PROCEDURE (N) ADDRESS;
DECLARE (TOT, N, I) ADDRESS;
TOT = N;
I = 2;
DO WHILE I*I <= N;
IF N MOD I = 0 THEN DO;
DO WHILE (N := N / I) MOD I = 0; END;
TOT = TOT - TOT / I;
END;
IF I=2 THEN I=1;
I = I+2;
END;
IF N > 1 THEN TOT = TOT - TOT / N;
RETURN TOT;
END TOTIENT;
SHOW$PRIME$COUNT: PROCEDURE (N, COUNT);
DECLARE (N, COUNT) ADDRESS;
CALL PRINT(.'THERE ARE $');
CALL PRINT$NUM(COUNT);
CALL PRINT(.' PRIMES UP TO $');
CALL PRINT$NUM(N);
CALL PRINT(.(13,10,'$'));
END SHOW$PRIME$COUNT;
DECLARE (N, TOT) ADDRESS;
DECLARE PRIME$COUNT ADDRESS INITIAL (0);
DO N = 1 TO 25;
CALL PRINT(.'PHI($');
CALL PRINT$NUM(N);
CALL PRINT(.') = $');
CALL PRINT$NUM(TOT := TOTIENT(N));
IF TOT = N-1 THEN DO;
CALL PRINT(.'; PRIME$');
PRIME$COUNT = PRIME$COUNT + 1;
END;
CALL PRINT(.(13,10,'$'));
END;
CALL SHOW$PRIME$COUNT(25, PRIME$COUNT);
DO N = 26 TO 10000;
IF TOTIENT(N) = N-1 THEN
PRIME$COUNT = PRIME$COUNT + 1;
IF N=100 OR N=1000 OR N=10000 THEN
CALL SHOW$PRIME$COUNT(N, PRIME$COUNT);
END;
CALL EXIT;
EOF

View file

@ -1,7 +1,7 @@
require "prime"
def 𝜑(n)
n.prime_division.inject(1) {|res, (pr, exp)| res *= (pr-1) * pr**(exp-1) }
n.prime_division.inject(1){|res, (pr, exp)| res * (pr-1) * pr**(exp-1) }
end
1.upto 25 do |n|