Two Palindrome Exercises
October 6, 2017
We’ve done the first task previously. One approach converts the number to a string, then compares, but it’s easy to strip off the digits of the number, one by one, comparing at the end:
(define (number-palindrome? n) (let loop ((x n) (z 0)) (if (zero? x) (= n z) (let ((q (quotient x 10)) (r (remainder x 10))) (loop q (+ (* z 10) r))))))
And here are some examples:
> (number-palindrome? 123454321) #t > (number-palindrome? 123456789) #f
For the second task, we convert the input strings to a list of characters and compare the list to its reverse; mappend
is like map
, but uses append
instead of cons
to assemble its output, thereby splitting multi-letter words into their individual letters:
(define (string-palindrome? xs) (let ((chars (mappend string->list xs))) (equal? chars (reverse chars))))
And here are some examples:
> (define x ‘(“a” “bcd” “ef” “g” “f” “ed” “c” “ba”))
> (string-palindrome? x)
#t
> (string-palindrome? (cdr x))
#f
You can run the program at https://ideone.com/9VdOBA.
We can avoid separate calls to
quotient
andremainder
by usingfloor/
which returns both.With SRFI 13, we can eliminate converting strings to lists and back, and just say:
That said, the successors of SRFI 13 do not support string-reverse, because it is only useful in artificial examples like these. In a Unicode world, “Hägar the Horrible”, when expressed in decomposed form (as here). reverses not to “elbirroH eht ragäH” but to “elibrroH eht rag̈aH”, with the umlaut on the “g” rather than the first “a”.
A Haskell version.
(defun palindromic-p (str)
(equal (string-reverse str) str))
(defun palindromic-integer-p (n)
(palindromic-p (int-to-string n)))
(defun palindromic-list-p (list)
(palindromic-p (apply #’concat list)))
;; (palindromic-integer-p 123454321)
;; t
;; (palindromic-integer-p 1234544321)
;; nil
;; (palindromic-list-p ‘(“a” “bcd” “ef” “g” “f” “ed” “c” “ba”))
;; t
;; (palindromic-list-p ‘(“a” “bcd” “ef” “xg” “f” “ed” “c” “ba”))
;; nil