; tri-48

(define (isqrt n)
  (if (not (and (positive? n) (integer? n)))
      (error 'isqrt "must be positive integer")
      (let loop ((x n))
        (let ((y (quotient (+ x (quotient n x)) 2)))
          (if (< y x) (loop y) x)))))

(define (square? n)
  (let ((root (isqrt n)))
    (= (* root root) n)))

(define (squares n)
  (let loop ((x (isqrt n)) (y 0) (zs '()))
    (cond ((< x y) zs)
          ((< (+ (* x x) (* y y)) n) (loop x (+ y 1) zs))
          ((< n (+ (* x x) (* y y))) (loop (- x 1) y zs))
          (else (loop (- x 1) (+ y 1) (cons (list x y) zs))))))

(display (squares (* 48 48))) (newline)

(define (tri n)
  (let loop ((a 1))
    (let ((c (+ (* a a) (* n n))))
      (when (square? c)
        (display (sort (list a (isqrt c) n) <))
        (newline)))
    (when (< a 1000) (loop (+ a 1)))))

(tri 48)