try to understand matching brackets & evaluation.

Posted 28 January 2014 - 11:38 PM

Getting frustrated with trying to understand line 6. I'm pretty sure that the c parameters in this line refer to values that are to be matched up with potential key pairs in our left_symbols hash and that if no key is associated with the inputted value nil is returned. Other wise I am trying to work out the logic of this line. I am thrown off by left_symbols.key occurring twice in this line since I am interpreting that each occurrence of left_symbols.key outputs the same value in a single iteration of str. Thanks for any help.

This is lazy evaluation at work - you see this in many languages. A boolean operator evaluates its arguments from left to right, until it knows whether it can return true or false. && knows that it if the first argument is false, then the whole && is false (because false && true is false, and false && false is false) so it doesn't bother evaluating the right hand side, and the return is not executed. So that should clear up your other question.

As an aside, I'm not sure if there's a version issue or what it is but I'm getting an error on

left_symbols.key(c)

but when I change it to access the value with square brackets it seems to work fine so I'm going to assume that's what's meant.

Re: try to understand matching brackets & evaluation.

Posted 29 January 2014 - 01:20 PM

Just looked it up: the key() method returns the key for a particular value. So I was wrong to read it as an access, it's a reverse lookup. So if the hash has a key for c, and the key for c is not the next thing on the stack, then we have an unbalanced paren situation

Re: try to understand matching brackets & evaluation.

Posted 29 January 2014 - 02:49 PM

stack << c if left_symbols.key?(c)
# bung all the left-brackets on this stack
return false if left_symbols.key(c) && left_symbols.key(c) != stack.pop
# if this is a right-bracket then get its key, which is the corresponding left-bracket;
# if this left-bracket isn't the last one added to the stack then bail (return false),
# otherwise.. the left-bracket has been matched (to the right bracket) and is
# removed from the stack.

Any characters other than left or right-brackets are ignored.

When the sequence finishes all left-brackets will either have been removed, having been paired with their right-brackets, or there are one or more unmatched left-brackets left in stack.

The function will only return true if all left-brackets have been correctly matched, and popped, and the stack is therefore empty.

Re: try to understand matching brackets & evaluation.

Posted 29 January 2014 - 02:57 PM

This is how I bork it down. The break down is in the comments.

def valid_string?(str)
stack = []
left_symbols = { '{' => '}', '[' => ']', '(' => ')' }
str.each_char do |c|
stack << c if left_symbols.key?(c) # check if a string char is a left-bracket - if so stack it.
return false if left_symbols.key(c) && left_symbols.key(c) != stack.pop # the stack is only popped when right bracket are currently being iterated through and the match the last item stacked.
end
stack.empty? #this returns true or false
end
=begin
Line six immediately returns false on the left side of the && statement if the current character
in the iteration is a left-sided bracket. We are trying to match up right-sided brackets with
the left-sided brackets most recently collected in our stack.
In other words if the current character in the iteration is a left-sided bracket false is returned automatically preventing
access to the stack.pop side of the && statement.
stack elements can only be 'popped' off when the current character in the iteration has a key
that matches the last char that was added to stack. If the stack is empty at the end of this
iteration the order/closure of brackets was correct - false if not correct. Stacks are sweet.
=end
puts valid_string?('[ ]') == true #=> true
puts valid_string?('[ ') == false #=> true
puts valid_string?('[ ( text ) {} ]') == true #=> true
puts valid_string?('[ ( text { ) } ]') == false #=> true

The double use of key was very confusing.

This post has been edited by xclite: 29 January 2014 - 03:45 PM
Reason for edit:: Fixed some broke-ass code tags.