(defun range (min max) (loop for n from min below (+ max 1) by 1 collect n))
(defun sum (list) (apply '+ list))
(defun select (expr list) (remove-if-not expr list))
(defun filter (expr list) (remove-if expr list))
(defun empty (list) (eq list nil))

(defun partial (func &rest args1)
  (lambda (&rest args2)
    (apply func (append args1 args2)))
)

(defun prime (n)
  (eq (length (member T (mapcar (lambda (a) (and (eq (mod n a) 0) (/= n a))) (range 2 (sqrt n))))) 0)
)

(defun cartesian-helper (thing list)
  (if (empty list)
    nil
    (cons (list thing (first list)) (cartesian-helper thing (rest list)))
  )
)

(defun cartesian (list-one list-two)
  (if (empty list-one)
    nil
    (append (cartesian-helper (first list-one) list-two) (cartesian (rest list-one) list-two))
  )
)

(defun number-to-digit-list (num)
  (if (< num 10)
    (list num)
    (append (number-to-digit-list (floor (/ num 10))) (list (mod num 10)))
  )
)

(defun digit-list-to-number (digit-list)
  (if (empty digit-list)
    0
    (+ (* (first digit-list) (expt 10 (- (length digit-list) 1))) (digit-list-to-number (rest digit-list)))
  )
)

(defun is-palindrome (num)
  (let* ((digit-list (number-to-digit-list num)))
    (equal (reverse digit-list) digit-list))
)

(defun resolve-tuple (expr tuple)
  (funcall expr (first tuple) (second tuple))
)

(defun resolve-tuples (expr tuple-list)
  (mapcar (partial #'resolve-tuple expr) tuple-list)
)

(defun max-of (list)
  (reduce #'max list)
)

(defun eratosthenes-helper (expr list-one list-two)
  (if (> (length list-one) 0) (eratosthenes-helper expr (filter (partial expr (first list-one)) (rest list-one)) (filter (partial expr (first list-one)) list-two)) list-two)
)

(defun eratosthenes (n)
  (eratosthenes-helper (lambda (x a) (and (eq (mod a x) 0) (/= a x))) (range 2 (sqrt n)) (range 2 n))
)

(defun combinations (count list)
  (cond
    ((zerop count) '(())) ; one combination of zero element.
    ((endp list)   '())   ; no combination from noe element.
    (t (nconc (mapcar (let ((item (first list))) (lambda (combi) (cons item combi)))
                      (combinations (1- count) (rest list)))
              (combinations count (rest list))))))
