(use 'clojure.contrib.lazy-seqs)
(def *ubound* 1000000)
(def prms (take-while #(< % *ubound*) primes))
(def prmsums (map + prms (lazy-cons 0 prmsums)))
(def primerange
     (let [primevec (vec prmsums)] ;this takes a couple of secs, once
       (fn [from to]
         (- (get primevec to) (get primevec (dec from) 0)))))
(defn find-range-for [n minlen]
  (loop [from 0 to minlen expand? true]
    (let [v (primerange from to)
          l (- (inc to) from)]
      (cond (< l minlen) nil
            (< v n)      (if expand? (recur from (inc to) true))
            (> v n)      (recur (inc from) to false)
            :else        [from to l]))))
(apply primerange
       (loop [[p & ps] (reverse prms) m 1 opt nil]
         (if p
           (let [[f t l] (find-range-for p m)]
             (if f
               (recur ps (max m l) (if (> l m) [f t] opt))
               (recur ps m opt)))


(use '[clojure.contrib.lazy-seqs :only (primes)])
(defn make-seq-accumulator [seq]
  (map first (iterate (fn [[sum s]]
            [(+ sum (first s)) (next s)])
              [(first seq) (rest seq)])))
(def prime-sums (conj (make-seq-accumulator primes) 0))
(defn euler-50 [goal]
  (loop [c   1]
    (let [bots (reverse (take c prime-sums))
      tops (take c (reverse (take-while #(> goal (- % (last bots)))
                        (rest prime-sums))))]
      (if-let [v (some #(if (prime? %) % nil)
               (map #(- %1 %2) tops bots))]
    (recur (inc c))))))
(euler-50 1000000) ;; "Elapsed time: 2.675548 msecs"