# Checking a numeric palindrome

Posted on

Problem

Given A and B, count the numbers N such that A ≤ N ≤ B and N is a
palindrome.

Input:

First line contains T, the number of testcases. Each testcase consists
of two integers A and B in one line.

Output:

For each testcase, print the required answer in one line.

Constraints:

1 ≤ T ≤ 10

0 ≤ A ≤ B ≤ 10^5

``````private static boolean[] isPalindrome = isPalindrome();
public static void main(String args[] ) throws NumberFormatException,
IOException{
System.in));
StringBuilder outputPalindromeCount = new StringBuilder();
for (int i = 0; i < totalTestCase; i++) {
int startNo = Integer.parseInt(input);
int endNo = Integer.parseInt(input);
int totalFoundPalindrome = getPalindromeCount(startNo, endNo);
outputPalindromeCount.append(totalFoundPalindrome + "n");
}
System.out.println(outputPalindromeCount);

}

private static int getPalindromeCount(int startNo, int endNo) {
int totalPalindromeFound = 0;
for (int i = startNo; i <= endNo ; i++ ){
if(isPalindrome[i]){
totalPalindromeFound++;
}
}
}

private static boolean[] isPalindrome() {
boolean[] isPalindrome = new boolean;
Arrays.fill(isPalindrome, 0, 10, true);
for (int i = 10; i <= 100000; i++) {
if (checkForPalindrome(i)) {
isPalindrome[i] = true;
}
}
return isPalindrome;
}

private static boolean checkForPalindrome(int i) {
int divNo = 1;
while (i / divNo >= 10) {
divNo = divNo * 10;
}

while (i != 0) {
int startingDigit = i / divNo;
int lastDigit = i % 10;
if (startingDigit != lastDigit) {
return false;
}
i = (i % divNo) / 10;
divNo = divNo / 100;

}
return true;
}

}
``````

For this input:

``````6
0 0
1 1
1 10
1 9
1 1000
1000 100000
``````

this code took 0.18 seconds. It’s taking almost 0.18-0.20 seconds for various sets of input (link of all inputs and time).

What are the other Efficient way of checking palindromes (not just a way of conversion to a string and then check but really efficient)?

How could have I optimized the above code further (apart from `BitSet` which is a trade off for runtime)?

Solution

`isPalindrome` is a very unfortunate name in this code:

• Names starting with “is” are typically methods returning a simple `boolean`
• … but in this code `isPalindrome` is a parameterless method returning a `boolean` array
• … and at the same time there is also a `boolean` array called `isPalindrome`

It would be better to use different names for the method and the array,

In the `isPalindrome` method, you could shorten this:

``````        if (checkForPalindrome(i)) {
isPalindrome[i] = true;
}
``````

to this:

``````        isPalindrome[i] = checkForPalindrome(i);
``````

I’m a big fan of descriptive variable names,
but I think you went a bit overboard, for example here:

``````private static int getPalindromeCount(int startNo, int endNo) {
int totalPalindromeFound = 0;
for (int i = startNo; i <= endNo ; i++ ){
if(isPalindrome[i]){
totalPalindromeFound++;
}
}
}
``````

I would simplify some of the names there to:

``````private static int getPalindromeCount(int start, int end) {
int palindromeCount = 0;
for (int i = start; i <= end; i++) {
if (isPalindrome[i]) {
palindromeCount++;
}
}
return palindromeCount;
}
``````

The numbers 100001 and 100000 are magic.
It would be good to create a constant from 100000 with a descriptive name.

A small tip: it’s a lot easier to parse simple input using a `Scanner`, with its `nextInt` and `nextLine` methods,
instead of a `BufferedReader` and `Integer.parseInt`.

Also, why build output in a `StringBuilder` if you will print its contents anyway inside the same method.
You could just print the results directly.

``````        int divNo = 1;
while (i / divNo >= 10) {
divNo = divNo * 10;
}

while (i != 0) {
int startingDigit = i / divNo;
int lastDigit = i % 10;
if (startingDigit != lastDigit) {
return false;
}

i = (i % divNo) / 10;
divNo = divNo / 100;
}
``````

This seems more complicated than it needs to be. First you are finding the location of the first digit. Then you go through digit by digit. Why not do both at once and get rid of `divNo`?

``````    private static boolean isPalindrome(int left) {
// a trailing zero is impossible to match
if (left % BASE == 0) {
// only a literal 0 will work
return left == 0;
}

int right = 0;
while (left > right) {
int currentDigit = left % BASE;
left /= BASE;

// if there are an odd number of digits,
// and the left half of the number equals the reversed right half,
// it's a palindrome
if (left == right) {
return true;
}

// reverse the right half, assuming no trailing zeroes
right = BASE * right + currentDigit;
}

// if there are an even number of digits
return left == right;
}
``````

Note that I also renamed `isPalindrome` to `generatePalindromes` and `checkPalindrome` to `isPalindrome`. And I added a constant to replace the magic number `10`. Algorithm explained inline with comments.