; list slices
(define (split n xs)
(let loop ((n n) (xs xs) (zs '()))
(if (or (zero? n) (null? xs))
(values (reverse zs) xs)
(loop (- n 1) (cdr xs) (cons (car xs) zs)))))
(define (filter pred? xs)
(let loop ((xs xs) (ys '()))
(cond ((null? xs) (reverse ys))
((pred? (car xs))
(loop (cdr xs) (cons (car xs) ys)))
(else (loop (cdr xs) ys)))))
(define (slice widths xs)
(let loop ((ws widths) (xs xs) (zs (list)))
(if (null? ws) (reverse zs)
(let-values (((front back) (split (car ws) xs)))
(loop (cdr ws) back (cons front zs))))))
(display (slice '(1 2 3) '(1 2 2 3 3 3))) (newline)
(display (slice '(1 2 3) '(1 2 2 3))) (newline)
(display (slice '(1 2 3) '(1 2 2))) (newline)
(display (slice '(1 2 3) '(1 2 2 3 3 3 4 4 4 4))) (newline)
(display (let ((xs (map list->string
(slice '(3 3 4)
(filter char-numeric?
(string->list "123.456.7890"))))))
(string-append "(" (car xs) ")" (cadr xs) "-" (caddr xs))))
(newline)