views:

2917

answers:

10

Any language. Any algorithm (except making the number a string and then reversing the string).

Also, I actually have to do this, and I'll be posting my solution too.

+27  A: 

This is one of the Project Euler problems. When I solved it in Haskell I did exactly what you suggest, convert the number to a String. It's then trivial to check that the string is a pallindrome. If it performs well enough, then why bother making it more complex? Being a pallindrome is a lexical property rather than a mathematical one.

Dan Dyer
Indeed. Any algorithm you make will have to at least split the number into base-10 digits, which is 90% converted to a string anyway.
Blorgbeard
@Blorgbeard: good point.
Esteban Araya
+2  A: 

Push each individual digit onto a stack, then pop them off. If it's the same forwards and back, it's a palindrome.

Grant Limberg
How do you push each individual digit from the integer?
Esteban Araya
Something along the lines of:int firstDigit = originalNumber % 10;int tmpNumber = originalNumber/10;int secondDigit = tmpNumber % 10;.... until you're done.
Grant Limberg
+22  A: 

For any given num:

 n = num;
 rev = 0;
 while (num > 0)
 {
      dig = num % 10;
      rev = rev * 10 + dig;
      num = num / 10;
 }

If n == rev then num is a palindrome:

cout << "Number " << (n == rev ? "IS" : "IS NOT") << " a palindrome" << endl;
smink
that's what i came up w/ too. i guess no sense in me posting it now. +1
Esteban Araya
Is this assuming that rev is initialized to zero?
Justsalt
Yes Justsalt. The rev variable is initialized to zero.
smink
+4  A: 
def ReverseNumber(n, partial=0):
    if n == 0:
        return partial
    return ReverseNumber(n / 10, partial * 10 + n % 10)

trial = 123454321    
if ReverseNumber(trial) == trial:
    print "It's a Palindrome!"
Mark Ransom
+3  A: 
int is_palindrome(unsigned long orig)
{
  unsigned long reversed = 0, n = orig;

  while (n > 0)
  {
    reversed = reversed * 10 + n % 10;
    n /= 10;
  }

  return orig == reversed;
}
Robert Gamble
+1  A: 

Pop off the first and last digits and compare them until you run out. There may be a digit left, or not, but either way, if all the popped off digits match, it is a palindrome.

Eli
A: 

I would be very interested to see an algorithm that is not equivalent -- modulo the +/- 48 needed to convert between ASCII digits and ints -- to converting to a string and reversing.


Edit: I should have read the other answers more carefully before I posted. smink's converts the stream of digits into the reversed number without just reversing the digits.

dysfunctor
+2  A: 

I answered the Euler problem using a very brute-forcy way. Naturally, there was a much smarter algorithm at display when I got to the new unlocked associated forum thread. Namely, a member who went by the handle Begoner had such a novel approach, that I decided to reimplement my solution using his algorithm. His version was in Python (using nested loops) and I reimplemented it in Clojure (using a single loop/recur).

Here for your amusement:

(defn palindrome? [n]
  (let [len (count n)]
    (and
      (= (first n) (last n))
      (or (>= 1 (count n))
        (palindrome? (. n (substring 1 (dec len))))))))

(defn begoners-palindrome []
  (loop [mx 0
         mxI 0
         mxJ 0
         i 999
         j 990]
    (if (> i 100)
      (let [product (* i j)]
        (if (and (> product mx) (palindrome? (str product)))
          (recur product i j
            (if (> j 100) i (dec i))
            (if (> j 100) (- j 11) 990))
          (recur mx mxI mxJ
            (if (> j 100) i (dec i))
            (if (> j 100) (- j 11) 990))))
      mx)))

(time (prn (begoners-palindrome)))

There were Common Lisp answers as well, but they were ungrokable to me.

Christian Vest Hansen
I tried some of the "mathematical" palindrome tests posted here, but was surprised that this string based version was the faster one.
Christian Vest Hansen
+2  A: 

Just for fun, this one also works.

a = num;
b = 0;
while (a>=b)
{
  if (a == b) return true;
  b = 10 * b + a % 10;
  if (a == b) return true;
  a = a / 10;
}
return false;
Gamecat
+1  A: 

Here is an Scheme version that constructs a function that will work against any base. It has a redundancy check: return false quickly if the number is a multiple of the base (ends in 0). And it doesn't rebuild the entire reversed number, only half. That's all we need.

(define make-palindrome-tester
   (lambda (base)
     (lambda (n)
       (cond
         ((= 0 (modulo n base)) #f)
         (else
          (letrec
              ((Q (lambda (h t)
                    (cond
                      ((< h t) #f)
                      ((= h t) #t)
                      (else
                       (let* 
                           ((h2 (quotient h base))
                            (m  (- h (* h2 base))))
                         (cond 
                           ((= h2 t) #t)
                           (else
                            (Q h2 (+ (* base t) m))))))))))           
            (Q n 0)))))))
z5h