Verify Brainfuck program
Brainfuck 76 bytes
>>+[<+++++++++[->---------<]+>-[--[[-]<->]<[<[->-]>[<+]<]>]<[-<+>]+>,]<<[<+]
This goes out of it's bonds if square brackets are unbalanced turning the bf interpreter/compiler to fail runtime and some of them have exit codes to reflect that.
requires eof=0, wrapping values and finit number of cells
In Ubuntu you can use the interpreter bf
(sudo apt-get install bf
)
% echo '[[[]' | bf -n bf_matching.bf
Error: Out of range! Youwanted to '<' below the first cell.
To solve, add some '>'s at the beginning, for example.
an error occured
% echo $?
5
% bf -n bf_matching.bf < bf_matching.bf
% echo $?
0
Befunge 98 - 26 31 20 19 chars
~:']-!\'[-!-+:0`j#q
Got rid of some massive conditionals. Now the program works as follows:
~: read an input char and duplicate it
']-! push a 1 if the char is the ] char, 0 otherwise
\ swap the comparison value for the duplicated input char
'[-! push a 1 if the char is the [ char, 0 otherwise
- subtract the two comparison values. If the second one is 1, the first is 0,
so the result is -1. Else if the second one is 0, the first is 1 and the result is
1. Else, the first and the second are both 0 and the result is 0
+ Add the number to the counter (which is 0 if there is none already)
:0` test if the counter is positive (that'd mean an invalid program). Pushes a 1 if
positive, 0 otherwise.
j#q if the counter is positive, then this jumps to the q. Otherwise, it skips the q
and continues to the ~ at the beginning of the line. If there are no more chars in
the input, then the IP will be sent back to the q.
q
quits the program and pops the top value as an error value. The error value will be -1 1 if there are too many ]
's, 0 if they are balanced, and positive negative if there are too many [
's. If the number is positive negative, then that many the absolute value of that number ]
's are needed to balance the program.
Edit: Switched increment and decrement. [
used to increment the counter and ]
used to decrement it. By switching it, I save 1 char, because for the exit condition, I only have to check if the counter is positive, rather than negative.
Old version
~:'[-!j;\1+\#;']-!j;1-#;:0\`j#q
This code works as follows:
~ read one char of input
: duplicate it
'[-! push 1 if the character is [, 0 otherwise
j jump that number of characters
; skip until next ;
\1+\ increment counter
similarily for ].
#q when end of input is reached, ~ reflects the IP back. q ends the program with the error value on the stack.
Edit: realized that this accepted inputs like ][
, now it ends whenever the count gets negative, using
:0\`j
ruby (64)
exit $<.read.tr('^[]','').tap{|x|0while x.gsub!('[]','')}.empty?
previously (68) it was:
exit ARGF.read.tr('^[]','').tap{|x| 0 while x.gsub!('[]','')}.empty?
Another equivalent solution uses
exit $<.read.tr('^[]','').tap{|x|0while x.gsub!('[]','')}.size>0
can't use size
alone because it would give false negatives (!!!) when the total number of unbalanced brackets is multiple of 256