From 1c28ce3bb1c2d5490c54e6be2947874d6ec1a81f Mon Sep 17 00:00:00 2001 From: Aqib Javid Bhat Date: Wed, 25 Oct 2023 07:56:03 +0530 Subject: [PATCH 1/5] Add Josephus Problem --- maths/josephus_problem.py | 64 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 maths/josephus_problem.py diff --git a/maths/josephus_problem.py b/maths/josephus_problem.py new file mode 100644 index 000000000000..9fdacfea00e6 --- /dev/null +++ b/maths/josephus_problem.py @@ -0,0 +1,64 @@ +""" +The Josephus problem is a famous theoretical problem related to a certain +counting-out game. This module provides functions to solve the Josephus problem +for n people and a step size of k. + +The Josephus problem is defined as follows: +- n people are standing in a circle. +- Starting with a specified person, you count around the circle, + skipping a fixed number of people (k). +- The person at which you stop counting is eliminated from the circle. +- The counting continues until only one person remains. + +For more information about the Josephus problem, refer to: +https://en.wikipedia.org/wiki/Josephus_problem +""" + + +def josephus(n: int, k: int) -> int: + """ + Solve the Josephus problem for n people and a step size of k. + + Args: + n (int): Number of people. + k (int): Step size for elimination. + + Returns: + int: The position of the last person remaining. + + Examples: + >>> josephus(7, 3) + 3 + >>> josephus(10, 2) + 4 + """ + if n == 1: + return 0 + + return (josephus(n - 1, k) + k) % n + + +def find_winner(n: int, k: int) -> int: + """ + Find the winner of the Josephus problem for n people and a step size of k. + + Args: + n (int): Number of people. + k (int): Step size for elimination. + + Returns: + int: The position of the last person remaining (1-based index). + + Examples: + >>> find_winner(7, 3) + 4 + >>> find_winner(10, 2) + 5 + """ + return josephus(n, k) + 1 + + +if __name__ == "__main__": + import doctest + + doctest.testmod() From f0d09207bfea9fb7095a37fdc5325031cef1d283 Mon Sep 17 00:00:00 2001 From: Aqib Javid Bhat Date: Wed, 25 Oct 2023 19:11:27 +0530 Subject: [PATCH 2/5] Add iterative implementation of Josephus Problem --- maths/josephus_problem.py | 39 +++++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/maths/josephus_problem.py b/maths/josephus_problem.py index 9fdacfea00e6..2a0863b74121 100644 --- a/maths/josephus_problem.py +++ b/maths/josephus_problem.py @@ -15,9 +15,9 @@ """ -def josephus(n: int, k: int) -> int: +def josephus_recursive(n: int, k: int) -> int: """ - Solve the Josephus problem for n people and a step size of k. + Solve the Josephus problem for n people and a step size of k recursively. Args: n (int): Number of people. @@ -27,15 +27,15 @@ def josephus(n: int, k: int) -> int: int: The position of the last person remaining. Examples: - >>> josephus(7, 3) + >>> josephus_recursive(7, 3) 3 - >>> josephus(10, 2) + >>> josephus_recursive(10, 2) 4 """ if n == 1: return 0 - return (josephus(n - 1, k) + k) % n + return (josephus_recursive(n - 1, k) + k) % n def find_winner(n: int, k: int) -> int: @@ -55,7 +55,34 @@ def find_winner(n: int, k: int) -> int: >>> find_winner(10, 2) 5 """ - return josephus(n, k) + 1 + return josephus_recursive(n, k) + 1 + + +def josephus_iterative(n: int, k: int) -> int: + """ + Solve the Josephus problem for n people and a step size of k iteratively. + + Args: + n (int): The number of people in the circle. + k (int): The number of steps to take before eliminating someone. + + Returns: + int: The position of the last person standing. + + Examples: + >>> josephus_iterative(5, 2) + 3 + >>> josephus_iterative(7, 3) + 4 + """ + circle = list(range(1, n + 1)) + current = 0 + + while len(circle) > 1: + current = (current + k - 1) % len(circle) + circle.pop(current) + + return circle[0] if __name__ == "__main__": From da302ee039af8f6d16b9547654facecb71e5145a Mon Sep 17 00:00:00 2001 From: Aqib Javid Bhat Date: Wed, 25 Oct 2023 19:22:36 +0530 Subject: [PATCH 3/5] Add descriptive variable names --- maths/josephus_problem.py | 40 +++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/maths/josephus_problem.py b/maths/josephus_problem.py index 2a0863b74121..af826b2673b1 100644 --- a/maths/josephus_problem.py +++ b/maths/josephus_problem.py @@ -1,12 +1,12 @@ """ The Josephus problem is a famous theoretical problem related to a certain counting-out game. This module provides functions to solve the Josephus problem -for n people and a step size of k. +for num_people and a step_size. The Josephus problem is defined as follows: -- n people are standing in a circle. +- num_people are standing in a circle. - Starting with a specified person, you count around the circle, - skipping a fixed number of people (k). + skipping a fixed number of people (step_size). - The person at which you stop counting is eliminated from the circle. - The counting continues until only one person remains. @@ -15,13 +15,13 @@ """ -def josephus_recursive(n: int, k: int) -> int: +def josephus_recursive(num_people: int, step_size: int) -> int: """ - Solve the Josephus problem for n people and a step size of k recursively. + Solve the Josephus problem for num_people and a step_size recursively. Args: - n (int): Number of people. - k (int): Step size for elimination. + num_people (int): Number of people. + step_size (int): Step size for elimination. Returns: int: The position of the last person remaining. @@ -32,19 +32,19 @@ def josephus_recursive(n: int, k: int) -> int: >>> josephus_recursive(10, 2) 4 """ - if n == 1: + if num_people == 1: return 0 - return (josephus_recursive(n - 1, k) + k) % n + return (josephus_recursive(num_people - 1, step_size) + step_size) % num_people -def find_winner(n: int, k: int) -> int: +def find_winner(num_people: int, step_size: int) -> int: """ - Find the winner of the Josephus problem for n people and a step size of k. + Find the winner of the Josephus problem for num_people and a step_size. Args: - n (int): Number of people. - k (int): Step size for elimination. + num_people (int): Number of people. + step_size (int): Step size for elimination. Returns: int: The position of the last person remaining (1-based index). @@ -55,16 +55,16 @@ def find_winner(n: int, k: int) -> int: >>> find_winner(10, 2) 5 """ - return josephus_recursive(n, k) + 1 + return josephus_recursive(num_people, step_size) + 1 -def josephus_iterative(n: int, k: int) -> int: +def josephus_iterative(num_people: int, step_size: int) -> int: """ - Solve the Josephus problem for n people and a step size of k iteratively. + Solve the Josephus problem for num_people and a step_size iteratively. Args: - n (int): The number of people in the circle. - k (int): The number of steps to take before eliminating someone. + num_people (int): The number of people in the circle. + step_size (int): The number of steps to take before eliminating someone. Returns: int: The position of the last person standing. @@ -75,11 +75,11 @@ def josephus_iterative(n: int, k: int) -> int: >>> josephus_iterative(7, 3) 4 """ - circle = list(range(1, n + 1)) + circle = list(range(1, num_people + 1)) current = 0 while len(circle) > 1: - current = (current + k - 1) % len(circle) + current = (current + step_size - 1) % len(circle) circle.pop(current) return circle[0] From b50614acddae141a9342707e0738c7e92a0cfef6 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Sun, 29 Oct 2023 13:42:04 +0100 Subject: [PATCH 4/5] Update maths/josephus_problem.py --- maths/josephus_problem.py | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/maths/josephus_problem.py b/maths/josephus_problem.py index af826b2673b1..38c0cd1f9b94 100644 --- a/maths/josephus_problem.py +++ b/maths/josephus_problem.py @@ -20,17 +20,31 @@ def josephus_recursive(num_people: int, step_size: int) -> int: Solve the Josephus problem for num_people and a step_size recursively. Args: - num_people (int): Number of people. - step_size (int): Step size for elimination. + num_people: Number of people. + step_size: Step size for elimination. Returns: - int: The position of the last person remaining. + The position of the last person remaining. Examples: - >>> josephus_recursive(7, 3) - 3 - >>> josephus_recursive(10, 2) - 4 + >>> josephus_recursive(7, 3) + 3 + >>> josephus_recursive(10, 2) + 4 + >>> josephus_recursive(0, 2) + ??? + >>> josephus_recursive(1.9, 2) + ??? + >>> josephus_recursive(-2, 2) + ??? + >>> josephus_recursive(7, 0) + ??? + >>> josephus_recursive(7, -2) + ??? + >>> josephus_recursive(1_000, 0.01) + ??? + >>> josephus_recursive("cat", "dog") + ??? """ if num_people == 1: return 0 From 7a42a2418dd8feb1898ce03100439ca0d2f37a50 Mon Sep 17 00:00:00 2001 From: Aqib Javid Bhat Date: Sun, 29 Oct 2023 19:37:41 +0530 Subject: [PATCH 5/5] Update josephus_problem.py --- maths/josephus_problem.py | 65 +++++++++++++++++++++++++++------------ 1 file changed, 45 insertions(+), 20 deletions(-) diff --git a/maths/josephus_problem.py b/maths/josephus_problem.py index 38c0cd1f9b94..271292ba1d9f 100644 --- a/maths/josephus_problem.py +++ b/maths/josephus_problem.py @@ -20,32 +20,57 @@ def josephus_recursive(num_people: int, step_size: int) -> int: Solve the Josephus problem for num_people and a step_size recursively. Args: - num_people: Number of people. - step_size: Step size for elimination. + num_people: A positive integer representing the number of people. + step_size: A positive integer representing the step size for elimination. Returns: The position of the last person remaining. + Raises: + ValueError: If num_people or step_size is not a positive integer. + Examples: - >>> josephus_recursive(7, 3) - 3 - >>> josephus_recursive(10, 2) - 4 - >>> josephus_recursive(0, 2) - ??? - >>> josephus_recursive(1.9, 2) - ??? - >>> josephus_recursive(-2, 2) - ??? - >>> josephus_recursive(7, 0) - ??? - >>> josephus_recursive(7, -2) - ??? - >>> josephus_recursive(1_000, 0.01) - ??? - >>> josephus_recursive("cat", "dog") - ??? + >>> josephus_recursive(7, 3) + 3 + >>> josephus_recursive(10, 2) + 4 + >>> josephus_recursive(0, 2) + Traceback (most recent call last): + ... + ValueError: num_people or step_size is not a positive integer. + >>> josephus_recursive(1.9, 2) + Traceback (most recent call last): + ... + ValueError: num_people or step_size is not a positive integer. + >>> josephus_recursive(-2, 2) + Traceback (most recent call last): + ... + ValueError: num_people or step_size is not a positive integer. + >>> josephus_recursive(7, 0) + Traceback (most recent call last): + ... + ValueError: num_people or step_size is not a positive integer. + >>> josephus_recursive(7, -2) + Traceback (most recent call last): + ... + ValueError: num_people or step_size is not a positive integer. + >>> josephus_recursive(1_000, 0.01) + Traceback (most recent call last): + ... + ValueError: num_people or step_size is not a positive integer. + >>> josephus_recursive("cat", "dog") + Traceback (most recent call last): + ... + ValueError: num_people or step_size is not a positive integer. """ + if ( + not isinstance(num_people, int) + or not isinstance(step_size, int) + or num_people <= 0 + or step_size <= 0 + ): + raise ValueError("num_people or step_size is not a positive integer.") + if num_people == 1: return 0