Skip to content
Programmingoneonone
Programmingoneonone

Learn everything about programming

  • Home
  • CS Subjects
    • Internet of Things (IoT)
    • Digital Communication
    • Human Values
    • Cybersecurity
  • Programming Tutorials
    • C Programming
    • Data structures and Algorithms
    • 100+ Java Programs
    • 100+ C Programs
  • HackerRank Solutions
    • HackerRank Algorithms Solutions
    • HackerRank C problems solutions
    • HackerRank C++ problems solutions
    • HackerRank Java problems solutions
    • HackerRank Python problems solutions
Programmingoneonone
Programmingoneonone

Learn everything about programming

HackerRank Stone Game problem solution

YASH PAL, 31 July 202430 November 2025

In this HackerRank Stone Game problem solution, Alice and Bob are playing the game of Nim with N piles of stones with sizes P0, P1,…., Pn-1. If Alice plays first, she loses if and only if the ‘xor sum’ (or ‘Nim sum’) of the piles is zero.

Since Bob already knows who will win (assuming optimal play), he decides to cheat by removing some stones in some piles before the game starts. However, to reduce the risk of suspicion, he must keep at least one pile unchanged. Your task is to count the number of ways Bob can remove the stones to force Alice into losing the game. Since the number can be very large, output the number of ways modulo 10 to power 9 plus 7. Assume that both players will try to optimize their strategy and try to win the game.

HackerRank Stone Game problem solution

Problem solution in Python.

import operator as op
import functools as ft
from sys import stderr
MOD = 1000000007

def readcase():
    npiles = int(input())
    piles = [int(fld) for fld in input().split()]
    assert npiles == len(piles)
    return piles

def numsolns(piles):
    return (numunrestrictedsolns(piles) - 
            numunrestrictedsolns([pile-1 for pile in piles if pile > 1])) % MOD

def numunrestrictedsolns(piles, MOD=MOD):
    if len(piles) == 0:
        return 1
    xorall = ft.reduce(op.xor, piles)
    leftmost = ft.reduce(op.or_, piles).bit_length() - 1
    rightmost = max(0, xorall.bit_length() - 1)
    ans = 0
    for first1 in range(rightmost, leftmost+1):
        premult = 1
        matchbit = 1 << first1
        for i, bigalt in enumerate(piles):
            if bigalt & matchbit != 0:
                even = 1
                odd = 0
                for pile in piles[i+1:]:
                    neweven = (1 + (pile & ~-matchbit)) * even
                    newodd = (1 + (pile & ~-matchbit)) * odd
                    if pile & matchbit != 0:
                        neweven += matchbit * odd
                        newodd += matchbit * even
                    even, odd = neweven % MOD, newodd % MOD
                ans += (even if xorall & matchbit != 0 else odd) * premult % MOD
            premult = (premult * ((bigalt & ~-matchbit) + 1)) % MOD
    if xorall == 0:
        ans += 1
    return ans % MOD

print(numsolns(readcase()))

Problem solution in Java.

import java.io.*;
import java.math.*;
import java.text.*;
import java.util.*;
import java.util.regex.*;

public class Solution {

  static final long MODULO = 1_000_000_007;
  static int[] mi;

  static int solve(int n, int k) {
    int[][] vx = new int[n+1][32];
    for (int i = 0; i <= 31; i++) {
      vx[0][i] = 0;
    }
    
    int[][][] dp = new int[n+1][32][2];
    dp[0][0][0] = 1;

    for (int i = 1; i <= n; i++) {
      for (int j = 0; j < 31; j++) {
        vx[i][j] = (vx[i-1][j] ^ (mi[i]&(1<<j)));
      }
    }

    boolean[] valid = new boolean[32];
    valid[31] = true;

    for (int i = 30; i >= 0; i--) {
      valid[i] = valid[i+1] && (vx[n][i] == (k & (1<<i)));
    }

    for (int i = 1; i <= n; i++) {
      for (int j = 0; j < 31; j++) {
        for (int kj = 0; kj < 2; kj++) {
          if (dp[i-1][j][kj] == 0) continue;

          for (int k1 = 0; k1 < 31; k1++) {
            if ((mi[i] & (1<<(k1))) != 0) {
              int small, tmpj, tmpkj;

              if (k1 > j) {
                small = j;
                tmpj = k1;
                tmpkj = (vx[i-1][k1] != 0 ? 1 : 0);
              } else {
                small = k1;
                tmpj = j;

                if (k1 == j) {
                  tmpkj = kj;
                } else {
                  tmpkj = kj^((mi[i] & (1<<j)) != 0 ? 1 : 0);
                }
              }

              dp[i][tmpj][tmpkj] = (int)((dp[i][tmpj][tmpkj] + ((long) dp[i-1][j][kj]) * (1<<small)) % MODULO);
            }
          }
        }
      }
    }

    int res = 0;

    for(int i = 30; i >= 0; i--) {
      if (valid[i+1]) {
        res = (int) ((res + dp[n][i][(k & (1<<i)) != 0 ? 1 : 0]) % MODULO);
      } else {
        break;
      }
    }

    return res;
  }
  
  public static void main(String[] args) throws IOException {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    BufferedWriter bw = new BufferedWriter(new FileWriter(System.getenv("OUTPUT_PATH")));

    StringTokenizer st = new StringTokenizer(br.readLine());
    int n = Integer.parseInt(st.nextToken());
    mi = new int[n+1];

    st = new StringTokenizer(br.readLine());
    for (int i = 1; i <= n; i++) {
      int pItem = Integer.parseInt(st.nextToken());
      mi[i] = pItem + 1;
    }

    int result = solve(n, 0);

    for(int i = 1; i <= n; i++) {
      mi[i]--;
    }
    result = (int)((result + MODULO - solve(n, 0)) % MODULO);
    
    bw.write(String.valueOf(result));
    bw.newLine();

    bw.close();
    br.close();
  }
}

Problem solution in C++.

#include<stdio.h>
#include<string.h>

typedef long long LL;
const int MODULO = 1000000007, N = 120;
int dp[N][32][2], vx[N][32], valid[32], mi[N];

int solve(int n,int k) {
    for(int i = 0;i <= 31; i++) vx[0][i] = 0;

        memset(dp,0,sizeof(dp));
        dp[0][0][0] = 1;

        for(int i = 1; i <= n; i++)
            for(int j = 0; j < 31; j++)
                vx[i][j] = (vx[i-1][j] ^ (mi[i]&(1<<j)));

        valid[31] = 1;

        for(int i = 30; i >= 0; i--)
            valid[i] = valid[i+1] && (vx[n][i] == (k & (1<<i)));

        for(int i = 1; i <= n; i++)
            for(int j = 0; j < 31; j++)
                for(int kj = 0; kj < 2; kj++) {
                    if (dp[i-1][j][kj] == 0) continue;

                    for(int k = 0; k < 31; k++)
                        if (mi[i] & (1<<(k))) {
                            int small, tmpj, tmpkj;

                            if (k > j) {
                                small = j;
                                tmpj = k;
                                tmpkj = (vx[i-1][k] ? 1 : 0);
                            } else {
                                small = k;
                                tmpj = j;

                                if (k == j)
                                    tmpkj = kj;
                                else
                                    tmpkj = kj^((mi[i] & (1<<j)) ? 1 : 0);
                            }

                            dp[i][tmpj][tmpkj] = (dp[i][tmpj][tmpkj] + ((LL) dp[i-1][j][kj]) * (1<<small)) % MODULO;
                        }
                }

        int res = 0;

        for(int i = 30; i >= 0; i--)
            if (valid[i+1])
                res = (res + dp[n][i][(k & (1<<i)) ? 1 : 0]) % MODULO;
            else break;

        return res;
}

int main() {
    int n, k = 0, res;

    scanf("%d", &n);

    for(int i = 1; i <= n; i++) {
        scanf("%d", &mi[i]);
        mi[i]++;
    }

    res = solve(n,k);

    for(int i = 1; i <= n; i++) mi[i]--;
    res = (res + MODULO - solve(n,k)) % MODULO;
    printf("%dn", res);

    return 0;
}

Problem solution in C.

#include <assert.h>
#include <limits.h>
#include <math.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MOD 1000000007

char* readline();
char** split_string(char*);

/*
 * Complete the stoneGame function below.
 */

long betterStoneGame(int p_count, int* p){
    long total = 0;
    long currp[p_count];
    for(int i = 0; i < p_count; i++){
        currp[i] = p[i];
    }

    long invtwopower[32];
    invtwopower[0] = 1;
    for(int i = 0; i < 31; i++){
        invtwopower[i + 1] = (invtwopower[i]*500000004)%MOD;
    }

    int addall0 = 1;
    for(int i = 31; i >= 0; i--){
        long numi0 = 1;
        long numi1 = 0;
        long allabove0 = 1;
        long allabove1 = 0;
        int numabove = 0;
        for(int j = 0; j < p_count; j++){
            long oldi0 = numi0;
            long oldi1 = numi1;
            long oldabove0 = allabove0;
            long oldabove1 = allabove1;
            if(((currp[j]>>i) & 1) == 1){
                numi0 = ((1<<i)*oldi0 + (currp[j] + 1 - (1<<i))*oldi1)%MOD;
                numi1 = ((1<<i)*oldi1 + (currp[j] + 1 - (1<<i))*oldi0)%MOD;
                allabove0 = ((currp[j] + 1 - (1<<i))*oldabove1)%MOD;
                allabove1 = ((currp[j] + 1 - (1<<i))*oldabove0)%MOD;
                numabove++;
                currp[j] -= (1<<i);
            }
            else{
                numi0 = ((currp[j] + 1)*numi0)%MOD;
                numi1 = ((currp[j] + 1)*numi1)%MOD;
                allabove0 = ((currp[j] + 1)*allabove0)%MOD;
                allabove1 = ((currp[j] + 1)*allabove1)%MOD;
            }
        }
        
        if((numabove & 1) == 1){
            total = (total + numi0*invtwopower[i])%MOD;
            addall0 = 0;
            break;
        }
        else{
            total = (total + ((numi0  + MOD - allabove0)*invtwopower[i]))%MOD;
        }
    }
    total = (total + addall0)%MOD;
    return total;
}

long stoneGame(int p_count, int* p) {
    int *subp = malloc(p_count*sizeof(int));
    for(int i = 0; i < p_count; i++){
        subp[i] = p[i] - 1;
    }
    return (betterStoneGame(p_count, p) + MOD  - betterStoneGame(p_count, subp))%MOD;
}

int main()
{
    FILE* fptr = fopen(getenv("OUTPUT_PATH"), "w");

    char* p_count_endptr;
    char* p_count_str = readline();
    int p_count = strtol(p_count_str, &p_count_endptr, 10);

    if (p_count_endptr == p_count_str || *p_count_endptr != '') { exit(EXIT_FAILURE); }

    char** p_temp = split_string(readline());

    int* p = malloc(p_count * sizeof(int));

    for (int p_itr = 0; p_itr < p_count; p_itr++) {
        char* p_item_endptr;
        char* p_item_str = *(p_temp + p_itr);
        int p_item = strtol(p_item_str, &p_item_endptr, 10);

        if (p_item_endptr == p_item_str || *p_item_endptr != '') { exit(EXIT_FAILURE); }

        *(p + p_itr) = p_item;
    }

    long result = stoneGame(p_count, p);

    fprintf(fptr, "%ldn", result);

    fclose(fptr);

    return 0;
}

char* readline() {
    size_t alloc_length = 1024;
    size_t data_length = 0;
    char* data = malloc(alloc_length);

    while (true) {
        char* cursor = data + data_length;
        char* line = fgets(cursor, alloc_length - data_length, stdin);

        if (!line) { break; }

        data_length += strlen(cursor);

        if (data_length < alloc_length - 1 || data[data_length - 1] == 'n') { break; }

        size_t new_length = alloc_length << 1;
        data = realloc(data, new_length);

        if (!data) { break; }

        alloc_length = new_length;
    }

    if (data[data_length - 1] == 'n') {
        data[data_length - 1] = '';
    }
    if(data[data_length - 1] != ''){
        data_length++;
        data = realloc(data, data_length);
        data[data_length - 1] = '';
    }

    data = realloc(data, data_length);

    return data;
}

char** split_string(char* str) {
    char** splits = NULL;
    char* token = strtok(str, " ");

    int spaces = 0;

    while (token) {
        splits = realloc(splits, sizeof(char*) * ++spaces);
        if (!splits) {
            return splits;
        }

        splits[spaces - 1] = token;

        token = strtok(NULL, " ");
    }

    return splits;
}

Algorithms coding problems solutions AlgorithmsHackerRank

Post navigation

Previous post
Next post

Are you a student and stuck with your career or worried about real-time things, and don't know how to manage your learning phase? Which profession to choose? and how to learn new things according to your goal, and land a dream job. Then this might help to you.

Hi My name is YASH PAL, founder of this Blog and a Senior Software engineer with 5+ years of Industry experience. I personally helped 40+ students to make a clear goal in their professional lives. Just book a one-on-one personal call with me for 30 minutes for 300 Rupees. Ask all your doubts and questions related to your career to set a clear roadmap for your professional life.

Book session - https://wa.me/qr/JQ2LAS7AASE2M1

Pages

  • About US
  • Contact US
  • Privacy Policy

Follow US

  • YouTube
  • LinkedIn
  • Facebook
  • Pinterest
  • Instagram
©2026 Programmingoneonone | WordPress Theme by SuperbThemes