Open In App

Winning Game by replacing numbers with factors (Brain Game)

Last Updated : 05 Mar, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Given 2 players A and B take turns alternatively to play a game in which they have N numbers on a paper. In one turn, a player can replace one of the numbers by any of its factors (except for 1 & the number itself). The player who is unable to make a move loses the game. Find the winner of the game if A starts the game and both play optimally.

Examples:

Input: nums = [5, 7, 3]
Output: B
Explanation: Since all the numbers are prime, so A will not be able to make the first move.

Input: nums = [2, 4, 7, 11]
Output: A
Explanation: In the first move A will replace 4 by 2, so the numbers will become [2, 2, 7, 11] now B will not be able to make a move since all the remaining numbers can only be divided by 1 or the number itself.

Approach: To solve the problem, follow the below idea:

In a game where all numbers are prime, Player A loses. If there’s only one composite number, Player A wins by replacing it with its prime factors. If there are two composite numbers with equal prime factors, Player A loses in optimal play. If the prime factors are unequal, Player A wins by choosing the number with more factors and matching the count. In general, if there are at least two numbers with unequal prime factors, Player A wins; otherwise, Player B wins.

Step-by-step algorithm:

  • To calculate the number of prime factors of each number we can run a loop for each number. Following are the steps to find the number of prime factors. Let the number be n and Initialize the count of prime factors for each number as 0, While n is divisible by 2, add the number of times it is divided by 2 to the count and divide n by 2.
  • After step 1, n must be odd. Now start a loop from i = 3 to the square root of n. While i divides n, add number of times that the number is divided to count and divide n by i. After i fails to divide n, increment i by 2 and continue. If n is a prime number and is greater than 2, then n will not become 1 by the above two steps. So add 1 to the count.
  • After finding the number of prime factors of each number we will store in an array and we will find the XOR value of all the numbers which we stored.
  • If the XOR value is zero that means, there are no 2 numbers which have different count of prime factors.
  • If the XOR is value is not zero, then Player A wins otherwise Player B wins.

Below is the implementation of the algorithm:

C++




// C++ Implementation
#include <bits/stdc++.h>
#include <iostream>
using namespace std;
 
// Function to check whether the number is prime or
// not
bool isPrime(int n)
{
    // Corner cases
    if (n <= 1)
        return false;
    if (n <= 3)
        return true;
 
    // This is checked so that we can skip
    // middle five numbers in below loop
    if (n % 2 == 0 || n % 3 == 0)
        return false;
 
    // Using concept of prime number
    // can be represented in form of
    // (6*n + 1) or(6*n - 1) hence
    // we have to go for every multiple of 6 and
    // prime number would always be 1 less or 1 more then
    // the multiple of 6.
    for (int i = 5; i * i <= n; i = i + 6)
        if (n % i == 0 || n % (i + 2) == 0)
            return false;
 
    return true;
}
int primeFactors(int n)
{
    // to store the count of prime factors
    int ans = 0;
    // Print the number of 2s that divide n
    while (n % 2 == 0) {
        ans++;
        n = n / 2;
    }
 
    // n must be odd at this point. So we can skip
    // one element (Note i = i +2)
    for (int i = 3; i <= sqrt(n); i = i + 2) {
        // While i divides n, print i and divide n
        while (n % i == 0) {
            ans++;
            n = n / i;
        }
    }
 
    // This condition is to handle the case when n
    // is a prime number greater than 2
    if (n > 2)
        ans++;
    return ans;
}
 
// Function to find which player will
// win
bool brainGame(vector<int> nums)
{
    vector<int> a(1005, 0);
    for (int i = 2; i <= 1000; i++) {
        if (!isPrime(i)) {
            a[i] = primeFactors(i) - 1;
        }
    }
    int x = 0;
    for (int i = 0; i < nums.size(); i++) {
        x = x ^ a[nums[i]];
    }
    if (x == 0)
        return false;
    return true;
}
 
// Driver code
int main()
{
 
    int n = 5;
    vector<int> nums = { 1, 4, 3, 4, 5 };
 
    // Function call
    if (brainGame(nums)) {
        cout << "A";
    }
    else {
        cout << "B";
    }
 
    return 0;
}


Java




import java.util.*;
 
public class Main {
 
    // Function to check whether the number is prime or not
    static boolean isPrime(int n) {
        // Corner cases
        if (n <= 1)
            return false;
        if (n <= 3)
            return true;
 
        // This is checked so that we can skip
        // middle five numbers in below loop
        if (n % 2 == 0 || n % 3 == 0)
            return false;
 
        // Using the concept of a prime number
        // can be represented in the form of
        // (6 * n + 1) or (6 * n - 1) hence
        // we have to go for every multiple of 6 and
        // prime number would always be 1 less or 1 more than
        // the multiple of 6.
        for (int i = 5; i * i <= n; i = i + 6)
            if (n % i == 0 || n % (i + 2) == 0)
                return false;
 
        return true;
    }
 
    static int primeFactors(int n) {
        // to store the count of prime factors
        int ans = 0;
        // Print the number of 2s that divide n
        while (n % 2 == 0) {
            ans++;
            n = n / 2;
        }
 
        // n must be odd at this point. So we can skip
        // one element (Note i = i + 2)
        for (int i = 3; i <= Math.sqrt(n); i = i + 2) {
            // While i divides n, print i and divide n
            while (n % i == 0) {
                ans++;
                n = n / i;
            }
        }
 
        // This condition is to handle the case when n
        // is a prime number greater than 2
        if (n > 2)
            ans++;
        return ans;
    }
 
    // Function to find which player will win
    static boolean brainGame(ArrayList<Integer> nums) {
        ArrayList<Integer> a = new ArrayList<>(Collections.nCopies(1005, 0));
        for (int i = 2; i <= 1000; i++) {
            if (!isPrime(i)) {
                a.set(i, primeFactors(i) - 1);
            }
        }
        int x = 0;
        for (int i = 0; i < nums.size(); i++) {
            x = x ^ a.get(nums.get(i));
        }
        return x != 0;
    }
 
    // Driver code
    public static void main(String[] args) {
        int n = 5;
        ArrayList<Integer> nums = new ArrayList<>(Arrays.asList(1, 4, 3, 4, 5));
 
        // Function call
        if (brainGame(nums)) {
            System.out.println("A");
        } else {
            System.out.println("B");
        }
    }
}


C#




using System;
using System.Collections.Generic;
 
public class MainClass {
    // Function to check whether the number is prime or not
    static bool IsPrime(int n)
    {
        // Corner cases
        if (n <= 1)
            return false;
        if (n <= 3)
            return true;
 
        // This is checked so that we can skip middle five
        // numbers in below loop
        if (n % 2 == 0 || n % 3 == 0)
            return false;
 
        // Using concept of prime number can be represented
        // in form of (6 * n + 1) or (6 * n - 1) hence we
        // have to go for every multiple of 6 and prime
        // number would always be 1 less or 1 more than the
        // multiple of 6.
        for (int i = 5; i * i <= n; i = i + 6)
            if (n % i == 0 || n % (i + 2) == 0)
                return false;
 
        return true;
    }
 
    // Function to count prime factors of a number
    static int PrimeFactors(int n)
    {
        // to store the count of prime factors
        int ans = 0;
        // Print the number of 2s that divide n
        while (n % 2 == 0) {
            ans++;
            n = n / 2;
        }
 
        // n must be odd at this point. So we can skip one
        // element (Note i = i + 2)
        for (int i = 3; i <= Math.Sqrt(n); i = i + 2) {
            // While i divides n, print i and divide n
            while (n % i == 0) {
                ans++;
                n = n / i;
            }
        }
 
        // This condition is to handle the case when n is a
        // prime number greater than 2
        if (n > 2)
            ans++;
        return ans;
    }
 
    // Function to find which player will win
    static bool BrainGame(List<int> nums)
    {
        int[] a = new int[1005];
        for (int i = 2; i <= 1000; i++) {
            if (!IsPrime(i)) {
                a[i] = PrimeFactors(i) - 1;
            }
        }
        int x = 0;
        foreach(int num in nums) { x ^= a[num]; }
        return x != 0;
    }
 
    // Driver code
    public static void Main(string[] args)
    {
        List<int> nums = new List<int>{ 1, 4, 3, 4, 5 };
 
        // Function call
        if (BrainGame(nums)) {
            Console.WriteLine("A");
        }
        else {
            Console.WriteLine("B");
        }
    }
}


Javascript




// Function to check whether the number is prime or not
function isPrime(n) {
    // Corner cases
    if (n <= 1)
        return false;
    if (n <= 3)
        return true;
 
    // This is checked so that we can skip
    // middle five numbers in below loop
    if (n % 2 === 0 || n % 3 === 0)
        return false;
 
    // Using the concept of prime number
    // can be represented in the form of
    // (6 * n + 1) or (6 * n - 1) hence
    // we have to go for every multiple of 6 and
    // the prime number would always be 1 less or 1 more than
    // the multiple of 6.
    for (let i = 5; i * i <= n; i = i + 6)
        if (n % i === 0 || n % (i + 2) === 0)
            return false;
 
    return true;
}
 
// Function to count prime factors
function primeFactors(n) {
    // to store the count of prime factors
    let ans = 0;
    // Print the number of 2s that divide n
    while (n % 2 === 0) {
        ans++;
        n = Math.floor(n / 2);
    }
 
    // n must be odd at this point. So we can skip
    // one element (Note i = i +2)
    for (let i = 3; i <= Math.sqrt(n); i = i + 2) {
        // While i divides n, print i and divide n
        while (n % i === 0) {
            ans++;
            n = Math.floor(n / i);
        }
    }
 
    // This condition is to handle the case when n
    // is a prime number greater than 2
    if (n > 2)
        ans++;
    return ans;
}
 
// Function to find which player will win
function brainGame(nums) {
    let a = new Array(1005).fill(0);
    for (let i = 2; i <= 1000; i++) {
        if (!isPrime(i)) {
            a[i] = primeFactors(i) - 1;
        }
    }
    let x = 0;
    for (let i = 0; i < nums.length; i++) {
        x = x ^ a[nums[i]];
    }
    if (x === 0)
        return false;
    return true;
}
 
// Driver code
function main() {
    let nums = [1, 4, 3, 4, 5];
 
    // Function call
    if (brainGame(nums)) {
        console.log("A");
    } else {
        console.log("B");
    }
}
 
// Call the main function
main();
//This code is contributed by utkarsh


Python3




# Python Implementation
 
import math
 
# Function to check whether the number is prime or not
def is_prime(n):
    if n <= 1:
        return False
    if n <= 3:
        return True
    if n % 2 == 0 or n % 3 == 0:
        return False
    for i in range(5, int(math.sqrt(n)) + 1, 6):
        if n % i == 0 or n % (i + 2) == 0:
            return False
    return True
 
# Function to calculate the number of prime factors
def prime_factors(n):
    ans = 0
    while n % 2 == 0:
        ans += 1
        n = n // 2
    for i in range(3, int(math.sqrt(n)) + 1, 2):
        while n % i == 0:
            ans += 1
            n = n // i
    if n > 2:
        ans += 1
    return ans
 
# Function to determine which player will win
def brain_game(nums):
    a = [0] * 1005
    # Pre-compute the prime factors for numbers from 2 to 1000
    for i in range(2, 1001):
        if not is_prime(i):
            a[i] = prime_factors(i) - 1
    x = 0
    # Calculate XOR of prime factors for each number in nums
    for num in nums:
        x = x ^ a[num]
    # If XOR result is 0, player B wins; otherwise, player A wins
    if x == 0:
        return False
    return True
 
# Main function
n = 5
nums = [1, 4, 3, 4, 5]
 
# Check the winner and print the result
if brain_game(nums):
    print("A")
else:
    print("B")
 
# This code is contributed by Tapesh(tapeshdu420)


Output

B






Time Complexity: O(N*sqrt(N)*logN)
Auxiliary Space: O(N)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads