From fe4d70f8a34e15a838df5e81adfe01e139a7a037 Mon Sep 17 00:00:00 2001 From: umutKaracelebi Date: Tue, 17 Feb 2026 22:33:50 +0300 Subject: [PATCH] Refactor kth_permutation and fix linter errors --- .../linear_discriminant_analysis.py | 8 ++-- maths/kth_lexicographic_permutation.py | 40 +++++++++++++++---- 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/machine_learning/linear_discriminant_analysis.py b/machine_learning/linear_discriminant_analysis.py index 8528ccbba..a1a85fdc1 100644 --- a/machine_learning/linear_discriminant_analysis.py +++ b/machine_learning/linear_discriminant_analysis.py @@ -249,16 +249,16 @@ def accuracy(actual_y: list, predicted_y: list) -> float: return (correct / len(actual_y)) * 100 -num = TypeVar("num") +T = TypeVar("T") def valid_input( - input_type: Callable[[object], num], # Usually float or int + input_type: Callable[[object], T], # Usually float or int input_msg: str, err_msg: str, - condition: Callable[[num], bool] = lambda _: True, + condition: Callable[[T], bool] = lambda _: True, default: str | None = None, -) -> num: +) -> T: """ Ask for user value and validate that it fulfill a condition. diff --git a/maths/kth_lexicographic_permutation.py b/maths/kth_lexicographic_permutation.py index b85558aca..835092644 100644 --- a/maths/kth_lexicographic_permutation.py +++ b/maths/kth_lexicographic_permutation.py @@ -1,24 +1,50 @@ -def kth_permutation(k, n): +def kth_permutation(k: int, n: int) -> list[int]: """ Finds k'th lexicographic permutation (in increasing order) of 0,1,2,...n-1 in O(n^2) time. + :param k: The index of the permutation (0-based) + :param n: The number of elements in the permutation + :return: The k-th lexicographic permutation of size n + Examples: - First permutation is always 0,1,2,...n - >>> kth_permutation(0,5) + First permutation is always 0,1,2,...n-1 + >>> kth_permutation(0, 5) [0, 1, 2, 3, 4] The order of permutation of 0,1,2,3 is [0,1,2,3], [0,1,3,2], [0,2,1,3], [0,2,3,1], [0,3,1,2], [0,3,2,1], [1,0,2,3], [1,0,3,2], [1,2,0,3], [1,2,3,0], [1,3,0,2] - >>> kth_permutation(10,4) + >>> kth_permutation(10, 4) [1, 3, 0, 2] + + >>> kth_permutation(10, 0) + Traceback (most recent call last): + ... + ValueError: n must be positive + + >>> kth_permutation(-1, 5) + Traceback (most recent call last): + ... + IndexError: k must be non-negative + + >>> kth_permutation(120, 5) + Traceback (most recent call last): + ... + IndexError: k out of bounds """ - # Factorails from 1! to (n-1)! + if n <= 0: + raise ValueError("n must be positive") + if k < 0: + raise IndexError("k must be non-negative") + + # Factorials from 1! to (n-1)! factorials = [1] for i in range(2, n): factorials.append(factorials[-1] * i) - assert 0 <= k < factorials[-1] * n, "k out of bounds" + + if k >= factorials[-1] * n: + raise IndexError("k out of bounds") permutation = [] elements = list(range(n)) @@ -28,7 +54,7 @@ def kth_permutation(k, n): factorial = factorials.pop() number, k = divmod(k, factorial) permutation.append(elements[number]) - elements.remove(elements[number]) + elements.pop(number) # elements.remove(elements[number]) is slower and redundant permutation.append(elements[0]) return permutation