; minimum split

(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 (sum xs) (apply + xs))

(define (min-split xs)
  (let loop ((i 0) (lo 0) (los (list)) (hi (sum xs)) (his xs)
             (best-point 0) (best-value (sum xs)))
    (cond ((or (null? his) (= lo hi)) (split best-point xs))
          ((< (abs (- lo hi)) best-value)
            (loop (+ i 1) (+ lo (car his)) (cons (car his) los)
                  (- hi (car his)) (cdr his) i (abs (- lo hi))))
          (else (loop (+ i 1) (+ lo (car his)) (cons (car his) los)
                      (- hi (car his)) (cdr his) best-point best-value)))))

(call-with-values
  (lambda () (min-split '(2 7 3 1 4)))
  (lambda (los his)
    (display los) (newline)
    (display his) (newline)))

(newline)

(call-with-values
  (lambda () (min-split '(1 2 4 7 3)))
  (lambda (los his)
    (display los) (newline)
    (display his) (newline)))

(newline)

(call-with-values
  (lambda () (min-split '(5 -5)))
  (lambda (los his)
    (display los) (newline)
    (display his) (newline)))