From 618f6e1f043b208b28220de0a41d9447c390d170 Mon Sep 17 00:00:00 2001 From: Gourav Saha Date: Sun, 19 Oct 2025 20:25:09 +0530 Subject: [PATCH 1/6] Added new file in divide and conquer folder --- divide_and_conquer/tower_of_hanoi.py | 66 ++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 divide_and_conquer/tower_of_hanoi.py diff --git a/divide_and_conquer/tower_of_hanoi.py b/divide_and_conquer/tower_of_hanoi.py new file mode 100644 index 000000000000..ee3eff5f7ae0 --- /dev/null +++ b/divide_and_conquer/tower_of_hanoi.py @@ -0,0 +1,66 @@ +""" +Towers of Hanoi is a mathematical puzzle that is solved using a recursive +divide-and-conquer strategy. + +It moves a stack of disks from a source pole to a destination pole, +using an auxiliary pole, subject to these rules: +1. Only one disk can be moved at a time. +2. Each move consists of taking the upper disk from one stack and + placing it on top of another stack or an empty pole. +3. No disk may be placed on top of a smaller disk. + +More information: +https://en.wikipedia.org/wiki/Tower_of_Hanoi +""" + + +def tower_of_hanoi(n: int, source: str = "A", auxiliary: str = "B", destination: str = "C") -> list[tuple[str, str]]: + """ + Pure python implementation of the Towers of Hanoi puzzle (recursive version), + returning the sequence of moves required to solve the puzzle. + + >>> tower_of_hanoi(1) + [('A', 'C')] + >>> tower_of_hanoi(2) + [('A', 'B'), ('A', 'C'), ('B', 'C')] + >>> tower_of_hanoi(3) + [('A', 'C'), ('A', 'B'), ('C', 'B'), ('A', 'C'), ('B', 'A'), ('B', 'C'), ('A', 'C')] + >>> tower_of_hanoi(0) + [] + """ + moves = [] + + def solve_hanoi(n: int, source: str, auxiliary: str, destination: str): + """Recursive helper function to generate the moves.""" + if n == 0: + return + + # 1. Move n-1 disks from Source to Auxiliary, using Destination as auxiliary. + # This is the "Divide" step. + solve_hanoi(n - 1, source, destination, auxiliary) + + # 2. Move the largest disk (n) from Source to Destination. + # This is the "Conquer" step (base step of the recursion). + moves.append((source, destination)) + + # 3. Move n-1 disks from Auxiliary to Destination, using Source as auxiliary. + # This is the "Combine" step. + solve_hanoi(n - 1, auxiliary, source, destination) + + solve_hanoi(n, source, auxiliary, destination) + return moves + + +if __name__ == "__main__": + try: + n_disks = int(input("Enter the number of disks for the Tower of Hanoi: ").strip()) + if n_disks < 0: + print("Please enter a non-negative number of disks.") + else: + all_moves = tower_of_hanoi(n_disks) + print(f"\nTotal moves required: {len(all_moves)}") + print("Sequence of Moves (Source -> Destination):") + for move in all_moves: + print(f"Move disk from {move[0]} to {move[1]}") + except ValueError: + print("Invalid input. Please enter an integer.") From 67c2a36201a5b041ccdc408184388cc02aab6699 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 19 Oct 2025 14:56:54 +0000 Subject: [PATCH 2/6] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- divide_and_conquer/tower_of_hanoi.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/divide_and_conquer/tower_of_hanoi.py b/divide_and_conquer/tower_of_hanoi.py index ee3eff5f7ae0..14ff8792346d 100644 --- a/divide_and_conquer/tower_of_hanoi.py +++ b/divide_and_conquer/tower_of_hanoi.py @@ -1,5 +1,5 @@ """ -Towers of Hanoi is a mathematical puzzle that is solved using a recursive +Towers of Hanoi is a mathematical puzzle that is solved using a recursive divide-and-conquer strategy. It moves a stack of disks from a source pole to a destination pole, @@ -14,7 +14,9 @@ """ -def tower_of_hanoi(n: int, source: str = "A", auxiliary: str = "B", destination: str = "C") -> list[tuple[str, str]]: +def tower_of_hanoi( + n: int, source: str = "A", auxiliary: str = "B", destination: str = "C" +) -> list[tuple[str, str]]: """ Pure python implementation of the Towers of Hanoi puzzle (recursive version), returning the sequence of moves required to solve the puzzle. @@ -53,7 +55,9 @@ def solve_hanoi(n: int, source: str, auxiliary: str, destination: str): if __name__ == "__main__": try: - n_disks = int(input("Enter the number of disks for the Tower of Hanoi: ").strip()) + n_disks = int( + input("Enter the number of disks for the Tower of Hanoi: ").strip() + ) if n_disks < 0: print("Please enter a non-negative number of disks.") else: From 6caae52734e465f8ce45b61b168f8ab25efe218d Mon Sep 17 00:00:00 2001 From: Gourav Saha Date: Tue, 21 Oct 2025 13:37:38 +0530 Subject: [PATCH 3/6] Fix formatting of error message for invalid input From 978317c1df492659c472a36885e1f7203b829001 Mon Sep 17 00:00:00 2001 From: Gourav Saha Date: Tue, 21 Oct 2025 13:42:13 +0530 Subject: [PATCH 4/6] Refactor tower_of_hanoi function parameters --- divide_and_conquer/tower_of_hanoi.py | 41 ++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/divide_and_conquer/tower_of_hanoi.py b/divide_and_conquer/tower_of_hanoi.py index 14ff8792346d..37d918932e01 100644 --- a/divide_and_conquer/tower_of_hanoi.py +++ b/divide_and_conquer/tower_of_hanoi.py @@ -15,7 +15,7 @@ def tower_of_hanoi( - n: int, source: str = "A", auxiliary: str = "B", destination: str = "C" + num_disks: int, source: str = "A", auxiliary: str = "B", destination: str = "C" ) -> list[tuple[str, str]]: """ Pure python implementation of the Towers of Hanoi puzzle (recursive version), @@ -32,14 +32,29 @@ def tower_of_hanoi( """ moves = [] - def solve_hanoi(n: int, source: str, auxiliary: str, destination: str): - """Recursive helper function to generate the moves.""" - if n == 0: + def solve_hanoi( + num_disks: int, source: str, auxiliary: str, destination: str + ) -> None: + """ + Recursive helper function to generate the moves and append them to the 'moves' list. + + >>> moves_test = [] + >>> def solve_hanoi_test(num_disks, source, auxiliary, destination): + ... if num_disks == 0: + ... return + ... solve_hanoi_test(num_disks - 1, source, destination, auxiliary) + ... moves_test.append((source, destination)) + ... solve_hanoi_test(num_disks - 1, auxiliary, source, destination) + >>> solve_hanoi_test(2, "S", "A", "D") + >>> moves_test + [('S', 'A'), ('S', 'D'), ('A', 'D')] + """ + if num_disks == 0: return # 1. Move n-1 disks from Source to Auxiliary, using Destination as auxiliary. # This is the "Divide" step. - solve_hanoi(n - 1, source, destination, auxiliary) + solve_hanoi(num_disks - 1, source, destination, auxiliary) # 2. Move the largest disk (n) from Source to Destination. # This is the "Conquer" step (base step of the recursion). @@ -47,21 +62,23 @@ def solve_hanoi(n: int, source: str, auxiliary: str, destination: str): # 3. Move n-1 disks from Auxiliary to Destination, using Source as auxiliary. # This is the "Combine" step. - solve_hanoi(n - 1, auxiliary, source, destination) + solve_hanoi(num_disks - 1, auxiliary, source, destination) - solve_hanoi(n, source, auxiliary, destination) + solve_hanoi(num_disks, source, auxiliary, destination) return moves if __name__ == "__main__": try: - n_disks = int( - input("Enter the number of disks for the Tower of Hanoi: ").strip() - ) - if n_disks < 0: + n_disks_input = input( + "Enter the number of disks for the Tower of Hanoi: " + ).strip() + num_disks = int(n_disks_input) + + if num_disks < 0: print("Please enter a non-negative number of disks.") else: - all_moves = tower_of_hanoi(n_disks) + all_moves = tower_of_hanoi(num_disks) print(f"\nTotal moves required: {len(all_moves)}") print("Sequence of Moves (Source -> Destination):") for move in all_moves: From 154785b87f53240a7bba04d74139cb1846ea7a77 Mon Sep 17 00:00:00 2001 From: Gourav Saha Date: Tue, 21 Oct 2025 13:49:19 +0530 Subject: [PATCH 5/6] Refactor doctest output line in tower_of_hanoi.py (E501 fixed) Shortened a long line in the doctest output for clarity. --- divide_and_conquer/tower_of_hanoi.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/divide_and_conquer/tower_of_hanoi.py b/divide_and_conquer/tower_of_hanoi.py index 37d918932e01..f2ca09cd753f 100644 --- a/divide_and_conquer/tower_of_hanoi.py +++ b/divide_and_conquer/tower_of_hanoi.py @@ -46,7 +46,7 @@ def solve_hanoi( ... moves_test.append((source, destination)) ... solve_hanoi_test(num_disks - 1, auxiliary, source, destination) >>> solve_hanoi_test(2, "S", "A", "D") - >>> moves_test + >>> moves_test # This line was previously too long due to the doctest content. [('S', 'A'), ('S', 'D'), ('A', 'D')] """ if num_disks == 0: From 8079cc2976bd36b77526209ee834be5ebb4c0edc Mon Sep 17 00:00:00 2001 From: Gourav Saha Date: Tue, 21 Oct 2025 14:06:20 +0530 Subject: [PATCH 6/6] Refactor doctest output and error handling Fix line length issue in doctest output and ensure consistent error message formatting. --- divide_and_conquer/tower_of_hanoi.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/divide_and_conquer/tower_of_hanoi.py b/divide_and_conquer/tower_of_hanoi.py index f2ca09cd753f..37d918932e01 100644 --- a/divide_and_conquer/tower_of_hanoi.py +++ b/divide_and_conquer/tower_of_hanoi.py @@ -46,7 +46,7 @@ def solve_hanoi( ... moves_test.append((source, destination)) ... solve_hanoi_test(num_disks - 1, auxiliary, source, destination) >>> solve_hanoi_test(2, "S", "A", "D") - >>> moves_test # This line was previously too long due to the doctest content. + >>> moves_test [('S', 'A'), ('S', 'D'), ('A', 'D')] """ if num_disks == 0: