Coding for Scrubs: Checking for Pairs (, {, [ (Ruby)

Aymes S.
3 min readApr 6, 2021

Welcome to another installment of “Coding for Scrubs,” where I, the self-proclaimed scrub, aim to improve my development skills through coding exercises. If you’re new here, I hope you find these posts helpful too. Let’s dive into this week’s coding challenge!

Problem:

We’re tasked with creating a function that checks whether parentheses (, brackets [, or braces { in a string have their corresponding closing pairs. For example, the string "(){[]}" should return false because { lacks a closing pair, whereas "(([{}]))" should return true.

Pseudocode:

Before diving into code, let’s outline our approach in simple English:

  1. Define opening characters.
  2. Track unmatched characters.
  3. Loop through the string.
  4. Flag an error on encountering an unmatched closing character.
  5. Keep track of opening characters and scrutinize closing ones.

Let’s Code!

Let’s start by defining our function, isBalanced, and initializing the variables for opening characters and an array to keep track of unpaired characters.

def isBalanced(string)
openers = ["(", "[", "{"]
unpaired = []
end
  • def isBalanced(string): Begins the definition of the function isBalanced that takes a string as its argument.
  • openers = ["(", "[", "{"]: Declares an array openers containing the opening characters (parentheses, brackets, braces).
  • unpaired = []: Initializes an empty array unpaired to keep track of opening characters that haven't been paired with their closing counterparts.

Next, we’ll break the string into characters and iterate through them. For each character, we’ll check if it’s an opening character; if so, we’ll add it to the unpaired array. Otherwise, we'll check for its corresponding closing character and remove the matched opener using .pop().

string.split('').each do |char|

string.each_char do |char|: Iterates through each character in the string. The each_char method is used instead of .split('') for better readability and direct access to each character.

if openers.include?(char)
unpaired.push(char)
  • if openers.include?(char): Checks if the current character char is an opening character.
  • unpaired.push(char): If it is an opening character, it's added to the unpaired array.
   else
partner = unpaired.pop
case char
when ")"
return false unless partner == "("
when "]"
return false unless partner == "["
when "}"
return false unless partner == "{"
else
return nil
end
end
  • else: This block is executed if the character is not an opening character.
  • partner = unpaired.pop: Removes the last element from unpaired and assigns it to partner. This represents the opening character that we're trying to match.
  • case char: Begins a case statement based on the current character.
  • when ")": Checks if the character is a closing parenthesis.
  • return false unless partner == "(": Returns false if the partner is not the corresponding opening parenthesis (.
  • Similarly, the checks for "]" and "}" ensure that the closing characters match their respective openers. If not, false is returned.
  • else return nil: If the character is not a recognized opener or closer, nil is returned.

The last step is to check if our unpaired array is empty. If it is, it means all opening characters have been successfully matched with their closing counterparts, so the function returns ‘true’.

def isBalanced(string)
openers ["(", "[", "{"]
unpaired = []

string.split('').each do |char|
if openers.include?(char)
unpaired.push(char)
else
partner = unpaired.pop
case char
when ")"
return false unless partner == "("
when "]"
return false unless partner == "["
when "}"
return false unless partner == "{"
else
return nil
end
end
end

unpaired.empty?
end

Thank you for following along with this series. Stay tuned for more coding adventures next week!

--

--