#lang scheme
(provide (all-defined-out))
(require test-engine/scheme-tests)

;; List Utilities

;; Remove the first element satisfying f (if any).
;; (X -> Boolean) [Listof X] -> [Listof X]
(define (remf f ls)
  (cond [(empty? ls) empty]
        [(f (first ls)) (rest ls)]
         (cons (first ls)
               (remf f (rest ls)))]))

;; X [Listof X] -> [Listof X]
;; Interleave x between each pair of elements in ys.
(define (interleave x ys)
  (cond [(empty? ys) ys]
        [(empty? (rest ys)) (list (first ys))]
         (cons (first ys)
               (cons x
                     (interleave x (rest ys))))]))

(check-expect (interleave 'a (make-list 3 'b))
              (list 'b 'a 'b 'a 'b))

;; [Listof X] Index -> [Listof X]
(define (remove-at ls i)
  (append (take ls i)
          (drop ls (add1 i))))

(check-expect (remove-at (list 'a) 0) empty)
(check-expect (remove-at (list 'a 'b) 0) (list 'b))
(check-expect (remove-at (list 'a 'b) 1) (list 'a))
;; [Listof X] X Index -> [Listof X]
(define (replace-at ls x i)
  (append (take ls i)
          (list x)
          (drop ls (add1 i))))

(check-expect (replace-at (list 'a) 'x 0) (list 'x))
(check-expect (replace-at (list 'a 'b) 'x 0) (list 'x 'b))
(check-expect (replace-at (list 'a 'b) 'x 1) (list 'a 'x))