简体   繁体   中英

Reverse the order of a given integer - Scheme

ive been given a task in Scheme (Dr Racket) to reverse to order of a given digit. The solution should be recursive, and this is what i got this far.. The truth is, im not quite sure if the given algorithm even works because i get: " application: not a procedure; expected a procedure that can be applied to arguments" error every time i run it.. Any thoughts or help on the issue?

(define reverse-digits
     (lambda (n) (if (> n 9)
               (+ (* 10 (modulo n 10)) (reverse-digits (quotient n 10)))
               (n)))) 
(reverse-digits 1234)

This is a HW assignment so I won't give you code.

Your problem is that multiplying (modulo n 10) by 10 doesn't get you to the position you need to be in. Consider (reverse-digits 123) :

(reverse-digits 123)
(+ 30 (reverse-digits 12))
(+ 30 (+ 20 (reverse-digits 1)))
(+ 30 (+ 20 1))
51

What you want is to multiply it by a different power of 10 every time depending on the length of the number. You could either make a function that calculates the length of the number (possibly by repeatedly dividing the number by 10 and keeping track of how many times it did that) or passing along the length of the number (possibly by creating another function that takes the number n as an argument and calculates the length, then passes it along to your function which will then subtract 1 from length every recursive call.

What you would then get is something like this:

(reverse-digits 123)
(+ 300 (reverse-digits 12))
(+ 300 (+ 20 (reverse-digits 1)))
(+ 300 (+ 20 1))
321

The error you're getting is because in your else-case, you do (n) . As n is not a procedure, you get an error. You just want n instead.

Are you bound to using specific procedures ? If not, there's an alternative to using modulo and adding numbers. It's about using list procedures such as

number->string

take

list->string

and so on.

This is my solution, it is not very efficient!

(define 
  invert-number-aux (λ (n res)
                  (if (empty? n) res
                      (invert-number-aux 
                       (take n (-(length n) 1)) ;new n
                       (append res (list (last n))) ;new res
                       )
                      )))
(define
  invert-number (λ (n)
                  (string->number (list->string (invert-number-aux (string->list(number->string n)) '())))
                  ))

It will be helpful to use smaller helper functions.

Here is one way to split the task in smaller parts:

; number->digits : natural -> list-of-digits
(define (number->digits n)
  ...)

; digits->number : list-of-digits -> natural
(define (number->digits n)
  ...)

With these helpers you can write:

(define (reverse-number x)
   (digits->number
     (reverse
        (number->digits x))))

Also - if you want to the error " application: not a procedure; expected a procedure that can be applied to arguments" replace (n) with n .

If you run your program in DrRacket, the application (n) ought to be colored red. The problem is that (42) means evaluate 42 and then call the result as if is a function. Since 42 is a number, you get the error.

Its important to understand that fixnums don't have just one representation and what the different digits are of a number might change with the base of its representation. Here is my take on it.

(define (number->digits number (base 10))
  (let loop ((n number) (acc '()))
    (if (zero? n)
        acc
        (let-values (((res rem) (quotient/remainder n base)))
          (loop res (cons rem acc))))))

(define (list->number lst (base 10))
  (foldl (lambda (x acc)
           (+ (* acc base) x))
         0
         lst))

(define (reverse-digits number (base 10))
  (list->number (reverse (number->digits number base))
                base))

(number->string (reverse-digits #b100111 #b10) #b10) ; ==> "111001" (or 39 => 57 in base 10)
(number->string (reverse-digits #xebabefac #x10) #x10) ; ==> "cafebabe" (or 3953913772 => 3405691582 in base 10)
(number->string (reverse-digits 1234)) ; ==> 4321

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM