; hamming numbers

(define (hamming n)
  (let ((aq (make-vector (+ n 1) 0))
        (i2 1) (i3 1) (i5 1) (x2 2) (x3 3) (x5 5))
    (vector-set! aq 1 1)
    (do ((h 2 (+ h 1))) ((< n h) aq)
      (let ((t (min x2 x3 x5)))
        (vector-set! aq h t)
        (when (= x2 t)
          (set! i2 (+ i2 1))
          (set! x2 (* 2 (vector-ref aq i2))))
        (when (= x3 t)
          (set! i3 (+ i3 1))
          (set! x3 (* 3 (vector-ref aq i3))))
        (when (= x5 t)
          (set! i5 (+ i5 1))
          (set! x5 (* 5 (vector-ref aq i5))))))))

(define (nth-hamming n) (vector-ref (hamming n) n))

(define h1000 (hamming 1000))

(do ((i 1 (+ i 1))) ((< 1000 i))
  (display i) (display #\tab)
  (display (vector-ref h1000 i))
  (newline))

(newline)

(display (nth-hamming 1000000)) (newline)
