[racket] static variables question

From: Joe Gilray (jgilray at gmail.com)
Date: Sun Feb 19 19:11:44 EST 2012

Thanks Gary (and Neil and Robby)

Very enlightening.  I didn't know about "when".  Of course what you said
about "set!" and "cond" makes perfect sense.  Minor mods to your code
(using your set! elimination idea twice and caching (integer-sqrt x)) gives
the code below.

I noticed that I can also remove the define for candidate if I'm willing to
call (first candidate-primes) twice.  Comments?

Thanks again!
-Joe

; function to create a list of prime factors of a number
; invoke as (factor n)
(define (factor n)
  (let loop-factors ([facts '()] [x n] [start 2] [end 1000]
[candidate-primes (primes-from-to 2 1000)])
    (define isqrtx (integer-sqrt x))
    (cond [(and (empty? candidate-primes) (>= end isqrtx))
           (if (= 1 x) facts (append facts (list x)))]
          [else (cond [(empty? candidate-primes)
                       ; attempt to pull in more primes in an efficient
manner
                       (set! start end)
                       (set! end (* 2 end))
                       (when (> (* 1.5 end) isqrtx)
                         (set! end isqrtx))
                       (loop-factors facts x start end (primes-from-to
start end))]
                      [else (define candidate (first candidate-primes))
                            (cond [(zero? (remainder x candidate))
                                   (loop-factors (append facts (list
candidate)) (quotient x candidate) start end candidate-primes)]
                                  [else
                                   (loop-factors facts x start end (rest
candidate-primes))])])])))



On Sun, Feb 19, 2012 at 12:50 PM, Gary Baumgartner <gfb at cs.toronto.edu>wrote:

> Applying a lot of what Neil said:
>
> ; function to create a list of prime factors of a number
> ; invoke as (factor n)
> (define (factor n)
>   (let loop-factors ([facts '()] [x n] [start 2] [end 1000]
>                                 [candidate-primes (primes-from-to 2 1000)])
>    (cond [(and (empty? candidate-primes) (>= end (integer-sqrt x)))
>           (if (= 1 x) facts (append facts (list x)))]
>          [else (cond [(empty? candidate-primes)
>                        ; attempt to pull in more primes in an efficient
> manner
>                       (set! start end)
>                       (set! end (* 2 end))
>                        (when (> (* 1.25 end) (integer-sqrt x))
>                         (set! end (integer-sqrt x)))
>                        (set! candidate-primes (primes-from-to start end))
>                        (loop-factors facts x start end candidate-primes)]
>                      [else (define candidate (first candidate-primes))
>                            (cond [(zero? (remainder x candidate))
>                                    (set! facts (append facts (list
> candidate)))
>                                   (loop-factors facts (quotient x
> candidate) start end
>                                                  candidate-primes)]
>                                  [else
>                                   (loop-factors facts x start end (rest
> candidate-primes))])])])))
>
> When you're using a lot of 'begin's in 'if's, consider 'cond' which has
> imlicit 'begin'.
>  And for single-branch 'if's [which must be for side-effect], 'when' or
> 'unless'.
>
> As for the 'set!'ing: notice, e.g., that
>                                    (set! facts (append facts (list
> candidate)))
>                                   (loop-factors facts (quotient x
> candidate) start end
>                                                 candidate-primes)
>  is just
>                                   (loop-factors (append facts (list
> candidate))
>                                                  (quotient x candidate)
> start end
>                                                 candidate-primes)
> ____________________
>  Racket Users list:
>  http://lists.racket-lang.org/users
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20120219/7c920f17/attachment.html>

Posted on the users mailing list.