; 8/10 palindromes
(define (digits n . args)
(let ((b (if (null? args) 10 (car args))))
(let loop ((n n) (d '()))
(if (zero? n) d
(loop (quotient n b)
(cons (modulo n b) d))))))
(define (undigits ds . args)
(let ((b (if (null? args) 10 (car args))))
(let loop ((ds ds) (n 0))
(if (null? ds) n
(loop (cdr ds) (+ (* n b) (car ds)))))))
(define (pal? xs) (equal? xs (reverse xs)))
(do ((n 0 (+ n 1))) ((< 100000 n))
(when (and (pal? (digits n)) (pal? (digits n 8)))
(display n) (newline)))
(define-syntax define-generator
(lambda (x)
(syntax-case x (lambda)
((stx name (lambda formals e0 e1 ...))
(with-syntax ((yield (datum->syntax (syntax stx) 'yield)))
(syntax (define name
(lambda formals
(let ((resume #f) (return #f))
(define yield
(lambda args
(call-with-current-continuation
(lambda (cont)
(set! resume cont)
(apply return args)))))
(lambda ()
(call-with-current-continuation
(lambda (cont)
(set! return cont)
(cond (resume (resume))
(else (let () e0 e1 ...)
(error 'name "unexpected return"))))))))))))
((stx (name . formals) e0 e1 ...)
(syntax (stx name (lambda formals e0 e1 ...)))))))
(define-generator (palindromes)
(do ((k 0 (+ k 1))) ((= k 10))
(yield k))
(do ((i 1 (* i 10))) (#f)
(do ((j i (+ j 1))) ((= j (* 10 i)))
(let ((ds (digits j)))
(yield (undigits (append ds (reverse ds))))))
(do ((j i (+ j 1))) ((= j (* 10 i)))
(let ((ds (digits j)))
(do ((k 0 (+ k 1))) ((= k 10))
(yield (undigits (append ds (list k) (reverse ds)))))))))
(let ((p (palindromes)))
(do ((n (p) (p))) ((< 100000000 n))
(when (pal? (digits n 8))
(display n) (newline))))