0

Im having some problems with racket. The assignment wants me to write a procedure that converts any number from base 10 to base 4, the solution should be written in a list. for example (convert-to-base-four 12) -> (list 3 0) Now i have written a procedure but it inserts each number in an individual list. heres my code.

(define (convert-to-base-four number)
  (cond
    [(<= number 3) (cons number empty)] 
    [(> number 3)  (reverse (list (remainder number 4)
                    (convert-to-base-four (floor (/ number 4)))))]))

Does anyone know what to do? Many thanks

  • You're using `list` when you should be using `cons`. Also the digits are going to be jumbled together in the wrong order because of the multiple `reverse` calls on different recursive steps. – Alex Knauth Nov 23 '17 at 16:29
  • the problem is that if I combined list and reverse it gets screwed up. Is this a paranthesis problem? – stuck_in_racket Nov 23 '17 at 16:32
  • No, it's not a paren problem. Your tree is fine. It's mostly a `list` vs. `cons` problem. Then once that's solved you have to figure out whether it should use reverse this way or not. – Alex Knauth Nov 23 '17 at 16:34
  • in other words when i use "list" I dont need the reverse but the numbers are put individually in lists for example (list (list 3) 0) – stuck_in_racket Nov 23 '17 at 16:37
  • Yes I know. But think about the signature of this function. I'm guessing it should return a list of digits. Now think about the signature of `list`. Given an X and an X, it returns a list of X. But you don't have an X and an X, you have a digit and a list of digits, and you want it to return a list of digits. You're violating the signature of `list`. It's the wrong thing to use here. – Alex Knauth Nov 23 '17 at 16:41
  • @stuck_in_racket, please see my answer – [`append` is usually the wrong solution in racket](https://stackoverflow.com/a/19213794/633183) – only use it when necessary – Mulan Nov 23 '17 at 18:11

2 Answers2

0

AlexKnauth's comment is the one you need to be following – you must define and adhere to a strict domain (input) and codomain (output) for your function

;; from your code
(list Y
      (convert-to-base-four X))

It doesn't matter what Y and X are here: if convert-to-base-four returns a list of some value and a recursive call to convert-to-base-four – which returns a list – you're going to end up with a list of lists!

One solution, as another points out, is to use append – but beware, it's a trap

(define (base4 n)
  (if (< n 4)
      (list n)
      (append (base4 (floor (/ n 4)))
              (list (remainder n 4)))))

(displayln (base4 12))     ; (3 0)
(displayln (base4 13))     ; (3 1)
(displayln (base4 14))     ; (3 2)
(displayln (base4 15))     ; (3 3)
(displayln (base4 16))     ; (1 0 0)
(displayln (base4 123456)) ; (1 3 2 0 2 1 0 0 0)

A better solution would avoid the costly use of append – here we do that using a named let loop with two loop state variables m and acc

(define (base4 n)
  (let loop ((m n) (acc empty))
    (if (< m 4)
        (cons m acc)
        (loop (floor (/ m 4))
              (cons (remainder m 4) acc)))))

(displayln (base4 12))     ; (3 0)
(displayln (base4 13))     ; (3 1)
(displayln (base4 14))     ; (3 2)
(displayln (base4 15))     ; (3 3)
(displayln (base4 16))     ; (1 0 0)
(displayln (base4 123456)) ; (1 3 2 0 2 1 0 0 0)
Mulan
  • 129,518
  • 31
  • 228
  • 259
-3

Try to use append on your list :)

Have fun with homework ;)

  • This is not an answer! Please read this before contributing: https://stackoverflow.com/help/how-to-answer – hmofrad Nov 23 '17 at 17:15