; 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)