; consecutive sums

(define (range . args)
  (case (length args)
    ((1) (range 0 (car args) (if (negative? (car args)) -1 1)))
    ((2) (range (car args) (cadr args) (if (< (car args) (cadr args)) 1 -1)))
    ((3) (let ((le? (if (negative? (caddr args)) >= <=)))
           (let loop ((x(car args)) (xs '()))
             (if (le? (cadr args) x)
                 (reverse xs)
                 (loop (+ x (caddr args)) (cons x xs))))))
    (else (error 'range "unrecognized arguments"))))

(define (consums n)
  (let loop ((i 1) (j 1) (s 0) (zs (list)))
    ;(display i) (display " ") (display j) (display " ")
    ;(display s) (display " ") (display zs) (newline)
    (cond ((< n (+ i i 1)) (reverse zs))
          ((< s n) (loop i (+ j 1) (+ s j) zs))
          ((< n s) (loop (+ i 1) (+ i 1) 0 zs))
          (else (loop (+ i 1) (+ i 1) 0
                      (cons (range i j) zs))))))

(display (consums 15)) (newline)

(define (consums n)
  (let loop ((len 2) (seqs (list)))
    (let ((sum (/ (* len (+ len 1)) 2)))
      (if (< n sum) seqs
        (if (positive? (modulo (- n sum) len))
            (loop (+ len 1) seqs)
            (let* ((mid (quotient n len))
                   (start (- mid (quotient len 2)
                             (if (even? len) -1 0)))
                   (seq (range start (+ start len))))
              (loop (+ len 1) (cons seq seqs))))))))

(display (consums 15)) (newline)

(display (map (lambda (n) (length (consums n)))
              '(10 100 1000 10000 100000 1000000)))