I am trying to write a function which takes an input number and outputs the number in reverse order.
Input -> 25
Output -> 52
Input -> 125
Output -> 521
I am new to lisp, if its helpful here is the working function in c++
int revs(int rev, int n)
if (n <= 0)
return revs((rev * 10) + (n % 10), n/10);
I have written it in Racket as follows:
(define (revs rev n)
(if (<= n 0)
(revs (+ (* rev 10) (modulo n 10)) (/ n 10))))
But when I run it with (revs 0 125) I get this error:
modulo: contract violation
argument position: 1st
Certainly I am doing something incorrect here, but I am unsure of what I am missing.
The division operator
/ doesn't do integer division, but general division, so when you call, e.g.,
(/ 25 2), you don't get
13, but rather the rational
25/2. I think you'd want
quotient instead, about which the documentation has:
procedure (quotient n m) → integer? n : integer? m : integer?
(truncate (/ n m)). Examples:
> (quotient 10 3) 3 > (quotient -10.0 3) -3.0 > (quotient +inf.0 3) quotient: contract violation expected: integer? given: +inf.0 argument position: 1st other arguments...: 3
Treating the operation lexicographically:
#lang racket (define (lexicographic-reverse x) (string->number (list->string (reverse (string->list (number->string x))))))
Works for any of Racket's numerical types.
[edit 1] "Works," I realized, is context dependent and with a bit of testing shows the implicit assumptions of the operation. My naive lexicographic approach makes a mess of negative integers, e.g.
(lexicographic-reverse -47) will produce an error.
However, getting an error rather than
-74 might be better when if I am reversing numbers for lexicographic reasons rather than numerical ones because it illuminates the fact that the definition of "reversing a number" is arbitrary. The reverse of 47 could just as well be -74 as 74 because reversing is not a mathematical concept - even though it might remind me of XOR permutation.
How the sign is handled is by a particular reversing function is arbitrary.
#lang racket ;; Reversing a number retains the sign (define (arbitrary1 x) (define (f n) (string->number (list->string (reverse (string->list (number->string n)))))) (if (>= x 0) (f x) (- (f (abs x))))) ;; Reversing a number reverses the sign (define (arbitrary2 x) (define (f n) (string->number (list->string (reverse (string->list (number->string n)))))) (if (>= x 0) (- (f x)) (f (abs x))))
The same considerations extend to Racket's other numerical type notations; decisions about reversing exact, inexact, complex, are likewise arbitrary - e.g. what is the reverse of IEEE
Here is my solution for this problem
(define (reverseInt number) (define (loop number reversedNumber) (if (= number 0) reversedNumber (let ((lastDigit (modulo number 10))) (loop (/ (- number lastDigit) 10) (+ (* reversedNumber 10) lastDigit))))) (loop number 0))
Each time we multiply the reversed number by 10 and add the last digit of number.
I hope it make sense.
A R6RS version (will work with R7RS with a little effort)
#!r6rs (import (rnrs) (srfi :8)) (define (numeric-reverse n) (let loop ((acc 0) (n n)) (if (zero? n) acc (receive (q r) (div-and-mod n 10) (loop (+ (* acc 10) r) q)))))
A Racket implementation:
#!racket (require srfi/8) (define (numeric-reverse n) (let loop ((acc 0) (n n)) (if (zero? n) acc (receive (q r) (quotient/remainder n 10) (loop (+ (* acc 10) r) q)))))