(ns grep-n)
(use 'clojure.test)
(defn grep-n [n f coll])
(deftest grep-n-test
(is (= '(0 1 2)
(grep-n 1 #{1} (range 10))))
(is (= '(2 3 4)
(grep-n 1 #{3} (range 10))))
(is (= '(4 5 6 7 8)
(grep-n 2 #{6} (range 10))))
(is (= '(3 4 5 6 7 12 13 14 15 16)
(grep-n 2 #{5 14} (range 20))))
(is (= '(0 1 2 3 4 5 6 7 8)
(grep-n 3 #{3 5} (range 10))))
(is (= '(4 5 6)
(grep-n 2 #{4} (range 4 10))))
(is (= '(3 4 5 6 7)
(grep-n 2 #(= 0 (mod % 5)) (range 1 10)))))
(run-tests)
;; be lazy :)
;; (take 15 (map println (grep-n 1 #(= 0 (mod % 5)) (iterate #(do (Thread/sleep 1000) (inc %)) 1))))
;; use prop based testing
;; (require '[clojure.test.check :as tc])
;; (require '[clojure.test.check.generators :as gen])
;; (require '[clojure.test.check.properties :as prop])
;; (def x (gen/sorted-set gen/nat))
;; (def y (gen/such-that not-empty x))
;; (def n (gen/such-that #(> % 0) gen/nat))
;; (def z (gen/bind y (fn [nn] (gen/tuple (gen/return nn) n (gen/large-integer* {:min (inc (apply max nn))})))))
;; (def grep-n-check
;; (prop/for-all [[matches n range-end] z]
;; (= (filter #(< % range-end) (remove neg? (into (sorted-set) (mapcat #(range (- % n) (+ % (inc n))) matches))))
;; (grep-n n matches (range range-end)))))