67 lines
2 KiB
Text
67 lines
2 KiB
Text
# set the precision of LONG LONG INT - large enough for !n up to ! 10 000 #
|
|
PR precision 36000 PR
|
|
# stores left factorials in an array #
|
|
# we calculate the left factorials, storing their values in the "values" array #
|
|
# if step is <= 1, we store we store every left factorial, otherwise we store !x when x MOD step = 0 #
|
|
# note this means values[ 0 ] is always !0 #
|
|
PROC get left factorials = ( REF[]LONG LONG INT values, INT step )VOID:
|
|
BEGIN
|
|
INT store position := LWB values;
|
|
INT max values := UPB values;
|
|
LONG LONG INT result := 0;
|
|
LONG LONG INT factorial k := 1;
|
|
FOR k FROM 0
|
|
WHILE
|
|
IF IF step <= 1 THEN TRUE ELSE k MOD step = 0 FI THEN
|
|
values[ store position ] := result;
|
|
store position +:= 1
|
|
FI;
|
|
store position <= max values
|
|
DO
|
|
result +:= factorial k;
|
|
factorial k *:= ( k + 1 )
|
|
OD
|
|
END # get left factorials # ;
|
|
|
|
# returns the number of digits in n #
|
|
OP DIGITCOUNT = ( LONG LONG INT n )INT:
|
|
BEGIN
|
|
INT result := 1;
|
|
LONG LONG INT v := ABS n;
|
|
WHILE v > 100 000 000 DO
|
|
result +:= 8;
|
|
v OVERAB 100 000 000
|
|
OD;
|
|
WHILE v > 10 DO
|
|
result +:= 1;
|
|
v OVERAB 10
|
|
OD;
|
|
result
|
|
END # DIGITCOUNT # ;
|
|
|
|
BEGIN
|
|
print( ( "!n for n = 0(1)10", newline ) );
|
|
[ 0 : 10 ]LONG LONG INT v;
|
|
get left factorials( v, 1 );
|
|
FOR i FROM 0 TO UPB v DO
|
|
print( ( whole( v[ i ], 0 ), newline ) )
|
|
OD
|
|
END;
|
|
|
|
BEGIN
|
|
print( ( "!n for n = 20(10)110", newline ) );
|
|
[ 0 : 11 ]LONG LONG INT v;
|
|
get left factorials( v, 10 );
|
|
FOR i FROM 2 TO UPB v DO
|
|
print( ( whole( v[ i ], 0 ), newline ) )
|
|
OD
|
|
END;
|
|
|
|
BEGIN
|
|
print( ( "digit counts of !n for n = 1000(1000)10 000", newline ) );
|
|
[ 0 : 10 ]LONG LONG INT v;
|
|
get left factorials( v, 1 000 );
|
|
FOR i FROM 1 TO UPB v DO
|
|
print( ( whole( DIGITCOUNT v[ i ], 0 ), newline ) )
|
|
OD
|
|
END
|