-1

Hello so I was doing this problem in which they give you a range from a minimum of 5 to a maximum of 100,000,000

and you have to find all prime palindromes from the first number to the second number

example:

input: 5 500

output:

5

7

11

101

131

151

181

191

313

353

373

383

So before you look at my solution you need to understand 2 things that all prime numbers except for some of the first ones end with this 4 digits 1,3,7,9 and that all palindromes with an even number of digits are divisible by 11

so understanding this you know that all prime palindromes need to start with one of these 4 digits and that there are no prime palindromes with an even number of digits example: 7557

so my solution was to create palindromes and check if they are prime and then print them and the way I used to check them was by having a number like 12 and then reversing it and appending it like 1221 and adding a number in the center from 1 to 9: 12121

but the way I did it was so that all numbers started with this 4 digits in this way:

from 1-1 3-3 7-7 9-9

 10-19 30-39 70-79 90 99

and I did this until the numbers produced were larger than the limit in which case I stopped creating new palindromes and the good thing about this is that I get them in order

creating my solution:

 #include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef vector < long long > vi;
typedef pair < long long, long long > pi;
typedef vector < pi > vpi;


ifstream fin("pprime.in");
ofstream fout("pprime.out");

int reverse2(int num, int middle) {
  int i, save = num, digit, combino = 1;
  for (i = 0; num; num /= 10) {
    digit = num % 10;
    i = 10 * i + digit;
    combino *= 10;
  }
  return i + 10 * combino * save + combino * middle;
}


bool prime(int n) {

  if (n <= 1)
    return false;

  for (int i = 2; i < n; i++)
    if (n % i == 0)
      return false;

  return true;
}

bool solve(int i, int n, int m, int digits) {

  int c, b;
  c = reverse2(i, 0);

  for (int j = 0; j <= 9; j++) {

    b = c + j * digits;
    
    if (b >= n && b <= m) {
      if (prime(b)) {
        fout << b << endl;
      }
    }
    if (b > m) {
      return 0;
    }

  }

  return 1;
}

int main() {

  int n, m;
  fin >> n >> m;

  if (5 >= n && 5 <= m) {
    fout << 5 << endl;
  }
  if (7 >= n && 7 <= m) {
    fout << 7 << endl;
  }
  if (11 >= n && 11 <= m) {
    fout << 11 << endl;
  }
  int arr[4] = { 1,3,7,9};

  bool b = 0;
int digits = 10;

  while (!b) {

    for (int j = 0; j < 4; j++) {
      int s = arr[j];
      int actualdigit = arr[j] * digits / 10;

      for (int i = actualdigit; i < (actualdigit/ s) * (s + 1); i++) {

        bool a = solve(i, n, m, digits);
        if (!a) {
          b = 1;
          j = 20;
          break;
        }

      }
    }

    digits *= 10;
  }

  return 0;
}

The problem here is that my solution runs out of time for example in this case: 9878210 9978210

even though the reverse function I used was gotten from another solution which also solves the problem

other guy's code:

#include <iostream.h>
#include <fstream.h>
#include <stdlib.h>

int primelist[100000];
int nprimes;

int isPrime(int num);
int reverse2(int i, int j);

int compare(const void *p, const void *q) { return *(int *)p-*(int *)q; }

void main (void) {
    ifstream infile("pprime.in");
    ofstream outfile("pprime.out"); 
    int i, j, begin, end, num;
    infile>>begin>>end;
    if (begin <= 11 && 11 <=end)
        primelist[nprimes++] = 11;
    for (j = 0; j <= 999; j++)
        for (i = 0; i <= 9; i++)  {
        num = reverse2(j,i);
        if (num >= begin && num <=end && isPrime(num)) 
            primelist[nprimes++] = num;
        }
    qsort(primelist, nprimes, sizeof(int), compare);
    for (i = 0; i < nprimes; i++)
    outfile << primelist[i] << "\n";
}

int
reverse2(int num, int middle) {
    int i, save=num, digit, combino = 1;
    for (i = 0; num; num /= 10) {
    digit = num % 10;
    i = 10 * i + digit;
    combino *= 10;
    }
    return i+10*combino*save+combino*middle;
}
    
int isPrime(int num) {
    int i;
    if (num <= 3) return 1;
    if (num%2 == 0 || num%3 ==0) return 0;
    for (i = 5; i*i <= num; i++)
    if (num %i ==0)
        return 0;
    return 1;
}

so the question is why does my program run out of time and his doesn't if both do the same thing but I do the procedure in fewer cases than him?

  • Replace the 1st line with only standard includes. Then delete the next 17 lines, and don't write anything like that. Then give all your variables longer names. Then will make it much easier to find the bug. – cigien Jul 09 '20 at 03:17
  • Please format your code and get rid of a lot of the blank lines to bring it up to the tidiness of the other guy's code. Also, compare his prime checker versus yours. – Ken Y-N Jul 09 '20 at 03:17

1 Answers1

0

Actually, as some of the comments have suggested the problem was my prime function which indeed works better if first checking the divisibility by 2 and by 3 2 very common divisors of a lot of numbers the solution would then be the following:

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef vector < long long > vi;
typedef pair < long long, long long > pi;
typedef vector < pi > vpi;


ifstream fin("pprime.in");
ofstream fout("pprime.out");

int reverse2(int num, int middle) {
  int i, save = num, digit, combino = 1;
  for (i = 0; num; num /= 10) {
    digit = num % 10;
    i = 10 * i + digit;
    combino *= 10;
  }
  return i + 10 * combino * save + combino * middle;
}


bool prime(int num) {
    int i;
    if (num <= 3) return 1;
    if (num%2 == 0 || num%3 ==0) return 0;
    for (i = 5; i*i <= num; i++)
    if (num %i ==0)
        return 0;
    return 1;
}

bool solve(int i, int n, int m, int digits) {

  int c, b;
  c = reverse2(i, 0);

  for (int j = 0; j <= 9; j++) {

    b = c + j * digits;

    if (b >= n && b <= m) {
      if (prime(b)) {
        fout << b << endl;
      }
    }
    if (b > m) {
      return 0;
    }

  }

  return 1;
}

int main() {

  int n, m;
  fin >> n >> m;

  if (5 >= n && 5 <= m) {
    fout << 5 << endl;
  }
  if (7 >= n && 7 <= m) {
    fout << 7 << endl;
  }
  if (11 >= n && 11 <= m) {
    fout << 11 << endl;
  }
  int arr[4] = { 1,3,7,9};

  bool b = 0;
int digits = 10;

  while (!b) {

    for (int j = 0; j < 4; j++) {
      int s = arr[j];
      int actualdigit = arr[j] * digits / 10;

      for (int i = actualdigit; i < (actualdigit/ s) * (s + 1); i++) {

        bool a = solve(i, n, m, digits);
        if (!a) {
          b = 1;
          j = 20;
          break;
        }

      }
    }

    digits *= 10;
  }

  return 0;
}