On Mon, Mar 19, 2012 at 04:35, Joe Gilray <jgil...@gmail.com> wrote: > Thanks Rodolfo and Eli for the education, very elegant solutions. > > I really like the clever use of the "(and (right-triangle? a b c) (list a > b c))))" idiom. > > 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. > > After going "D'oh" about the infinite loop, here is the code I ended up > with: > > (define (pythagorean-triple n) > (let loop-ab ([a 1] [b 2]) > (define c (- n a b)) > (cond [(>= a n) '()] > [(<= c b) (loop-ab (add1 a) (+ a 2))] > [(right-triangle? a b c) (list a b c)] > [else (loop-ab a (add1 b))]))) > > 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? > > Before you asked I wrote this:
; by Rodolfo Carvalho (define (pythagorean-triple/alt n) (for*/first ([a (in-range 1 (ceiling (/ n 3)))] [b (in-range (add1 a) (ceiling (/ (- n a) 2)))] [c (in-value (- n a b))] #:when (and (< b c) (right-triangle? a b c))) (list a b c))) ; by Eli on the mailing list, modified by Rodolfo (define (pythagorean-triple/alt2 n) (for*/or ([a (in-range 1 n)] [b (in-range (add1 a) n)]) ; start from `a+1' instead of `a'. (define c (- n a b)) (and (< b c) (right-triangle? a b c) (list a b c)))) ; added `(< b c)' check. And counted how many times they call right-triangle -- the same number of times. Indeed your (first) solution with let loops seems slightly faster, but not by a significant margin in my experiments. 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. []'s Rodolfo Carvalho
____________________ Racket Users list: http://lists.racket-lang.org/users