Power with divide & conquer algorithm - algorithm

i want to find for calculating X^46, how many multiplication occurs with optimal D&C approach for calculating Power.
I think this is the best optimal code for calculating power with divide & conquer approach.
int power(int x, unsigned int y)
{
int temp;
if( y == 0)
return 1;
temp = power(x, y/2);
if (y%2 == 0)
return temp*temp;
else
return x*temp*temp;
}
in one note wrote for calculating X^46 with optimal Power code in D&C we need 8 multiplication, but in my code there is 10. anyone correct me?
Edit:
the last code is:
int power(int x, unsigned int y)
{
int temp;
if( y == 0)
return 1;
if( y ==1)
return x;
temp = power(x, y/2);
if (y%2 == 0)
return temp*temp;
else
return x*temp*temp;
}

You left out the optimizing base case of
if (y==1)
return x
and instead require extra multiplications from
temp = power(x, 0)
return x * temp * temp
The extra pair of multiplications come from the unnecessary final recursive call.

You have redundant multiplies due to not earlying out when y==1.
When y==1, you execute the last line:
return x*temp*temp;
which simplifies to:
return x*1*1;
Adding a special case for y==1 will get rid of the additional 2 multiplies.

int power(int x, unsigned int y)
{
int temp;
if( y ==1)
return x;
if (y%2 == 0){
temp = power(x, y/2);
return temp*temp;
}
else{
temp = power(x, (y-1)/2);
return x*temp*temp;
}
}

Best way to do it using the divide and conquer strategy. it will take O(log N) time to complete the execution. It will work for negative exponential also.
I'm doing this in C++:
#include <iostream>
using namespace std;
float power(int a, int b)
{
if (b == 0)
{
return 1;
}
else
{
float temp = power(a, b / 2);
if (b > 0)
{
if (b % 2 == 0)
{
return temp * temp;
}
else
{
return a * temp * temp;
}
}
else
{
return 1/power(a,-b);
}
}
}
int main()
{ int a , b ;
cout<<"Enter a Number:";cin>>a; cout<<"Enter its exponential:";cin>>b;
cout << power(a, b);
}
Output:
Output will be as follow

Related

Please explain this code for modular exponential

here x can be negative
i am not able to understand that why we have written d+x in if(x<0) condition and why we have taken modulo ans%d at last since we have already taken modulo with d while finding ans inside if-else condition
public class Solution {
public int pow(int x, int n, int d) {
long ans;
if(x==0) return 0;
if(n==0) return 1;
if(x<0) return pow(d+x,n,d);
long temp = pow(x,n/2,d);
if(n%2==0)
ans = ((temp%d)*(temp%d))%d;
else
ans = ((((x%d)*(temp%d))%d)*(temp%d))%d;
return (int)ans%d;
}
}
From definition of modular exponentiation,
c = xn % d where 0 <= c < d
When x < 0, the answer returned can be negative. So by changing x to x+d,
if(x<0) return pow(d+x,n,d);
we are trying to avoid negative answer as solution.
At the last you don't need to perform modulo again,
(int)ans;
However, you can altogether ignore the x < 0 case by changing last line to ,
return (int)(ans+d)%d
Code,
public class Solution {
public int pow(int x, int n, int d) {
long ans;
if(x==0) return 0;
if(n==0) return 1;
long temp = pow(x,n/2,d);
if(n%2==0)
ans = ((temp%d)*(temp%d))%d;
else
ans = ((((x%d)*(temp%d))%d)*(temp%d))%d;
return (int)(ans+d)%d;
}
}

Find the maximum number of pieces a rod can be cut

Here is the complete problem statement:
Given a rope of length n, you need to find the maximum number of pieces
you can make such that the length of every piece is in set {a, b, c} for
the given three values a, b, c
I know that the optimal solution can be achieved through Dynamic Programming, however, I have not learned that topic yet and I need to solve this problem recursively. With recursion, the main thing is to identify a subproblem and that's what I'm mainly having difficulty with doing. Can anyone give me an intuitive way to think of this problem? Sort of like a higher level description of the recursion if that makes sense. Is there an easier problem similar to this that I can try first that would help me solve this?
Thanks in advance.
It's already quite simple, with recursion we can just check all posibilities, in one step we can either cut away a piece of length a, b, or c so from problem of size n we get sup-problem of smaller size n-x
Of course we need a base case, so when n=0 we have succeeded so we can return 0, in case of n < 0 we have failed so we can return some negative infinity constant
Sample pseudo-code:
int solve(int n){
if(n < 0) return -123456789; //-Infinity
if(n == 0) return 0;
return 1 + max(solve(n-a), solve(n-b), solve(n-c));
}
going to dynamic programming is as simple as setting up memo lookup table
int solve(int n){
if(n < 0) return -123456789; //-Infinity
if(n == 0) return 0;
if(n in memo)return memo[n]
return memo[n] = 1 + max(solve(n-a), solve(n-b), solve(n-c));
}
int maxcut(int n, int a,int b,int c)
{
if(n==0) return 0;
if(n<0) return 1;
int result = max( maxcut(n-a,a,b,c), maxcut(n-b,a,b,c), maxcur(n-c,a,b,c));
if(res == -1) return -1;
return(result+1)
}
The way we should tackle the recursion problem is:
Finding the recursion case (Finding the subproblems)
Finding the base case (The last subproblem case we cannot break in subproblems)
Specific to this problem :
Recursion case: Cutting rope we all the possible values till we cannot break it further smaller subproblem.
Base case: a. It can be completely cut. (valid try)
b.It can't be completely cut. (invalid try)
int maxcut(int n, int a,int b,int c)
{
if(n==0) return 0; //base case a.
if(n<0) return -1; //base case b.
int result = max( maxcut(n-a,a,b,c), maxcut(n-b,a,b,c), maxcur(n-c,a,b,c)); //subproblems for all the cases
if(res == -1) return -1; // boundry coundtion
return(result+1); //to count the valid conditions and return to parent
}
here is the complete code for your problem
#include <iostream>
using namespace std;
int max(int a, int b, int c)
{
if (a > b)
{
if (a > c)
{
return a;
}
else
{
return c;
}
}
else
{
if (b > c)
{
return b;
}
else
{
return c;
}
}
}
int maxpiece(int l, int a, int b, int c)
{
int r;
if (l == 0)
{
return 0;
}
if (l<0)
{
return -1;
}
r = max(maxpiece(l-a, a, b, c), maxpiece(l-b, a, b, c), maxpiece(l-c, a, b, c));
if (r == -1)
return -1;
return r + 1;
}
int main()
{
int lenth;
cout << "enter rope lenth ";
cin >> lenth;
int p1, p2, p3;
cout << endl
<< "enter the only three parameters in which rope can be cut ";
cin >> p1 >> p2 >> p3;
cout << endl
<<"ans = "<< maxpiece(lenth, p1, p2, p3);
}
int cutRope(int n, int a, int b, int c){
// Base cases
if(n == 0) return 0;
if(n < 0) return -1;
int res = max(max(cutRope(n - a, a, b, c), cutRope(n - b, a, b, c)), cutRope(n - c, a, b, c));
if(res == -1) return -1;
return res + 1;
}
int main() {
cout << cutRope(23, 11, 9, 12) << endl;
return 0;
}

Corner cases while calculating pow(x,n)%d

I've come up with a working code for the above problem, for both positive and negative values of x. And the answers for the majority of situations is correct, however the code fails at a corner case and I can't seem to find what the issue is! What condition am I missing:`
int pow(int x, int n, int d) {
int i=0,rem=1;
long long l;
if(x==0)
{
return 0;
}
if(x==1)
{
return 1;
}
if(n==0)
{
return 1;
}
x=x%d;
if(n%2==0||n==0)
{
l = ((pow(x,n/2,d))*(pow((x),n/2,d)))%d;
}
else
{
l = ((x)*(pow(x,(n-1)/2,d))*(pow((x),(n-1)/2,d)))%d;
}
if(x<0 && n%2!=0)
{
return d+l;
}
else
{
return l;
}
}
`
The case at which the code gives wrong ans:
A: 71045970
B : 41535484
C : 64735492
My Output: 12942068
Actual Output:20805472
Here is the simplified version of yours.
int pow(int x, int n, int d) {
long long l;
if(n==0)
{
return 1;
}
if(n%2==0)
{
l = (long long)pow(x,n/2,d);
return (int)((l * l) % (long long)d);
}
else
{
//check negative value of x, and make it positive, so that negative values never come in result
if (x < 0) {
x += d;
}
return (int)(((long long)x * (long long)pow(x,n-1,d)) % (long long)d);
}
}
I think your code is logically correct but there exists a data overflow problem on int data type if the modulo d value is large enough.
eg. (pow(x,n/2,d))*(pow((x),n/2,d)) here two big int value multiplication can result in datatype overflow.

Dynamic Programming Altogorithm

I'm trying to construct an algorithm that runs at O(nb) time with the following input/question:
input: an array A[1..n] of n different integers and an integer b (i am assuming that the numbers in A are sequential, starting at 1 ending at n, i.e. for n=4 A[1,2,3,4].
question: in how many ways can b be written as the sum of elements of the array when elements in A[] can only be used once?
I've kind of hit a wall on this one. I'm looking for some kind of recursive solution, but I don't see how to avoid using repeat numbers. Like, for instance, if we started at 1 and stored all the ways to make one (just 1) then 2 (just 2) then three (3 or 2+1) etc, it shouldn't be hard to see how many ways we can make larger numbers. But if, for instance, we take 5, we will see that it can be broken into 4+1, and 4 can be further broken down into 3+1, so then we would see 2 solutions (4+1, and 3+1+1), but one of those has a repeat of a number. Am I missing something obvious? Thanks so much!
Recursive and dynamic solutions in C:
#include <stddef.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
typedef unsigned char uchar;
typedef unsigned int uint;
typedef struct tAddend
{
struct tAddend* pPrev;
uint Value;
} tAddend;
void findRecursiveSolution(uint n, uint maxAddend, tAddend* pPrevAddend)
{
uint i;
for (i = maxAddend; ; i--)
{
if (n == 0)
{
while (pPrevAddend != NULL)
{
printf("+%u", pPrevAddend->Value);
pPrevAddend = pPrevAddend->pPrev;
}
printf("\n");
return;
}
if (n >= i && i > 0)
{
tAddend a;
a.pPrev = pPrevAddend;
a.Value = i;
findRecursiveSolution(n - i, i - 1, &a);
}
if (i <= 1)
{
break;
}
}
}
void printDynamicSolution(uchar** pTable, uint n, uint idx, uint sum, tAddend* pPrevAddend)
{
uchar el = pTable[idx][sum];
assert((el != 0) && (el != 5) && (el != 7));
if (el & 2) // 2,3,6 - other(s)
{
printDynamicSolution(pTable,
n,
idx - 1,
sum,
pPrevAddend);
}
if (el & 4) // self + other(s)
{
tAddend a;
a.pPrev = pPrevAddend;
a.Value = idx + 1;
printDynamicSolution(pTable,
n,
idx - 1,
sum - (idx + 1),
&a);
}
if (el & 1) // self, found a solution
{
tAddend a;
a.pPrev = pPrevAddend;
a.Value = idx + 1;
pPrevAddend = &a;
while (pPrevAddend != NULL)
{
printf("+%u", pPrevAddend->Value);
pPrevAddend = pPrevAddend->pPrev;
}
printf("\n");
}
}
void findDynamicSolution(uint n)
{
uchar** table;
uint i, j;
if (n == 0)
{
return;
}
// Allocate the DP table
table = malloc(sizeof(uchar*) * n);
if (table == NULL)
{
printf("not enough memory\n");
return;
}
for (i = 0; i < n; i++)
{
table[i] = malloc(n + 1);
if (table[i] == NULL)
{
while (i > 0)
{
free(table[--i]);
}
free(table);
printf("not enough memory\n");
return;
}
}
// Fill in the DP table
for (i = 0; i < n; i++)
{
for (j = 0; j <= n; j++)
{
if (i == 0)
{
table[i][j] = (i + 1 == j); // self
}
else
{
table[i][j] = (i + 1 == j) + // self
2 * (table[i - 1][j] != 0) + // other(s)
4 * ((j >= i + 1) && (table[i - 1][j - (i + 1)] != 0)); // self + other(s)
}
}
}
printDynamicSolution(table, n, n - 1, n, NULL);
for (i = 0; i < n; i++)
{
free(table[i]);
}
free(table);
}
int main(int argc, char** argv)
{
uint n;
if (argc != 2 || sscanf(argv[1], "%u", &n) != 1)
{
n = 10;
}
printf("Recursive Solution:\n");
findRecursiveSolution(n, n, NULL);
printf("\nDynamic Solution:\n");
findDynamicSolution(n);
return 0;
}
Output:
for 10:
Recursive Solution:
+10
+1+9
+2+8
+3+7
+1+2+7
+4+6
+1+3+6
+1+4+5
+2+3+5
+1+2+3+4
Dynamic Solution:
+1+2+3+4
+2+3+5
+1+4+5
+1+3+6
+4+6
+1+2+7
+3+7
+2+8
+1+9
+10
See also on ideone.
Let F(x,i) be the number of ways elements of A[1:i] can be summed to get x.
F(x,i+1) = F(x-A[i+1],i) + F(x,i)
That is it!
This is not a dynamic programming solution though. Non-recursive.
Assumption that arr is sorted in your case like [i....j] where a[i] <= a[j]
That's easy enough
void summer(int[] arr, int n , int b)
{
int lowerbound = 0;
int upperbound = n-1;
while (lowerbound < upperbound)
{
if(arr[lowerbound]+arr[upperbound] == b)
{
// print arr[lowerbound] and arr[upperbound]
lowerbound++; upperbound--;
}
else if(arr[lowerbound]+arr[upperbound] < b)
lowerbound++;
else
upperbound--;
}
}
The above program is easily modifiable to a recursive you need to only change the function definition by passing lowerbound and upperbound.
Case for termination is still lowerbound < upperbound
Base case is if arr[lowerbound] +arr[upperbound] == b
Edited based on comments
You will need to use a modified version of integer knapsack problem. The values of [i,j] both need to be modified accordingly. You are having the problem because you are not most probably modifying your i carefully, Increase your i accordingly then their will not be repetition like the one you are having.

what is the fastest way to find the gcd of n numbers?

what is the fastest way to compute the greatest common divisor of n numbers?
Without recursion:
int result = numbers[0];
for(int i = 1; i < numbers.length; i++){
result = gcd(result, numbers[i]);
}
return result;
For very large arrays, it might be faster to use the fork-join pattern, where you split your array and calculate gcds in parallel. Here is some pseudocode:
int calculateGCD(int[] numbers){
if(numbers.length <= 2){
return gcd(numbers);
}
else {
INVOKE-IN-PARALLEL {
left = calculateGCD(extractLeftHalf(numbers));
right = calculateGCD(extractRightHalf(numbers));
}
return gcd(left,right);
}
}
You may want to sort the numbers first and compute the gcd recursively starting from the smallest two numbers.
C++17
I have written this function for calculating gcd of n numbers by using C++'s inbuilt __gcd(int a, int b) function.
int gcd(vector<int> vec, int vsize)
{
int gcd = vec[0];
for (int i = 1; i < vsize; i++)
{
gcd = __gcd(gcd, vec[i]);
}
return gcd;
}
To know more about this function visit this link .
Also refer to Dijkstra's GCD algorithm from the following link. It works without division. So it could be slightly faster (Please correct me if I am wrong.)
You should use Lehmer's GCD algorithm.
How about the following using Euclidean algorithm by subtraction:
function getGCD(arr){
let min = Math.min(...arr);
let max= Math.max(...arr);
if(min==max){
return min;
}else{
for(let i in arr){
if(arr[i]>min){
arr[i]=arr[i]-min;
}
}
return getGCD(arr);
}
}
console.log(getGCD([2,3,4,5,6]))
The above implementation takes O(n^2) time. There are improvements that can be implemented but I didn't get around trying these out for n numbers.
If you have a lot of small numbers, factorization may be actually faster.
//Java
int[] array = {60, 90, 45};
int gcd = 1;
outer: for (int d = 2; true; d += 1 + (d % 2)) {
boolean any = false;
do {
boolean all = true;
any = false;
boolean ready = true;
for (int i = 0; i < array.length; i++) {
ready &= (array[i] == 1);
if (array[i] % d == 0) {
any = true;
array[i] /= d;
} else all = false;
}
if (all) gcd *= d;
if (ready) break outer;
} while (any);
}
System.out.println(gcd);
(works for some examples, but not really tested)
Use the Euclidean algorithm :
function gcd(a, b)
while b ≠ 0
t := b;
b := a mod b;
a := t;
return a;
You apply it for the first two numbers, then the result with the third number, etc... :
read(a);
read(b);
result := gcd(a, b);
i := 3;
while(i <= n){
read(a)
result := gcd(result, a);
}
print(result);
Here below is the source code of the C program to find HCF of N numbers using Arrays.
#include<stdio.h>
int main()
{
int n,i,gcd;
printf("Enter how many no.s u want to find gcd : ");
scanf("%d",&n);
int arr[n];
printf("\nEnter your numbers below :- \n ");
for(i=0;i<n;i++)
{
printf("\nEnter your %d number = ",i+1);
scanf("%d",&arr[i]);
}
gcd=arr[0];
int j=1;
while(j<n)
{
if(arr[j]%gcd==0)
{
j++;
}
else
{
gcd=arr[j]%gcd;
i++;
}
}
printf("\nGCD of k no.s = %d ",gcd);
return 0;
}
For more refer to this website for further clarification.......
You can use divide and conquer. To calculate gcdN([]), you divide the list into first half and second half. if it only has one num for each list. you calculate using gcd2(n1, n2).
I just wrote a quick sample code. (assuming all num in the list are positive Ints)
def gcdN(nums):
n = len(nums)
if n == 0: return "ERROR"
if n == 1: return nums[0]
if n >= 2: return gcd2(gcdN(nums[:n//2]), gcdN(nums[n//2:]))
def gcd2(n1, n2):
for num in xrange(min(n1, n2), 0, -1):
if n1 % num == 0 and n2 % num == 0:
return num
Here's a gcd method that uses the property that gcd(a, b, c) = gcd(a, gcd(b, c)).
It uses BigInteger's gcd method since it is already optimized.
public static BigInteger gcd(BigInteger[] parts){
BigInteger gcd = parts[0];
for(int i = 1; i < parts.length; i++)
gcd = parts[i].gcd(gcd);
return gcd;
}
//Recursive solution to get the GCD of Two Numbers
long long int gcd(long long int a,long long int b)<br>
{
return b==0 ? a : gcd(b,a%b);
}
int main(){
long long int a,b;
cin>>a>>b;
if(a>b) cout<<gcd(a,b);
else cout<<gcd(b,a);
return 0;
}
import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
class GCDArray{
public static int [] extractLeftHalf(int [] numbers)
{
int l =numbers.length/2;
int arr[] = Arrays.copyOf(numbers, l+1);
return arr;
}
public static int [] extractRightHalf(int [] numbers)
{
int l =numbers.length/2;
int arr[] = Arrays.copyOfRange(numbers,l+1, numbers.length);
return arr;
}
public static int gcd(int[] numbers)
{
if(numbers.length==1)
return numbers[0];
else {
int x = numbers[0];
int y = numbers[1];
while(y%x!=0)
{
int rem = y%x;
y = x;
x = rem;
}
return x;
}
}
public static int gcd(int x,int y)
{
while(y%x!=0)
{
int rem = y%x;
y = x;
x = rem;
}
return x;
}
public static int calculateGCD(int[] numbers){
if(numbers.length <= 2){
return gcd(numbers);
}
else {
int left = calculateGCD(extractLeftHalf(numbers));
int right = calculateGCD(extractRightHalf(numbers));
return gcd(left,right);
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int arr[] = new int[n];
for(int i=0;i<n;i++){
arr[i]=sc.nextInt();
}
System.out.println(calculateGCD(arr));
}
}
**
Above is the java working code ..... the pseudo code of which is
already mention by https://stackoverflow.com/users/7412/dogbane
**
A recursive JavaScript (ES6) one-liner for any number of digits.
const gcd = (a, b, ...c) => b ? gcd(b, a % b, ...c) : c.length ? gcd(a, ...c) : Math.abs(a);
This is what comes off the top of my head in Javascript.
function calculateGCD(arrSize, arr) {
if(!arrSize)
return 0;
var n = Math.min(...arr);
for (let i = n; i > 0; i--) {
let j = 0;
while(j < arrSize) {
if(arr[j] % i === 0) {
j++;
}else {
break;
}
if(j === arrSize) {
return i;
}
}
}
}
console.log(generalizedGCD(4, [2, 6, 4, 8]));
// Output => 2
Here was the answer I was looking for.
The best way to find the gcd of n numbers is indeed using recursion.ie gcd(a,b,c)=gcd(gcd(a,b),c). But I was getting timeouts in certain programs when I did this.
The optimization that was needed here was that the recursion should be solved using fast matrix multiplication algorithm.

Resources