r-s
r-s

Reputation: 1035

Reversing an integer

I am trying to write a function which takes an input number and outputs the number in reverse order.

Ie:

Input -> 25 Output -> 52

Input -> 125 Output -> 521

I am new to lisp, if its helpful here is the working function in c++

function.cpp

int revs(int rev, int n)
{
  if (n <= 0)
    return rev;

  return revs((rev * 10) + (n % 10), n/10);
}

I have written it in Racket as follows:

(define (revs rev n)
  (if (<= n 0)
     rev
     (revs (+ (* rev 10) (modulo n 10)) (/ n 10))))

But when I run it with (revs 0 125) I get this error:

modulo: contract violation
  expected: integer?
  given: 25/2
  argument position: 1st
  other arguments...:
   10

Certainly I am doing something incorrect here, but I am unsure of what I am missing.

Upvotes: 4

Views: 3068

Answers (5)

21rw
21rw

Reputation: 1126

With recursion, you can do something like:

#lang racket

(define (reverse-num n)
  (let f ([acc 0]
          [n n])
    (cond
      [(zero? n) acc]
      [else (f (+ (* acc 10) (modulo n 10)) (quotient n 10))])))

Upvotes: 0

Tal Delbari
Tal Delbari

Reputation: 121

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 makes sense.

Upvotes: 1

ben rudgers
ben rudgers

Reputation: 3669

Treating the operation lexicographically:

#lang racket
(define (lexicographic-reverse  x)
  (string->number
   (list->string
    (reverse
     (string->list
      (number->string x))))))

Works[1] 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 +inf.0 or +nan.0?

Upvotes: 5

Sylwester
Sylwester

Reputation: 48775

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)))))

Upvotes: 0

Joshua Taylor
Joshua Taylor

Reputation: 85913

The division operator / doesn't do integer division, but general division, so when you call, e.g., (/ 25 2), you don't get 12 or 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?

Returns (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

Upvotes: 8

Related Questions