Caridorc
Caridorc

Reputation: 6661

Digits of a number in Racket are in random order

I decided to write a function that given a number will return a list containing the digits in that number, my attempt is:

(define (rev-digits n)
  (if (= n 0)
    '()
    (cons (modulo n 10) (digits (quotient n 10)))))

(define (digits n)
  (reverse (rev-digits n)))

The fact is, I need the digits to be in proper order, but the function returns, for example:

> (digits 1234567890)
'(9 7 5 3 1 2 4 6 8 0)

In seemingly random order... can you help me getting a more ordinated output?

Upvotes: 1

Views: 481

Answers (3)

soegaard
soegaard

Reputation: 31145

A simple solution:

#lang racket
(define (digits n)
  (for/list ([c (number->string n)])
    (- (char->integer c) (char->integer #\0))))

Upvotes: 1

Óscar López
Óscar López

Reputation: 236122

The answer given by @JayKominek is spot-on and fixes the error in your code. To complement it, here's an alternative implementation:

(define (rev-digits n)
  (let loop ((n n) (acc '()))
    (if (< n 10)
        (cons n acc)
        (loop (quotient n 10) (cons (modulo n 10) acc)))))

The advantages of the above code are:

  • It's tail recursive and hence more efficient
  • It correctly handles the edge case when n is zero (your code returns an empty list)
  • It doesn't require a helper procedure, thanks to the use of a named let
  • It builds the list in the correct order, there's no need to reverse it at the end

Upvotes: 1

Jay Kominek
Jay Kominek

Reputation: 8783

rev-digits needs to call itself, not digits.

(define (rev-digits n)
  (if (= n 0)
    '()
    (cons (modulo n 10) (rev-digits (quotient n 10)))))

(define (digits n)
  (reverse (rev-digits n)))

should work.

It's worth noting that your "random" output was not in fact random; rather the digits were "bouncing" back and forth from the start to the end of the list. Which makes sense, because you were effectively switching back and forth between a "normal" and reversed version of your digits function.

Upvotes: 1

Related Questions