I've been looking into Ruby and felt I was learning quite a bit. I'm currently trying to solve the balanced brackets algorithm but struggling with a condition. Here's what I have:
def balanced?(list_of_brackets)
if list_of_brackets.length % 2 != 0
false
else
stack = []
bracket_sets = {
'{' => '}',
'[' => ']',
'(' => ')'
}
list_of_brackets.chars do |bracket|
if bracket == "{" or "[" or "("
puts "#{bracket} is an opening bracket"
else
puts "#{bracket} is a closing bracket"
end
end
end
stack.empty?
end
puts balanced?('{}()[]')
The result I get is:
{ is an opening bracket
} is an opening bracket
( is an opening bracket
) is an opening bracket
[ is an opening bracket
] is an opening bracket
The closing brackets are somehow getting through the first condition. I'm missing something here but I can't spot it. Maybe another set of eyes can help me here. I'd appreciate any help and/or advice!
CodePudding user response:
The if statement if bracket == "{" or "[" or "("
needs to have a bracket == X
for each or
condition in the statement. Change:
if bracket == "{" or "[" or "("
to
if bracket == "{" or bracket == "[" or bracket == "("
...and that should work. The full code would be:
def balanced?(list_of_brackets)
if list_of_brackets.length % 2 != 0
false
else
stack = []
bracket_sets = {
'{' => '}',
'[' => ']',
'(' => ')'
}
list_of_brackets.chars do |bracket|
if bracket == "{" or bracket == "[" or bracket == "("
puts "#{bracket} is an opening bracket"
else
puts "#{bracket} is a closing bracket"
end
end
end
stack.empty?
end
puts balanced?('{}()[]')
CodePudding user response:
This
if bracket == "{" or "[" or "("
is basically checking if bracket is equal to "{" or if "[" is truthy or "(" is truthy, you missed the bracket ==
for the rest of them. That's why they take the if branch and you get all of them are opening brackets. The solution for that problem is to compare every of them:
if bracket == "{" || bracket == "[" || bracket == "("
...
PS: make sure to not confuse OR
with ||
, they have a different procedence.
CodePudding user response:
I will use the term enclosures to refer to parentheses ('('
and ')'
), brackets ('['
and ']'
) and braces ('{'
and '}'
). A string of enclosures is balanced if:
- each left parenthesis has a matching right parenthesis, and vice-versa;
- each left bracket has a matching right bracket, and vice-versa;
- each left brace has a matching right brace, and vice-versa; and
- all matched pairs are well-nested in the sense every each matched pair must be separated by a string comprised of matched pairs.
For example, '([{}])'
is well-nested whereas '([{]})'
is not, as the string separating the matched pair '[..]'
('{'
) is not a matched pair.
If, in the code in the question, the length of the string is even stack
is initialized to an empty array never changed, so the return value stack.empty
will always be true
. For example, balanced?(')[') #=> true
. You need something like the following.
RIGHT_ENCLOSURE_PAIRS = { '}'=>'{', ']'=>'[', ')'=>'(' }
RIGHT_ENCLOSURES = RIGHT_ENCLOSURE_PAIRS.keys
def balanced?(str)
return false if str.length.odd?
stack = []
str.each_char do |c|
if RIGHT_ENCLOSURES.include?(c)
return false if stack.empty? || stack.last != RIGHT_ENCLOSURE_PAIRS[c]
stack.pop
else
stack << c
end
end
stack.empty?
end
balanced? '{}()[]' #=> true
balanced? '([{}])' #=> true
balanced? '([{}]{})' #=> true
balanced? '((([[[{{{}}}]]])))' #=> true
balanced? '{[]' #=> false
balanced? '{{(([[' #=> false
balanced? '{()[{]}(([]))' #=> false
I have not included puts
statements such as puts "#{c} is an opening enclosure"
as they would normally only be used for debugging, but they could of course be added if desired, in which case it might be more helpful to write
ENCLOSURE_TYPE = { '('=>'left parenthesis', ')'=>'right parenthesis',
'['=>'left bracket', ']'=>'right bracket',
'{'=>'left brace', '}'=>'right brace' }
puts "#{c} is a #{ENCLOSURE_TYPE[c]}"
CodePudding user response:
bracket == "{" or bracket == "[" or bracket == "("
can be shortened using this approach:
["{", "[" , "("].include? bracket