; balanced delimiters
(define (balanced? str)
(let ((starters '(#\( #\[ #\{)) (enders '(#\) #\] #\})))
(let loop ((cs (string->list str)) (xs (list)))
(cond ((null? cs) (null? xs)) ; #t if stack is empty, or #f
((member (car cs) starters) ; push starter on stack
(loop (cdr cs) (cons (car cs) xs)))
((member (car cs) enders) ; pop matching ender from stack, or #f
(and (pair? xs)
(or (and (char=? (car xs) #\() (char=? (car cs) #\)))
(and (char=? (car xs) #\[) (char=? (car cs) #\]))
(and (char=? (car xs) #\{) (char=? (car cs) #\})))
(loop (cdr cs) (cdr xs))))
(else (loop (cdr cs) xs)))))) ; neither starter nor ender
(display (map balanced?
'("{}" "[]" "()" "a(b)c" "abc[d]" "a(b)c{d[e]}" ; these work
"{]" "(]" "a(b]c" "abc[d}" "a(b)c{d[e}]"))) ; these don't