[racket] static variables question
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>