September 2017 Update

This commit is contained in:
Ingy döt Net 2017-09-23 10:01:46 +02:00
parent bba7bfd280
commit ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions

View file

@ -0,0 +1,67 @@
# 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

View file

@ -0,0 +1,38 @@
MODULE LAIROTCAF !Calculates "left factorials".
CONTAINS !The usual suspects.
INTEGER*8 FUNCTION FACT(N) !Factorial, the ordinary.
INTEGER N !The number won't ever get far.
INTEGER I !The stepper.
FACT = 1 !Here we go.
DO I = 2,N !Does nothing for N < 2.
FACT = FACT*I !Perhaps this overflows.
IF (FACT.LE.0) STOP "Factorial: Overflow!" !Two's complement arithmetic.
END DO !No longer any IF OVERFLOW tests.
END FUNCTION FACT !Simple enough.
INTEGER*8 FUNCTION LFACT(N) !Left factorial.
INTEGER N !This number won't get far either.
INTEGER K !A stepper.
LFACT = 0 !Here we go.
DO K = 0,N - 1 !Apply the definition.
LFACT = LFACT + FACT(K) !Perhaps this overflows.
IF (LFACT.LE.0) STOP "Lfact: Overflow!" !Unreliable test.
END DO !On to the next step in the summation.
END FUNCTION LFACT !No attempts at saving effort.
END MODULE LAIROTCAF !Just the minimum.
PROGRAM POKE
USE LAIROTCAF
INTEGER I
WRITE (6,*) "Left factorials, from 0 to 10..."
DO I = 0,10
WRITE (6,1) I,LFACT(I)
1 FORMAT ("!",I0,T6,I0)
END DO
WRITE (6,*) "Left factorials, from 20 to 110 by tens..."
DO I = 20,110,10
WRITE (6,1) I,LFACT(I)
END DO
END

View file

@ -0,0 +1,67 @@
Calculates "left factorials", in sequence, and shows some.
INTEGER ENUFF,BASE !Some parameters.
PARAMETER (BASE = 10, ENUFF = 40000) !This should do.
INTEGER LF,F(ENUFF),LS,S(ENUFF) !Big numbers in digits F(1:LF), S(1:LS)
INTEGER N !A stepper.
INTEGER L !Locates digits.
INTEGER C !A carry for arithmetic.
INTEGER MSG !I/O unit number.
MSG = 6 !Standard output.
LF = 1; F(1) = 1 !Set F = 1 = 0!
LS = 1; S(1) = 0 !Set S = 0 = !0
WRITE (MSG,1) 0,0 !Pre-emptive first result.
1 FORMAT ("!",I0,T6,666I1) !This will do for reasonable sizes.
10 DO N = 1,10000 !Step away.
Commence the addition of F to S.
20 C = 0 !Clear the carry.
DO L = 1,MIN(LF,LS) !First, both S and F have low-order digits.
C = S(L) + F(L) + C !So, a three-part addition.
S(L) = MOD(C,BASE) !Place the digit.
C = C/BASE !Carry to the next digit up.
END DO !Ends with L and C important.
Careful. L fingers the next digit up, and C is to carry in to that digit.
IF (LF.GT.LS) THEN !Has F more digits than S?
DO L = L,LF !Yes. Continue adding, with leading zero digits from S.
C = F(L) + C !Thus.
LS = LS + 1 !Another digit for S.
S(LS) = MOD(C,BASE) !Place.
C = C/BASE !Carry to the next digit up.
END DO !Continue to the end of F.
END IF !Either way, F has been added in.
Continue carrying, with C for digit L.
DO WHILE(C .GT. 0) !Extend the carry into S.
IF (L.LE.LS) THEN !If F had fewer digits than S,
C = C + S(L) !S digits await.
ELSE !Otherwise,
LS = LS + 1 !Extend S.
END IF !C is ready.
S(L) = MOD(C,BASE) !Place it.
C = C/BASE !The carry for the next digit up.
L = L + 1 !Locate it.
END DO !Perhaps a multi-digit carry.
Contemplate what to do with the current S.
IF (N.LE.10) THEN !First selection: !N for 0 to 10.
WRITE (MSG,1) N,S(LS:1:-1) !Show the value. Digits from the high-order end down.
ELSE IF (20.LE.N .AND. N.LE.110) THEN !Second selection: for 20 to 110,
IF (MOD(N,10).EQ.0) WRITE (MSG,1) N,S(LS:1:-1) !Show only every tenth.
ELSE !Third selection
IF (MOD(N,1000).EQ.0) WRITE (MSG,21) N,LS !Show only the number of digits.
21 FORMAT ("!",I0," has ",I0," digits.") !Which is why BASE is only 10.
END IF !So much for the selection of output.
Calculate the next factorial, ready for the next one up.
C = 0 !Start a multiply.
DO L = 1,LF !Step up the digits to produce N! in F.
C = F(L)*N + C !A digit.
F(L) = MOD(C,BASE) !Place.
C = C/BASE !Extract the carry.
END DO !On to the next digit.
DO WHILE(C .GT. 0) !While any carry remains,
LF = LF + 1 !Add another digit to F.
IF (LF.GT.ENUFF) STOP "F overflow!" !Perhaps not.
F(LF) = MOD(C,BASE) !The digit.
C = C/BASE !Carry to the next digit up.
END DO !If there is one, as when N > BASE.
END DO !On to the next result.
END !Ends with a new factorial that won't be used.

View file

@ -0,0 +1,43 @@
' FB 1.05.0 Win64
#include "gmp.bi"
Sub leftFactorial(rop As __mpz_struct, op As ULong)
Dim As __mpz_struct t1
mpz_init_set_ui(@t1, 1)
mpz_set_ui(@rop, 0)
For i As ULong = 1 To op
mpz_add(@rop, @rop, @t1)
mpz_mul_ui(@t1, @t1, i)
Next
mpz_clear(@t1)
End Sub
Function digitCount(op As __mpz_struct) As ULong
Dim As ZString Ptr t = mpz_get_str(0, 10, @op)
Dim As ULong ret = Len(*t)
Deallocate(t)
Return ret
End Function
Dim As __mpz_struct t
mpz_init(@t)
For i As ULong = 0 To 110
If i <= 10 OrElse i Mod 10 = 0 Then
leftFactorial(t, i)
gmp_printf(!"!%u = %Zd\n", i, @t)
End If
Next
Print
For i As ULong = 1000 To 10000 Step 1000
leftFactorial(t, i)
Print "!"; Str(i); " has "; digitCount(t); " digits"
Next
mpz_clear(@t)
Print
Print "Press any key to quit"
Sleep

View file

@ -1,18 +1,20 @@
fact :: [Integer]
fact = scanl (*) 1 [1..]
fact = scanl (*) 1 [1 ..]
leftFact :: [Integer]
leftFact = scanl (+) 0 fact
main = do
putStrLn "0 ~ 10:"
putStrLn $ show $ map (\n -> leftFact !! n) [0..10]
putStrLn ""
putStrLn "20 ~ 110 by tens:"
putStrLn $ unlines $ map show $ map (\n -> leftFact !! n) [20,30..110]
putStrLn ""
putStrLn "length of 1,000 ~ 10,000 by thousands:"
putStrLn $ show $ map (\n -> length $ show $ leftFact !! n) [1000,2000..10000]
putStrLn ""
main :: IO ()
main =
mapM_
putStrLn
[ "0 ~ 10:"
, show $ (leftFact !!) <$> [0 .. 10]
, ""
, "20 ~ 110 by tens:"
, unlines $ show . (leftFact !!) <$> [20,30 .. 110]
, ""
, "length of 1,000 ~ 10,000 by thousands:"
, show $ (length . show . (leftFact !!)) <$> [1000,2000 .. 10000]
, ""
]

View file

@ -0,0 +1,23 @@
// version 1.0.6
import java.math.BigInteger
fun leftFactorial(n: Int): BigInteger {
if (n == 0) return BigInteger.ZERO
var fact = BigInteger.ONE
var sum = fact
for (i in 1 until n) {
fact *= BigInteger.valueOf(i.toLong())
sum += fact
}
return sum
}
fun main(args: Array<String>) {
for (i in 0..110)
if (i <= 10 || (i % 10) == 0)
println("!${i.toString().padEnd(3)} = ${leftFactorial(i)}")
println("\nLength of the following left factorials:")
for (i in 1000..10000 step 1000)
println("!${i.toString().padEnd(5)} has ${leftFactorial(i).toString().length} digits")
}

View file

@ -0,0 +1,32 @@
include builtins\bigatom.e
sequence lf_list
procedure init(integer n)
bigatom f = ba_new(1)
atom t1 = time()+1
lf_list = repeat(f,n+1)
for i=1 to n do
f = ba_multiply(f,i)
lf_list[i+1] = f
if time()>t1 then
printf(1,"loading main table (%d of %d)...\n",{i,n})
t1 = time()+1
end if
end for
end procedure
function lf(integer n)
-- Returns left factorial of n, as a string
bigatom sumf = ba_new(0)
for k=0 to n-1 do sumf = ba_add(sumf, lf_list[k+1]) end for
return ba_sprint(sumf)
end function
-- Main procedure
atom t0 = time()
init(10000)
for i=0 to 10 do printf(1,"!%d = %s\n",{i,lf(i)}) end for
for i=20 to 110 by 10 do printf(1,"!%d = %s\n",{i,lf(i)}) end for
for i=1000 to 10000 by 1000 do printf(1,"!%d contains %d digits\n",{i,length(lf(i))}) end for
printf(1,"complete (%3.2fs)\n",{time()-t0})

View file

@ -0,0 +1,27 @@
(import (scheme base) ;; library imports in R7RS style
(scheme write)
(srfi 1 lists))
(define (factorial n)
(fold * 1 (iota n 1)))
(define (left-factorial n)
(fold + 0 (map factorial (iota n))))
(define (show i r) ; to pretty print the results
(display "!") (display i) (display " ") (display r) (newline))
;; show left factorials for zero through ten (inclusive)
(for-each
(lambda (i) (show i (left-factorial i)))
(iota 11))
;; show left factorials for 20 through 110 (inclusive) by tens
(for-each
(lambda (i) (show i (left-factorial i)))
(iota 10 20 10))
;; number of digits in 1000 through 10000 by thousands:
(for-each
(lambda (i) (show i (string-length (number->string (left-factorial i)))))
(iota 10 1000 1000))

View file

@ -1,3 +1,3 @@
func left_fact(k) {
^k -> map {|n| n! } -> sum(0)
^k -> map {|n| n! } -> sum
}

View file

@ -1,3 +1,3 @@
func left_fact(k) {
^k -> reduce { |a,b| a + b! } + 1
^k -> reduce({ |a,b| a + b! }, 0)
}

View file

@ -1,9 +1,7 @@
for r in [range(0, 10), range(20, 110).by(10)] {
for i in r {
printf("!%d = %s\n", i, left_fact(i));
}
for i (0..10, 20..110 `by` 10) {
printf("!%d = %s\n", i, left_fact(i))
}
for i in range(1000, 10000).by(1000) {
printf("!%d has %d digits.\n", i, left_fact(i).len);
for i (1000..10000 `by` 1000) {
printf("!%d has %d digits.\n", i, left_fact(i).len)
}

View file

@ -0,0 +1,6 @@
var BN=Import("zklBigNum");
fcn leftFact(n){
[1..n].reduce(fcn(p,n,rf){ p+=rf.value; rf.set(rf.value*n); p },
BN(0),Ref(BN(1)));
}

View file

@ -0,0 +1,7 @@
println("First 11 left factorials:\n", [0..10].apply(leftFact));
lfs:=[20..111,10].apply(leftFact);
println(("\n20 through 110 (inclusive) by tens:\n" +
"%d\n"*lfs.len()).fmt(lfs.xplode()));
println("Digits in 1,000 through 10,000 by thousands:\n",
[0d1_000..0d10_000, 1000].pump(List,fcn(n){leftFact(n).toString().len()}));