Scheme number to list
Asked Answered
S

3

2

I need a subroutine for my program written in scheme that takes an integer, say 34109, and puts it into a list with elements 3, 4, 1, 0, 9. The integer can be any length. Does anyone have a trick for this? I've thought about using modulo for every place, but I don't think it should be that complicated.

Seiden answered 11/10, 2012 at 7:41 Comment(2)
Use modulo, it's not that compilcated :) i'm not sure what you mean by 'every place'. You just extract leat significant digit with modulo 10, divide the number by 10, and repeat (perhaps recursively).Banas
Hey thanks piokuc, that makes sense to use division as well to keep reducing the number.Seiden
W
4

The simplest way I can think of, is by using arithmetic operations and a named let for implementing a tail-recursion:

(define (number->list num)
  (let loop ((num num)
             (acc '()))
    (if (< num 10)
        (cons num acc)
        (loop (quotient num 10)
              (cons (remainder num 10) acc)))))

Alternatively, you can solve this problem using string operations:

(define char-zero (char->integer #\0))

(define (char->digit c)
  (- (char->integer c) char-zero))

(define (number->list num)
  (map char->digit
       (string->list (number->string num))))

This can be compressed into a single function, but I believe it's easier to understand if we split the problem in subparts as above.

(define (number->list num)
  (map (lambda (c) (- (char->integer c) (char->integer #\0)))
       (string->list
        (number->string num))))

Anyway, the results are as expected:

(number->list 34109)
> '(3 4 1 0 9)
Wheelman answered 11/10, 2012 at 14:30 Comment(0)
T
2

Something like this:

(define (num2list-helper num lst)
  (cond ((< num 10) (cons num lst))
        (else (num2list-helper (floor (/ num 10)) (cons (modulo num 10) lst)))))

(define (num2list num)
  (num2list-helper num '()))

(num2list 1432)

As itsbruce commented you can hide helper function inside main one:

(define (num2list num)
  (define (num2list-helper num lst)
    (cond ((< num 10) (cons num lst))
          (else (num2list-helper (floor (/ num 10)) (cons (modulo num 10) lst)))))

    (num2list-helper num '()))

(num2list 1432)

to be continued...

Thanks answered 11/10, 2012 at 10:43 Comment(2)
you can keep things tidier by using a named let inside num2list, instead of having an external helper. The essential code would be the same, but it would be contained within the function that needs the help. Only reason to have it at the top level is if you have more than one function that needs this particular help.Entomophilous
I have updated my answer and hide helper function inside the main one. But I had not managed to use 'let' or 'lambda' in this code :( I call num2list-helper recursively and I don't know how to call recursivelly anonimous function. So I will be thankfull if you share this code for me.Thanks
S
1

I'm not a fan of manual looping, so here's a solution based on unfold (load SRFI 1 and SRFI 26 first):

(define (digits n)
  (unfold-right zero? (cut modulo <> 10) (cut quotient <> 10) n))

This returns an empty list for 0, though. If you want it to return (0) instead, we add a special case:

(define (digits n)
  (case n
   ((0) '(0))
   (else (unfold-right zero? (cut modulo <> 10) (cut quotient <> 10) n))))

Of course, you can generalise this for other bases. Here, I implement this using optional arguments, so if you don't specify the base, it defaults to 10:

(define (digits n (base 10))
  (case n
   ((0) '(0))
   (else (unfold-right zero? (cut modulo <> base) (cut quotient <> base) n))))

Different Scheme implementations use different syntaxes for optional arguments; the above uses Racket-style (and/or SRFI 89-style) syntax.

Synchroscope answered 11/10, 2012 at 20:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.