Hello Joe,<br><br>I'd like to make a few suggestions also.<br><br>~ 1 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br><br>I repeat what Neil V. said:<br><br><blockquote style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class="gmail_quote">
Formatting-wise, you might consider generally putting newlines between
each of the three parts of an "if" form. It's easier to distinguish the
parts at a glance, especially if the parts contain parens, and you can
also sometimes better see symmetries/asymmetries between the branches.</blockquote><br>And a similar rule would apply to let-, cond-, etc-clauses (i.e. the ones around square brackets []).<br><br>So instead of<br><br>(let ([a 1] [b 2] [c 3])<br>
...)<br><br>I'd write for clarity:<br><br>(let ([a 1]<br> [b 2]<br> [c 3])<br> ...)<br><br><br><br>~ 2 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br><br>The three `cond' uses are like `if's. They only have 1 test and an else clause. So considering the cond's and if's, the code branches like this:<br>
<br>cond --- if ---- [1]<br> \ \---- [2]<br> \<br> \----- cond --- [3]<br> \<br> \------- cond ------ [4]<br> \----------- [5]<br><br><br>It is possible to replace a pattern like this:<br>
<br>(cond<br> [..a..]<br> [else (cond<br> [..b..]<br> ...)])<br><br>With this simpler:<br><br>(cond<br>
[..a..]<br>
[..b..]<br>
...)<br><br>That's one of the things that makes cond's different than if's...<br><br>After applying the above, the branching structure becomes:<br><br>cond --- if ---- [1]<br>
| \---- [2]<br>
|------ [3]<br>
|------ [4]<br>
|------ [5]<br><br><br><br>~ 3 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br><br>Using DrRacket's Debugger, I noticed that to compute (factor 4) the code was iterating many unnecessary times in the loop, until the candidate-primes list was exhausted.<br>
<br>Looking back at the code, we see that there's only one way to stop the recursion, which is when (and (empty? candidate-primes) (>= end isqrtx)) holds true.<br>So even when we want to factorize small numbers we have to go through the entire list of computed primes.<br>
This suggests rethinking about the conditions...<br><br><br>Here's the code with my changes:<br><br><br>; function to create a list of prime factors of a number<br>; invoke as (factor n)<br>(define (factor n)<br> (let loop-factors ([facts '()]<br>
[x n]<br> [start 2]<br> [end 1000]<br> [candidate-primes (primes-from-to 2 1000)])<br> (define isqrtx (integer-sqrt x))<br> (cond<br>
[(and (empty? candidate-primes)<br>
(>= end isqrtx))<br> (if (= 1 x)<br> facts<br> (append facts (list x)))]<br> [(empty? candidate-primes)<br> ; attempt to pull in more primes in an efficient manner<br> (set! start end)<br>
(set! end (* 2 end))<br> (when (> (* 1.5 end) isqrtx)<br> (set! end isqrtx))<br> (loop-factors facts<br> x<br> start<br> end<br> (primes-from-to start end))]<br>
[(zero? (remainder x (first candidate-primes)))<br> (loop-factors (append facts (list (first candidate-primes)))<br> (quotient x (first candidate-primes))<br> start<br>
end<br>
candidate-primes)]<br> [else<br> (loop-factors facts<br> x<br> start<br> end<br> (rest candidate-primes))])))<br>
<br><br><br>[]'s<br><br clear="all">Rodolfo Carvalho<br>