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 A stones game problem solution

YASH PAL, 31 July 202430 November 2025

In this HackerRank A stones game problem solution Koga and Ryuho, new generation Athena’s saints, are training to improve their control over the cosmos. According to the ancient Masters, a saint’s power to control the cosmos strengthens, when one allows the energy of the universe to flow within the body and then concentrates it. This energy can even be used to explore objects.

Today’s training is based on a game, and the goal is to use as little cosmos as possible to win. Two saints play as follows:

Initially, there are N piles of stones; pile 1 has 1 stone, pile 2 has 2 stones, and so on. Thus, the ith pile has I stones. The saints take turns and in each turn, a saint must select a non-empty pile and destroy at least half of the stones in it. The winner is the saint who destroys the last available stone.

HackerRank A stones game problem solution

Problem solution in Python.

#!/usr/bin/env python3

import sys

from functools import lru_cache
@lru_cache(maxsize=None)
def grundy(n):
    if n==0:
        return 0
    S = [grundy(m) for m in range(n//2+1)]
    g = 0
    while g in S:
        g += 1
    return g

def main():
    T = int(sys.stdin.readline())
    for _ in range(T):
        N = int(sys.stdin.readline())
        L = N.bit_length()
        G = 1  # for the single 1
        if N&1==0:  # value L if appears an odd nb of times (i.e. N even)
            G ^= L
        D = 1
        if G!=1:
            GA = 1<<(G.bit_length()-1)
            A = 1<<(GA-1)
            GB = G^GA
            B = min((1<<GB)-1, A>>1) if GB else 0
            D = A-B
        sys.stdout.write('%dn' % D)

main()

Problem solution in Java.

import java.io.*;
import java.util.Scanner;

public class AStoneGame {

    private static int log2(int val) {
        return 31 - Integer.numberOfLeadingZeros(val);
    }

    private static int solve(int val) {
        if (val <= 1) return val;

        int maxNim = log2(val) + 1;
        int maxNimCnt = val - (1 << (maxNim - 1)) + 1;

        if (maxNimCnt % 2 == 0) return 1;

        int nimToReduce = 1 << log2(maxNim);

        int targetNim = maxNim;
        targetNim = targetNim ^ nimToReduce;
        targetNim = targetNim ^ 1;

        int targetValueToReduce = (1 << (nimToReduce - 1));
        int reduceTo = (1 << (targetNim)) - 1;
        int minCut = targetValueToReduce / 2 + targetValueToReduce % 2;

        return targetValueToReduce - minCut >= reduceTo ? targetValueToReduce - reduceTo : minCut;
    }

    public static void main(String[] params) throws Exception {
        Scanner scanner = new Scanner(System.in);
        OutputWriter writer = new OutputWriter(System.out);

        int t = Integer.valueOf(scanner.nextLine());
        for (int i = 0; i < t; ++i) {
            writer.printInt(solve(Integer.valueOf(scanner.nextLine())));
            writer.newLine();
        }
        writer.flush();
    }

    static class OutputWriter {
        private static final int outBufferSize = 1 << 25;

        private PrintStream out;
        private byte[] outBuffer = new byte[outBufferSize];
        private int outByteCnt = 0;
        private byte[] intToStringBuffer = new byte[11];

        public OutputWriter(PrintStream out) {
            this.out = out;
        }

        public void flush() {
            out.write(outBuffer, 0, outByteCnt);
        }

        public void printInt(int val) {
            int outBufferPos = intToStringBuffer.length;
            if (val == 0) {
                outBufferPos = intToStringBuffer.length - 1;
                intToStringBuffer[outBufferPos] = '0';
            } else {
                boolean minus = false;
                if (val < 0) {
                    minus = true;
                    val = -val;
                }
                while (val != 0) {
                    byte digitChar = (byte)(val % 10 + '0');
                    intToStringBuffer[--outBufferPos] = digitChar;
                    val = val / 10;
                }
                if (minus) intToStringBuffer[--outBufferPos] = '-';
            }

            System.arraycopy(intToStringBuffer, outBufferPos, outBuffer, outByteCnt, intToStringBuffer.length - outBufferPos);
            outByteCnt += intToStringBuffer.length - outBufferPos;
        }

        public void newLine() {
            outBuffer[outByteCnt++] = 'n';
        }
    }
}

Problem solution in C++.

#include <cstdio>
#include<iostream>
#include<cassert>
using namespace std;
int tab[32][32];
inline void compute(){
    register int i, j, sfx, tfx;
    for (i = 1; i <= 31; ++i)
        for (j = 0; j < i; ++j) {

            sfx = 1 << (i - 1);
            if (j == 0){
                tab[i][j] = sfx;
            } else if (i - j == 1) {
                tab[i][j] = sfx >> 1;
            } else {
                tfx = (1 << j) - 1;
                tab[i][j] = sfx - tfx;
            }
        }
}
const int TEST = 10;
int main() {
    compute();
    int t;
    cin >> t;
    assert(1 <= t && t <= 1e6);
    register int N, X, tot, targ, px, i, ans, tx, mx;
    while (scanf("%d", &N) != EOF) {
        assert(1 <= N && N <= 1e9);
        if (N == 1 || N == 2) {printf("1n");continue;}
        X = 1, px = 1;
        while(X <= N) {X <<= 1; ++px;}
        X >>= 1, --px;
        tot = N - X + 1;
        if (tot & 1) {
            targ = 1 ^ px, ans = X - 1, mx = px - (tot == 1);
            for (i = 2; i <= mx; ++i) {
                tx = targ ^ i;
                if (tx < i) {
                    if (ans == -1 || ans > tab[i][tx])
                        ans = tab[i][tx];
                }
            }
            printf("%dn", ans);
        }
        else printf("1n");
    }
    return 0;
}

Problem solution in C.

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

int main() {
    int t;
    scanf("%dn", &t);
    for (int i = 0; i < t; i++) {
        int n;
        scanf("%dn", &n);
        int nimber = 1;
        int topnimber = floor(log2(n)) + 1;
        if (!(n&1)) nimber ^= topnimber;
        int changenimber = 1<< (int)floor(log2(nimber));
        int tonumber = changenimber ^ nimber;
        int minchangepile = 1<<(changenimber - 1);
        int maxtopile = (1<<tonumber) - 1;
        if (maxtopile * 2 > minchangepile) maxtopile = minchangepile / 2;
        int answer = minchangepile - maxtopile;
        printf("%dn", answer);
    }
    return 0;
}

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