Problem of the Day
A new programming or logic puzzle every Mon-Fri

Palindromic Numbers

A palindromic number is a number that reads the same forwards as it does backwards. 123321 is a palindromic number where as 321321 is not. Negative numbers may be considered palindromic or not; it's up to you until someone proves otherwise.

Your mission, should you choose to accept it, is to create a program to return whether a number is a palindromic number or not. To make things slightly more interesting you may not use a string or array in your solution. Thus doing something like "123.toString()" is not allowed.

Good luck!

Permalink: http://problemotd.com/problem/palindromic-numbers/

Comments:

  • Steve Mostovoy - 10 years, 9 months ago

    Simple solution in C#:

    bool IsPalindromic(int number) {
        if (number < 0) {
            return false;
        }
    
        int digits = CountDigits(number);
        int index = 0;
    
        while (index < digits / 2) {
            int digitOne = number / (int)(Math.Pow(10, (digits - index - 1))) % 10;
            int digitTwo = number / (int)(Math.Pow(10, index)) % 10;
            if (digitOne != digitTwo) {
                return false;
            }
            index++;
        }
    
        return true;
    }
    
    int CountDigits(int number) {
        int digits = 1;
        int digitTester = number;
        while ((digitTester /= 10) > 0) {
            digits++;
        }
        return digits;
    }
    

    reply permalink

  • Len Payne - 10 years, 9 months ago

    You can simplify CountDigits even further by using Math.log10.

    reply permalink

  • THOR - 10 years, 9 months ago

    use integer and modulo operation. while input > 0, do module. make variable accept the result of modulo by appending it.

    if the new result == input, then input is palindrome

    reply permalink

  • Len Payne - 10 years, 9 months ago

    Basic C Solution: #include <stdio.h> #include <stdbool.h> #include <stdlib.h> #include <math.h>

    bool isPalindromic(long n) {
            int digits = ceil(log10(labs(n)));
    
            if (digits <= 1) return true;
    
            for (int i = 0; i <= digits / 2; i++) {
                    long A = pow(10, i);
                    long B = pow(10, digits - i - 1);
                    int digitA = n / A % 10;
                    int digitB = n / B % 10;
                    if (digitA != digitB) return false;
            }
            return true;
    }
    
    int main (int argc, char* argv[]) {
            long testCases[7] =
                    { 2, -12, 123, -121, 12321, 9876543456789, -1234554321};
            for (int i = 0; i < 7; i++) {
                    printf("%ld is Palindromic: %s\n",
                            testCases[i],
                            isPalindromic(testCases[i]) ? "true" :     "false");
            }
    }
    

    reply permalink

  • Len Payne - 10 years, 9 months ago

    Stupid formatting... I'm not sure why the includes were not in the code block. Possibly the #. Probably a user error.

    reply permalink

  • Anonymous - 10 years, 9 months ago

    Javascript solution:

    `function pal(num){ var length = 0; var temp = num; while(temp > 10){ length++; temp /= 10; }

    var forward = 0; while(forward < length){ if(Math.floor(num/Math.pow(10, forward)%10) == Math.floor(num/Math.pow(10, length)%10)){ forward++; length--; } else { return false; } } return true; }

    document.write(pal(123));`

    reply permalink

  • Anonymous - 10 years, 9 months ago

    function pal(num){
        var length = 0;
        var temp = num;
        while(temp > 10){
            length++;
            temp /= 10;
        }
    
        var forward = 0;
        while(forward < length){
            if(Math.floor(num/Math.pow(10, forward)%10) == Math.floor(num/Math.pow(10, length)%10)){
                forward++;
                length--;
            } else {
                return false;
            }
        }
        return true;
    }
    
    document.write(pal(123));
    

    reply permalink

  • ende76 - 10 years, 9 months ago

    Functional recursive approach in JS. Expects (but doesn't check for) integers as input. Negative integers are rejected as non-palindromes.

    Small, possibly platform-dependent code-smell: On my platform (nodev0.10.26 on OS X 10.9), my calculation for the exponent in base 10 does not equal 3 for log10(1000), but a float value slightly smaller (off by about 10E-16). I use this empirically determined point of failure to correct the direct calculation for the exponent of the most significant digit in base 10. This might fail on other platforms and/or for other values. A safer way would be to loop/recurse, using only integer division – which we don't have in JS :( – but I liked the closed calculation more for this smaller exercise.

    function is_palindrome_helper(n, highUnit) {
        var highestDigit;
    
        if (n < 0) {
            return false;
        }
    
        if (n < 10) {
            return true;
        }
    
        highestDigit = Math.floor(n / highUnit);
    
        return highestDigit === n % 10 && is_palindrome_helper(Math.floor((n - highestDigit * highUnit) / 10), highUnit / 100);
    }
    
    function is_palindrome(n) {
        var exp = Math.floor(Math.log(n) / Math.log(10)
                    + 3 - Math.log(1000) / Math.log(10)); // using corrective epsilon for value 1000
    
        return is_palindrome_helper(n, Math.pow(10, exp));
    }
    

    reply permalink

  • Pearce Keesling - 10 years, 9 months ago

    Simple solution in C++

    #include <iostream>
    #include <sstream>
    #include <cmath>
    
    using namespace std;
    
    int main(int argc, char *argv[])
    {
       int num,rev, buff;
       stringstream(argv[1]) >> num;
       buff = num;
       for(int i= 0; i < ceil(log10(num));i++)
        {
            rev = rev * 10 + (buff % 10);
            buff /=10;
        }
        cout << ((rev == num) ? "" : "Not a") << "Palindrome" << endl;
       return 0;
    }
    

    reply permalink

  • Derik Evangelista - 10 years, 9 months ago

    Simple ruby solution:

    def reverse(n, p = 0) while n.nonzero? p = (p * 10) + (n % 10) n /= 10 end p end

    def palindromic reverse(self) == self end

    reply permalink

  • Hannele - 10 years, 9 months ago

    Correct me if I'm wrong, but reverse is a string function, no?

    reply permalink

  • Travis Manning - 10 years, 9 months ago

    Pretty easy in Python. I think without input validation, it could be a one liner.

    <pre><code>def is_palindrome(x): from math import log if x==0: return 1 elif x<0 or x!=int(x): return 0 l,f=int(log(x,10)+1),0#number of digits in x, fail flag for i in range(l//2+1): if int(x//10i)%10!=int(x//(10(l-i-1)))%10: f=1 break return not f

    tests=[123454321,123,1,12345678987654321,50,0] results=[1,0,1,1,0,1]

    for el in tests: print(is_palindrome(el)) </code></pre>

    reply permalink

  • Travis Manning - 10 years, 9 months ago

    Figures I would mess up the markdown. Whatever.

    reply permalink

  • Anonymous - 10 years, 9 months ago

    !/usr/bin/env ruby

    def get_nth num, n ( num / (10**n) ) % 10 end

    begin

    num = Integer(ARGV.first, 10)

    abort('must be positive') unless num > 0

    n_digits = ( Math.log( ( num+1 ), 10 )).ceil index = 0

    begin this_number_pos = index opposite_number_pos = (n_digits-1) - index

    abort('it aint') if get_nth(num, this_number_pos) != get_nth(num, opposite_number_pos)
    
    index += 1
    

    end while index < n_digits / 2

    puts 'it is'

    rescue ArgumentError puts 'please use only numbers!' end

    reply permalink

  • Dave - 10 years, 9 months ago

    In Python 2.7-

    from sys import argv
    
    def get_length(x):
        i=0
        while x/10**i != 0:
            i+=1
        return i
    
    
    def is_palindrome(x):
    
        len_x = get_length(x)
        first,last = x/10**(len_x-1) , x % 10
        same = (first == last)
    
    
        if not same:
            return False
        else:
            if len_x <=2:
                return True
            else:
                #isolate middle numbers
    
                x = (x/10)-(10**(len_x-2)*(x/10**(len_x-1)).__trunc__())
    
                return True and is_palindrome(x)
    
    
    
    if __name__ == '__main__':
    
        num = int(argv[1])
    
        print is_palindrome(num)
    

    reply permalink

  • Joseph - 10 years, 9 months ago

    I'm not sure if this counts as using an array since all these data structures are implemented using recursion, but here's a short Haskell solution:

    isPalindrome n = let l = fmap (`mod` 10) . takeWhile (/=0) . zipWith div (repeat . abs $ n) . iterate (*10) $ 1 in l == reverse l
    

    reply permalink

  • Apanatshka - 10 years, 9 months ago

    Take input number n of which is to be determined whether it is a palindromic number.
    Let s equal the flooring of the 10-log of n.
    Construct equation n = \sum_{0<=i<s/2} a_i * x_i, with a_i = 10^{s-i} + 10^i except when s-i = i, then a_i = 10^i.
    Now solve this equation for integers x_i with constraints 1 <= x_0 <= 9 and 0 <= x_i <= 9 for the other i.
    If an answer is found, n is a palindromic number and the answer of x_is give the numbers of the left side of the palindrome in order. If the equation can't be solved, n is not a palindromic number.

    I realise that the latex text isn't that readable or intuitive, so an example:
    n = 123321
    s = 5
    equation: 123321 = 100001 * x_0 + 010010 * x_1 + 001100 * x_2 (I've added extra leading zeroes to show the method, they are still all decimal numbers)
    constraints: 1 <= x_0 <= 9, 0 <= x_1 <= 9, 0 <= x_2 <= 9
    solution: x_0 = 1, x_1 = 2, x_2 = 3

    Exceptions to this method: 0 is not recognised as a palindromic number, but you can add an extra rule before doing the ILP solving to catch that case.

    reply permalink

  • Anonymous - 10 years, 9 months ago

    This one's in J. Not line noise...^_^

    NB. Returns 1 if integer y is a palindromic number, 0 otherwise. Assumes y
    NB. to be non-negative. Monad.
    ispalindromic=: 3 : 0
      log10=: 0: ` ([: <. 10&^.) @. * y
      *./ (= |.) 10 | <. y % (10x ^ i.>:log10)
    )
    
    echo ispalindromic 12345678987654321  NB. => 1
    echo ispalindromic 1234567898765432   NB. => 0
    

    reply permalink

  • John - 10 years, 9 months ago

    My first attempt (ugly): [code]function isPalindrome(num) { var numberOfDigits = digitCount(num); var first = maxDigit(num);

    if (num === false || num < 0) return false; // in case reduceNumber returns false if (numberOfDigits === 1) return true; // recursion break return firstEqualsLast(num) && isPalindrome(reduceNumber(num));

    // helper functions function digitCount(num){ return num > 9 ? digitCount(num/10) + 1 : 1; } function maxDigit(num) { return parseInt(num/(Math.pow(10,numberOfDigits-1))); } function reduceNumber(num){ var numberOfDigits = digitCount(num); if (numberOfDigits < 2) { return num; } var rtn = parseInt((num-first*Math.pow(10,numberOfDigits-1))/10); if (digitCount(rtn) != numberOfDigits - 2) { if (rtn % 10 != 0) { // First digit was 0 and left off // return false if last digit is not 0. return false; } else { // reduce again to maintain first/last matching. return reduceNumber(parseInt(rtn / 10)); } } else { return rtn; } } function firstEqualsLast(num){ return first === num % 10; } }[/code]

    Second attempt after reading comments: [code]function isPal(num){ var numDigits = Math.ceil(Math.log(num+1)/Math.LN10); for (var i=0; i < numDigits / 2; i++) { if (Math.floor(num/Math.pow(10, numDigits-1-i)%10) != Math.floor(num/Math.pow(10, i)%10)) return false; } return true; }[/code]

    reply permalink

  • John - 10 years, 9 months ago

    Let's try this again...

    My first attempt (ugly): function isPalindrome(num) { var numberOfDigits = digitCount(num); var first = maxDigit(num);

      if (num === false || num < 0) return false; // in case reduceNumber returns false
      if (numberOfDigits === 1) return true; // recursion break
      return firstEqualsLast(num) && isPalindrome(reduceNumber(num));
    
      // helper functions
      function digitCount(num){
        return num > 9 ? digitCount(num/10) + 1 : 1;
      }
      function maxDigit(num) {
        return parseInt(num/(Math.pow(10,numberOfDigits-1)));
      }
      function reduceNumber(num){
        var numberOfDigits = digitCount(num);
        if (numberOfDigits < 2) {
          return num;
        }
        var rtn = parseInt((num-first*Math.pow(10,numberOfDigits-1))/10);
        if (digitCount(rtn) != numberOfDigits - 2) {
          if (rtn % 10 != 0) { 
            // First digit was 0 and left off
            // return false if last digit is not 0.
            return false;
          } else { // reduce again to maintain first/last matching.
            return reduceNumber(parseInt(rtn / 10));
          }
        } else {
          return rtn;
        }
      }
      function firstEqualsLast(num){
        return first === num % 10;
      }
    }
    

    Second attempt after reading comments: function isPal(num){ var numDigits = Math.ceil(Math.log(num+1)/Math.LN10); for (var i=0; i < numDigits / 2; i++) { if (Math.floor(num/Math.pow(10, numDigits-1-i)%10) != Math.floor(num/Math.pow(10, i)%10)) return false; } return true; }

    reply permalink

  • John - 10 years, 9 months ago

    Last try.

    function isPalindrome(num) {
      var numberOfDigits = digitCount(num);
      var first = maxDigit(num);
    
      if (num === false || num < 0) return false; // in case reduceNumber returns false
      if (numberOfDigits === 1) return true; // recursion break
      return firstEqualsLast(num) && isPalindrome(reduceNumber(num));
    
      // helper functions
      function digitCount(num){
        return num > 9 ? digitCount(num/10) + 1 : 1;
      }
      function maxDigit(num) {
        return parseInt(num/(Math.pow(10,numberOfDigits-1)));
      }
      function reduceNumber(num){
        var numberOfDigits = digitCount(num);
        if (numberOfDigits < 2) {
          return num;
        }
        var rtn = parseInt((num-first*Math.pow(10,numberOfDigits-1))/10);
        if (digitCount(rtn) != numberOfDigits - 2) {
          if (rtn % 10 != 0) { 
            // First digit was 0 and left off
            // return false if last digit is not 0.
            return false;
          } else { // reduce again to maintain first/last matching.
            return reduceNumber(parseInt(rtn / 10));
          }
        } else {
          return rtn;
        }
      }
      function firstEqualsLast(num){
        return first === num % 10;
      }
    }
    
    
    
    
    function isPal(num){
      var numDigits = Math.ceil(Math.log(num+1)/Math.LN10);
        for (var i=0; i < numDigits / 2; i++) {
          if (Math.floor(num/Math.pow(10, numDigits-1-i)%10) != Math.floor(num/Math.pow(10, i)%10))
            return false;
        }
      return true;
    }
    

    reply permalink

  • toteto - 10 years, 9 months ago

    Java solutions.

    Making a reverse of the number and comparing it to the original one (Average time: 70ns) <code> public static boolean isPalindromeReverse(long x) { // building reverse of x long num = x, reverse = 0; while (num != 0) { reverse = reverse * 10 + num % 10; num /= 10; } return reverse == x; } </code>

    Recursive (Average time 40ns) <code> static long y; public static boolean isPalindromeRecursive(long x) { if (x < 0) return false; if (x == 0) return true; if (isPalindromeRecursive(x / 10) && (x % 10 == y % 10)) { y /= 10; return true; } else return false; }

    public static boolean isPalindrome(long x) {
        y = x;
        return isPalindromeRecursive(x);
    }
    

    </code>

    reply permalink

  • toteto - 10 years, 9 months ago

    public static boolean isPalindromeReverse(long x) { // building reverse of x long num = x, reverse = 0; while (num != 0) { reverse = reverse * 10 + num % 10; num /= 10; } return reverse == x; }

    reply permalink

  • Javier Guzman - 10 years, 9 months ago

    My PHP can be found here: http://pastebin.com/V7kcXFuS it's always a treat to see other's code.

    reply permalink

  • Tim Lowrimore - 10 years, 9 months ago

    Implemented in Ruby
    module Palindrome
      def self.palindrome?(n)
        n == reverse(n)
      end
    
      def self.reverse(n)
        rs = 0
        while n > 0
          n, r  = n.divmod 10
          rs    = rs * 10 + r
        end
        rs
      end
    end
    

    reply permalink

  • Flavio - 10 years, 9 months ago

    using namespace std;

    int main() { long long l,m,r;

    for (;;) {
        cout << "0 to finish" << endl;
        cin >> r;
        if (!r) break;
        l=0;
        if (r > 9) do {
            l = l * 10 + r % 10;
            r /= 10;
        } while (l < r);
        cout << (l && l == r || r && l / 10 == r || !l ? "" : "not ") << "Palindromic" << endl;
    }
    return 0;
    

    }

    reply permalink

  • Ethan - 10 years, 9 months ago

    I just copied a piece of code from my very first programming class. This is a pretty common first program that you do long before you learn about strings.

    public static int reverse(int num) {
        int rev = 0;
    
        while(num != 0) {
            rev *= 10;
            rev = rev + (num % 10);
            num = num / 10;
        } return rev;
    }
    

    This is just the method for getting the reverse of a number. From there it's just == ?. :)

    reply permalink

  • Connor - 10 years, 9 months ago

    solution in python with negatives also being palindromes.

    import math
    import sys
    
    def isPalindrome (integer):
    
        x = integer + 0
        numbers = [];
    
        while x >= 1:
    
            y = float(x)/10
            x = math.floor(y)
            numbers.append(round(10 * (y - x)))
    
        n = len(numbers)
        last = n - 1
    
        for i in range(n/2):
    
            if (numbers[i] != numbers[last-i]):
    
                return False
    
        return True
    

    reply permalink

  • Hannele - 10 years, 9 months ago

    Simple python recursive solution:

    from math import *
    
    def isPalindrome(i):
    
        n_digits = floor(log10(abs(i)))
        if (n_digits == 0): return True
    
        a1 = i % 10
        a2 = floor(i / 10 ** (n_digits))
    
        if (n_digits == 1): return a1 == a2
    
        i = floor((i - 10 ** (n_digits) * a2) / 10)
    
        return isPalindrome(i)
    
    
    print(isPalindrome(123123))
    print(isPalindrome(123321))
    print(isPalindrome(12321))
    

    reply permalink

  • Hannele - 10 years, 9 months ago

    Whoops, missed a small thing! It needs one more check, just after a1 and a2 are determined:

    if (a1 != a2): return false
    

    reply permalink

  • Anonymous - 10 years, 8 months ago

    public class PalindromicNumbers {

    private static Function<Integer, Integer> reverseFunc = (num) -> {
        int r = 0;
        while (num != 0) {
            int m = num % 10;
            r = (r * 10) + m;
            num /= 10;
        }
        return r;
    };
    
    public static void main(String[] args) throws Exception {
        String input = null;
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    
        input = reader.readLine();
        while (!input.toLowerCase().startsWith("q")) {
            if (input.matches("[0-9]+")) {
    
                int num = Integer.parseInt(input);
                int rev = reverseFunc.apply(num);
                String msg = String.format("%s is palindromic %s",num,(num==rev));
                System.out.println(msg);
    
    
            } else {
                System.out.println("Not a number, try again");
            }
            input = reader.readLine();
        }
    }
    

    }

    reply permalink

Content curated by @MaxBurstein