Left factorials,   !n,   may refer to either   subfactorials   or to   factorial sums;

the same notation can be confusingly seen being used for the two different definitions.

Sometimes,   subfactorials   (also known as derangements)   may use any of the notations:

     !n`   
     !n  
     n¡  


(It may not be visually obvious, but the last example uses an upside-down exclamation mark.)



This Rosetta Code task will be using this formula   (factorial sums)   for   left factorial:


   



!
n
=

∑

k
=
0


n
−
1


k
!


{\displaystyle !n=\sum _{k=0}^{n-1}k!}




 where


   



!
0
=
0


{\displaystyle !0=0}






Task
Display the left factorials for:

   zero through ten     (inclusive)
   20   through   110   (inclusive)   by tens


Display the length (in decimal digits) of the left factorials for:

   1,000   through   10,000   (inclusive), by thousands.


Also see

   The OEIS entry: A003422 left factorials
   The MathWorld entry: left factorial
   The MathWorld entry: factorial sums
   The MathWorld entry: subfactorial


Related task

   permutations/derangements (subfactorials)


# 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
 