**Prerequisites: **

Sprague Gruncy theorem

Grundy Numbers

Nim is a famous game in which two players take turns removing items from distinct piles. During each turn, a player must remove one or more items from a single, non-empty pile. The winner of the game is whichever player removes the last item from the last non-empty pile.

Now, For each non-empty pile, either player can remove zero items from that pile and have it count as their move; however, this move can only be performed once per pile by either player.

Given the number of items in each pile, determine who will win the game; Player 1 or player 2. If player 1 starts the game and both plays optimally.

Examples:

Input : 3 [18, 47, 34] Output : Player 2 wins G = g(18)^g(47)^g(34) = (17)^(48)^(33) = 0 Grundy number(G), for this game is zero. Player 2 wins. Input : 3 [32, 49, 58] Output : Player 1 wins G = g(31)^g(50)^g(57) = (17)^(48)^(33) = 20 Grundy number(G), for this game is non-zero. Player 1 wins.

**Approach:**

Grundy number for each pile is calculated based on the number of stones.To compensate the zero move we will have to modify grundy values we used in standard nim game.

If pile size is odd; grundy number is size+1 and

if pile size is even; grundy number is size-1.

We XOR all the grundy number values to check if final Grundy number(G) of game is non zero or not to decide who is winner of game.

**Explanation:**

Grundy number of a state is the **smallest positive integer that cannot be reached in one valid move**.

So, we need to calculate **mex value** for each n, bottom up wise so that we can induce the grundy number for each n. where n is the pile size.

**Winning state**: A tuple of values from where the current player will win the game no matter what opponent does. (If G!=0)

**Losing state**: A tuple of values from where the current player will lose the game no matter what opponent does. (If G=0)

For a given pile size n, we have two states: (1) n with no zero moves available, grundy number will same as standard nim game. (2) n with zero moves available, we can reach above state and other states with zero moves remaining. For, n = 0, g(0) = 0, empty pile For, n = 1, we can reach two states: (1) n = 0 (zero move not used) (2) n = 1 (zero move used) Therefore, g(1) = mex{0, 1} which implies that g(1)=2. For, n = 2, we can reach : (1) n = 0 (zero move not used) state because this is a valid move. (2) n = 1 (zero move not used) is a valid move, whose grundy nuber is 2. Therefore, g(2) = mex{0,2} which implies that g(2)=1. note that n=1 (zero move used) is not a valid move.If we try to build a solution bottom-up like this, it turns out that if n is even, the grundy number is n - 1 and when it is odd, the grundy is n + 1.

Below is the implementation of above approach:

## C++

`// CPP program for the variation ` `// in nim game ` `#include <bits/stdc++.h> ` `using` `namespace` `std; ` ` ` `// Function to return final ` `// grundy Number(G) of game ` `int` `solve(` `int` `p[], ` `int` `n) ` `{ ` ` ` `int` `G = 0; ` ` ` `for` `(` `int` `i = 0; i < n; i++) { ` ` ` ` ` `// if pile size is odd ` ` ` `if` `(p[i] & 1) ` ` ` ` ` `// We XOR pile size+1 ` ` ` `G ^= (p[i] + 1); ` ` ` ` ` `else` `// if pile size is even ` ` ` ` ` `// We XOR pile size-1 ` ` ` `G ^= (p[i] - 1); ` ` ` `} ` ` ` `return` `G; ` `} ` ` ` `// driver program ` `int` `main() ` `{ ` ` ` `// Game with 3 piles ` ` ` `int` `n = 3; ` ` ` ` ` `// pile with different sizes ` ` ` `int` `p[3] = { 32, 49, 58 }; ` ` ` ` ` `// Function to return result of game ` ` ` `int` `res = solve(p, n); ` ` ` ` ` `if` `(res == 0) ` `// if G is zero ` ` ` `cout << ` `"Player 2 wins"` `; ` ` ` `else` `// if G is non zero ` ` ` `cout << ` `"Player 1 wins"` `; ` ` ` ` ` `return` `0; ` `} ` |

*chevron_right*

*filter_none*

## Java

`// Java program for the variation ` `// in nim game ` `class` `GFG { ` ` ` ` ` `// Function to return final ` ` ` `// grundy Number(G) of game ` ` ` `static` `int` `solve(` `int` `p[], ` `int` `n) ` ` ` `{ ` ` ` ` ` `int` `G = ` `0` `; ` ` ` `for` `(` `int` `i = ` `0` `; i < n; i++) { ` ` ` ` ` `// if pile size is odd ` ` ` `if` `(p[i]%` `2` `!=` `0` `) ` ` ` ` ` `// We XOR pile size+1 ` ` ` `G ^= (p[i] + ` `1` `); ` ` ` ` ` `else` `// if pile size is even ` ` ` ` ` `// We XOR pile size-1 ` ` ` `G ^= (p[i] - ` `1` `); ` ` ` `} ` ` ` ` ` `return` `G; ` ` ` `} ` ` ` ` ` `//Driver code ` ` ` `public` `static` `void` `main (String[] args) ` ` ` `{ ` ` ` ` ` `// Game with 3 piles ` ` ` `int` `n = ` `3` `; ` ` ` ` ` `// pile with different sizes ` ` ` `int` `p[] = { ` `32` `, ` `49` `, ` `58` `}; ` ` ` ` ` `// Function to return result of game ` ` ` `int` `res = solve(p, n); ` ` ` ` ` `if` `(res == ` `0` `) ` `// if G is zero ` ` ` `System.out.print(` `"Player 2 wins"` `); ` ` ` `else` `// if G is non zero ` ` ` `System.out.print(` `"Player 1 wins"` `); ` ` ` `} ` `} ` ` ` `// This code is contributed by Anant Agarwal. ` |

*chevron_right*

*filter_none*

## Python3

`# Python3 program for the ` `# variation in nim game ` ` ` `# Function to return final ` `# grundy Number(G) of game ` `def` `solve(p, n): ` ` ` `G ` `=` `0` ` ` `for` `i ` `in` `range` `(n): ` ` ` ` ` `# if pile size is odd ` ` ` `if` `(p[i] ` `%` `2` `!` `=` `0` `): ` ` ` ` ` `# We XOR pile size+1 ` ` ` `G ^` `=` `(p[i] ` `+` `1` `) ` ` ` ` ` `# if pile size is even ` ` ` `else` `: ` ` ` ` ` `# We XOR pile size-1 ` ` ` `G ^` `=` `(p[i] ` `-` `1` `) ` ` ` ` ` `return` `G ` ` ` `# Driver code ` ` ` `# Game with 3 piles ` `n ` `=` `3` ` ` `# pile with different sizes ` `p ` `=` `[` `32` `, ` `49` `, ` `58` `] ` ` ` `# Function to return result of game ` `res ` `=` `solve(p, n) ` ` ` `if` `(res ` `=` `=` `0` `): ` `# if G is zero ` ` ` `print` `(` `"Player 2 wins"` `) ` ` ` `else` `: ` `# if G is non zero ` ` ` `print` `(` `"Player 1 wins"` `) ` ` ` `# This code is contributed by Anant Agarwal. ` |

*chevron_right*

*filter_none*

## C#

`// C# program for the variation ` `// in nim game ` `using` `System; ` `class` `GFG { ` ` ` ` ` `// Function to return final ` ` ` `// grundy Number(G) of game ` ` ` `static` `int` `solve(` `int` `[] p, ` `int` `n) ` ` ` `{ ` ` ` ` ` `int` `G = 0; ` ` ` `for` `(` `int` `i = 0; i < n; i++) { ` ` ` ` ` `// if pile size is odd ` ` ` `if` `(p[i] % 2 != 0) ` ` ` ` ` `// We XOR pile size+1 ` ` ` `G ^= (p[i] + 1); ` ` ` ` ` `else` `// if pile size is even ` ` ` ` ` `// We XOR pile size-1 ` ` ` `G ^= (p[i] - 1); ` ` ` `} ` ` ` ` ` `return` `G; ` ` ` `} ` ` ` ` ` `// Driver code ` ` ` `public` `static` `void` `Main() ` ` ` `{ ` ` ` ` ` `// Game with 3 piles ` ` ` `int` `n = 3; ` ` ` ` ` `// pile with different sizes ` ` ` `int` `[] p = { 32, 49, 58 }; ` ` ` ` ` `// Function to return result of game ` ` ` `int` `res = solve(p, n); ` ` ` ` ` `if` `(res == 0) ` `// if G is zero ` ` ` `Console.WriteLine(` `"Player 2 wins"` `); ` ` ` ` ` `else` `// if G is non zero ` ` ` `Console.WriteLine(` `"Player 1 wins"` `); ` ` ` `} ` `} ` ` ` `// This code is contributed by vt_m. ` |

*chevron_right*

*filter_none*

## PHP

`<?php ` `// php program for the variation ` `// in nim game ` ` ` `// Function to return final ` `// grundy Number(G) of game ` `function` `solve(` `$p` `,` `$n` `) ` `{ ` ` ` `$G` `= 0; ` ` ` `for` `(` `$i` `= 0; ` `$i` `< ` `$n` `; ` `$i` `++) ` ` ` `{ ` ` ` ` ` `// if pile size is odd ` ` ` `if` `(` `$p` `[` `$i` `] & 1) ` ` ` ` ` `// We XOR pile size+1 ` ` ` `$G` `^= (` `$p` `[` `$i` `] + 1); ` ` ` ` ` `else` `// if pile size is even ` ` ` ` ` `// We XOR pile size-1 ` ` ` `$G` `^= (` `$p` `[` `$i` `] - 1); ` ` ` `} ` ` ` `return` `$G` `; ` `} ` ` ` ` ` `// Driver Code ` ` ` `// Game with 3 piles ` ` ` `$n` `= 3; ` ` ` ` ` `// pile with different sizes ` ` ` `$p` `= ` `array` `( 32, 49, 58 ); ` ` ` ` ` `// Function to return result of game ` ` ` `$res` `= solve(` `$p` `, ` `$n` `); ` ` ` ` ` `if` `(` `$res` `== 0) ` `// if G is zero ` ` ` `echo` `"Player 2 wins"` `; ` ` ` `else` `// if G is non zero ` ` ` `echo` `"Player 1 wins"` `; ` ` ` `// This code is contributed by mits ` `?> ` |

*chevron_right*

*filter_none*

**Output:**

Player 1 wins

**Time Complexity:** O(n)

## Recommended Posts:

- Game Theory (Normal-form game) | Set 3 (Game with Mixed Strategy)
- Game Theory (Normal-form Game) | Set 7 (Graphical Method [M X 2] Game)
- Game Theory (Normal-form Game) | Set 6 (Graphical Method [2 X N] Game)
- Game Theory (Normal-form Game) | Set 5 (Dominance Property-Mixed Strategy)
- Game Theory (Normal-form Game) | Set 4 (Dominance Property-Pure Strategy)
- Game Theory (Normal - form game) | Set 1 (Introduction)
- Combinatorial Game Theory | Set 2 (Game of Nim)
- Implementation of Tic-Tac-Toe game
- A modified game of Nim
- Design Snake Game
- Find the winner of the Game
- Optimal Strategy for a Game | Set 3
- Check if the game is valid or not
- Find the winner in nim-game
- Optimal Strategy for a Game | DP-31
- Game of N stones where each player can remove 1, 3 or 4
- Game of replacing array elements
- Find the player who will win the Coin game
- Optimal strategy for a Game with modifications
- Number guessing game in Python