Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Balanced brackets conditional issue

Tags:

ruby

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!

like image 721
J. Finlay Avatar asked Dec 31 '21 15:12

J. Finlay


People also ask

What is balanced Paranthesis problem?

The most basic version of this problem asks, given a string containing only ( and ) , are the parentheses in the string balanced? For the parentheses to be balanced, each open parenthesis must have a corresponding close parenthesis, in the correct order.

How do you know if a bracket is balanced?

Search if the top of the stack is the opening bracket of the same nature. If this holds then pop the stack and continue the iteration , in the end if the stack is empty, it means all brackets are well-formed and return Balanced , else return Not Balanced.

How do I know if my braces are balanced Python?

One approach to check balanced parentheses is to use stack. Each time, when an open parentheses is encountered push it in the stack, and when closed parenthesis is encountered, match it with the top of stack and pop it. If stack is empty at the end, return Balanced otherwise, Unbalanced.

What is a balance brackets problem?

Balance Brackets is a very common problem. In general the idea is that you are given a set of brackets and are sked to determine if the brackets are balanced. I knew I have solved similar versions of the problem.

What is a matching pair of brackets that is not balanced?

A matching pair of brackets is not balanced if the set of brackets it encloses are not matched. For example, { [ (])} is not balanced because the contents in between { and } are not balanced.

How do you know if a string of brackets is balanced?

By this logic, we say a sequence of brackets is balanced if the following conditions are met: It contains no unmatched brackets. The subset of brackets enclosed within the confines of a matched pair of brackets is also a matched pair of brackets. Given strings of brackets, determine whether each sequence of brackets is balanced.

What is an example of an unbalanced string?

For example, if the input is “ { [ (])}”, the pair of square brackets, “ []”, encloses a single unbalanced opening round bracket, “ (“. Similarly, the pair of round brackets, “ ()”, encloses a single unbalanced closing square bracket, “]”. Thus, the input string “ { [ (])}” is unbalanced.


3 Answers

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?('{}()[]')
like image 89
DogEatDog Avatar answered Oct 24 '22 06:10

DogEatDog


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.

like image 3
Sebastian Palma Avatar answered Oct 24 '22 06:10

Sebastian Palma


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 zero or more matched pairs.

For example, '([{}])' is well-nested whereas '([{]})' is not, as the string separating the matched pair, '[' and ]', namely '{', 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 that is 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)
  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 initially had the following guard clause as the first line of the method.

return false if str.length.odd?

After reflection, however, I removed it, as the time spent executing it unnecessarily for strings with even numbers of enclosures was probably much greater than the time saved for strings with odd numbers of enclosures.

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]}"
like image 3
Cary Swoveland Avatar answered Oct 24 '22 04:10

Cary Swoveland