; nearly-square divisors
(define (nsq-div1 n)
(let loop ((d 1))
(if (and (zero? (modulo n d))
(<= n (* d d)))
(list d (/ n d))
(loop (+ d 1)))))
(display (nsq-div1 36)) (newline)
(display (nsq-div1 60)) (newline)
(display (nsq-div1 183783600)) (newline)
(define (unique eql? xs)
(cond ((null? xs) '())
((null? (cdr xs)) xs)
((eql? (car xs) (cadr xs))
(unique eql? (cdr xs)))
(else (cons (car xs) (unique eql? (cdr xs))))))
(define (factors n)
(if (even? n) (cons 2 (factors (/ n 2)))
(let loop ((n n) (f 3) (fs '()))
(cond ((< n (* f f)) (reverse (cons n fs)))
((zero? (modulo n f))
(loop (/ n f) f (cons f fs)))
(else (loop n (+ f 2) fs))))))
(define (divisors n)
(define (times x) (lambda (y) (* x y)))
(let divs ((fs (factors n)))
(unique = (sort
(if (null? fs) '(1)
(let ((ds (divs (cdr fs))))
(append ds (map (times (car fs)) ds)))) <))))
(define (nsq-div2 n)
(let* ((divs (divisors n))
(len (length divs))
(b (list-ref divs (quotient (- len 1) 2))))
(list (/ n b) b)))
(display (nsq-div2 36)) (newline)
(display (nsq-div2 60)) (newline)
(display (nsq-div2 183783600)) (newline)