-3

I am trying to solve the following problem: For given n and α, determine the smallest number k for which n can be expressed as a sum of k numbers each of which is a perfect α-th power.

My first idea was to create a sequence of length n, then using recursion to create every possible sequence with the perfect α-th powers. After creating the sequence I would check to see if the sum of all the numbers in the sequence sum to n, then check if the total amount of numbers is less then k, if those are both true then I would update k. I wrote a program that solves most cases but for some reason doesn't create every possible sequence. For example if the user inputs 92 for n and 3 for α, then k should be 3 because 4^3 + 3^3 + 1^3 = 92, but my program returns k=92.

#include<iostream>
#include<cmath>

void check(const int &N, const int &A, int *pSeq, int position, int &K){
  int sum=0;
  int total=0;
  for(int i=0; i<N; ++i){
    sum+=pSeq[i];
    if(pSeq[i]>0){
      ++total;
    }
  }
  if(sum==N){
    if(total < k){
      K=total;
      std::cout<<"Print seq: ";
      for(int i =0; i<N; ++i){
        std::cout<<pSeq[i] <<" ";
      }
      std::cout<<std::endl;
    }
  }
  if(sum<N){
    if(position < N){
      for(int i=0; pow(i, A)<N+1; ++i){
        pSeq[position]=pow(i, A);
        check(N, A, pSeq, position+1, K);
      }
    }
  }
}

int main(){
  int n, a;
  std::cout<<"Enter n and a: ";
  std::cin>>n >>a;
  int k=n;
  int *sequence=new int[n];
  for(int i=0; i<n; ++i){
    sequence[i]=0;
  }

  check(n, a, sequence, 0, k);

  std::cout<<"k=" <<k <<std::endl;

  return 0;
}
idknuttin
  • 105
  • 1
  • 5
  • 2
    Try stepping through with a debugger. That's what a debugger is for. – Peter Apr 13 '17 at 22:46
  • 1
    @Peter I tried to display all of the sequences as it created them and I saw that it wasn't creating every possibility, I also printed out the sum of each sequence each time, the loops and recursion looks like it should create every possible sequence for I can't figure out why it isn't. – idknuttin Apr 13 '17 at 22:50

1 Answers1

1

Ok, you don't have any feedback. Let's take your example: Loops make array ... 0 0 64 64 and then they go ... 0 1 64 64 etc. But 64+64 = 128 > 92. So we need last ended loop to decrease power and consider ... 0 1 27 64, which is the answer. I added these "feedbacks" to your code.

#include<iostream>
#include<cmath>

int k = 99999;

void check(const int &N, const int &A, int *pSeq, int position, int &K,bool& too_big,bool& ready){
  if (ready)
    return;
  int sum=0;
  int total=0;
  for(int i=0; i<N; ++i){
    sum+=pSeq[i];
    if(pSeq[i]>0){
      ++total;
    }
  }
  if(sum==N){
    if(total < k){
      K=total;
      std::cout<<"Print seq: ";
      for(int i =0; i<N; ++i){
        std::cout<<pSeq[i] <<" ";
      }
      std::cout<<std::endl;
      ready = true;
      return;
    }
  }
  if(sum<N){
    if(position < N){
      for(int i=0; pow(i, A)<N+1; ++i){
        pSeq[position]=pow(i, A);
        check(N, A, pSeq, position+1, K,too_big,ready);
        if (too_big) {
          too_big = false;
          pSeq[position]=pow(i-1, A);
          return;
        }
      }
    }
  }
  else
    too_big = true;

}

int main(){
  int n, a;
  std::cout<<"Enter n and a: ";
  std::cin>>n >>a;
  int k=n;
  int *sequence=new int[n];
  for(int i=0; i<n; ++i){
    sequence[i]=0;
  }

  bool too_big = false,ready = false;
  check(n, a, sequence, 0, k,too_big,ready);

  std::cout<<"k=" <<k <<std::endl;

  return 0;
}

And the answer is

Print seq: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 27 64 
k=3
Sklert
  • 242
  • 5
  • 12