; jumping jack
(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 (jack n)
(define (diff-parity? t n)
(not (= (modulo t 2) (modulo n 2))))
(let loop ((k 0) (t 0))
(if (or (< t (abs n)) (diff-parity? t (abs n)))
(loop (+ k 1) (+ t k 1))
k)))
(define (jacks n)
(define (diff-parity? t n)
(not (= (modulo t 2) (modulo n 2))))
(if (negative? n)
(map (lambda (x) (- x)) (jacks (- n)))
(let loop ((k 0) (t 0))
(if (or (< t n) (diff-parity? t n))
(loop (+ k 1) (+ t k 1))
(let loop ((d (/ (- t n) 2)) (xs (range k 0)) (zs (list)))
(if (null? xs) zs
(if (<= (car xs) d)
(loop (- d (car xs)) (cdr xs) (cons (- (car xs)) zs))
(loop d (cdr xs) (cons (car xs) zs)))))))))
(do ((n -24 (+ n 1))) ((= n 25))
(display n) (display #\tab) (display (jack n))
(display #\tab) (display (jacks n)) (newline))