Thanks Gary (and Neil and Robby)<div><br></div><div>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.</div>
<div><br></div><div>I noticed that I can also remove the define for candidate if I'm willing to call (first candidate-primes) twice. Comments?</div><div><br></div><div>Thanks again!</div><div>-Joe</div><div><br></div>
<div><div>; function to create a list of prime factors of a number</div><div>; invoke as (factor n)</div><div>(define (factor n)</div><div> (let loop-factors ([facts '()] [x n] [start 2] [end 1000] [candidate-primes (primes-from-to 2 1000)])</div>
<div> (define isqrtx (integer-sqrt x))</div><div> (cond [(and (empty? candidate-primes) (>= end isqrtx))</div><div> (if (= 1 x) facts (append facts (list x)))]</div><div> [else (cond [(empty? candidate-primes)</div>
<div> ; attempt to pull in more primes in an efficient manner</div><div> (set! start end)</div><div> (set! end (* 2 end))</div><div> (when (> (* 1.5 end) isqrtx)</div>
<div> (set! end isqrtx))</div><div> (loop-factors facts x start end (primes-from-to start end))]</div><div> [else (define candidate (first candidate-primes))</div>
<div> (cond [(zero? (remainder x candidate))</div><div> (loop-factors (append facts (list candidate)) (quotient x candidate) start end candidate-primes)]</div><div>
[else</div><div> (loop-factors facts x start end (rest candidate-primes))])])])))</div></div><div><br></div><div><br><br><div class="gmail_quote">On Sun, Feb 19, 2012 at 12:50 PM, Gary Baumgartner <span dir="ltr"><<a href="mailto:gfb@cs.toronto.edu">gfb@cs.toronto.edu</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">Applying a lot of what Neil said:<br>
<br>
; function to create a list of prime factors of a number<br>
; invoke as (factor n)<br>
(define (factor n)<br>
</div> (let loop-factors ([facts '()] [x n] [start 2] [end 1000]<br>
[candidate-primes (primes-from-to 2 1000)])<br>
(cond [(and (empty? candidate-primes) (>= end (integer-sqrt x)))<br>
(if (= 1 x) facts (append facts (list x)))]<br>
[else (cond [(empty? candidate-primes)<br>
<div class="im"> ; attempt to pull in more primes in an efficient manner<br>
(set! start end)<br>
(set! end (* 2 end))<br>
</div> (when (> (* 1.25 end) (integer-sqrt x))<br>
(set! end (integer-sqrt x)))<br>
<div class="im"> (set! candidate-primes (primes-from-to start end))<br>
</div> (loop-factors facts x start end candidate-primes)]<br>
[else (define candidate (first candidate-primes))<br>
(cond [(zero? (remainder x candidate))<br>
<div class="im"> (set! facts (append facts (list candidate)))<br>
(loop-factors facts (quotient x candidate) start end<br>
</div> candidate-primes)]<br>
[else<br>
(loop-factors facts x start end (rest candidate-primes))])])])))<br>
<br>
When you're using a lot of 'begin's in 'if's, consider 'cond' which has imlicit 'begin'.<br>
And for single-branch 'if's [which must be for side-effect], 'when' or 'unless'.<br>
<br>
As for the 'set!'ing: notice, e.g., that<br>
<div class="im"> (set! facts (append facts (list candidate)))<br>
(loop-factors facts (quotient x candidate) start end<br>
candidate-primes)<br>
</div> is just<br>
(loop-factors (append facts (list candidate))<br>
<div class="im HOEnZb"> (quotient x candidate) start end<br>
candidate-primes)<br>
</div><div class="HOEnZb"><div class="h5">____________________<br>
Racket Users list:<br>
<a href="http://lists.racket-lang.org/users" target="_blank">http://lists.racket-lang.org/users</a><br>
</div></div></blockquote></div><br></div>