chainyn1234
chainyn1234

Reputation: 23

splitting digits of an integer into a vector, rotating them, then converting back to an integer

My goal is to take an integer, my example is 197, check if it's prime, if it is prime, rotate the digits and check primality until I get back to 197, otherwise break the look. I plan on looping through a ton of numbers to do this.

My first method used is myPow. It is used to take long int powers (like 2^20).

long myPow(long x, long p) {
    if (p == 0) { return 1; }
    if (p == 1){ return x; }
    return x * myPow(x, p - 1);
}

This function counts the number of digits.

int numdigits(long r){
    unsigned int number_of_digits = 0;

    do {
        ++number_of_digits;
        r /= 10;
    } while (r);
    return number_of_digits;
}

This checks for primality.

bool isPrime(unsigned long long n) {
if (n <= 3) {
    return n > 1;
}

if (n % 2 == 0 || n % 3 == 0) {
    return false;
}

for (unsigned long long i = 5; i * i <= n; i += 6) {
    if (n % i == 0 || n % (i + 2) == 0) {
        return false;
    }
}

return true;
}

This takes an integer and splits the digits into a vector (integer 123 -> vector(1,2,3))

vector<int> digits(int x){
    vector<int> myvec;
    while (x >= 10){
        myvec.push_back(x % 10);
        x = x / 10; 
}

    myvec.push_back(x);
    reverse(myvec.begin(), myvec.end());
    return myvec;
}

This is the main class.
It loops through each integer, checks if it is prime. If it is prime, I use k to compare it to i, because eventually it will rotate to itself and the while look will finish. I set the flag to be true, it is set to false when a different rotation of the number fails to be prime and after the loop finishes, it will not count the integer. I create the vector mydigs to store the digits, let h = the number of digits. I assign a = h to avoid computing numdigits(i) in the while loop.

This is where i think things are wrong. I rotate once and I assign k to be the integer. I check if that is prime, if not, break and set flag to false. Otherwise it will continue to loop and keep rotating. The problem is that when I run this for just 197, which I know would be prime every time I rotate the integer, I end up failing because when I rotate a second time I get the wrong number. Which is why I have it outputting k, just to see why things are wrong.

What output should be:

971, 719, 1

Output I get:

971, 1690, < -- this I don't understand. 0,

int main(){
unsigned t0 = clock();
int totalcircle = 0;
for (int i = 197; i < 198; i += 2){
    if (isPrime(i)){
        long k = 0;
        bool flag = true;
        vector<int> mydigs = digits(i);
        int h = numdigits(i); 
        int a;
        while (i != k){
            a = h;
            rotate(mydigs.begin(), mydigs.begin()+1, mydigs.end());
            for (vector<int>::iterator it = mydigs.begin(); it !=  mydigs.end(); ++it){
                k += (*it) * myPow(10, a - 1);
                a--;
            }

            std::cout << k << std::endl;
            if (!isPrime(k)){
                flag = false;
                break;
            }

        }
        if (flag){
            std::cout << i << endl;
            totalcircle++;
        }
    }

}

std::cout << totalcircle << endl;
unsigned elapsed = clock() - t0;
std::cout << "Elapsed time: " << elapsed << endl;
std::system("pause");
return 0;
}

Upvotes: 0

Views: 392

Answers (1)

Steephen
Steephen

Reputation: 15824

You can use std::rotate in place of your function as follows

#include <iostream>     
#include <algorithm>    
#include <vector>      
int main () {
  std::vector<int> myvector={1,9,7};
  std::rotate(myvector.begin(),myvector.end()-1,  myvector.end());
  std::cout << "myvector contains:";
  for ( auto &x : myvector)
     std::cout<<x;
  std::cout << '\n';

  return 0;
}

Upvotes: 1

Related Questions