diff --git a/DIRECTORY.md b/DIRECTORY.md index 6d098f1f845a..7d18029ade79 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -726,6 +726,7 @@ * [Continued Fraction](maths/continued_fraction.py) * [Decimal Isolate](maths/decimal_isolate.py) * [Decimal To Fraction](maths/decimal_to_fraction.py) + * [Derangement](maths/derangement.py) * [Dodecahedron](maths/dodecahedron.py) * [Double Factorial](maths/double_factorial.py) * [Dual Number Automatic Differentiation](maths/dual_number_automatic_differentiation.py) @@ -876,6 +877,7 @@ * [Two Pointer](maths/two_pointer.py) * [Two Sum](maths/two_sum.py) * [Volume](maths/volume.py) + * [Weighted Average](maths/weighted_average.py) * [Zellers Congruence](maths/zellers_congruence.py) ## [Matrix](matrix) diff --git a/maths/derangement.py b/maths/derangement.py new file mode 100644 index 000000000000..238c798e7983 --- /dev/null +++ b/maths/derangement.py @@ -0,0 +1,42 @@ +""" +A Python implementation for finding number of +derangements possible for k objects +https://en.wikipedia.org/wiki/Derangement +""" + + +def derangement(objects: int) -> int: + """ + Calculates the number of derangements of k objects. + :param objects:the number of objects ( -1 < objects < 1560 ) + :return :the number of derangements + :raises :ValueError: If objects is negative. + + Examples: + >>> derangement(3) + 2 + >>> derangement(5) + 44 + >>> derangement(10) + 1334961 + """ + if objects < 0: + raise ValueError("k must be a non-negative integer. Retry") + + # Base cases + if objects in (0, 1): + return 0 + + # Initialize the derangement counts + derange_1 = 1 + derange_2 = 0 + answer = 1 + + # Calculate derangements using dynamic programming + # Answer: F(n) = (n - 1) * ( F(n - 1) + F(n - 2) ) + for i in range(3, objects + 1): + answer = (i - 1) * (derange_1 + derange_2) + derange_2 = derange_1 + derange_1 = answer + + return answer