; maximum product of two primes less than n

(define (primes n)
  (let ((sieve (make-vector (+ n 1) #t)))
    (let loop ((p 2)(ps (list)))
      (cond ((< n p) (reverse ps))
            ((vector-ref sieve p)
              (do ((i (* p p) (+ i p))) ((< n i))
                (vector-set! sieve i #f))
              (loop (+ p 1) (cons p ps)))
            (else (loop (+ p 1) ps))))))

(define (max-prod-primes n)
  (let* ((ps (list->vector (primes (quotient n 2))))
         (len (vector-length ps)))
    (define (p n) (vector-ref ps n))
    (let loop ((lo 0) (hi (- len 1)) (max-lo 0)
               (max-hi (- len 1)) (max-prod 0))
      (cond ((< hi lo) (list (p max-lo) (p max-hi) max-prod))
            ((< n (* (p lo) (p hi)))
              (loop lo (- hi 1) max-lo max-hi max-prod))
            ((< max-prod (* (p lo) (p hi)))
              (loop (+ lo 1) hi lo hi (* (p lo) (p hi))))
            (else (loop (+ lo 1) hi max-lo max-hi max-prod))))))

(display (max-prod-primes 27)) (newline)
(display (max-prod-primes 50)) (newline)