; longest consecutive sequence of squares
(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 (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 (squares n)
(define (square x) (* x x))
(let loop ((lo 1) (hi 1) (sum 1))
(cond ((< n (* hi hi)) (list))
((< sum n) (loop lo (+ hi 1) (+ sum (square (+ hi 1)))))
((< n sum) (loop (+ lo 1) hi (- sum (square lo))))
(else (list lo hi)))))
(define (sum-squares lo hi)
(define (sum-squares n) (* n (+ n 1) (+ n n 1) 1/6))
(- (sum-squares hi) (sum-squares (- lo 1))))
(display (squares 595)) (newline)
(display (sum-squares 6 12)) (newline)
(display
(map (lambda (xs) (sum-squares (car xs) (cadr xs)))
(filter pair? (map squares (range 300)))))