;; Pythagorean triples using combinations. (1.01)
(use-modules (srfi srfi-1))
;; Utility.
(define (pair-map proc sequence)
(pair-fold-right (lambda (item init)
(cons (proc item) init))
'() sequence))
(define (pair-append-map proc sequence)
(apply append (pair-map proc sequence)))
;; Combinations.
(define (combinations sequence k)
(if (zero? k)
(list '())
(pair-append-map (lambda (rest)
(map (lambda (comb)
(cons (car rest) comb))
(combinations (cdr rest) (- k 1))))
sequence)))
;; 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)
(sort
(filter-map
(lambda (triple)
(apply (lambda (x y z)
(if (primitive-pythagorean-triple? x y z)
triple
#f))
triple))
(combinations (iota n 1) 3))
(lambda (x y) (< (third x) (third y)))))
;; Show.
(define n 5)
(define a (iota n 1))
(for-each (lambda (k)
(format #t "~A~%" (combinations a k)))
(iota n 1))
(newline)
(format #t "~A~%" (pythagorean-triples 53))
OzsgUHl0aGFnb3JlYW4gdHJpcGxlcyB1c2luZyBjb21iaW5hdGlvbnMuICgxLjAxKQoKKHVzZS1tb2R1bGVzIChzcmZpIHNyZmktMSkpCgo7OyBVdGlsaXR5LgoKKGRlZmluZSAocGFpci1tYXAgcHJvYyBzZXF1ZW5jZSkKICAocGFpci1mb2xkLXJpZ2h0IChsYW1iZGEgKGl0ZW0gaW5pdCkKICAgICAgICAgICAgICAgICAgICAgKGNvbnMgKHByb2MgaXRlbSkgaW5pdCkpCiAgICAgICAgICAgICAgICAgICAnKCkgc2VxdWVuY2UpKQoKKGRlZmluZSAocGFpci1hcHBlbmQtbWFwIHByb2Mgc2VxdWVuY2UpCiAgKGFwcGx5IGFwcGVuZCAocGFpci1tYXAgcHJvYyBzZXF1ZW5jZSkpKQoKOzsgQ29tYmluYXRpb25zLgoKKGRlZmluZSAoY29tYmluYXRpb25zIHNlcXVlbmNlIGspCiAgKGlmICh6ZXJvPyBrKQogICAgICAobGlzdCAnKCkpCiAgICAgIChwYWlyLWFwcGVuZC1tYXAgKGxhbWJkYSAocmVzdCkKICAgICAgICAgICAgICAgICAgICAgICAgIChtYXAgKGxhbWJkYSAoY29tYikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY29ucyAoY2FyIHJlc3QpIGNvbWIpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY29tYmluYXRpb25zIChjZHIgcmVzdCkgKC0gayAxKSkpKQogICAgICAgICAgICAgICAgICAgICAgIHNlcXVlbmNlKSkpCgo7OyBQeXRoYWdvcmVhbiB0cmlwbGVzLgoKKGRlZmluZSAocHJpbWl0aXZlLXB5dGhhZ29yZWFuLXRyaXBsZT8geCB5IHopCiAgKGFuZCAoPCB4IHkgeikKICAgICAgICg9ICgrICgqIHggeCkgKCogeSB5KSkgKCogeiB6KSkKICAgICAgICg9IChnY2QgeCB5IHopIDEpKSkKCihkZWZpbmUgKHB5dGhhZ29yZWFuLXRyaXBsZXMgbikKICAoc29ydAogICAgKGZpbHRlci1tYXAKICAgICAgKGxhbWJkYSAodHJpcGxlKQogICAgICAgIChhcHBseSAobGFtYmRhICh4IHkgeikKICAgICAgICAgICAgICAgICAoaWYgKHByaW1pdGl2ZS1weXRoYWdvcmVhbi10cmlwbGU/IHggeSB6KQogICAgICAgICAgICAgICAgICAgICB0cmlwbGUKICAgICAgICAgICAgICAgICAgICAgI2YpKQogICAgICAgICAgICAgICB0cmlwbGUpKQogICAgIChjb21iaW5hdGlvbnMgKGlvdGEgbiAxKSAzKSkKICAgKGxhbWJkYSAoeCB5KSAoPCAodGhpcmQgeCkgKHRoaXJkIHkpKSkpKQoKOzsgU2hvdy4KCihkZWZpbmUgbiA1KQooZGVmaW5lIGEgKGlvdGEgbiAxKSkKKGZvci1lYWNoIChsYW1iZGEgKGspCiAgICAgICAgICAgIChmb3JtYXQgI3QgIn5BfiUiIChjb21iaW5hdGlvbnMgYSBrKSkpCiAgICAgICAgICAoaW90YSBuIDEpKQoobmV3bGluZSkKKGZvcm1hdCAjdCAifkF+JSIgKHB5dGhhZ29yZWFuLXRyaXBsZXMgNTMpKQ==