;; Generate Pythagorean triples using combinations. (1.04)
;; @see RhRctK
(use-modules (srfi srfi-1) ; pair-for-each
(srfi srfi-67) ; list-compare
(ice-9 format)) ; advanced formatting
;; Combinations.
(define (combinations sequence k yield)
(let loop ((start sequence) (k k) (result '()))
(if (zero? k)
(yield (reverse result))
(pair-for-each (lambda (rest)
(loop (cdr rest) (- k 1) (cons (car rest) result)))
start))))
;; Pythagorean triples.
(define (primitive-pythagorean-triple? x y z)
(and (< x y z)
(= (+ (* x x) (* y y)) (* z z))
(= (gcd x y z) 1)))
(define (pythagorean-triples n)
(let* ((out '())
(collect (lambda (v)
(apply (lambda (x y z)
(when (primitive-pythagorean-triple? x y z)
(set! out (cons v out))))
v))))
(combinations (iota n 1) 3 collect)
(reverse out)))
;; Main.
(define (list-less-reverse x y)
(< (list-compare (reverse x) (reverse y)) 0))
(for-each (lambda (v)
(format #t "(~{~2D~^ ~})~%" v))
(sort (pythagorean-triples 97) list-less-reverse))