How to resolve the algorithm Left factorials step by step in the Python programming language

Published on 12 May 2024 09:40 PM

How to resolve the algorithm Left factorials step by step in the Python programming language

Table of Contents

Problem Statement

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:

(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:

Display the left factorials for:

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

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Left factorials step by step in the Python programming language

LFactorial Generator

The first provided code, implemented in Python, generates the left factorial series. The left factorial series is defined as the partial sums of the factorial series:

  • lfact() generates the left factorial series by iteratively multiplying and summing each successive natural number.
  • The islice() function is used to extract the first 11 elements and print them, followed by elements from 20 to 110 in steps of 10, and finally, the number of digits in elements from 1,000 to 10,000 in steps of 1,000.

Left Factorial Series Implementation

The second code provides a more abstract implementation of the left factorial series using Haskell.

  • leftFact: Generates the left factorial series by accumulating the sum of the factorial series.
  • fact: Generates the factorial series by accumulating the product of the natural numbers.

Testing

The main function in the Haskell code tests the leftFact function by printing:

  • The first 11 terms of the series
  • Terms 20 to 110 in steps of 10
  • The number of digits in terms 1k to 10k in steps of 1k

Generic Functions

The code also includes several generic functions:

  • compose: Composes two functions, f and g, by applying g to the result of applying f to an argument.
  • scanl: Applies a reduction function from left to right, accumulating intermediate results.
  • take: Takes the first n elements of a list or string.
  • takeFromThenTo: Takes values from a series between positions a and b in steps of size z.

Source code in the python programming language

from itertools import islice

def lfact():
    yield 0
    fact, summ, n = 1, 0, 1 
    while 1:
        fact, summ, n = fact*n, summ + fact, n + 1
        yield summ

print('first 11:\n  %r' % [lf for i, lf in zip(range(11), lfact())])
print('20 through 110 (inclusive) by tens:')
for lf in islice(lfact(), 20, 111, 10):
    print(lf)
print('Digits in 1,000 through 10,000 (inclusive) by thousands:\n  %r' 
      % [len(str(lf)) for lf in islice(lfact(), 1000, 10001, 1000)] )


'''Left factorials'''

from itertools import (accumulate, chain, count, islice)
from operator import (mul, add)


# leftFact :: [Integer]
def leftFact():
    '''Left factorial series defined in terms
       of the factorial series.
    '''
    return accumulate(
        chain([0], fact()), add
    )


# fact :: [Integer]
def fact():
    '''The factorial series.
    '''
    return accumulate(
        chain([1], count(1)), mul
    )


# ------------------------- TEST -------------------------
# main :: IO ()
def main():
    '''Tests'''
    print(
        'Terms 0 thru 10 inclusive:\n  %r'
        % take(11)(leftFact())
    )

    print('\nTerms 20 thru 110 (inclusive) by tens:')
    for x in takeFromThenTo(20)(30)(110)(leftFact()):
        print(x)

    print(
        '\n\nDigit counts for terms 1k through 10k (inclusive) by k:\n  %r'
        % list(map(
            compose(len)(str),
            takeFromThenTo(1000)(2000)(10000)(
                leftFact()
            )
        ))
    )


# ----------------------- GENERIC ------------------------

# compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
def compose(g):
    '''Function composition.'''
    return lambda f: lambda x: g(f(x))


# scanl :: (b -> a -> b) -> b -> [a] -> [b]
def scanl(f):
    '''scanl is like reduce, but defines a succession of
       intermediate values, building from the left.
    '''
    def go(a):
        def g(xs):
            return accumulate(chain([a], xs), f)
        return g
    return go


# take :: Int -> [a] -> [a]
# take :: Int -> String -> String
def take(n):
    '''The prefix of xs of length n,
       or xs itself if n > length xs'''
    return lambda xs: (
        xs[0:n]
        if isinstance(xs, list)
        else list(islice(xs, n))
    )


# takeFromThenTo :: Int -> Int -> Int -> [a] -> [a]
def takeFromThenTo(a):
    '''Values drawn from a series betweens positions a and b
       at intervals of size z'''
    return lambda b: lambda z: lambda xs: islice(
        xs, a, 1 + z, b - a
    )


if __name__ == '__main__':
    main()


  

You may also check:How to resolve the algorithm Non-decimal radices/Output step by step in the Mathematica/Wolfram Language programming language
You may also check:How to resolve the algorithm Loops/While step by step in the E programming language
You may also check:How to resolve the algorithm Array length step by step in the TI-83 BASIC programming language
You may also check:How to resolve the algorithm Sorting algorithms/Cocktail sort step by step in the Eiffel programming language
You may also check:How to resolve the algorithm Equilibrium index step by step in the VBScript programming language