[racket] a small programming exercise

From: Justin Zamora (justin at zamora.com)
Date: Thu Oct 14 18:19:59 EDT 2010

On Thu, Oct 14, 2010 at 2:26 PM, Joe Marshall <jmarshall at alum.mit.edu> wrote:
> Here's a fast way to get the leftmost digit of a number:
> ...
> This version is slightly slower for small numbers, but much much better
> for large ones:
> (defun leftmost-digit (n base)
>  (if (> base n)
>      n
>      (do* ((i base next)
>            (next (* base base) (* i i)))
>        ((> next n) (leftmost-digit (floor n i) base)))))

I tried a comparison of your method to the string-conversion method
and was surprised that the string-comparison version ran 3 times
faster!  I think I implemented your method correctly (at least it
appears to produce correct results).  Any insights?

(define (first-digit-string n)
  (- (char->integer (string-ref (number->string n) 0))
     (char->integer #\0)))

(define (first-digit-fast n)
  (if (> 10 n)
      (let loop ([i 10]
                 [next 100])
        (if (> next n)
            (first-digit-fast (floor (/ n i)))
            (loop next (* i i))))))

(define *the-list* (filter positive? (build-list 10000000 (lambda (i)
(random (+ i 1))))))

> (time (for-each first-digit-string *the-list*))
cpu time: 3969 real time: 4016 gc time: 718
> (time (for-each first-digit-fast *the-list*))
cpu time: 11875 real time: 11907 gc time: 391


Posted on the users mailing list.