On Tue, 2006-05-09 at 04:01 +0900, James Edward Gray II wrote:
> Ross Bamford has submitted a quiz that exceeded the mark I said I
> would give a book to.  Way to go Ross!  (Thanks to everyone else who
> entered as well.)

Wow - I never win _anything_ :) Part of me wants to say I couldn't take
the prize, to let the contest run, but another part of me (the part
that's wanted this book for ages and still doesn't have it ;)) just
can't do that... Thanks to everyone who coded up solutions, and big
thanks to James for the contest, and for running the Ruby Quiz.

Here's my own basic solution, modified slightly as we refined the
problem:

#!/usr/local/bin/ruby
def check_parens(s, parens = '()[]{}')
stack = []
s = s.gsub(/\\[#{Regexp.escape(parens)}]/, '')
s.split(//).each_with_index do |c,i|
if tp = parens.index(c)
if tp == (pg_start = (tp / 2) * 2)
# opening paren
stack << [c,i]
else
# closing paren
if (stack.last || []).first == parens[pg_start,1]
stack.pop
else
stack << [c,i]
break
end
end
end
end
stack
end

def balanced_and_valid?(s, parens = '()[]{}')
!!if check_parens(s,parens).empty?
rx = /#{parens.scan(/../).map { |e| Regexp.escape(e) }.join('|')}/
true unless s =~ rx
end
end

if \$0 == __FILE__
raise ArgumentError, 'No input', [] unless brackets = ARGV.first
exit(balanced_and_valid?(brackets) ? 0 : 1)
end

--
Ross Bamford - rosco / roscopeco.REMOVE.co.uk