From 419864ef68196c42aaf9a7290210f8b6cdec5d3a Mon Sep 17 00:00:00 2001 From: Tauseef-Hilal Date: Mon, 2 Oct 2023 00:05:07 +0530 Subject: [PATCH 1/4] Add Bell Numbers --- maths/bell_numbers.py | 81 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 maths/bell_numbers.py diff --git a/maths/bell_numbers.py b/maths/bell_numbers.py new file mode 100644 index 000000000000..78650f0eae4b --- /dev/null +++ b/maths/bell_numbers.py @@ -0,0 +1,81 @@ +""" +Bell numbers represent the number of ways to partition a set into non-empty subsets. This module provides functions to calculate Bell numbers for sets of integers. In other words, the first (n + 1) Bell numbers. + +For more information about Bell numbers, refer to: +https://en.wikipedia.org/wiki/Bell_number + +Example: +To calculate the Bell numbers for sets of lengths from 0 to 5: + +>>> import bell_numbers +>>> bell_numbers.bell_numbers(5) +[1, 1, 2, 5, 15, 52] +""" + + +def bell_numbers(n: int) -> list[int]: + """ + Calculate Bell numbers for the sets of lengths from 0 to n. In other words, calculate first (n + 1) Bell numbers. + + Args: + n (int): The maximum length of the sets for which Bell numbers are calculated. + + Returns: + list: A list of Bell numbers for sets of lengths from 0 to n. + + Examples: + >>> bell_numbers(0) + [1] + >>> bell_numbers(1) + [1, 1] + >>> bell_numbers(5) + [1, 1, 2, 5, 15, 52] + """ + if n < 0: + raise ValueError("n must be non-negative") + + bell = [0] * (n + 1) + bell[0] = 1 + + for i in range(1, n + 1): + for j in range(i): + bell[i] += _binomial_coefficient(i - 1, j) * bell[j] + + return bell + + +def _binomial_coefficient(n: int, k: int) -> int: + """ + Calculate the binomial coefficient C(n, k) using dynamic programming. + + Args: + n (int): Total number of elements. + k (int): Number of elements to choose. + + Returns: + int: The binomial coefficient C(n, k). + + Examples: + >>> _binomial_coefficient(5, 2) + 10 + >>> _binomial_coefficient(6, 3) + 20 + """ + if k == 0 or k == n: + return 1 + + if k > n - k: + k = n - k + + coefficient = 1 + for i in range(k): + coefficient *= n - i + coefficient //= i + 1 + + return coefficient + + +if __name__ == "__main__": + import doctest + + doctest.testmod() From fcfd92f317e279852186fe12452d74e074330050 Mon Sep 17 00:00:00 2001 From: Tauseef-Hilal Date: Mon, 2 Oct 2023 00:21:11 +0530 Subject: [PATCH 2/4] Use descriptive variable names --- maths/bell_numbers.py | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/maths/bell_numbers.py b/maths/bell_numbers.py index 78650f0eae4b..dc8ffc8281eb 100644 --- a/maths/bell_numbers.py +++ b/maths/bell_numbers.py @@ -1,5 +1,7 @@ """ -Bell numbers represent the number of ways to partition a set into non-empty subsets. This module provides functions to calculate Bell numbers for sets of integers. In other words, the first (n + 1) Bell numbers. +Bell numbers represent the number of ways to partition a set into non-empty +subsets. This module provides functions to calculate Bell numbers for sets of +integers. In other words, the first (n + 1) Bell numbers. For more information about Bell numbers, refer to: https://en.wikipedia.org/wiki/Bell_number @@ -13,15 +15,17 @@ """ -def bell_numbers(n: int) -> list[int]: +def bell_numbers(max_set_length: int) -> list[int]: """ - Calculate Bell numbers for the sets of lengths from 0 to n. In other words, calculate first (n + 1) Bell numbers. + Calculate Bell numbers for the sets of lengths from 0 to max_set_length. + In other words, calculate first (max_set_length + 1) Bell numbers. Args: - n (int): The maximum length of the sets for which Bell numbers are calculated. + max_set_length (int): The maximum length of the sets for which + Bell numbers are calculated. Returns: - list: A list of Bell numbers for sets of lengths from 0 to n. + list: A list of Bell numbers for sets of lengths from 0 to max_set_length. Examples: >>> bell_numbers(0) @@ -31,29 +35,29 @@ def bell_numbers(n: int) -> list[int]: >>> bell_numbers(5) [1, 1, 2, 5, 15, 52] """ - if n < 0: - raise ValueError("n must be non-negative") + if max_set_length < 0: + raise ValueError("max_set_length must be non-negative") - bell = [0] * (n + 1) + bell = [0] * (max_set_length + 1) bell[0] = 1 - for i in range(1, n + 1): + for i in range(1, max_set_length + 1): for j in range(i): bell[i] += _binomial_coefficient(i - 1, j) * bell[j] return bell -def _binomial_coefficient(n: int, k: int) -> int: +def _binomial_coefficient(total_elements, elements_to_choose): """ - Calculate the binomial coefficient C(n, k) using dynamic programming. + Calculate the binomial coefficient C(total_elements, elements_to_choose) Args: - n (int): Total number of elements. - k (int): Number of elements to choose. + total_elements (int): The total number of elements. + elements_to_choose (int): The number of elements to choose. Returns: - int: The binomial coefficient C(n, k). + int: The binomial coefficient C(total_elements, elements_to_choose). Examples: >>> _binomial_coefficient(5, 2) @@ -61,15 +65,15 @@ def _binomial_coefficient(n: int, k: int) -> int: >>> _binomial_coefficient(6, 3) 20 """ - if k == 0 or k == n: + if elements_to_choose in {0, total_elements}: return 1 - if k > n - k: - k = n - k + if elements_to_choose > total_elements - elements_to_choose: + elements_to_choose = total_elements - elements_to_choose coefficient = 1 - for i in range(k): - coefficient *= n - i + for i in range(elements_to_choose): + coefficient *= total_elements - i coefficient //= i + 1 return coefficient From 908261cbefb2f432333e9f5ede0a47afbd76eb0a Mon Sep 17 00:00:00 2001 From: Tauseef-Hilal Date: Mon, 2 Oct 2023 00:22:36 +0530 Subject: [PATCH 3/4] Add type hints --- maths/bell_numbers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maths/bell_numbers.py b/maths/bell_numbers.py index dc8ffc8281eb..335854bcdd74 100644 --- a/maths/bell_numbers.py +++ b/maths/bell_numbers.py @@ -48,7 +48,7 @@ def bell_numbers(max_set_length: int) -> list[int]: return bell -def _binomial_coefficient(total_elements, elements_to_choose): +def _binomial_coefficient(total_elements: int, elements_to_choose: int) -> int: """ Calculate the binomial coefficient C(total_elements, elements_to_choose) From 8985a318b7672111b2ea0e6177d2592cb2a044de Mon Sep 17 00:00:00 2001 From: Tauseef-Hilal Date: Mon, 2 Oct 2023 00:35:51 +0530 Subject: [PATCH 4/4] Fix failing tests --- maths/bell_numbers.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/maths/bell_numbers.py b/maths/bell_numbers.py index 335854bcdd74..660ec6e6aa09 100644 --- a/maths/bell_numbers.py +++ b/maths/bell_numbers.py @@ -5,13 +5,6 @@ For more information about Bell numbers, refer to: https://en.wikipedia.org/wiki/Bell_number - -Example: -To calculate the Bell numbers for sets of lengths from 0 to 5: - ->>> import bell_numbers ->>> bell_numbers.bell_numbers(5) -[1, 1, 2, 5, 15, 52] """