<div><div class="gmail_quote">On Mon, Mar 19, 2012 at 04:35, Joe Gilray <span dir="ltr"><<a href="mailto:jgilray@gmail.com">jgilray@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Thanks Rodolfo and Eli for the education, very elegant solutions.<div><br></div><div>I really like the clever use of the "(and (right-triangle? a b c) (list a b c))))" idiom.<br><div><br></div><div>I had to look up in-value... unfortunately the manual is a bit sparse there, but I got the gift by running some examples... thanks.</div>
<div><br></div><div>After going "D'oh" about the infinite loop, here is the code I ended up with:<div><div><br></div><div><div>(define (pythagorean-triple n)</div><div> (let loop-ab ([a 1] [b 2])</div><div class="im">
<div>
(define c (- n a b))</div></div><div> (cond [(>= a n) '()]</div><div> [(<= c b) (loop-ab (add1 a) (+ a 2))]</div><div> [(right-triangle? a b c) (list a b c)]</div><div> [else (loop-ab a (add1 b))])))</div>
<div><br></div><div>I noticed that the sequence-based solutions are quite a bit slower than the code above probably because they don't short-cut on (<= c b), is there an elegant way to speed them up?</div><div><br>
</div><div></div></div></div></div></div></blockquote></div><br></div><div>Before you asked I wrote this:<div><br></div><div><div>; by Rodolfo Carvalho</div><div>(define (pythagorean-triple/alt n)</div><div> (for*/first ([a (in-range 1 (ceiling (/ n 3)))]</div>
<div> [b (in-range (add1 a) (ceiling (/ (- n a) 2)))]</div><div> [c (in-value (- n a b))]</div><div> #:when (and (< b c)</div><div> (right-triangle? a b c)))</div>
<div> (list a b c)))</div><div><br></div><div><br></div><div>; by Eli on the mailing list, modified by Rodolfo</div><div>(define (pythagorean-triple/alt2 n)</div><div> (for*/or ([a (in-range 1 n)]</div><div> [b (in-range (add1 a) n)]) ; start from `a+1' instead of `a'.</div>
<div> (define c (- n a b))</div><div> (and (< b c) (right-triangle? a b c) (list a b c)))) ; added `(< b c)' check.</div></div><div><br></div><div><br></div><div><br></div><div>And counted how many times they call right-triangle -- the same number of times.</div>
<div>Indeed your (first) solution with let loops seems slightly faster, but not by a significant margin in my experiments.</div><div><br></div><div>I didn't take the time to analyze it much, but looking at the code expansion using the Macro Stepper suggested that the for macros generate a lot more code to be executed than the nested lets.</div>
<div><br></div><div><br></div><div>[]'s</div><div><br clear="all">Rodolfo Carvalho<br><br></div></div><div><br></div><div><br></div>