(module assignment1 racket
  ;question 1
  (define (drop-divisible divisor number-list)
    (filter (lambda (x)
              (or
               (not
                (eq? (modulo x divisor) 0))
               (eq? x divisor)))
            number-list))

  ;question 2
  (define (sieve-with divisor-list number-list)
    (define (iter divs lst)
      (cond
        [(empty? divs) lst]
        [else (iter (rest divs) (drop-divisible (first divs) lst))]))
    (iter divisor-list number-list))

  ;question 3
  (define (sieve potential-prime)
    ;never need to check for primes below 2
    ;you also never need to check for a number above the square root in a given range
    ;plus one just for off by one errors
    (sieve-with (range 2 (+ (integer-sqrt potential-prime) 1)) (range 2 potential-prime)))
    

  (module+ test
    (require rackunit)
    (check-equal? (drop-divisible 2 (list 2 3 4 5 6 7 8 9 10)) (list 2 3 5 7 9))
    (check-equal? (drop-divisible 3 (list 2 3 4 5 6 7 8 9 10)) (list 2 3 4 5 7 8 10))
    (check-equal? (drop-divisible 5 (list 2 3 4 5 6 7 8 9 10)) (list 2 3 4 5 6 7 8 9))

    (check-equal? (sieve-with '(2 3) (list 2 3 4 5 6 7 8 9 10)) (list 2 3 5 7))
    (check-equal? (sieve-with '() (list 2 3 4 5 6 7 8 9 10)) (list 2 3 4 5 6 7 8 9 10))

    (check-equal? (sieve 10) (list 2 3 5 7))

    ;question 4
    (require math/number-theory)
    (check-equal? (sieve 100) (filter prime? (range 1 100)))
    (check-equal? (sieve 100000) (filter prime? (range 1 100000)))
    ))