diff --git a/list.rkt b/list.rkt index cfe39c3..44d050f 100644 --- a/list.rkt +++ b/list.rkt @@ -93,3 +93,17 @@ [(> j (length xs)) (error 'sublist (format "ending index ~a exceeds length of list" j))] [(>= j i) (take (drop xs i) (- j i))] [else (error 'sublist (format "starting index ~a is larger than ending index ~a" i j))])) + +(define increasing-positive? (λ(xs) (apply < 0 xs))) +(define increasing-positive-list? (and/c list? increasing-positive?)) + +(define+provide/contract (break-at xs bps) + (list? (and/c coerce/list? increasing-positive-list?) . -> . (listof list?)) + (when (ormap (λ(bp) (>= bp (length xs))) bps) + (error 'break-at (format "breakpoint in ~v is greater than or equal to input list length = ~a" bps (length xs)))) + ;; easier to do back to front, because then the list index for each item won't change during the recursion + (reverse (let loop ([xs xs][bps (reverse bps)]) + (if (empty? bps) + (cons xs null) ; return whatever's left, because no more splits are possible + (let-values ([(head tail) (split-at xs (car bps))]) + (cons tail (loop head (cdr bps)))))))) \ No newline at end of file diff --git a/tests.rkt b/tests.rkt index 9e2ed8a..1016b85 100644 --- a/tests.rkt +++ b/tests.rkt @@ -160,4 +160,8 @@ (check-equal? (sublist (range 5) 0 0) '()) (check-equal? (sublist (range 5) 0 1) '(0)) -(check-equal? (sublist (range 5) 0 5) '(0 1 2 3 4)) \ No newline at end of file +(check-equal? (sublist (range 5) 0 5) '(0 1 2 3 4)) + +(check-equal? (break-at '(5 6 7 8) '(1 2 3)) '((5) (6) (7) (8))) +(check-equal? (break-at '(5 6 7 8) '(1 3)) '((5) (6 7) (8))) +(check-equal? (break-at '(5 6 7 8) '(1)) (break-at '(5 6 7 8) 1)) \ No newline at end of file