約数を求める(完全版)

(define nil '())

(define (gen-primes limit)
  (let ((v (make-vector (+ limit 1) 1)))
    
    (define (set-not-prime! ini-idx)
      (define (iter i)
        (if (> i limit)
            'done
            (begin
              (vector-set! v i 0)
              (iter (+ i ini-idx)))))
      (iter (* ini-idx 2)))
    
    (define (init)
      (vector-set! v 0 0)
      (vector-set! v 1 0)
      (set-not-prime! 2))

    (define (set-prime! i)
      (if (> i (floor (sqrt limit)))
          'done
          (begin
            (set-not-prime! i)
            (set-prime! (+ i 2)))))

    (define (print-prime l h)
      (define (iter i)
        (if (> i h)
            (newline)
            (begin
              (display (vector-ref v i))
              (display " ")
              (iter (+ i 1)))))
      (iter l))

    (define (count-prime)
      (define (iter i c)
        (if (> i limit)
            c
            (iter (+ i 1) (+ c (vector-ref v i)))))
      (iter 1 0))

    (define (make-primes n)
      (let ((primes (make-vector n 0)))
        (define (iter i j)
          (cond ((>= j n) primes)
                (else
                 (let ((p (vector-ref v i)))
                   (if (= p 1)
                       (begin
                         (vector-set! primes j i)
                         (iter (+ i 1) (+ j 1)))
                       (iter (+ i 1) j ))))))
        (iter 2 0)))
    
    (begin
      (init)
      (set-prime! 3)
      (make-primes (count-prime)))))

(define (prime? n)
  (let ((primes (gen-primes 100)))
    (define (search l h)
      (let* ((m (+ l (floor (/ (- h l) 2))))
             (p (vector-ref primes m)))
        (cond ((> l h) #false)
              ((= n p) #true)
              ((< n p) (search l (- m 1)))
              (else (search (+ m 1) h)))))
    (if (< n 2)
        #false
        (search 0 (- (vector-length primes) 1)))))

(define (factorize num)
  (let ((primes (gen-primes num)))
    (define (iter n i facts)
      (if (= n 1)
          facts
          (let ((p (vector-ref primes i)))
            (if (= 0 (remainder n p))
                (iter (/ n p) i (append facts (cons p nil)))
                (iter n (+ i 1) facts)))))
    (if (prime? num)
        (list num)
        (iter num 0 nil))))

;;

(define (element-of-set? x set)
  (cond ((null? set) #f)
        ((equal? x (car set)) #t)
        (else (element-of-set? x (cdr set)))))

(define (uniq set)
  (define (iter x s)
    (if (null? x)
        s
        (iter (cdr x)
              (if (element-of-set? (car x) s)
                  s
                  (cons (car x) s)))))
  (iter set nil))

(define (subsets s)
  (if (null? s)
      (list nil)
      (let ((rest (subsets (cdr s))))
        (append rest (map (lambda (x) (cons (car s) x)) rest)))))

(define (divisor num)
  (let ((facts (factorize num)))
    (cons 1
          (sort (map (lambda (x) (apply * x)) (uniq (cdr (subsets facts))))))))

gen-prime, prime?, factorize 手続きを実装しました。
それぞれ、素数列を生成する手続き、素数判定をする手続き、素因数分解した結果をリストで返す手続きです。
素数列は大きくなるのでリストではなく、vector を使っています。また、素数の生成のアルゴリズムはエラトステネスの篩を使用しています。

divisor 手続きは、引数に数値を受け取るようにして、factorize 手続きを使うように修正します。

gosh> (divisor 12)
(1 2 3 4 6 12)
gosh> (divisor 256)
(1 2 4 8 16 32 64 128 256)
gosh> (divisor 111)
(1 3 37 111)

このように約数を求めることができます。