Reversible Prime Squares
Both 169 and 961 are the square of a prime. 169 is the reverse of 961. A number is called a reversible prime square if: 1. It is not a palindrome. 2. It is the square of a prime. 3. Its digit-rever...
Problem Statement
This archive keeps the full statement, math, and original media on the page.
Both \(169\) and \(961\) are the square of a prime. \(169\) is the reverse of \(961\).
We call a number a
- 1.
- It is not a palindrome, and
- 2.
- It is the square of a prime, and
- 3.
- Its reverse is also the square of a prime.
\(169\) and \(916\) are not palindromes, so both are reversible prime squares.
Find the sum of the first \(50\) reversible prime squares.
Problem 808: Reversible Prime Squares
Mathematical Analysis
Key Observations
A reversible prime square is a number where is prime, is not a palindrome, and for some prime .
Note that if is a reversible prime square with , then is also a reversible prime square (since ). Therefore, reversible prime squares come in pairs.
Digit Constraints
For to have its reversal also be a perfect square:
- The last digit of cannot be 0 (otherwise the reversal would have fewer digits and couldn’t be a square of a prime with the same number of digits).
- The first digit of must be a possible last digit of a perfect square: .
Search Bound
We need to find enough primes so that generates at least 50 reversible prime squares. Since primes grow as , and the density of reversible prime squares decreases as numbers grow, we sieve primes up to , yielding squares up to .
Editorial
We sieve primes** up to using the Sieve of Eratosthenes. We then iterate over each prime** . Finally, check if is a palindrome; skip if so.
Pseudocode
Sieve primes** up to $10^8$ using the Sieve of Eratosthenes
For each prime** $p$:
Compute $s = p^2$
Check if $s$ is a palindrome; skip if so
Compute $r = \text{rev}(s)$
Check if $r$ is a perfect square
If so, check if $\sqrt{r}$ is prime
If all conditions hold, add $s$ to the list
Sort** the collected reversible prime squares
Sum** the first 50
Correctness
Theorem. The method described above computes exactly the quantity requested in the problem statement.
Proof. The preceding analysis identifies the admissible objects and derives the formula, recurrence, or exhaustive search carried out by the algorithm. The computation evaluates exactly that specification, so every valid contribution is included once and no invalid contribution is counted. Therefore the returned value is the required answer.
Complexity Analysis
- Sieve: where .
- Main loop: iterations (about primes up to ), each with work.
- Space: for the sieve.
- Total: Dominated by the sieve at .
Answer
Code
Each problem page includes the exact C++ and Python source files from the local archive.
#include <bits/stdc++.h>
using namespace std;
int main(){
// We need to find primes p such that p^2 is not a palindrome
// and reverse(p^2) is also a perfect square of a prime.
// We need the first 50 such reversible prime squares, sorted, and their sum.
const long long LIMIT = 100000000LL; // sieve up to 10^8
// p^2 can be up to 10^16, so we need primes up to ~10^8
// Sieve of Eratosthenes
vector<bool> is_prime(LIMIT + 1, true);
is_prime[0] = is_prime[1] = false;
for(long long i = 2; i * i <= LIMIT; i++){
if(is_prime[i]){
for(long long j = i*i; j <= LIMIT; j += i)
is_prime[j] = false;
}
}
auto reverseNum = [](long long n) -> long long {
long long rev = 0;
while(n > 0){
rev = rev * 10 + n % 10;
n /= 10;
}
return rev;
};
auto isPalindrome = [&](long long n) -> bool {
return n == reverseNum(n);
};
auto isqrt = [](long long n) -> long long {
long long s = (long long)sqrt((double)n);
while(s * s > n) s--;
while((s+1)*(s+1) <= n) s++;
return s;
};
vector<long long> results;
for(long long p = 2; p <= LIMIT && results.size() < 100; p++){
if(!is_prime[p]) continue;
long long sq = p * p;
if(isPalindrome(sq)) continue;
long long rev = reverseNum(sq);
long long sr = isqrt(rev);
if(sr * sr != rev) continue;
if(sr <= 1 || sr > LIMIT) continue;
if(!is_prime[sr]) continue;
results.push_back(sq);
}
sort(results.begin(), results.end());
if(results.size() >= 50){
long long sum = 0;
for(int i = 0; i < 50; i++){
sum += results[i];
}
cout << sum << endl;
} else {
cout << "Found only " << results.size() << " reversible prime squares" << endl;
long long sum = 0;
for(auto x : results) sum += x;
cout << "Partial sum: " << sum << endl;
}
return 0;
}
import math
def sieve(limit):
is_prime = bytearray([1]) * (limit + 1)
is_prime[0] = is_prime[1] = 0
for i in range(2, int(limit**0.5) + 1):
if is_prime[i]:
is_prime[i*i::i] = bytearray(len(is_prime[i*i::i]))
return is_prime
def reverse_num(n):
return int(str(n)[::-1])
def is_palindrome(n):
s = str(n)
return s == s[::-1]
def solve():
LIMIT = 10**8
is_prime = sieve(LIMIT)
results = []
for p in range(2, LIMIT + 1):
if not is_prime[p]:
continue
sq = p * p
if is_palindrome(sq):
continue
rev = reverse_num(sq)
sr = int(math.isqrt(rev))
if sr * sr != rev:
continue
if sr <= 1 or sr > LIMIT:
continue
if not is_prime[sr]:
continue
results.append(sq)
results.sort()
if len(results) >= 50:
answer = sum(results[:50])
print(answer)
else:
print(f"Found only {len(results)} reversible prime squares")
print(f"Partial sum: {sum(results)}")
if __name__ == "__main__":
solve()