Program to find winner of a rower breaking game in Python

Suppose we have an array of tower heights. There are n different towers with different heights. Amal and Bimal are playing a tower breaking game with specific rules.

Game Rules

  • Amal always plays first

  • During each move, the current player selects a tower of height X and breaks it down into Y different towers of height Z each, where Y*Z = X and both X and Y > 1

  • The player who cannot make a move loses the game

Algorithm Approach

This is a classic game theory problem that can be solved using the Sprague-Grundy theorem. We need to calculate the Grundy number for each tower height and then XOR all values to determine the winner.

Example

If the input is height = [3,1,2], the output will be "Bimal". Here's why ?

  • Initial heights: {3, 1, 2}
  • Amal breaks tower of height 2 into two towers of height 1: {3, 1, 1, 1}
  • Bimal breaks tower of height 3 into three towers of height 1: {1, 1, 1, 1, 1, 1}
  • Amal has no valid moves (height 1 cannot be broken), so Bimal wins

Implementation

The solution uses dynamic programming to precompute Grundy numbers for all possible tower heights ?

def util(limit=1005):
    result = [0] * limit
    
    for i in range(2, limit):
        s = set()
        for j in range(1, int(i**0.5) + 1):
            d, r = divmod(i, j)
            
            if r == 0:
                if j & 1:  # j is odd
                    s.add(result[d])
                if d & 1:  # d is odd
                    s.add(result[j])
        
        j = 0
        while j in s: 
            j += 1
        result[i] = j
    
    return result

g = util()

def solve(height):
    r = 0
    for i in height:
        r ^= g[i]
    
    if r:
        return "Amal"
    else:
        return "Bimal"

# Test the function
height = [3, 1, 2]
print(solve(height))
Bimal

How It Works

The algorithm works as follows ?

  • Grundy Number Calculation: For each height i, we find all possible ways to break it and compute the minimum excludant (mex) of the resulting Grundy numbers

  • Valid Moves: A tower of height X can be broken into Y towers of height Z where Y*Z = X, Y > 1, and Z > 0

  • Game Theory: The XOR of all Grundy numbers determines the winner. If the result is non-zero, the first player (Amal) wins; otherwise, the second player (Bimal) wins

Testing with Different Inputs

# Test with different tower configurations
test_cases = [
    [3, 1, 2],
    [4, 6, 8],
    [2, 2, 2],
    [5, 7, 11]
]

for heights in test_cases:
    winner = solve(heights)
    print(f"Heights: {heights} ? Winner: {winner}")
Heights: [3, 1, 2] ? Winner: Bimal
Heights: [4, 6, 8] ? Winner: Amal
Heights: [2, 2, 2] ? Winner: Bimal
Heights: [5, 7, 11] ? Winner: Bimal

Conclusion

This tower breaking game is solved using the Sprague-Grundy theorem by calculating Grundy numbers for each tower height and XORing them together. If the final XOR result is non-zero, Amal (first player) wins; otherwise, Bimal wins.

Updated on: 2026-03-26T18:15:52+05:30

461 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements