4
\$\begingroup\$

This Common Lisp program is an exercise to print an integer and its digits reversed to the screen:

(defun read-number () (format t "Enter a number: ~%") (read))
(defun reverse-string (the-string) 
 (if (eq (length the-string) 0) 
 "" 
 (concatenate 'string (reverse-string (subseq the-string 1)) (subseq the-string 0 1))))
(defun reverse-digits (the-number) (reverse-string (write-to-string the-number)))
(let ((the-number (read-number)))
 (format t "N->: ~a~%<-N: ~a~%" the-number (reverse-digits the-number)))
Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked Mar 10, 2011 at 2:10
\$\endgroup\$
2
  • \$\begingroup\$ Wow, lots of Lisp exercises. Is this for school, or did you just pick it up for the hell of it? :) \$\endgroup\$ Commented Mar 10, 2011 at 2:24
  • \$\begingroup\$ Just picked it up for the heck of it :) I've always heard Lisp is a good language to learn. \$\endgroup\$ Commented Mar 10, 2011 at 6:27

2 Answers 2

4
\$\begingroup\$

This problem is more about numbers than strings, so I felt the need to post a non-string-based solution. I've got my original Scheme version, and a Common Lisp adaptation of same.

Scheme version:

(define (reverse-digits n)
 (let loop ((n n) (r 0))
 (if (zero? n) r
 (loop (quotient n 10) (+ (* r 10) (remainder n 10))))))

Common Lisp translation of the Scheme version:

(defun reverse-digits (n)
 (labels ((next (n v)
 (if (zerop n) v
 (multiple-value-bind (q r)
 (truncate n 10)
 (next q (+ (* v 10) r))))))
 (next n 0)))
answered Mar 10, 2011 at 3:58
\$\endgroup\$
5
  • \$\begingroup\$ I meanwhile wrote my own version of quotient, idiv. remainder and module seem to be synonyms. \$\endgroup\$ Commented Mar 10, 2011 at 4:16
  • \$\begingroup\$ @user unknown: remainder and modulo have different behaviour if the dividend is negative. (remainder -5 3) => -2, whereas (modulo -5 3) => 1. \$\endgroup\$ Commented Mar 10, 2011 at 4:24
  • \$\begingroup\$ Yeah, I didn't test negative values. For such, I would use a wrapper method. (if (< 0 x) (* -1 (redigit (* -1 x) 0))) \$\endgroup\$ Commented Mar 10, 2011 at 7:12
  • \$\begingroup\$ +1 - Just keep in mind that TCO isn't guaranteed in CL the way it is in Scheme. \$\endgroup\$ Commented Mar 10, 2011 at 15:18
  • 1
    \$\begingroup\$ @Inaimathi: Of course. But how many digits is your number going to have? ;-) \$\endgroup\$ Commented Mar 10, 2011 at 15:19
1
\$\begingroup\$

You're talking about digits and integer, but to me, as an non-lisper, it looks as if you operate on Strings.

  • I would take the number, modulo 10, print that digit.
  • If the rest is> 0 recursively call the function with the (number - digit) / 10.

In most languages with integer-arithmetic you can omit the subtraction, since 37/10 => 3 :==: (37-7)/10 => 3

In scala it would look like this:

def redigit (n: Int, sofar: Int = 0) : Int = { 
 if (n == 0) sofar else 
 redigit (n / 10, sofar * 10 + n % 10)}
redigit (123)
321 

It uses default arguments. First tests with DrScheme didn't succeed. Here is what I came up with:

;; redigit : number number -> number
(define (redigit in sofar)
 (cond [(< in 1) sofar]
 [else (redigit (/ in 10) (+ (* 10 sofar) (modulo in 10)))]) 
)
(redigit 134 0) 

But the division is precise and doesn't cut off the digits behind the floting point. I get this error:

modulo: expects type as 1st argument, given: 67/5; other arguments were: 10

I looked for a function toInt, asInt, floor, round and so on for the term (/ in 10) but I didn't find something useful. Maybe you know it yourself?

answered Mar 10, 2011 at 2:42
\$\endgroup\$
1
  • \$\begingroup\$ You need to use quotient and remainder. See my answer. :-) \$\endgroup\$ Commented Mar 10, 2011 at 4:08

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.