Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Program to find out if we win in a game in Python
Suppose we are playing a two-player game where there are n number of marbles and in each round, a player has to take a positive square number of marbles. If a player can't take that square number of marbles, he/she loses. So, given a number n, we have to find out if we can win the game or not. We always make the first turn and select an optimal number of marbles.
So, if the input is like 14, then the output will be True. Because at the first turn, we take 9 marbles. That leaves 5 marbles from which the other player can take a maximum of 4 marbles leaving 1 marble behind. So, in the next turn, we take the last marble leaving 0 marbles behind the opponent can't make a move. Thus, we win.
Algorithm
To solve this, we will follow these steps ?
- if n <= 0, then
- return False
- ans := False
- for i in range integer part of (square root of (n)) to -1, decrease by 1, do
- if i * i > n, then
- come out from the loop
- ans := ans OR (not solve(n - i * i))
- if ans is True, then
- return ans
- if i * i > n, then
- return ans
Example
Let us see the following implementation to get better understanding ?
from math import sqrt
def solve(n):
if n <= 0:
return False
ans = False
for i in range(int(sqrt(n)), 0, -1):
if i * i > n:
break
ans = ans | (not solve(n - i * i))
if ans:
return ans
return ans
print(solve(14))
True
How It Works
The solution uses recursion to check if a winning move exists. For each possible square number of marbles we can take, we check if the opponent would lose in the resulting game state. If any move leads to the opponent losing, we can win.
Optimized Solution with Memoization
Since the recursive solution recalculates the same states multiple times, we can optimize it using memoization ?
from math import sqrt
def solve_optimized(n, memo={}):
if n in memo:
return memo[n]
if n <= 0:
memo[n] = False
return False
for i in range(1, int(sqrt(n)) + 1):
if i * i <= n and not solve_optimized(n - i * i, memo):
memo[n] = True
return True
memo[n] = False
return False
# Test with multiple values
test_values = [1, 4, 7, 14, 16]
for val in test_values:
result = solve_optimized(val)
print(f"solve({val}) = {result}")
solve(1) = True solve(4) = True solve(7) = False solve(14) = True solve(16) = True
Key Points
- The game follows optimal play - both players make the best possible moves
- A position is winning if there exists at least one move that puts the opponent in a losing position
- A position is losing if all possible moves put the opponent in a winning position
- Memoization significantly improves performance for larger inputs
Conclusion
This marble game problem demonstrates game theory concepts using recursive thinking. The key insight is that we win if we can make a move that forces our opponent into a losing position.
