Combinatorial Game Theory | Set 2 (Game of Nim)
Last Updated :
23 Sep, 2022
We strongly recommend to refer below article as a prerequisite of this. Combinatorial Game Theory | Set 1 (Introduction) In this post, Game of Nim is discussed. The Game of Nim is described by the following rules- “ Given a number of piles in which each pile contains some numbers of stones/coins. In each turn, a player can choose only one pile and remove any number of stones (at least one) from that pile. The player who cannot move is considered to lose the game (i.e., one who take the last stone is the winner). ” For example, consider that there are two players- A and B, and initially there are three piles of coins initially having 3, 4, 5 coins in each of them as shown below. We assume that first move is made by A. See the below figure for clear understanding of the whole game play.
A Won the match (Note: A made the first move) So was A having a strong expertise in this game ? or he/she was having some edge over B by starting first ? Let us now play again, with the same configuration of the piles as above but this time B starting first instead of A.
B Won the match (Note: B made the first move) By the above figure, it must be clear that the game depends on one important factor – Who starts the game first ? So does the player who starts first will win everytime ? Let us again play the game, starting from A , and this time with a different initial configuration of piles. The piles have 1, 4, 5 coins initially. Will A win again as he has started first ? Let us see.
A made the first move, but lost the Game. So, the result is clear. A has lost. But how? We know that this game depends heavily on which player starts first. Thus, there must be another factor which dominates the result of this simple-yet-interesting game. That factor is the initial configuration of the heaps/piles. This time the initial configuration was different from the previous one. So, we can conclude that this game depends on two factors-
- The player who starts first.
- The initial configuration of the piles/heaps.
In fact, we can predict the winner of the game before even playing the game ! Nim-Sum : The cumulative XOR value of the number of coins/stones in each piles/heaps at any point of the game is called Nim-Sum at that point. “If both A and B play optimally (i.e- they don’t make any mistakes), then the player starting first is guaranteed to win if the Nim-Sum at the beginning of the game is non-zero. Otherwise, if the Nim-Sum evaluates to zero, then player A will lose definitely." For the proof of the above theorem, see- https://en.wikipedia.org/wiki/Nim#Proof_of_the_winning_formula
Optimal Strategy :
- If the XOR sum of 'n' numbers is already zero then there is no possibility to make the XOR sum zero by single reduction of a number.
- If the XOR sum of 'n' numbers is non-zero then there is at least a single approach by which if you reduce a number, the XOR sum is zero.
Initially two cases could exist. Case 1: Initial Nim Sum is zero As we know, in this case if played optimally B wins, which means B would always prefer to have Nim sum of zero for A's turn. So, as the Nim Sum is initially zero, whatever number of items A removes the new Nim Sum would be non-zero (as mentioned above). Also, as B would prefer Nim sum of zero for A's turn, he would then play a move so as to make the Nim Sum zero again (which is always possible, as mentioned above). The game will run as long as there are items in any of the piles and in each of their respective turns A would make Nim sum non-zero and B would make it zero again and eventually there will be no elements left and B being the one to pick the last wins the game. It is evident by above explanation that the optimal strategy for each player is to make the Nim Sum for his opponent zero in each of their turn, which will not be possible if it's already zero. Case 2: Initial Nim Sum is non-zero Now going by the optimal approach A would make the Nim Sum to be zero now (which is possible as the initial Nim sum is non-zero, as mentioned above). Now, in B's turn as the nim sum is already zero whatever number B picks, the nim sum would be non-zero and A can pick a number to make the nim sum zero again. This will go as long as there are items available in any pile. And A will be the one to pick the last item. So, as discussed in the above cases, it should be obvious now that Optimal strategy for any player is to make the nim sum zero if it's non-zero and if it is already zero then whatever moves the player makes now, it can be countered.
Let us apply the above theorem in the games played above. In the first game A started first and the Nim-Sum at the beginning of the game was, 3 XOR 4 XOR 5 = 2, which is a non-zero value, and hence A won. Whereas in the second game-play, when the initial configuration of the piles were 1, 4, and 5 and A started first, then A was destined to lose as the Nim-Sum at the beginning of the game was 1 XOR 4 XOR 5 = 0 .
Implementation:
In the program below, we play the Nim-Game between computer and human(user) The below program uses two functions knowWinnerBeforePlaying() : : Tells the result before playing. playGame() : plays the full game and finally declare the winner. The function playGame() doesn’t takes input from the human(user), instead it uses a rand() function to randomly pick up a pile and randomly remove any number of stones from the picked pile. The below program can be modified to take input from the user by removing the rand() function and inserting cin or scanf() functions.
C++
/* A C++ program to implement Game of Nim. The program
assumes that both players are playing optimally */
#include <iostream>
#include <math.h>
using namespace std;
#define COMPUTER 1
#define HUMAN 2
/* A Structure to hold the two parameters of a move
A move has two parameters-
1) pile_index = The index of pile from which stone is
going to be removed
2) stones_removed = Number of stones removed from the
pile indexed = pile_index */
struct move
{
int pile_index;
int stones_removed;
};
/*
piles[] -> Array having the initial count of stones/coins
in each piles before the game has started.
n -> Number of piles
The piles[] are having 0-based indexing*/
// A C function to output the current game state.
void showPiles (int piles[], int n)
{
int i;
cout <<"Current Game Status -> ";
for (i=0; i<n; i++)
cout << " " << piles[i];
cout <<"\n";
return;
}
// A C function that returns True if game has ended and
// False if game is not yet over
bool gameOver(int piles[], int n)
{
int i;
for (i=0; i<n; i++)
if (piles[i]!=0)
return (false);
return (true);
}
// A C function to declare the winner of the game
void declareWinner(int whoseTurn)
{
if (whoseTurn == COMPUTER)
cout <<"\nHUMAN won\n\n";
else
cout <<"\nCOMPUTER won\n\n";
return;
}
// A C function to calculate the Nim-Sum at any point
// of the game.
int calculateNimSum(int piles[], int n)
{
int i, nimsum = piles[0];
for (i=1; i<n; i++)
nimsum = nimsum ^ piles[i];
return(nimsum);
}
// A C function to make moves of the Nim Game
void makeMove(int piles[], int n, struct move * moves)
{
int i, nim_sum = calculateNimSum(piles, n);
// The player having the current turn is on a winning
// position. So he/she/it play optimally and tries to make
// Nim-Sum as 0
if (nim_sum != 0)
{
for (i=0; i<n; i++)
{
// If this is not an illegal move
// then make this move.
if ((piles[i] ^ nim_sum) < piles[i])
{
(*moves).pile_index = i;
(*moves).stones_removed =
piles[i]-(piles[i]^nim_sum);
piles[i] = (piles[i] ^ nim_sum);
break;
}
}
}
// The player having the current turn is on losing
// position, so he/she/it can only wait for the opponent
// to make a mistake(which doesn't happen in this program
// as both players are playing optimally). He randomly
// choose a non-empty pile and randomly removes few stones
// from it. If the opponent doesn't make a mistake,then it
// doesn't matter which pile this player chooses, as he is
// destined to lose this game.
// If you want to input yourself then remove the rand()
// functions and modify the code to take inputs.
// But remember, you still won't be able to change your
// fate/prediction.
else
{
// Create an array to hold indices of non-empty piles
int non_zero_indices[n], count;
for (i=0, count=0; i<n; i++)
if (piles[i] > 0)
non_zero_indices [count++] = i;
(*moves).pile_index = (rand() % (count));
(*moves).stones_removed =
1 + (rand() % (piles[(*moves).pile_index]));
piles[(*moves).pile_index] =
piles[(*moves).pile_index] - (*moves).stones_removed;
if (piles[(*moves).pile_index] < 0)
piles[(*moves).pile_index]=0;
}
return;
}
// A C function to play the Game of Nim
void playGame(int piles[], int n, int whoseTurn)
{
cout <<"\nGAME STARTS\n\n";
struct move moves;
while (gameOver (piles, n) == false)
{
showPiles(piles, n);
makeMove(piles, n, &moves);
if (whoseTurn == COMPUTER)
{
cout <<"COMPUTER removes" << moves.stones_removed << "stones from pile at index "
<< moves.pile_index << endl;
whoseTurn = HUMAN;
}
else
{
cout <<"HUMAN removes"<< moves.stones_removed << "stones from pile at index "
<< moves.pile_index << endl;
whoseTurn = COMPUTER;
}
}
showPiles(piles, n);
declareWinner(whoseTurn);
return;
}
void knowWinnerBeforePlaying(int piles[], int n,
int whoseTurn)
{
cout <<"Prediction before playing the game -> ";
if (calculateNimSum(piles, n) !=0)
{
if (whoseTurn == COMPUTER)
cout <<"COMPUTER will win\n";
else
cout <<"HUMAN will win\n";
}
else
{
if (whoseTurn == COMPUTER)
cout <<"HUMAN will win\n";
else
cout <<"COMPUTER will win\n";
}
return;
}
// Driver program to test above functions
int main()
{
// Test Case 1
int piles[] = {3, 4, 5};
int n = sizeof(piles)/sizeof(piles[0]);
// We will predict the results before playing
// The COMPUTER starts first
knowWinnerBeforePlaying(piles, n, COMPUTER);
// Let us play the game with COMPUTER starting first
// and check whether our prediction was right or not
playGame(piles, n, COMPUTER);
/*
Test Case 2
int piles[] = {3, 4, 7};
int n = sizeof(piles)/sizeof(piles[0]);
// We will predict the results before playing
// The HUMAN(You) starts first
knowWinnerBeforePlaying (piles, n, COMPUTER);
// Let us play the game with COMPUTER starting first
// and check whether our prediction was right or not
playGame (piles, n, HUMAN); */
return(0);
}
// This code is contributed by shivanisinghss2110
C
/* A C program to implement Game of Nim. The program
assumes that both players are playing optimally */
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define COMPUTER 1
#define HUMAN 2
/* A Structure to hold the two parameters of a move
A move has two parameters-
1) pile_index = The index of pile from which stone is
going to be removed
2) stones_removed = Number of stones removed from the
pile indexed = pile_index */
struct move
{
int pile_index;
int stones_removed;
};
/*
piles[] -> Array having the initial count of stones/coins
in each piles before the game has started.
n -> Number of piles
The piles[] are having 0-based indexing*/
// A C function to output the current game state.
void showPiles (int piles[], int n)
{
int i;
printf ("Current Game Status -> ");
for (i=0; i<n; i++)
printf ("%d ", piles[i]);
printf("\n");
return;
}
// A C function that returns True if game has ended and
// False if game is not yet over
bool gameOver(int piles[], int n)
{
int i;
for (i=0; i<n; i++)
if (piles[i]!=0)
return (false);
return (true);
}
// A C function to declare the winner of the game
void declareWinner(int whoseTurn)
{
if (whoseTurn == COMPUTER)
printf ("\nHUMAN won\n\n");
else
printf("\nCOMPUTER won\n\n");
return;
}
// A C function to calculate the Nim-Sum at any point
// of the game.
int calculateNimSum(int piles[], int n)
{
int i, nimsum = piles[0];
for (i=1; i<n; i++)
nimsum = nimsum ^ piles[i];
return(nimsum);
}
// A C function to make moves of the Nim Game
void makeMove(int piles[], int n, struct move * moves)
{
int i, nim_sum = calculateNimSum(piles, n);
// The player having the current turn is on a winning
// position. So he/she/it play optimally and tries to make
// Nim-Sum as 0
if (nim_sum != 0)
{
for (i=0; i<n; i++)
{
// If this is not an illegal move
// then make this move.
if ((piles[i] ^ nim_sum) < piles[i])
{
(*moves).pile_index = i;
(*moves).stones_removed =
piles[i]-(piles[i]^nim_sum);
piles[i] = (piles[i] ^ nim_sum);
break;
}
}
}
// The player having the current turn is on losing
// position, so he/she/it can only wait for the opponent
// to make a mistake(which doesn't happen in this program
// as both players are playing optimally). He randomly
// choose a non-empty pile and randomly removes few stones
// from it. If the opponent doesn't make a mistake,then it
// doesn't matter which pile this player chooses, as he is
// destined to lose this game.
// If you want to input yourself then remove the rand()
// functions and modify the code to take inputs.
// But remember, you still won't be able to change your
// fate/prediction.
else
{
// Create an array to hold indices of non-empty piles
int non_zero_indices[n], count;
for (i=0, count=0; i<n; i++)
if (piles[i] > 0)
non_zero_indices [count++] = i;
(*moves).pile_index = (rand() % (count));
(*moves).stones_removed =
1 + (rand() % (piles[(*moves).pile_index]));
piles[(*moves).pile_index] =
piles[(*moves).pile_index] - (*moves).stones_removed;
if (piles[(*moves).pile_index] < 0)
piles[(*moves).pile_index]=0;
}
return;
}
// A C function to play the Game of Nim
void playGame(int piles[], int n, int whoseTurn)
{
printf("\nGAME STARTS\n\n");
struct move moves;
while (gameOver (piles, n) == false)
{
showPiles(piles, n);
makeMove(piles, n, &moves);
if (whoseTurn == COMPUTER)
{
printf("COMPUTER removes %d stones from pile "
"at index %d\n", moves.stones_removed,
moves.pile_index);
whoseTurn = HUMAN;
}
else
{
printf("HUMAN removes %d stones from pile at "
"index %d\n", moves.stones_removed,
moves.pile_index);
whoseTurn = COMPUTER;
}
}
showPiles(piles, n);
declareWinner(whoseTurn);
return;
}
void knowWinnerBeforePlaying(int piles[], int n,
int whoseTurn)
{
printf("Prediction before playing the game -> ");
if (calculateNimSum(piles, n) !=0)
{
if (whoseTurn == COMPUTER)
printf("COMPUTER will win\n");
else
printf("HUMAN will win\n");
}
else
{
if (whoseTurn == COMPUTER)
printf("HUMAN will win\n");
else
printf("COMPUTER will win\n");
}
return;
}
// Driver program to test above functions
int main()
{
// Test Case 1
int piles[] = {3, 4, 5};
int n = sizeof(piles)/sizeof(piles[0]);
// We will predict the results before playing
// The COMPUTER starts first
knowWinnerBeforePlaying(piles, n, COMPUTER);
// Let us play the game with COMPUTER starting first
// and check whether our prediction was right or not
playGame(piles, n, COMPUTER);
/*
Test Case 2
int piles[] = {3, 4, 7};
int n = sizeof(piles)/sizeof(piles[0]);
// We will predict the results before playing
// The HUMAN(You) starts first
knowWinnerBeforePlaying (piles, n, COMPUTER);
// Let us play the game with COMPUTER starting first
// and check whether our prediction was right or not
playGame (piles, n, HUMAN); */
return(0);
}
Java
/* A Java program to implement Game of Nim. The program
assumes that both players are playing optimally */
import java.util.*;
/* A Class to hold the two parameters of a move
A move has two parameters-
1) pile_index = The index of pile from which stone is
going to be removed
2) stones_removed = Number of stones removed from the
pile indexed = pile_index */
class move {
public int pile_index;
public int stones_removed;
};
class GFG {
static int COMPUTER = 1;
static int HUMAN = 2;
static move moves = new move();
/*
piles[] -> Array having the initial count of
stones/coins in each piles before the game has started.
n -> Number of piles
The piles[] are having 0-based indexing*/
// A Java function to output the current game state.
static void showPiles(int[] piles, int n)
{
int i;
System.out.print("Current Game Status -> ");
for (i = 0; i < n; i++)
System.out.print(" " + piles[i]);
System.out.println();
return;
}
// A Java function that returns True if game has ended and
// False if game is not yet over
static boolean gameOver(int[] piles, int n)
{
int i;
for (i = 0; i < n; i++)
if (piles[i] != 0)
return false;
return true;
}
// A Java function to declare the winner of the game
static void declareWinner(int whoseTurn)
{
if (whoseTurn == COMPUTER)
System.out.print("\nHUMAN won\n\n");
else
System.out.print("\nCOMPUTER won\n\n");
return;
}
// A C# function to calculate the Nim-Sum at any point
// of the game.
static int calculateNimSum(int[] piles, int n)
{
int i, nimsum = piles[0];
for (i = 1; i < n; i++)
nimsum = nimsum ^ piles[i];
return (nimsum);
}
// A C# function to make moves of the Nim Game
static void makeMove(int[] piles, int n, move moves)
{
// create instance of Random class
Random rand = new Random();
int i, nim_sum = calculateNimSum(piles, n);
// The player having the current turn is on a
// winning position. So he/she/it play optimally and
// tries to make Nim-Sum as 0
if (nim_sum != 0) {
for (i = 0; i < n; i++) {
// If this is not an illegal move
// then make this move.
if ((piles[i] ^ nim_sum) < piles[i]) {
(moves).pile_index = i;
(moves).stones_removed
= piles[i] - (piles[i] ^ nim_sum);
piles[i] = (piles[i] ^ nim_sum);
break;
}
}
}
// The player having the current turn is on losing
// position, so he/she/it can only wait for the
// opponent to make a mistake(which doesn't happen
// in this program as both players are playing
// optimally). He randomly choose a non-empty pile
// and randomly removes few stones from it. If the
// opponent doesn't make a mistake,then it doesn't
// matter which pile this player chooses, as he is
// destined to lose this game.
// If you want to input yourself then remove the
// rand() functions and modify the code to take
// inputs. But remember, you still won't be able to
// change your fate/prediction.
else {
// Create an array to hold indices of non-empty
// piles
int[] non_zero_indices = new int[n];
int count = 0;
for (i = 0; i < n; i++) {
if (piles[i] > 0) {
non_zero_indices[count] = i;
count += 1;
}
}
(moves).pile_index = (rand.nextInt(count));
(moves).stones_removed
= 1
+ (rand.nextInt(1 + piles[(moves).pile_index]));
piles[(moves).pile_index]
= piles[(moves).pile_index]
- (moves).stones_removed;
if (piles[(moves).pile_index] < 0)
piles[(moves).pile_index] = 0;
}
return;
}
// A C# function to play the Game of Nim
static void playGame(int[] piles, int n, int whoseTurn)
{
System.out.print("\nGAME STARTS\n\n");
while (gameOver(piles, n) == false) {
showPiles(piles, n);
makeMove(piles, n, moves);
if (whoseTurn == COMPUTER) {
System.out.println(
"COMPUTER removes "
+ moves.stones_removed
+ "stones from pile at index "
+ moves.pile_index);
whoseTurn = HUMAN;
}
else {
System.out.println(
"HUMAN removes" + moves.stones_removed
+ "stones from pile at index "
+ moves.pile_index);
whoseTurn = COMPUTER;
}
}
showPiles(piles, n);
declareWinner(whoseTurn);
return;
}
static void knowWinnerBeforePlaying(int[] piles, int n,
int whoseTurn)
{
System.out.println(
"Prediction before playing the game -> ");
if (calculateNimSum(piles, n) != 0) {
if (whoseTurn == COMPUTER)
System.out.println("COMPUTER will win\n");
else
System.out.println("HUMAN will win\n");
}
else {
if (whoseTurn == COMPUTER)
System.out.print("HUMAN will win\n");
else
System.out.print("COMPUTER will win\n");
}
return;
}
// Driver program to test above functions
public static void main(String[] arg)
{
// Test Case 1
int[] piles = { 3, 4, 5 };
int n = piles.length;
// We will predict the results before playing
// The COMPUTER starts first
knowWinnerBeforePlaying(piles, n, COMPUTER);
// Let us play the game with COMPUTER starting first
// and check whether our prediction was right or not
playGame(piles, n, COMPUTER);
/*
Test Case 2
int piles[] = {3, 4, 7};
int n = sizeof(piles)/sizeof(piles[0]);
// We will predict the results before playing
// The HUMAN(You) starts first
knowWinnerBeforePlaying (piles, n, COMPUTER);
// Let us play the game with COMPUTER starting first
// and check whether our prediction was right or not
playGame (piles, n, HUMAN); */
}
}
// This code is contributed by phasing17
Python3
# A Python3 program to implement Game of Nim. The program
# assumes that both players are playing optimally
import random
COMPUTER = 1
HUMAN = 2
# A Structure to hold the two parameters of a move
# move has two parameters-
# 1) pile_index = The index of pile from which stone is
# going to be removed
# 2) stones_removed = Number of stones removed from the
# pile indexed = pile_index */
class move:
def __init__(self):
self.pile_index = 0
self.stones_removed = 0
# piles[] -> Array having the initial count of stones/coins
# in each piles before the game has started.
# n -> Number of piles
# The piles[] are having 0-based indexing
# A function to output the current game state.
def showPiles(piles, n):
print("Current Game Status -> ")
print(*piles)
# A function that returns True if game has ended and
# False if game is not yet over
def gameOver(piles, n):
for i in range(n):
if (piles[i] != 0):
return False
return True
# A function to declare the winner of the game
def declareWinner(whoseTurn):
if (whoseTurn == COMPUTER):
print("\nHUMAN won")
else:
print("\nCOMPUTER won")
return
# A function to calculate the Nim-Sum at any point
# of the game.
def calculateNimSum(piles, n):
nimsum = piles[0]
for i in range(1, n):
nimsum = nimsum ^ piles[i]
return nimsum
# A function to make moves of the Nim Game
def makeMove(piles, n, moves):
nim_sum = calculateNimSum(piles, n)
# The player having the current turn is on a winning
# position. So he/she/it play optimally and tries to make
# Nim-Sum as 0
if (nim_sum != 0):
for i in range(n):
# If this is not an illegal move
# then make this move.
if ((piles[i] ^ nim_sum) < piles[i]):
moves.pile_index = i
moves.stones_removed = piles[i]-(piles[i] ^ nim_sum)
piles[i] = (piles[i] ^ nim_sum)
break
# The player having the current turn is on losing
# position, so he/she/it can only wait for the opponent
# to make a mistake(which doesn't happen in this program
# as both players are playing optimally). He randomly
# choose a non-empty pile and randomly removes few stones
# from it. If the opponent doesn't make a mistake,then it
# doesn't matter which pile this player chooses, as he is
# destined to lose this game.
# If you want to input yourself then remove the rand()
# functions and modify the code to take inputs.
# But remember, you still won't be able to change your
# fate/prediction.
else:
# Create an array to hold indices of non-empty piles
non_zero_indices = [None for _ in range(n)]
count = 0
for i in range(n):
if (piles[i] > 0):
non_zero_indices[count] = i
count += 1
moves.pile_index = int(random.random() * (count))
moves.stones_removed = 1 + \
int(random.random() * (piles[moves.pile_index]))
piles[moves.pile_index] -= moves.stones_removed
if (piles[moves.pile_index] < 0):
piles[moves.pile_index] = 0
return
# A C function to play the Game of Nim
def playGame(piles, n, whoseTurn):
print("\nGAME STARTS")
moves = move()
while (gameOver(piles, n) == False):
showPiles(piles, n)
makeMove(piles, n, moves)
if (whoseTurn == COMPUTER):
print("COMPUTER removes", moves.stones_removed,
"stones from pile at index ", moves.pile_index)
whoseTurn = HUMAN
else:
print("HUMAN removes", moves.stones_removed,
"stones from pile at index", moves.pile_index)
whoseTurn = COMPUTER
showPiles(piles, n)
declareWinner(whoseTurn)
return
def knowWinnerBeforePlaying(piles, n, whoseTurn):
print("Prediction before playing the game -> ", end="")
if (calculateNimSum(piles, n) != 0):
if (whoseTurn == COMPUTER):
print("COMPUTER will win")
else:
print("HUMAN will win")
else:
if (whoseTurn == COMPUTER):
print("HUMAN will win")
else:
print("COMPUTER will win")
return
# Driver program to test above functions
# Test Case 1
piles = [3, 4, 5]
n = len(piles)
# We will predict the results before playing
# The COMPUTER starts first
knowWinnerBeforePlaying(piles, n, COMPUTER)
# Let us play the game with COMPUTER starting first
# and check whether our prediction was right or not
playGame(piles, n, COMPUTER)
# This code is contributed by phasing17
C#
/* A C# program to implement Game of Nim. The program
assumes that both players are playing optimally */
using System;
using System.Collections.Generic;
/* A Class to hold the two parameters of a move
A move has two parameters-
1) pile_index = The index of pile from which stone is
going to be removed
2) stones_removed = Number of stones removed from the
pile indexed = pile_index */
class move {
public int pile_index;
public int stones_removed;
};
class GFG {
static int COMPUTER = 1;
static int HUMAN = 2;
static move moves = new move();
/*
piles[] -> Array having the initial count of
stones/coins in each piles before the game has started.
n -> Number of piles
The piles[] are having 0-based indexing*/
// A C# function to output the current game state.
static void showPiles(int[] piles, int n)
{
int i;
Console.Write("Current Game Status -> ");
for (i = 0; i < n; i++)
Console.Write(" " + piles[i]);
Console.WriteLine();
return;
}
// A C# function that returns True if game has ended and
// False if game is not yet over
static bool gameOver(int[] piles, int n)
{
int i;
for (i = 0; i < n; i++)
if (piles[i] != 0)
return false;
return true;
}
// A C# function to declare the winner of the game
static void declareWinner(int whoseTurn)
{
if (whoseTurn == COMPUTER)
Console.Write("\nHUMAN won\n\n");
else
Console.Write("\nCOMPUTER won\n\n");
return;
}
// A C# function to calculate the Nim-Sum at any point
// of the game.
static int calculateNimSum(int[] piles, int n)
{
int i, nimsum = piles[0];
for (i = 1; i < n; i++)
nimsum = nimsum ^ piles[i];
return (nimsum);
}
// A C# function to make moves of the Nim Game
static void makeMove(int[] piles, int n, move moves)
{
var rand = new Random();
int i, nim_sum = calculateNimSum(piles, n);
// The player having the current turn is on a
// winning position. So he/she/it play optimally and
// tries to make Nim-Sum as 0
if (nim_sum != 0) {
for (i = 0; i < n; i++) {
// If this is not an illegal move
// then make this move.
if ((piles[i] ^ nim_sum) < piles[i]) {
(moves).pile_index = i;
(moves).stones_removed
= piles[i] - (piles[i] ^ nim_sum);
piles[i] = (piles[i] ^ nim_sum);
break;
}
}
}
// The player having the current turn is on losing
// position, so he/she/it can only wait for the
// opponent to make a mistake(which doesn't happen
// in this program as both players are playing
// optimally). He randomly choose a non-empty pile
// and randomly removes few stones from it. If the
// opponent doesn't make a mistake,then it doesn't
// matter which pile this player chooses, as he is
// destined to lose this game.
// If you want to input yourself then remove the
// rand() functions and modify the code to take
// inputs. But remember, you still won't be able to
// change your fate/prediction.
else {
// Create an array to hold indices of non-empty
// piles
int[] non_zero_indices = new int[n];
int count = 0;
for (i = 0; i < n; i++) {
if (piles[i] > 0) {
non_zero_indices[count] = i;
count += 1;
}
}
(moves).pile_index = (rand.Next(count));
(moves).stones_removed
= 1
+ (rand.Next(piles[(moves).pile_index]));
piles[(moves).pile_index]
= piles[(moves).pile_index]
- (moves).stones_removed;
if (piles[(moves).pile_index] < 0)
piles[(moves).pile_index] = 0;
}
return;
}
// A C# function to play the Game of Nim
static void playGame(int[] piles, int n, int whoseTurn)
{
Console.Write("\nGAME STARTS\n\n");
while (gameOver(piles, n) == false) {
showPiles(piles, n);
makeMove(piles, n, moves);
if (whoseTurn == COMPUTER) {
Console.WriteLine(
"COMPUTER removes "
+ moves.stones_removed
+ "stones from pile at index "
+ moves.pile_index);
whoseTurn = HUMAN;
}
else {
Console.WriteLine(
"HUMAN removes" + moves.stones_removed
+ "stones from pile at index "
+ moves.pile_index);
whoseTurn = COMPUTER;
}
}
showPiles(piles, n);
declareWinner(whoseTurn);
return;
}
static void knowWinnerBeforePlaying(int[] piles, int n,
int whoseTurn)
{
Console.Write(
"Prediction before playing the game -> ");
if (calculateNimSum(piles, n) != 0) {
if (whoseTurn == COMPUTER)
Console.Write("COMPUTER will win\n");
else
Console.Write("HUMAN will win\n");
}
else {
if (whoseTurn == COMPUTER)
Console.Write("HUMAN will win\n");
else
Console.Write("COMPUTER will win\n");
}
return;
}
// Driver program to test above functions
public static void Main(string[] arg)
{
// Test Case 1
int[] piles = { 3, 4, 5 };
int n = piles.Length;
// We will predict the results before playing
// The COMPUTER starts first
knowWinnerBeforePlaying(piles, n, COMPUTER);
// Let us play the game with COMPUTER starting first
// and check whether our prediction was right or not
playGame(piles, n, COMPUTER);
/*
Test Case 2
int piles[] = {3, 4, 7};
int n = sizeof(piles)/sizeof(piles[0]);
// We will predict the results before playing
// The HUMAN(You) starts first
knowWinnerBeforePlaying (piles, n, COMPUTER);
// Let us play the game with COMPUTER starting first
// and check whether our prediction was right or not
playGame (piles, n, HUMAN); */
}
}
// This code is contributed by phasing17
JavaScript
/* A JavaScript program to implement Game of Nim. The program
assumes that both players are playing optimally */
let COMPUTER = 1;
let HUMAN = 2;
/* A Structure to hold the two parameters of a move
A move has two parameters-
1) pile_index = The index of pile from which stone is
going to be removed
2) stones_removed = Number of stones removed from the
pile indexed = pile_index */
class move
{
constructor()
{
this.pile_index;
this.stones_removed;
}
};
/*
piles[] -> Array having the initial count of stones/coins
in each piles before the game has started.
n -> Number of piles
The piles[] are having 0-based indexing*/
// A function to output the current game state.
function showPiles (piles, n)
{
let i;
process.stdout.write("Current Game Status -> ");
for (i=0; i<n; i++)
process.stdout.write(" " + piles[i]);
process.stdout.write("\n");
return;
}
// A function that returns True if game has ended and
// False if game is not yet over
function gameOver(piles, n)
{
let i;
for (i=0; i<n; i++)
if (piles[i]!=0)
return false;
return true;
}
// A function to declare the winner of the game
function declareWinner(whoseTurn)
{
if (whoseTurn == COMPUTER)
console.log("\nHUMAN won\n");
else
console.log("\nCOMPUTER won\n");
return;
}
// A function to calculate the Nim-Sum at any point
// of the game.
function calculateNimSum(piles, n)
{
let i, nimsum = piles[0];
for (i=1; i<n; i++)
nimsum = nimsum ^ piles[i];
return nimsum;
}
// A function to make moves of the Nim Game
function makeMove(piles, n, moves)
{
let i, nim_sum = calculateNimSum(piles, n);
// The player having the current turn is on a winning
// position. So he/she/it play optimally and tries to make
// Nim-Sum as 0
if (nim_sum != 0)
{
for (i=0; i<n; i++)
{
// If this is not an illegal move
// then make this move.
if ((piles[i] ^ nim_sum) < piles[i])
{
moves.pile_index = i;
moves.stones_removed =
piles[i]-(piles[i]^nim_sum);
piles[i] = (piles[i] ^ nim_sum);
break;
}
}
}
// The player having the current turn is on losing
// position, so he/she/it can only wait for the opponent
// to make a mistake(which doesn't happen in this program
// as both players are playing optimally). He randomly
// choose a non-empty pile and randomly removes few stones
// from it. If the opponent doesn't make a mistake,then it
// doesn't matter which pile this player chooses, as he is
// destined to lose this game.
// If you want to input yourself then remove the rand()
// functions and modify the code to take inputs.
// But remember, you still won't be able to change your
// fate/prediction.
else
{
// Create an array to hold indices of non-empty piles
let non_zero_indices = new Array(n);
let count;
for (i=0, count=0; i<n; i++)
if (piles[i] > 0)
non_zero_indices [count++] = i;
moves.pile_index = Math.floor(Math.random() * (count));
moves.stones_removed = 1 + Math.floor(Math.random() * (piles[moves.pile_index]));
piles[moves.pile_index] =
piles[moves.pile_index] - moves.stones_removed;
if (piles[moves.pile_index] < 0)
piles[moves.pile_index]=0;
}
return;
}
// A C function to play the Game of Nim
function playGame(piles, n, whoseTurn)
{
console.log("\nGAME STARTS\n");
let moves = new move();
while (gameOver (piles, n) == false)
{
showPiles(piles, n);
makeMove(piles, n, moves);
if (whoseTurn == COMPUTER)
{
console.log("COMPUTER removes", moves.stones_removed, "stones from pile at index ", moves.pile_index);
whoseTurn = HUMAN;
}
else
{
console.log("HUMAN removes", moves.stones_removed, "stones from pile at index", moves.pile_index);
whoseTurn = COMPUTER;
}
}
showPiles(piles, n);
declareWinner(whoseTurn);
return;
}
function knowWinnerBeforePlaying(piles, n, whoseTurn)
{
process.stdout.write("Prediction before playing the game -> ");
if (calculateNimSum(piles, n) !=0)
{
if (whoseTurn == COMPUTER)
console.log("COMPUTER will win");
else
console.log("HUMAN will win");
}
else
{
if (whoseTurn == COMPUTER)
console.log("HUMAN will win");
else
console.log("COMPUTER will win");
}
return;
}
// Driver program to test above functions
// Test Case 1
let piles = [3, 4, 5];
let n = piles.length;
// We will predict the results before playing
// The COMPUTER starts first
knowWinnerBeforePlaying(piles, n, COMPUTER);
// Let us play the game with COMPUTER starting first
// and check whether our prediction was right or not
playGame(piles, n, COMPUTER);
/*
Test Case 2
int piles[] = {3, 4, 7};
int n = sizeof(piles)/sizeof(piles[0]);
// We will predict the results before playing
// The HUMAN(You) starts first
knowWinnerBeforePlaying (piles, n, COMPUTER);
// Let us play the game with COMPUTER starting first
// and check whether our prediction was right or not
playGame (piles, n, HUMAN); */
// This code is contributed by phasing17
Output : May be different on different runs as random numbers are used to decide next move (for the losing player).
Prediction before playing the game -> COMPUTER will win
GAME STARTS
Current Game Status -> 3 4 5
COMPUTER removes 2 stones from pile at index 0
Current Game Status -> 1 4 5
HUMAN removes 3 stones from pile at index 1
Current Game Status -> 1 1 5
COMPUTER removes 5 stones from pile at index 2
Current Game Status -> 1 1 0
HUMAN removes 1 stones from pile at index 1
Current Game Status -> 1 0 0
COMPUTER removes 1 stones from pile at index 0
Current Game Status -> 0 0 0
COMPUTER won
References : https://en.wikipedia.org/wiki/Nim
Similar Reads
Number Theory for DSA & Competitive Programming
What is Number Theory?Number theory is a branch of pure mathematics that deals with the properties and relationships of numbers, particularly integers. It explores the fundamental nature of numbers and their mathematical structures. Number theory has been studied for centuries and has deep connectio
3 min read
Number Theory (Interesting Facts and Algorithms)
Questions based on various concepts of number theory and different types of number are quite frequently asked in programming contests. In this article, we discuss some famous facts and algorithms:Interesting Facts of Number Theory :1. All 4 digit palindromic numbers are divisible by 11.2. If we repe
5 min read
How to prepare for ACM - ICPC?
ACM ICPC(Association for Computing Machinery - International Collegiate Programming Contest) is a worldwide annual multi-tiered programming contest being organized for over thirteen years. The contest is sponsored by IBM. This article focuses on what all topics that are important for competitive pro
7 min read
Basics of Number Theory
Program to Find GCD or HCF of Two Numbers
Given two numbers a and b, the task is to find the GCD of the two numbers.Note: The GCD (Greatest Common Divisor) or HCF (Highest Common Factor) of two numbers is the largest number that divides both of them. Examples:Input: a = 20, b = 28Output: 4Explanation: The factors of 20 are 1, 2, 4, 5, 10 an
15+ min read
Program to find LCM of two numbers
LCM of two numbers is the smallest number which can be divided by both numbers. Input : a = 12, b = 18Output : 3636 is the smallest number divisible by both 12 and 18Input : a = 5, b = 11Output : 5555 is the smallest number divisible by both 5 and 11[Naive Approach] Using Conditional Loop This appro
8 min read
Factorial of a Number
Given the number n (n >=0), find its factorial. Factorial of n is defined as 1 x 2 x ... x n. For n = 0, factorial is 1. We are going to discuss iterative and recursive programs in this post.Examples:Input: n = 5Output: 120Explanation: 5! = 5 * 4 * 3 * 2 * 1 = 120Input: n = 4Output: 24Explanation
7 min read
Print all prime factors of a given number
Given a number n, the task is to find all prime factors of n.Examples:Input: n = 24Output: 2 2 2 3Explanation: The prime factorization of 24 is 23Ã3.Input: n = 13195Output: 5 7 13 29Explanation: The prime factorization of 13195 is 5Ã7Ã13Ã29.Approach:Every composite number has at least one prime fact
6 min read
Binomial Coefficient
Given an integer values n and k, the task is to find the value of Binomial Coefficient C(n, k).A binomial coefficient C(n, k) can be defined as the coefficient of x^k in the expansion of (1 + x)^n.A binomial coefficient C(n, k) also gives the number of ways, disregarding order, that k objects can be
15+ min read
Program for nth Catalan Number
Catalan numbers are defined as a mathematical sequence that consists of positive integers, which can be used to find the number of possibilities of various combinations. The nth term in the sequence denoted Cn, is found in the following formula: \frac{(2n)!}{((n + 1)! n!)} The first few Catalan numb
13 min read
Euclid's lemma
We are given two numbers x and y. We know that a number p divides their product. Can we say for sure that p also divides one of them? The answer is no. For example, consider x = 15, y = 6 and p = 9. p divides the product 15*6, but doesn't divide any of them. What if p is prime? Euclid's lemma states
1 min read
Euclidean algorithms (Basic and Extended)
The Euclidean algorithm is a way to find the greatest common divisor of two positive integers. GCD of two numbers is the largest number that divides both of them. A simple way to find GCD is to factorize both numbers and multiply common prime factors.Examples:input: a = 12, b = 20Output: 4Explanatio
9 min read
Modular Arithmetic
Modular Arithmetic
Modular arithmetic is a system of arithmetic for numbers where numbers "wrap around" after reaching a certain value, called the modulus. It mainly uses remainders to get the value after wrap around. It is often referred to as "clock arithmetic. As you can see, the time values wrap after reaching 12
10 min read
Modular Addition
Modular addition is a basic math concept used in computers and number systems. It is commonly used in areas like cryptography (data security), coding, and digital signal processing. In modular addition, you add two numbers normally, but if the result reaches a certain fixed number (called the modulu
4 min read
Modular Multiplication
Modular arithmetic, or clock arithmetic, is a system of arithmetic for integers, where numbers "wrap around" upon reaching a certain value This mathematical concept is widely used in various fields such as computer science, cryptography, number theory, and even everyday situations like clock time ca
6 min read
Modular Division
Modular division is the process of dividing one number by another in modular arithmetic. In modular arithmetic, division is defined differently from regular arithmetic because there is no direct "division" operation. Instead, modular division involves multiplying by the modular multiplicative invers
10 min read
Euler's Totient Function
Euler's Totient function Φ(n) for an input n is the count of numbers in {1, 2, 3, ..., n-1} that are relatively prime to n, i.e., the numbers whose GCD (Greatest Common Divisor) with n is 1. If n is a positive integer and its prime factorization is; n = p_1^{e_1} \cdot p_2^{e_2} \cdot \ldots \cdot p
15+ min read
Euler's Totient function for all numbers smaller than or equal to n
Euler's Totient function ?(n) for an input n is the count of numbers in {1, 2, 3, ..., n} that are relatively prime to n, i.e., the numbers whose GCD (Greatest Common Divisor) with n is 1. For example, ?(4) = 2, ?(3) = 2 and ?(5) = 4. There are 2 numbers smaller or equal to 4 that are relatively pri
13 min read
Modular Exponentiation (Power in Modular Arithmetic)
Modular Exponentiation is the process of computing: xy (modââp). where x, y, and p are integers. It efficiently calculates the remainder when xy is divided by p or (xy) % p, even for very large y.Examples : Input: x = 2, y = 3, p = 5Output: 3Explanation: 2^3 % 5 = 8 % 5 = 3.Input: x = 2, y = 5, p =
8 min read
Program to find remainder without using modulo or % operator
Given two numbers 'num' and 'divisor', find remainder when 'num' is divided by 'divisor'. The use of modulo or % operator is not allowed.Examples : Input: num = 100, divisor = 7 Output: 2 Input: num = 30, divisor = 9 Output: 3 Method 1 : C++ // C++ program to find remainder without using // modulo o
9 min read
Modular multiplicative inverse
Given two integers A and M, find the modular multiplicative inverse of A under modulo M.The modular multiplicative inverse is an integer X such that:A X â¡ 1 (mod M) Note: The value of X should be in the range {1, 2, ... M-1}, i.e., in the range of integer modulo M. ( Note that X cannot be 0 as A*0 m
15+ min read
Multiplicative order
In number theory, given an integer A and a positive integer N with gcd( A , N) = 1, the multiplicative order of a modulo N is the smallest positive integer k with A^k( mod N ) = 1. ( 0 < K < N ) Examples : Input : A = 4 , N = 7 Output : 3 explanation : GCD(4, 7) = 1 A^k( mod N ) = 1 ( smallest
7 min read
Compute nCr%p using Lucas Theorem
Given three numbers n, r and p, compute the value of nCr mod p. Examples: Input: n = 10, r = 2, p = 13 Output: 6 Explanation: 10C2 is 45 and 45 % 13 is 6. Input: n = 1000, r = 900, p = 13 Output: 8 We strongly recommend referring below post as a prerequisite of this.Compute nCr % p | Set 1 (Introduc
12 min read
Compute nCr%p using Fermat Little Theorem
Given three numbers n, r and p, compute the value of nCr mod p. Here p is a prime number greater than n. Here nCr is Binomial Coefficient.Example: Input: n = 10, r = 2, p = 13 Output: 6 Explanation: 10C2 is 45 and 45 % 13 is 6. Input: n = 6, r = 2, p = 13 Output: 2Recommended PracticenCrTry It! We h
15+ min read
Introduction to Chinese Remainder Theorem
We are given two arrays num[0..k-1] and rem[0..k-1]. In num[0..k-1], every pair is coprime (gcd for every pair is 1). We need to find minimum positive number x such that: x % num[0] = rem[0], x % num[1] = rem[1], .......................x % num[k-1] = rem[k-1] Basically, we are given k numbers which
7 min read
Implementation of Chinese Remainder theorem (Inverse Modulo based implementation)
We are given two arrays num[0..k-1] and rem[0..k-1]. In num[0..k-1], every pair is coprime (gcd for every pair is 1). We need to find minimum positive number x such that: x % num[0] = rem[0], x % num[1] = rem[1], ....................... x % num[k-1] = rem[k-1] Example: Input: num[] = {3, 4, 5}, rem[
11 min read
Find Square Root under Modulo p | Set 1 (When p is in form of 4*i + 3)
Given a number 'n' and a prime 'p', find square root of n under modulo p if it exists. It may be given that p is in the form for 4*i + 3 (OR p % 4 = 3) where i is an integer. Examples of such primes are 7, 11, 19, 23, 31, ... etc,Examples: Input: n = 2, p = 7Output: 3 or 4Explanation: 3 and 4 both a
14 min read
Find Square Root under Modulo p | Set 2 (Shanks Tonelli algorithm)
Given a number ânâ and a prime âpâ, find square root of n under modulo p if it exists. Examples: Input: n = 2, p = 113 Output: 62 62^2 = 3844 and 3844 % 113 = 2 Input: n = 2, p = 7 Output: 3 or 4 3 and 4 both are square roots of 2 under modulo 7 because (3*3) % 7 = 2 and (4*4) % 7 = 2 Input: n = 2,
15+ min read
Modular Division
Modular division is the process of dividing one number by another in modular arithmetic. In modular arithmetic, division is defined differently from regular arithmetic because there is no direct "division" operation. Instead, modular division involves multiplying by the modular multiplicative invers
10 min read
Cyclic Redundancy Check and Modulo-2 Division
Cyclic Redundancy Check or CRC is a method of detecting accidental changes/errors in the communication channel. CRC uses Generator Polynomial which is available on both sender and receiver side. An example generator polynomial is of the form like x3 + x + 1. This generator polynomial represents key
15+ min read
Primitive root of a prime number n modulo n
Given a prime number n, the task is to find its primitive root under modulo n. The primitive root of a prime number n is an integer r between[1, n-1] such that the values of r^x(mod n) where x is in the range[0, n-2] are different. Return -1 if n is a non-prime number. Examples: Input : 7 Output : S
15 min read
Euler's criterion (Check if square root under modulo p exists)
Given a number 'n' and a prime p, find if square root of n under modulo p exists or not. A number x is square root of n under modulo p if (x*x)%p = n%p. Examples : Input: n = 2, p = 5 Output: false There doesn't exist a number x such that (x*x)%5 is 2 Input: n = 2, p = 7 Output: true There exists a
11 min read
Using Chinese Remainder Theorem to Combine Modular equations
Given N modular equations: A ? x1mod(m1) . . A ? xnmod(mn) Find x in the equation A ? xmod(m1*m2*m3..*mn) where mi is prime, or a power of a prime, and i takes values from 1 to n. The input is given as two arrays, the first being an array containing values of each xi, and the second array containing
12 min read
Multiply large integers under large modulo
Given an integer a, b, m. Find (a * b ) mod m, where a, b may be large and their direct multiplication may cause overflow. However, they are smaller than half of the maximum allowed long long int value. Examples: Input: a = 426, b = 964, m = 235Output: 119Explanation: (426 * 964) % 235 = 410664 % 23
7 min read
Compute n! under modulo p
Given a large number n and a prime p, how to efficiently compute n! % p?Examples : Input: n = 5, p = 13 Output: 3 5! = 120 and 120 % 13 = 3 Input: n = 6, p = 11 Output: 5 6! = 720 and 720 % 11 = 5 A Naive Solution is to first compute n!, then compute n! % p. This solution works fine when the value o
15+ min read
Wilson's Theorem
Wilson's Theorem is a fundamental result in number theory that provides a necessary and sufficient condition for determining whether a given number is prime. It states that a natural number p > 1 is a prime number if and only if:(p - 1)! â¡ â1 (mod p)This means that the factorial of p - 1 (the pro
2 min read
Number Theory
Introduction to Primality Test and School Method
Given a positive integer, check if the number is prime or not. A prime is a natural number greater than 1 that has no positive divisors other than 1 and itself. Examples of the first few prime numbers are {2, 3, 5, ...}Examples : Input: n = 11Output: trueInput: n = 15Output: falseInput: n = 1Output:
10 min read
Fermat Method of Primality Test
Given a number n, check if it is prime or not. We have introduced and discussed the School method for primality testing in Set 1.Introduction to Primality Test and School MethodIn this post, Fermat's method is discussed. This method is a probabilistic method and is based on Fermat's Little Theorem.
10 min read
Primality Test | Set 3 (MillerâRabin)
Given a number n, check if it is prime or not. We have introduced and discussed School and Fermat methods for primality testing.Primality Test | Set 1 (Introduction and School Method) Primality Test | Set 2 (Fermat Method)In this post, the Miller-Rabin method is discussed. This method is a probabili
15+ min read
Solovay-Strassen method of Primality Test
We have already been introduced to primality testing in the previous articles in this series. Introduction to Primality Test and School MethodFermat Method of Primality TestPrimality Test | Set 3 (MillerâRabin)The SolovayâStrassen test is a probabilistic algorithm used to check if a number is prime
13 min read
Legendre's formula - Largest power of a prime p in n!
Given an integer n and a prime number p, the task is to find the largest x such that px (p raised to power x) divides n!.Examples: Input: n = 7, p = 3Output: x = 2Explanation: 32 divides 7! and 2 is the largest such power of 3.Input: n = 10, p = 3Output: x = 4Explanation: 34 divides 10! and 4 is the
6 min read
Carmichael Numbers
A number n is said to be a Carmichael number if it satisfies the following modular arithmetic condition: power(b, n-1) MOD n = 1, for all b ranging from 1 to n such that b and n are relatively prime, i.e, gcd(b, n) = 1 Given a positive integer n, find if it is a Carmichael number. These numbers have
8 min read
Number Theory | Generators of finite cyclic group under addition
Given a number n, find all generators of cyclic additive group under modulo n. Generator of a set {0, 1, ... n-1} is an element x such that x is smaller than n, and using x (and addition operation), we can generate all elements of the set.Examples: Input : 10 Output : 1 3 7 9 The set to be generated
5 min read
Sum of divisors of factorial of a number
Given a number n, we need to calculate the sum of divisors of factorial of the number. Examples: Input : 4 Output : 60 Factorial of 4 is 24. Divisors of 24 are 1 2 3 4 6 8 12 24, sum of these is 60. Input : 6 Output : 2418 A Simple Solution is to first compute the factorial of the given number, then
14 min read
GFact | 2x + 1(where x > 0) is prime if and only if x is a power of 2
A number of the form 2x + 1 (where x > 0) is prime if and only if x is a power of 2, i.e., x = 2n. So overall number becomes 22n + 1. Such numbers are called Fermat Number (Numbers of form 22n + 1). The first few Fermat numbers are 3, 5, 17, 257, 65537, 4294967297, .... An important thing to note
1 min read
Sieve of Eratosthenes
Given a number n, print all primes smaller than or equal to n. It is also given that n is a small number. Examples:Input: n = 10Output: 2 3 5 7Explanation: The prime numbers up to 10 obtained by Sieve of Eratosthenes are 2 3 5 7 .Input: n = 20Output: 2 3 5 7 11 13 17 19Explanation: The prime numbers
6 min read
Program for Goldbachâs Conjecture (Two Primes with given Sum)
Goldbach's conjecture is one of the oldest and best-known unsolved problems in the number theory of mathematics. Every even integer greater than 2 can be expressed as the sum of two primes. Examples: Input : n = 44 Output : 3 + 41 (both are primes) Input : n = 56 Output : 3 + 53 (both are primes) Re
12 min read
Pollard's Rho Algorithm for Prime Factorization
Given a positive integer n, and that it is composite, find a divisor of it.Example:Input: n = 12;Output: 2 [OR 3 OR 4]Input: n = 187;Output: 11 [OR 17]Brute approach: Test all integers less than n until a divisor is found. Improvisation: Test all integers less than ?nA large enough number will still
14 min read
Practice Problems
Rabin-Karp Algorithm for Pattern Searching
Given two strings text and pattern string, your task is to find all starting positions where the pattern appears as a substring within the text. The strings will only contain lowercase English alphabets.While reporting the results, use 1-based indexing (i.e., the first character of the text is at po
12 min read
Measure one litre using two vessels and infinite water supply
There are two vessels of capacities 'a' and 'b' respectively. We have infinite water supply. Give an efficient algorithm to make exactly 1 litre of water in one of the vessels. You can throw all the water from any vessel any point of time. Assume that 'a' and 'b' are Coprimes.Following are the steps
15 min read
Program to find last digit of n'th Fibonacci Number
Given a number 'n', write a function that prints the last digit of n'th ('n' can also be a large number) Fibonacci number. Examples : Input : n = 0 Output : 0 Input: n = 2 Output : 1 Input : n = 7 Output : 3 Recommended PracticeThe Nth FibonnaciTry It! Method 1 : (Naive Method) Simple approach is to
13 min read
GCD of two numbers when one of them can be very large
Given two numbers 'a' and 'b' such that (0 <= a <= 10^12 and b <= b < 10^250). Find the GCD of two given numbers.Examples : Input: a = 978 b = 89798763754892653453379597352537489494736 Output: 6 Input: a = 1221 b = 1234567891011121314151617181920212223242526272829 Output: 3 Solution : In
9 min read
Find Last Digit of a^b for Large Numbers
You are given two integer numbers, the base a (number of digits d, such that 1 <= d <= 1000) and the index b (0 <= b <= 922*10^15). You have to find the last digit of a^b.Examples: Input : 3 10Output : 9Input : 6 2Output : 6Input : 150 53Output : 0 After taking few examples, we can notic
9 min read
Remainder with 7 for large numbers
Given a large number as a string, find the remainder of number when divided by 7. Examples : Input : num = 1234 Output : 2 Input : num = 1232 Output : 0 Input : num = 12345 Output : 4Recommended PracticeRemainder with 7Try It! Simple Approach is to convert a string into number and perform the mod op
8 min read
Find (a^b)%m where 'a' is very large
Given three numbers a, b and m where 1<=b,m<=10^6 and 'a' may be very large and contains upto 10^6 digits. The task is to find (a^b)%m. Examples: Input : a = 3, b = 2, m = 4 Output : 1 Explanation : (3^2)%4 = 9%4 = 1 Input : a = 987584345091051645734583954832576, b = 3, m = 11 Output: 10Recomm
15+ min read
Find sum of modulo K of first N natural number
Given two integer N ans K, the task is to find sum of modulo K of first N natural numbers i.e 1%K + 2%K + ..... + N%K. Examples : Input : N = 10 and K = 2. Output : 5 Sum = 1%2 + 2%2 + 3%2 + 4%2 + 5%2 + 6%2 + 7%2 + 8%2 + 9%2 + 10%2 = 1 + 0 + 1 + 0 + 1 + 0 + 1 + 0 + 1 + 0 = 5.Recommended PracticeReve
9 min read
Count sub-arrays whose product is divisible by k
Given an integer K and an array arr[], the task is to count all the sub-arrays whose product is divisible by K.Examples: Input: arr[] = {6, 2, 8}, K = 4 Output: 4 Required sub-arrays are {6, 2}, {6, 2, 8}, {2, 8}and {8}.Input: arr[] = {9, 1, 14}, K = 6 Output: 1 Naive approach: Run nested loops and
15+ min read
Partition a number into two divisible parts
Given a number (as string) and two integers a and b, divide the string in two non-empty parts such that the first part is divisible by a and the second part is divisible by b. If the string can not be divided into two non-empty parts, output "NO", else print "YES" with the two parts. Examples: Input
15+ min read
Find power of power under mod of a prime
Given four numbers A, B, C and M, where M is prime number. Our task is to compute A raised to power (B raised to power C) modulo M. Example: Input : A = 2, B = 4, C = 3, M = 23Output : 643 = 64 so,2^64(mod 23) = 6 A Naive Approach is to calculate res = BC and then calculate Ares % M by modular expon
7 min read
Rearrange an array in maximum minimum form in O(1) extra space
Given a sorted array of positive integers, rearrange the array alternately i.e first element should be the maximum value, second minimum value, third-second max, fourth-second min and so on. Examples:Input: arr[] = {1, 2, 3, 4, 5, 6, 7} Output: arr[] = {7, 1, 6, 2, 5, 3, 4}Explanation: First 7 is th
8 min read
Subset with no pair sum divisible by K
Given an array of integer numbers, we need to find maximum size of a subset such that sum of each pair of this subset is not divisible by K. Examples : Input : arr[] = [3, 7, 2, 9, 1] K = 3 Output : 3 Maximum size subset whose each pair sum is not divisible by K is [3, 7, 1] because, 3+7 = 10, 3+1 =
7 min read
Number of substrings divisible by 6 in a string of integers
Given a string consisting of integers 0 to 9. The task is to count the number of substrings which when convert into integer are divisible by 6. Substring does not contain leading zeroes. Examples: Input : s = "606". Output : 5 Substrings "6", "0", "6", "60", "606" are divisible by 6. Input : s = "48
9 min read
Miscellaneous Practice Problems