diff --git a/backtracking/all_permutations.py b/backtracking/all_permutations.py index ff8a53e0dd0e..b66edd767270 100644 --- a/backtracking/all_permutations.py +++ b/backtracking/all_permutations.py @@ -7,9 +7,44 @@ """ from __future__ import annotations +from itertools import permutations -def generate_all_permutations(sequence: list[int | str]) -> None: - create_state_space_tree(sequence, [], 0, [0 for i in range(len(sequence))]) + +def permutation_tuple_to_list(arr: list[int | str]) -> list[list[int | str]]: + """ + Default permutation output is list of tuples + >>> permutation_tuple_to_list([1,2]) + [[1, 2], [2, 1]] + >>> permutation_tuple_to_list(['a', 'b']) + [['a', 'b'], ['b', 'a']] + """ + return [list(output_tuple) for output_tuple in permutations(arr)] + + +def generate_all_permutations(sequence: list[int | str]) -> list[list[int | str]]: + """ + >>> generate_all_permutations([]) + [[]] + >>> generate_all_permutations([1]) + [[1]] + >>> generate_all_permutations([1, 2]) + [[1, 2], [2, 1]] + >>> generate_all_permutations([1, 2, 3]) + [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]] + >>> generate_all_permutations([-1, 2]) + [[-1, 2], [2, -1]] + >>> generate_all_permutations([1, -2]) + [[1, -2], [-2, 1]] + >>> generate_all_permutations(['a', 'b']) + [['a', 'b'], ['b', 'a']] + >>> from itertools import permutations + >>> test_arr = [num for num in range(0, 6)] + >>> generate_all_permutations(test_arr) == permutation_tuple_to_list(test_arr) + True + """ + output: list[list[int | str]] = [] + create_state_space_tree(sequence, [], 0, [0 for i in range(len(sequence))], output) + return output def create_state_space_tree( @@ -17,6 +52,7 @@ def create_state_space_tree( current_sequence: list[int | str], index: int, index_used: list[int], + output: list[list[int | str]], ) -> None: """ Creates a state space tree to iterate through each branch using DFS. @@ -25,14 +61,20 @@ def create_state_space_tree( """ if index == len(sequence): - print(current_sequence) + # Copying b/c popping current_sequence is part of this recursive algo. + # Can't have pointer to that arr + current_sequence_copy = list(current_sequence) + output.append(current_sequence_copy) return for i in range(len(sequence)): if not index_used[i]: current_sequence.append(sequence[i]) index_used[i] = True - create_state_space_tree(sequence, current_sequence, index + 1, index_used) + # function spaced like this b/c linter 88 char limit + create_state_space_tree( + sequence, current_sequence, index + 1, index_used, output + ) current_sequence.pop() index_used[i] = False @@ -49,3 +91,8 @@ def create_state_space_tree( sequence_2: list[int | str] = ["A", "B", "C"] generate_all_permutations(sequence_2) + +if __name__ == "__main__": + from doctest import testmod + + testmod()