How to resolve the algorithm Left factorials step by step in the Python programming language
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
andg
, by applyingg
to the result of applyingf
to an argument.scanl
: Applies a reduction function from left to right, accumulating intermediate results.take
: Takes the firstn
elements of a list or string.takeFromThenTo
: Takes values from a series between positionsa
andb
in steps of sizez
.
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