Fun with Matching Braces

PHP, -4 (156 - 20*3 - 30 - 50 - 20)

<?php $x=preg_replace("!(//.*|/\*.*\*/|[^()[\]{}<>])!sm",'',$argv[1]);while(strlen($x)!=strlen($x=str_replace(str_split('()[]{}<>',2),'',$x)));print $x?0:1;
  1. It removes comments
  2. It filters out all characters different than (, ), [, ], {, }, <, >
  3. It replaces all (), [], {}, <> pairs until there are no matches
  4. Prints 1 if the string is empty, 0 otherwise

(Edit: changed the regex; the source code is now 156 instead of 175)


GolfScript, 38 chars − 3 × 20 − 30 = −52 points

0\{")]>}([<{"?.4/"4^^{0}*

;"n/=~}/;]!

Prints 1 if all the braces in the input are correctly balanced, 0 otherwise.

Bonus points for:

  • handling all four types of braces: 3 × 20 points
  • not allowing mismatched braces: 30 points

This solution uses the GolfScript internal stack to keep track of which braces have been seen so far. When an opening brace is encountered, it is pushed onto the stack; when a closing brace is encountered, the code checks if there's a matching opening brace on the stack. If there is, it is popped off; otherwise a sentinel value (0) matching no brace is push onto the stack, ensuring that it cannot ever be popped off.

One such sentinel value is pushed onto the stack at the beginning, to guard against stack underflow if there are too many closing braces. At the end, the program simply checks whether the stack is empty except for the initial sentinel value.


Perl, (136 130 129 chars - (20*3) - 30 - 50 - 20 - 50) == -81

<3 recursive REs.

$/=$_;print!(<>!~m#^(([^][<{('"/)}>]|'[^']*'|"[^"]*"|/((?![*/])|\*((?!\*/).)*\*/|/[^\n]*+)|<(?1)>|\((?1)\)|\[(?1)]|{(?1)})*)$#s)