Double-base Palindromes
Find the sum of all natural numbers less than 10^6 that are palindromic in both base 10 and base 2. Leading zeros are not permitted in either representation.
Problem Statement
This archive keeps the full statement, math, and original media on the page.
The decimal number, \(585 = 1001001001_2\) (binary), is palindromic in both bases.
Find the sum of all numbers, less than one million, which are palindromic in base \(10\) and base \(2\).
Problem 36: Double-base Palindromes
Mathematical Development
Definitions
Definition 1. Let be an integer. A positive integer is a palindrome in base if its base- representation with satisfies for all .
Definition 2. A positive integer is a double-base palindrome if it is simultaneously a palindrome in base 10 and a palindrome in base 2.
Theoretical Development
Theorem 1 (Parity constraint). Every double-base palindrome is odd.
Proof. Let be a binary palindrome with representation , where (since leading zeros are excluded). By Definition 1, . Since and , we have .
Corollary 1.1. All even numbers can be excluded from the search, halving the candidate space.
Lemma 1 (Enumeration of base-10 palindromes below ). The number of base-10 palindromes in is exactly , partitioned by digit count as follows:
| Digits | Canonical form | Free digits | Count |
|---|---|---|---|
| 1 | 9 | ||
| 2 | 9 | ||
| 3 | 90 | ||
| 4 | 90 | ||
| 5 | 900 | ||
| 6 | 900 |
Proof. A -digit palindrome is uniquely determined by its first digits. The leading digit ranges over (9 choices), and each subsequent free digit ranges over (10 choices each). For digits, the count is . Summing: .
Lemma 2 (Binary palindrome test). A positive integer is a binary palindrome if and only if , where denotes the integer obtained by reversing the binary digits of . This test requires bit operations.
Proof. Let have binary digits. Construct by iterating: extract the least significant bit of via , append to an accumulator via left-shift-and-add, then right-shift . After iterations, the accumulator equals . By Definition 1, is a binary palindrome iff this reversed value equals . Each iteration performs work, giving total.
Theorem 2 (Efficiency of palindrome generation). Generating all base-10 palindromes below and testing each for the binary palindrome property requires operations, which is strictly less than the cost of testing every integer below .
Proof. Each binary palindrome test on a number costs . Testing all generated palindromes: operations. The brute-force alternative tests numbers at cost . Since , the generation approach is superior by a factor of .
Editorial
We avoid scanning all integers below by generating only the decimal palindromes in that range. Each such palindrome is obtained by mirroring its free leading digits, and then its binary representation is tested for the same palindromic property. Summing exactly those candidates that pass both tests yields the required total.
Pseudocode
Algorithm: Sum of Double-base Palindromes
Require: The bound 10^6.
Ensure: The sum of all numbers below 10^6 that are palindromic in both base 10 and base 2.
1: Initialize total ← 0.
2: Generate every decimal palindrome below 10^6 by mirroring a positive seed, considering both even and odd lengths.
3: For each generated palindrome p, compute its binary expansion.
4: If that binary expansion is also palindromic, update total ← total + p.
5: Return total.
Complexity Analysis
Proposition. The algorithm runs in time and auxiliary space, where and .
Proof. The generation phase enumerates exactly palindromes using nested loops with work per palindrome (arithmetic construction, no string operations needed). Each palindrome is tested via in time (Lemma 2). No arrays or sieves are required; only a running sum and loop variables are maintained. Total time: . Auxiliary space: .
Answer
Code
Each problem page includes the exact C++ and Python source files from the local archive.
#include <bits/stdc++.h>
using namespace std;
bool isBinaryPalindrome(int n) {
int rev = 0, orig = n;
while (n > 0) {
rev = (rev << 1) | (n & 1);
n >>= 1;
}
return rev == orig;
}
int main() {
int total = 0;
// 1-digit palindromes
for (int a = 1; a <= 9; a++)
if (isBinaryPalindrome(a)) total += a;
// 2-digit: aa
for (int a = 1; a <= 9; a++) {
int n = a * 11;
if (isBinaryPalindrome(n)) total += n;
}
// 3-digit: aba
for (int a = 1; a <= 9; a++)
for (int b = 0; b <= 9; b++) {
int n = a * 101 + b * 10;
if (isBinaryPalindrome(n)) total += n;
}
// 4-digit: abba
for (int a = 1; a <= 9; a++)
for (int b = 0; b <= 9; b++) {
int n = a * 1001 + b * 110;
if (isBinaryPalindrome(n)) total += n;
}
// 5-digit: abcba
for (int a = 1; a <= 9; a++)
for (int b = 0; b <= 9; b++)
for (int c = 0; c <= 9; c++) {
int n = a * 10001 + b * 1010 + c * 100;
if (isBinaryPalindrome(n)) total += n;
}
// 6-digit: abccba
for (int a = 1; a <= 9; a++)
for (int b = 0; b <= 9; b++)
for (int c = 0; c <= 9; c++) {
int n = a * 100001 + b * 10010 + c * 1100;
if (isBinaryPalindrome(n)) total += n;
}
cout << total << endl;
return 0;
}
"""Project Euler Problem 36: Double-base Palindromes"""
def is_binary_palindrome(n):
rev, t = 0, n
while t:
rev = (rev << 1) | (t & 1)
t >>= 1
return rev == n
def generate_base10_palindromes(limit):
pals = []
for a in range(1, 10):
if a < limit: pals.append(a)
for a in range(1, 10):
n = a * 11
if n < limit: pals.append(n)
for a in range(1, 10):
for b in range(10):
n = a * 101 + b * 10
if n < limit: pals.append(n)
for a in range(1, 10):
for b in range(10):
n = a * 1001 + b * 110
if n < limit: pals.append(n)
for a in range(1, 10):
for b in range(10):
for c in range(10):
n = a * 10001 + b * 1010 + c * 100
if n < limit: pals.append(n)
for a in range(1, 10):
for b in range(10):
for c in range(10):
n = a * 100001 + b * 10010 + c * 1100
if n < limit: pals.append(n)
return pals
total = sum(p for p in generate_base10_palindromes(1_000_000) if is_binary_palindrome(p))
print(total)