; jane's homework

(define range (case-lambda ; start, start+step, ..., start+step<stop
  ((stop) (range 0 stop (if (negative? stop) -1 1)))
  ((start stop) (range start stop (if (< start stop) 1 -1)))
  ((start stop step) (let ((le? (if (negative? step) >= <=)))
    (let loop ((x start) (xs (list)))
      (if (le? stop x) (reverse xs) (loop (+ x step) (cons x xs))))))
  (else (error 'range "unrecognized arguments"))))

(define (sum xs) (apply + xs)) ; sum of elements of xs

(define digits (case-lambda ; list of base-b digits of n
  ((n) (digits n 10))
  ((n b) (do ((n n (quotient n b))
              (ds (list) (cons (modulo n b) ds)))
             ((zero? n) ds)))))

(define (part k xs) ; k'th lexicographical left-partition of xs
  (let loop ((ds (reverse (digits k 2))) (xs xs) (ys (list)))
    (if (null? ds) (reverse ys)
      (if (zero? (car ds))
          (loop (cdr ds) (cdr xs) ys)
          (loop (cdr ds) (cdr xs) (cons (car xs) ys))))))

(define (max-lcm xs) ; max lcm of part-sums of 2-partitions of xs
  (let ((len (length xs)) (tot (sum xs)))
    (apply max (map (lambda (s) (lcm s (- tot s)))
                    (map sum (map (lambda (k) (part k xs))
                                  (range (expt 2 (- len 1)))))))))

(display (max-lcm '(2 3 4))) (newline) ; 20
(display (max-lcm '(2 3 4 6))) (newline) ; 56