; The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17.
; Find the sum of all the primes below two million.
(set! *warn-on-reflection* true)
(defn zero-multiples-of [n nums]
  (loop [new-nums nums mult-ix (- (* n n) 2)]
	(if (>= mult-ix (count nums)) new-nums
	  (recur (assoc new-nums mult-ix 0) (+ n mult-ix)))))

(defn ith-p [nums target-ix]
  (loop [nums-found 0 vec-ix 0]
    (if (>= vec-ix (count nums)) nil
	  (let [cur-num (nth nums vec-ix)]
		(if (and (pos? cur-num) (= nums-found target-ix)) cur-num
		  (recur
			(if (pos? cur-num) (inc nums-found) nums-found)
			(inc vec-ix)))))))

(defn sieve-to [^Integer max]
  (loop [nums (vec (range 2 max)) i 0 p 2]
	(if (>= (* p p) max) nums
	  (let [new-nums (zero-multiples-of p nums)]
		(recur new-nums (inc i) (ith-p new-nums (inc i)))))))

(println
  ;(zero-multiples-of 3 (vec (range 2 100)))
  ;(sieve-to 100)
  (time (reduce + (sieve-to 200000)))
)