Left factorials: Difference between revisions

From Rosetta Code
Content added Content deleted
m (added an extra blank line for the formula (to read better).)
(→‎{{header|Perl 6}}: Added Perl 6 implementation)
Line 30: Line 30:
* The MathWorld (TM) entry: [[http://mathworld.wolfram.com/FactorialSums.html factorial sums]] in Wolfram MathWorld (TM).
* The MathWorld (TM) entry: [[http://mathworld.wolfram.com/FactorialSums.html factorial sums]] in Wolfram MathWorld (TM).
* The MathWorld (TM) entry: [[http://mathworld.wolfram.com/Subfactorial.html subfactorial]] in Wolfram MathWorld (TM).
* The MathWorld (TM) entry: [[http://mathworld.wolfram.com/Subfactorial.html subfactorial]] in Wolfram MathWorld (TM).


=={{header|Perl 6}}==
Perl 6 doesn't have a built in factorial function, so the first two lines implement postfix ! factorial. The newly implemented factorial function is used to implement left factorial using a prefix ! in the next two lines. Note that this redefines the core prefix ! (not) function. The last two lines are display code for the various sub task requirements.

<lang perl6>multi sub postfix:<!> (0) { 1 };
multi sub postfix:<!> ($n) { [*] 1 .. $n };
multi sub prefix:<!> (0) { 0 };
multi sub prefix:<!> ($k) { [+] (^$k).map: { $_! } }

printf "!%d = %s\n", $_, !$_ for ^11, 20, 30 ... 110;
printf "!%d has %d digits.\n", $_, (!$_).chars for 1000, 2000 ... 10000;</lang>
{{out}}
<pre>!0 = 0
!1 = 1
!2 = 2
!3 = 4
!4 = 10
!5 = 34
!6 = 154
!7 = 874
!8 = 5914
!9 = 46234
!10 = 409114
!20 = 128425485935180314
!30 = 9157958657951075573395300940314
!40 = 20935051082417771847631371547939998232420940314
!50 = 620960027832821612639424806694551108812720525606160920420940314
!60 = 141074930726669571000530822087000522211656242116439949000980378746128920420940314
!70 = 173639511802987526699717162409282876065556519849603157850853034644815111221599509216528920420940314
!80 = 906089587987695346534516804650290637694024830011956365184327674619752094289696314882008531991840922336528920420940314
!90 = 16695570072624210767034167688394623360733515163575864136345910335924039962404869510225723072235842668787507993136908442336528920420940314
!100 = 942786239765826579160595268206839381354754349601050974345395410407078230249590414458830117442618180732911203520208889371641659121356556442336528920420940314
!110 = 145722981061585297004706728001906071948635199234860720988658042536179281328615541936083296163475394237524337422204397431927131629058103519228197429698252556442336528920420940314
!1000 has 2565 digits.
!2000 has 5733 digits.
!3000 has 9128 digits.
!4000 has 12670 digits.
!5000 has 16322 digits.
!6000 has 20062 digits.
!7000 has 23875 digits.
!8000 has 27749 digits.
!9000 has 31678 digits.
!10000 has 35656 digits.</pre>





Revision as of 00:03, 30 March 2014

Left factorials is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

Left factorials have a confusing name as it can refer to:

  • subfactorials:     !n
  • factorial sums:   !n

and one can see the exact notation being used for both.

Sometimes, subfactorials use the notation:   !n`   or   !n'   or   .

(Subfactorials are also known as derangements.)

This Rosetta Code task will be using the formula for left factorial:

 
where
!0 = 0
task requirements

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


Perl 6

Perl 6 doesn't have a built in factorial function, so the first two lines implement postfix ! factorial. The newly implemented factorial function is used to implement left factorial using a prefix ! in the next two lines. Note that this redefines the core prefix ! (not) function. The last two lines are display code for the various sub task requirements.

<lang perl6>multi sub postfix:<!> (0) { 1 }; multi sub postfix:<!> ($n) { [*] 1 .. $n }; multi sub prefix:<!> (0) { 0 }; multi sub prefix:<!> ($k) { [+] (^$k).map: { $_! } }

printf "!%d = %s\n", $_, !$_ for ^11, 20, 30 ... 110; printf "!%d has %d digits.\n", $_, (!$_).chars for 1000, 2000 ... 10000;</lang>

Output:
!0  = 0
!1  = 1
!2  = 2
!3  = 4
!4  = 10
!5  = 34
!6  = 154
!7  = 874
!8  = 5914
!9  = 46234
!10  = 409114
!20  = 128425485935180314
!30  = 9157958657951075573395300940314
!40  = 20935051082417771847631371547939998232420940314
!50  = 620960027832821612639424806694551108812720525606160920420940314
!60  = 141074930726669571000530822087000522211656242116439949000980378746128920420940314
!70  = 173639511802987526699717162409282876065556519849603157850853034644815111221599509216528920420940314
!80  = 906089587987695346534516804650290637694024830011956365184327674619752094289696314882008531991840922336528920420940314
!90  = 16695570072624210767034167688394623360733515163575864136345910335924039962404869510225723072235842668787507993136908442336528920420940314
!100  = 942786239765826579160595268206839381354754349601050974345395410407078230249590414458830117442618180732911203520208889371641659121356556442336528920420940314
!110  = 145722981061585297004706728001906071948635199234860720988658042536179281328615541936083296163475394237524337422204397431927131629058103519228197429698252556442336528920420940314
!1000 has 2565 digits.
!2000 has 5733 digits.
!3000 has 9128 digits.
!4000 has 12670 digits.
!5000 has 16322 digits.
!6000 has 20062 digits.
!7000 has 23875 digits.
!8000 has 27749 digits.
!9000 has 31678 digits.
!10000 has 35656 digits.


REXX

<lang rexx>/*REXX pgm computes/shows the left factorial (or width) of N (or range).*/ parse arg bot top inc . /*obtain optional args from C.L. */ if bot== then bot=1 /*BOT defined? Then use default.*/ td= bot<0 /*if BOT < 0, only show # digs.*/ bot=abs(bot) /*use the |bot| for the DO loop.*/ if top== then top=bot /* " " top " " " " */ if inc= then inc=1 /* " " inc " " " " */ @='left ! of ' /*a literal used in the display. */ w=length(H) /*width of largest number request*/

          do j=bot  to top  by inc    /*traipse through  #'s requested.*/
          if td  then say @ right(j,w)  " ───► "  length(L!(j)) ' digits'
                 else say @ right(j,w)  " ───► "  L!(j)
          end   /*j*/                  /* [↑]  show either L! or #digits*/

exit /*stick a fork in it, we're done.*/ /*──────────────────────────────────L! subroutine───────────────────────*/ L!: procedure; parse arg x .; if x<3 then return x; s=4 /*shortcuts.*/ !=2; do f=3 to x-1 /*compute L! for all numbers───►X*/

        !=!*f                         /*compute intermediate factorial.*/
        if pos(.,!)\==0 then numeric digits digits()*1.5%1 /*bump digs.*/
        s=s+!                         /*add the factorial ───► L!  sum.*/
        end   /*f*/                   /* [↑]  handles gi-hugeic numbers*/

return s /*return the sum (L!) to invoker.*/</lang> output when using the input:   0 10

left ! of   0  ───►  0
left ! of   1  ───►  1
left ! of   2  ───►  2
left ! of   3  ───►  4
left ! of   4  ───►  10
left ! of   5  ───►  34
left ! of   6  ───►  154
left ! of   7  ───►  874
left ! of   8  ───►  5914
left ! of   9  ───►  46234
left ! of  10  ───►  409114

output when using the input:   20 110 10

left ! of   20  ───►  128425485935180314
left ! of   30  ───►  9157958657951075573395300940314
left ! of   40  ───►  20935051082417771847631371547939998232420940314
left ! of   50  ───►  620960027832821612639424806694551108812720525606160920420940314
left ! of   60  ───►  141074930726669571000530822087000522211656242116439949000980378746128920420940314
left ! of   70  ───►  173639511802987526699717162409282876065556519849603157850853034644815111221599509216528920420940314
left ! of   80  ───►  906089587987695346534516804650290637694024830011956365184327674619752094289696314882008531991840922336528920420940314
left ! of   90  ───►  16695570072624210767034167688394623360733515163575864136345910335924039962404869510225723072235842668787507993136908442336528920420940314
left ! of  100  ───►  942786239765826579160595268206839381354754349601050974345395410407078230249590414458830117442618180732911203520208889371641659121356556442336528920420940314
left ! of  110  ───►  145722981061585297004706728001906071948635199234860720988658042536179281328615541936083296163475394237524337422204397431927131629058103519228197429698252556442336528920420940314

output when using the input:   -1000 10000 1000

left ! of   1000  ───►  2565  digits
left ! of   2000  ───►  5733  digits
left ! of   3000  ───►  9128  digits
left ! of   4000  ───►  12670  digits
left ! of   5000  ───►  16322  digits
left ! of   6000  ───►  20062  digits
left ! of   7000  ───►  23875  digits
left ! of   8000  ───►  27749  digits
left ! of   9000  ───►  31678  digits
left ! of  10000  ───►  35656  digits