Title: Calculate multifactorials in Python
I recently stumbled across a mathematical concept that I didn't know about: multifactorials.
The factorial of the number N is written N! and equals N × (N - 1) × (N - 2) ... 2 × 1. For example, 5! = 5 × 4 × 3 × 2 × 1 = 120.
The double factorial of N is written N!! and equals N × (N - 2) × (N - 3) ... 1. For example, 5!! = 5 × 3 × 1 = 15.
More generally, the Kth factorial of N equals N × (N - K) × (N - 2K) ... 1. Here are the first three equations.
For another explanation of multifactorials, see the Wolfram Mathworld article Multifactorial and follow the links to the Factorial and Double Factorial articles.
For an even longer explanation including more information such as reasons why you might use multifactorials, see the Wikipedia article Double factorial.
This example uses three methods to make working with multifactorials a bit easier:
- multifactorial_name - Returns the name of a value as in 9!!
- multifactorial_products - Returns the products that make up the result as in 9 × 7 × 5 × 3
- multifactorial - Returns the multifactorial's result as in 945.
These are easy enough to generate by using loops. It's a bit more interesting to try to use a more Pythonic approach. If you like, give it a try before you read further.
multifactorial_name
The following multifactorial_name method returns the name of a multifactorial as in 5!!! or 12!!!!.
def multifactorial_name(n, k=1):
return f'{n}{"!" * k}'
The return statement starts with the number. It then repeats an exclamation mark the necessary number of times.
multifactorial_products
The following multifactorial_products method returns a string holding the products that go into the multifactorial.
def multifactorial_products(n, k=1):
return ' × '.join([str(i) for i in range(n, 1, - k)])
This code uses a list comprehension to make a list containing the product's operands as strings. It then uses ' × '.join to join those values separated by the × symbol.
multifactorial
The following code shows the multifactorial function itself.
def multifactorial(n, k=1):
return math.prod([i for i in range(n, 1, - k)])
This statement uses a list comprehension to make a list holding the values needed to calculate the product. It then uses math.prod to multiply them together.
Main Program
The following code shows the example's main program.
n = 12
for k in range(1, n):
name = multifactorial_name(n, k)
products = multifactorial_products(n, k)
result = multifactorial(n, k)
print(f'{name:<{n+1}} = {products:<44} = {result}')
Here I've broken output into three pieces to make it easier to read.
The program sets the value for N and then loops through all of the possible multifactorials for N. For each, it calls multifactorial_name, multifactorial_products, and multifactorial and displays the results.
That's all there is to it. Download the example to experiment with it.
|