Minimum number of operations to convert a given sequence into a Geometric Progression
Given a sequence of N elements, only three operations can be performed on any element at most one time. The operations are:
- Add one to the element.
- Subtract one from the element.
- Leave the element unchanged.
Perform any one of the operations on all elements in the array. The task is to find the minimum number of operations(addition and subtraction) that can be performed on the sequence, in order to convert it into a Geometric Progression. If it is not possible to generate a GP by performing the above operations, print -1.
Examples:
Input: a[] = {1, 1, 4, 7, 15, 33}
Output: The minimum number of operations are 4.
Steps:
- Keep a1 unchanged
- Add one to a2.
- Keep a3 unchanged
- Subtract one from a4.
- Subtract one from a5.
- Add one to a6.
The resultant sequence is {1, 2, 4, 8, 16, 32}
Input: a[] = {20, 15, 20, 15}
Output: -1
Approach The key observation to be made here is that any Geometric Progression is uniquely determined by only its first two elements (Since the ratio between each of the next pairs has to be the same as the ratio between this pair, consisting of the first two elements). Since only 3*3 permutations are possible. The possible combination of operations are (+1, +1), (+1, 0), (+1, -1), (-1, +1), (-1, 0), (-1, -1), (0, +1), (0, 0) and (0, -1). Using brute force all these 9 permutations and checking if they form a GP in linear time will give us the answer. The minimum of the operations which result in combinations which are in GP will be the answer.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void construct( int n, pair< double , double > ans_pair)
{
if (ans_pair.first == -1) {
cout << "Not possible" ;
return ;
}
double a1 = ans_pair.first;
double a2 = ans_pair.second;
double r = a2 / a1;
cout << "The resultant sequence is:\n" ;
for ( int i = 1; i <= n; i++) {
double ai = a1 * pow (r, i - 1);
cout << ai << " " ;
}
}
void findMinimumOperations( double * a, int n)
{
int ans = INT_MAX;
int c[] = { -1, 0, 1 };
int possibilities = 3;
int pos1 = -1, pos2 = -1;
for ( int i = 0; i < possibilities; i++) {
for ( int j = 0; j < possibilities; j++) {
double a1 = a[1] + c[i];
double a2 = a[2] + c[j];
int temp = abs (a1 - a[1]) + abs (a2 - a[2]);
if (a1 == 0 || a2 == 0)
continue ;
double r = a2 / a1;
for ( int pos = 3; pos <= n; pos++) {
double ai = a1 * pow (r, pos - 1);
if (a[pos] == ai) {
continue ;
}
else if (a[pos] + 1 == ai || a[pos] - 1 == ai) {
temp++;
}
else {
temp = INT_MAX;
break ;
}
}
if (temp < ans) {
ans = temp;
pos1 = a1;
pos2 = a2;
}
}
}
if (ans == -1) {
cout << "-1" ;
return ;
}
cout << "Minimum Number of Operations are " << ans << "\n" ;
pair< double , double > ans_pair = { pos1, pos2 };
construct(n, ans_pair);
}
int main()
{
double a[] = { 0, 7, 20, 49, 125 };
int n = sizeof (a) / sizeof (a[0]);
findMinimumOperations(a, n - 1);
return 0;
}
|
Java
import java.util.*;
class GFG
{
static class pair
{
double first, second;
public pair( double first, double second)
{
this .first = first;
this .second = second;
}
}
static void construct( int n, pair ans_pair)
{
if (ans_pair.first == - 1 )
{
System.out.print( "Not possible" );
return ;
}
double a1 = ans_pair.first;
double a2 = ans_pair.second;
double r = a2 / a1;
System.out.print( "The resultant sequence is:\n" );
for ( int i = 1 ; i <= n; i++)
{
int ai = ( int ) (a1 * Math.pow(r, i - 1 ));
System.out.print(ai + " " );
}
}
static void findMinimumOperations( double []a, int n)
{
int ans = Integer.MAX_VALUE;
int c[] = { - 1 , 0 , 1 };
int possibilities = 3 ;
int pos1 = - 1 , pos2 = - 1 ;
for ( int i = 0 ; i < possibilities; i++)
{
for ( int j = 0 ; j < possibilities; j++)
{
double a1 = a[ 1 ] + c[i];
double a2 = a[ 2 ] + c[j];
int temp = ( int ) (Math.abs(a1 - a[ 1 ]) + Math.abs(a2 - a[ 2 ]));
if (a1 == 0 || a2 == 0 )
continue ;
double r = a2 / a1;
for ( int pos = 3 ; pos <= n; pos++)
{
double ai = a1 * Math.pow(r, pos - 1 );
if (a[pos] == ai)
{
continue ;
}
else if (a[pos] + 1 == ai || a[pos] - 1 == ai)
{
temp++;
}
else
{
temp = Integer.MAX_VALUE;
break ;
}
}
if (temp < ans)
{
ans = temp;
pos1 = ( int ) a1;
pos2 = ( int ) a2;
}
}
}
if (ans == - 1 )
{
System.out.print( "-1" );
return ;
}
System.out.print( "Minimum Number of Operations are " + ans+ "\n" );
pair ans_pair = new pair( pos1, pos2 );
construct(n, ans_pair);
}
public static void main(String[] args)
{
double a[] = { 0 , 7 , 20 , 49 , 125 };
int n = a.length;
findMinimumOperations(a, n - 1 );
}
}
|
Python3
from sys import maxsize as INT_MAX
def construct(n: int , ans_pair: tuple ):
if ans_pair[ 0 ] = = - 1 :
print ( "Not possible" )
return
a1 = ans_pair[ 0 ]
a2 = ans_pair[ 1 ]
r = a2 / a1
print ( "The resultant sequence is" )
for i in range ( 1 , n + 1 ):
ai = a1 * pow (r, i - 1 )
print ( int (ai), end = " " )
def findMinimumOperations(a: list , n: int ):
ans = INT_MAX
c = [ - 1 , 0 , 1 ]
possibilities = 3
pos1 = - 1
pos2 = - 1
for i in range (possibilities):
for j in range (possibilities):
a1 = a[ 1 ] + c[i]
a2 = a[ 2 ] + c[j]
temp = abs (a1 - a[ 1 ]) + abs (a2 - a[ 2 ])
if a1 = = 0 or a2 = = 0 :
continue
r = a2 / a1
for pos in range ( 3 , n + 1 ):
ai = a1 * pow (r, pos - 1 )
if a[pos] = = ai:
continue
elif a[pos] + 1 = = ai or a[pos] - 1 = = ai:
temp + = 1
else :
temp = INT_MAX
break
if temp < ans:
ans = temp
pos1 = a1
pos2 = a2
if ans = = - 1 :
print ( "-1" )
return
print ( "Minimum number of Operations are" , ans)
ans_pair = (pos1, pos2)
construct(n, ans_pair)
if __name__ = = "__main__" :
a = [ 0 , 7 , 20 , 49 , 125 ]
n = len (a)
findMinimumOperations(a, n - 1 )
|
C#
using System;
class GFG
{
class pair
{
public double first, second;
public pair( double first, double second)
{
this .first = first;
this .second = second;
}
}
static void construct( int n, pair ans_pair)
{
if (ans_pair.first == -1)
{
Console.Write( "Not possible" );
return ;
}
double a1 = ans_pair.first;
double a2 = ans_pair.second;
double r = a2 / a1;
Console.Write( "The resultant sequence is:\n" );
for ( int i = 1; i <= n; i++)
{
int ai = ( int ) (a1 * Math.Pow(r, i - 1));
Console.Write(ai + " " );
}
}
static void findMinimumOperations( double []a, int n)
{
int ans = int .MaxValue;
int []c = { -1, 0, 1 };
int possibilities = 3;
int pos1 = -1, pos2 = -1;
for ( int i = 0; i < possibilities; i++)
{
for ( int j = 0; j < possibilities; j++)
{
double a1 = a[1] + c[i];
double a2 = a[2] + c[j];
int temp = ( int ) (Math.Abs(a1 - a[1]) + Math.Abs(a2 - a[2]));
if (a1 == 0 || a2 == 0)
continue ;
double r = a2 / a1;
for ( int pos = 3; pos <= n; pos++)
{
double ai = a1 * Math.Pow(r, pos - 1);
if (a[pos] == ai)
{
continue ;
}
else if (a[pos] + 1 == ai || a[pos] - 1 == ai)
{
temp++;
}
else
{
temp = int .MaxValue;
break ;
}
}
if (temp < ans)
{
ans = temp;
pos1 = ( int ) a1;
pos2 = ( int ) a2;
}
}
}
if (ans == -1)
{
Console.Write( "-1" );
return ;
}
Console.Write( "Minimum Number of Operations are " + ans+ "\n" );
pair ans_pair = new pair( pos1, pos2 );
construct(n, ans_pair);
}
public static void Main(String[] args)
{
double []a = { 0, 7, 20, 49, 125 };
int n = a.Length;
findMinimumOperations(a, n - 1);
}
}
|
Javascript
<script>
class pair
{
constructor(first, second)
{
this .first = first;
this .second = second;
}
}
function construct(n, ans_pair)
{
if (ans_pair.first == -1)
{
document.write( "Not possible" );
return ;
}
var a1 = ans_pair.first;
var a2 = ans_pair.second;
var r = a2 / a1;
document.write( "The resultant sequence is:<br>" );
for ( var i = 1; i <= n; i++)
{
var ai = parseInt(a1 * Math.pow(r, i - 1));
document.write(ai + " " );
}
}
function findMinimumOperations(a, n)
{
var ans = 1000000000;
var c = [-1, 0, 1];
var possibilities = 3;
var pos1 = -1, pos2 = -1;
for ( var i = 0; i < possibilities; i++)
{
for ( var j = 0; j < possibilities; j++)
{
var a1 = a[1] + c[i];
var a2 = a[2] + c[j];
var temp = (Math.abs(a1 - a[1]) +
Math.abs(a2 - a[2]));
if (a1 == 0 || a2 == 0)
continue ;
var r = a2 / a1;
for ( var pos = 3; pos <= n; pos++)
{
var ai = a1 * Math.pow(r, pos - 1);
if (a[pos] == ai)
{
continue ;
}
else if (a[pos] + 1 == ai ||
a[pos] - 1 == ai)
{
temp++;
}
else
{
temp = 1000000000;
break ;
}
}
if (temp < ans)
{
ans = temp;
pos1 = a1;
pos2 = a2;
}
}
}
if (ans == -1)
{
document.write( "-1" );
return ;
}
document.write( "Minimum Number of " +
"Operations are " + ans + "<br>" );
var ans_pair = new pair( pos1, pos2 );
construct(n, ans_pair);
}
var a = [ 0, 7, 20, 49, 125 ];
var n = a.length;
findMinimumOperations(a, n - 1);
</script>
|
Output:
Minimum Number of Operations are 2
The resultant sequence is:
8 20 50 125
Time Complexity : O(9*N)
Space Complexity: O(1)
Last Updated :
25 Apr, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...