; square pyramidal numbers

(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 (list)))
              (if (le? (cadr args) x) (reverse xs)
                (loop (+ x (caddr args)) (cons x xs))))))
    (else (error 'range "unrecognized arguments"))))

(define (sum xs) (apply + xs))

(define (square x) (* x x))

(define (sq-pyr n) (sum (map square (range 1 (+ n 1)))))

(display (sq-pyr 15)) (newline)

(define (sq-pyr n) (/ (+ (* 2 n n n) (* 3 n n) n) 6))

(display (sq-pyr 15)) (newline)

(display (sq-pyr 1000000)) (newline)