; three farmers
(define-syntax fold-of
(syntax-rules (range in is)
((_ "z" f b e) (set! b (f b e)))
((_ "z" f b e (v range fst pst stp) c ...)
(let* ((x fst) (p pst) (s stp)
(le? (if (positive? s) <= >=)))
(do ((v x (+ v s))) ((le? p v) b)
(fold-of "z" f b e c ...))))
((_ "z" f b e (v range fst pst) c ...)
(let* ((x fst) (p pst) (s (if (< x p) 1 -1)))
(fold-of "z" f b e (v range x p s) c ...)))
((_ "z" f b e (v range pst) c ...)
(fold-of "z" f b e (v range 0 pst) c ...))
((_ "z" f b e (x in xs) c ...)
(do ((t xs (cdr t))) ((null? t) b)
(let ((x (car t)))
(fold-of "z" f b e c ...))))
((_ "z" f b e (x is y) c ...)
(let ((x y)) (fold-of "z" f b e c ...)))
((_ "z" f b e p? c ...)
(if p? (fold-of "z" f b e c ...)))
((_ f i e c ...)
(let ((b i)) (fold-of "z" f b e c ...)))))
(define-syntax list-of (syntax-rules ()
((_ arg ...) (reverse (fold-of
(lambda (d a) (cons a d)) '() arg ...)))))
(display
(list-of (list am pm first second third)
(c range 1 52) (pm range 1 202)
(zero? (modulo (- 10500 (* (- 52 c) pm)) c))
(am is (quotient (- 10500 (* (- 52 c) pm)) c))
(zero? (modulo (- 3500 (* 10 pm)) (- am pm)))
(zero? (modulo (- 3500 (* 16 pm)) (- am pm)))
(zero? (modulo (- 3500 (* 26 pm)) (- am pm)))
(first is (quotient (- 3500 (* 10 pm)) (- am pm)))
(second is (quotient (- 3500 (* 16 pm)) (- am pm)))
(third is (quotient (- 3500 (* 26 pm)) (- am pm)))
(<= 0 first 10) (<= 0 second 16) (<= 0 third 26)))