Left factorials

Built-in:

say 20.of { .left_factorial }

Straightforward:

func left_factorial(n) {
    ^n -> sum { _! }
}

Memory efficient with Range.reduce():

func left_factorial(n) {
    ^n -> reduce({ |a,b| a + b! }, 0)
}

A faster approach:

func left_factorial(n) {
    static cached    = 0
    static factorial = 1
    static leftfact  = 0

    if (n < cached) {
        cached    = 0
        factorial = 1
        leftfact  = 0
    }

    while (n > cached) {
        leftfact  += factorial
        factorial *= ++cached
    }

    leftfact
}

Completing the task:

for n in (0..10, 20..110 `by` 10) {
    printf("!%d  = %s\n", n, left_factorial(n))
}

for n in (1000..10000 `by` 1000) {
    printf("!%d has %d digits.\n", n, left_factorial(n).len)
}

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.

Last updated