Find a positive number M such that gcd(N^M, N&M) is maximum

Given a number N, the task is to find a positive number M such that gcd(N^M, N&M) is the maximum possible and M < N. The task is to print the maximum gcd thus obtained.

Examples:

Input: N = 5 
Output: 7 
gcd(2^5, 2&5) = 7 

Input: N = 15 
Output: 5 

Approach: There are two cases which need to be solved to get the maximum gcd possible.

  • If a minimum of one bit is not set in the number, then M will be a number whose bits are flipped at every position of N. And after that get the maximum gcd.
  • If all bits are set, then the answer will the maximum factor of that number except the number itself.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to implement above approach
  
#include <bits/stdc++.h>
using namespace std;
  
// Recursive function to count
// the number of unset bits
int countBits(int n)
{
    // Base case
    if (n == 0)
        return 0;
  
    // unset bit count
    else
        return !(n & 1) + countBits(n >> 1);
}
  
// Function to return the max gcd
int maxGcd(int n)
{
  
    // If no unset bits
    if (countBits(n) == 0) {
        // Find the maximum factor
        for (int i = 2; i * i <= n; i++) {
            // Highest factor
            if (n % i == 0) {
                return n / i;
            }
        }
    }
    else {
  
        int val = 0;
        int power = 1;
        int dupn = n;
  
        // Find the flipped bit number
        while (n) {
            // If bit is not set
            if (!(n & 1)) {
                val += power;
            }
  
            // Next power of 2
            power = power * 2;
  
            // Right shift the number
            n = n >> 1;
        }
  
        // Return the answer
        return __gcd(val ^ dupn, val & dupn);
    }
  
    // If a prime number
    return 1;
}
  
// Driver Code
int main()
{
    // First example
    int n = 5;
    cout << maxGcd(n) << endl;
  
    // Second example
    n = 15;
    cout << maxGcd(n) << endl;
  
    return 0;
}

chevron_right


PHP

filter_none

edit
close

play_arrow

link
brightness_4
code

<?php
// PHP program to implement above approach 
  
// Recursive function to count 
// the number of unset bits 
function countBits($n
{
    // Base case 
    if ($n == 0) 
        return 0; 
  
    // unset bit count 
    else
        return !($n & 1) + 
                 countBits($n >> 1); 
  
// Recursive function to return
// gcd of a and b 
function gcd($a, $b
  
    // Everything divides 0 
    if ($a == 0) 
        return $b
    if ($b == 0) 
        return $a
  
    // base case 
    if($a == $b
        return $a
      
    // a is greater 
    if($a > $b
        return gcd($a - $b , $b ); 
  
    return gcd($a , $b - $a ); 
  
// Function to return the max gcd 
function maxGcd($n
  
    // If no unset bits 
    if (countBits($n) == 0) 
    
          
        // Find the maximum factor 
        for ($i = 2; $i * $i <= $n; $i++) 
        
              
            // Highest factor 
            if ($n % $i == 0) 
            
                return floor($n / $i); 
            
        
    
    else 
    
        $val = 0; 
        $power = 1; 
        $dupn = $n
  
        // Find the flipped bit number 
        while ($n
        
              
            // If bit is not set 
            if (!($n & 1))
            
                $val += $power
            
  
            // Next power of 2 
            $power = $power * 2; 
  
            // Right shift the number 
            $n = $n >> 1; 
        
  
        // Return the answer 
        return gcd($val ^ $dupn, $val & $dupn); 
    
  
    // If a prime number 
    return 1; 
  
// Driver Code 
  
// First example 
$n = 5; 
echo maxGcd($n), "\n"
  
// Second example 
$n = 15; 
echo maxGcd($n), "\n"
  
// This code is contributed by Ryuga
?>

chevron_right


Output:

7
5


My Personal Notes arrow_drop_up