Joe
Joe

Reputation: 15359

How to find out all palindromic numbers

A palindromic number or numeral palindrome is a "symmetrical" number like 16461, that remains the same when its digits are reversed.

The term palindromic is derived from palindrome, which refers to a word like rotor that remains unchanged under reversal of its letters.

The first palindromic numbers (in decimal) are:

0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22,
33, 44, 55, 66, 77, 88, 99, 101, 111,
121, 131, 141, 151, 161, 171, 181,
191, ...

How to find out all palindromic numbers below, say, 10000?

Upvotes: 13

Views: 22206

Answers (7)

user1031307
user1031307

Reputation: 19

I wrote these methods in C# which may be of some help. The main method builds a definitive list of all palindromic numbers up to the given number of digits. Its fast and commented throughout to help explain the processes I have used.

I've also included some support methods including a fast palindromic test and its worth pointing out that pow10[x] is an array of the powers of 10 to further improve speed.

                    lhs *= 10;
                    rhs /= 10;
                }
                palindrome = MathExt.Concat( lhs * 10, MathExt.ReverseDigits( rhs ) );      // Multiplying the lhs by 10 is equivalent to adding b == 0
                result.Add( palindrome );       // Add numbers of the form aaa + 0 + aaa

                lhs = a;
                for ( ulong b = 1; b != 10; b++ )
                {
                    rhs = a * 10 + b; // Adding b before we reverse guarantees that there is no trailing 0s
                    palindrome = MathExt.Concat( lhs, MathExt.ReverseDigits( rhs ) );       // Works except when b == 0
                    result.Add( palindrome );       // Add numbers of the form aaa + b + aaa
                }
                a++;
            }
            pow *= 10;        // Each pass of the outer loop add an extra digit to aaa
        } 
        return (result);
    }


    /// <summary>
    ///  Reverses the digits in a number returning it as a new number. Trailing '0's will be lost.
    /// </summary>
    /// <param name="n">The number to reverse.</param>
    /// <param name="radix">The radix or base of the number to reverse.</param>
    /// <returns>The reversed number.</returns>
    static public ulong ReverseDigits( ulong n, uint radix = 10 )
    {
        // Reverse the number
        ulong result = 0;
        do
        {
            // Extract the least significant digit using standard modular arithmetric
            result *= radix;
            result += n % radix;
            n /= radix;
        } while ( n != 0 );
        return (result);
    }


/// <summary>
    /// Concaternates the specified numbers 'a' and 'b' forming a new number 'ab'.
    /// </summary>
    /// <example>If a = 1234 and b = 5678 then Concat(a,b) = 12345678.</example>
    /// <param name="a">The first number.</param>
    /// <param name="b">The second number.</param>
    /// <returns>The concaternated number 'ab'.</returns>
    public static ulong Concat( this ulong a, ulong b )
    {
        // Concaternate the two numbers by shifting 'a' to the left by the number of digits in 'b' and then adding 'b'
        return (a * pow10[NumberOfDigits( b )] + b);
    }

    /// <summary>
    /// Evaluate whether the passed integer is a palindrome in base 10 or not.
    /// </summary>
    /// <param name="n">Integer to test.</param>
    /// <returns>True - Palindrome, False - Non palindrome.</returns>
    static public bool IsPalindrome( this ulong n )
    {
        uint divisor = NumberOfDigits( n ) - 1;
        do
        {
            // Extract the most and least significant digits of (n)
            ulong msd = n / pow10[divisor];
            ulong lsd = n % 10;

            // Check they match!
            if ( msd != lsd )
                return (false);

            // Remove the msd and lsd from (n) and test the next most and least significant digits.
            n -= msd * pow10[divisor];  // Remove msd
            n /= 10;                    // Remove lsd
            divisor -= 2;               // Number has reduced in size by 2 digits 
        } while ( n != 0 );
        return (true);
    }

Upvotes: 0

aashima
aashima

Reputation: 1203

Loops similar to the one below can be used to print palindrome numbers:

for(int i = 1; i <= 9; i++) {
        for(int j = 0; j <= 9; j++) {
            for(int k = 0; k <= 9; k++) {
                System.out.println("" + i + j + k + j + i);
            }
        }
    }

Upvotes: 1

aioobe
aioobe

Reputation: 421360

Generating all palindromes up to a specific limit.

public static Set<Integer> allPalindromic(int limit) {

    Set<Integer> result = new HashSet<Integer>();

    for (int i = 0; i <= 9 && i <= limit; i++)
        result.add(i);

    boolean cont = true;
    for (int i = 1; cont; i++) {
        StringBuffer rev = new StringBuffer("" + i).reverse();
        cont = false;
        for (String d : ",0,1,2,3,4,5,6,7,8,9".split(",")) {
            int n = Integer.parseInt("" + i + d + rev);
            if (n <= limit) {
                cont = true;
                result.add(n);
            }
        }
    }

    return result;
}


Testing for palindromicity

Using Strings

public static boolean isPalindromic(String s, int i, int j) {
    return j - i < 1 || s.charAt(i) == s.charAt(j) && isPalindromic(s,i+1,j-1);
}

public static boolean isPalindromic(int i) {
    String s = "" + i;
    return isPalindromic(s, 0, s.length() - 1);
}

Using integers

public static boolean isPalindromic(int i) {
    int len = (int) Math.ceil(Math.log10(i+1));
    for (int n = 0; n < len / 2; n++)
        if ((i / (int) Math.pow(10, n)) % 10 !=
            (i / (int) Math.pow(10, len - n - 1)) % 10)
            return false;
    return true;
}

Upvotes: 15

Priyank Bhatnagar
Priyank Bhatnagar

Reputation: 814

There is a brute force approach, that you loop through all the numbers and check whether they are palindrome or not. To check, reverse the number and compare. Complexity should be O(n log10(n)). [ Not that log10() matters, but for sake of completeness. ]

Other one is to, generate palindromes according to number of digits. Lets say you have to generate 5 digit palindromes, they are of the form ABCBA, so just loop through 0-9 and fill all the positions. Now, if you have generate palindromes below 10^4, then generate palindromes of 1,2,3 and 4 digits.

I wrote quick(and dirty) C++ codes to test the speed of both the algorithms (8 digit palindrome). Brute force : Ideone. (3.4s) Better algorithm : Ideone. (0s)

I have removed print statements, because Ideone doesn't allow this large data in output.

On my computer the times are :

Brute force:
real    0m7.150s
user    0m7.052s
Better algorithm:
real    0m0.024s
user    0m0.012s

I know that you have mentioned language as Java, but i don't know Java and these codes simply show you the difference between the algorithms, and you can write your own Java code.

PS: I have tested my code for 8 digit palindromes with brute force, can't be sure if it produces wrong for above 8 digits, though the approach used is general. Also, i would have liked to give the links to code in comments, as correct approach is already mentioned, but i don't have required privileges.

Upvotes: 3

amit
amit

Reputation: 178521

one approach is simply iterating over all numebrs, and checking each number: is it is a palyndrome or not, something like that:

public static boolean isPalindrome(Integer x) {
        String s = x.toString();
        int len = s.length();
        for (int i = 0;i<len;i+=2) {
            if (s.charAt(i) != s.charAt(len-i-1)) return false;
        }
        return true;
    }
public static void main(String[] args) {
        int N = 10000;
        for (Integer x = 0;x<N;x++) { 
            if (isPalindrome(x)) System.out.println(x);
        }
    } 

Upvotes: 2

M Platvoet
M Platvoet

Reputation: 1654

Revert your reasoning. Not try to find these numbers but instead create them. You can simply take any number and mirror it (which is always even in length) and for that same number simply add 0..9 in between (for the numbers with odd length).

Upvotes: 27

b_erb
b_erb

Reputation: 21261

Brute force approach: Make a foreach loop from 1…10000 and test against the constraints. Even easier, convert the number to string, reverse it and compare it to the original value. This is inefficient and lame.

Better approach: Think about the patterns of a palindrome. Think about the different possibilities there are for palindromes, depending on the length of the number. Now provide a method that generates palindromes of the given length. (I will not do this, because it's obviously homework.)

Upvotes: 1

Related Questions