<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jonathan Patterson</title>
    <description>The latest articles on DEV Community by Jonathan Patterson (@jonpatt92).</description>
    <link>https://dev.to/jonpatt92</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F352484%2Fc4764973-6cac-49f9-ac03-9a9bb6667d42.jpeg</url>
      <title>DEV Community: Jonathan Patterson</title>
      <link>https://dev.to/jonpatt92</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jonpatt92"/>
    <language>en</language>
    <item>
      <title>Solving the common Well-Formed-Strings technical challenge using stacks in Ruby</title>
      <dc:creator>Jonathan Patterson</dc:creator>
      <pubDate>Mon, 20 Apr 2020 00:38:44 +0000</pubDate>
      <link>https://dev.to/jonpatt92/solving-the-common-well-formed-strings-technical-challenge-using-stacks-in-ruby-1j02</link>
      <guid>https://dev.to/jonpatt92/solving-the-common-well-formed-strings-technical-challenge-using-stacks-in-ruby-1j02</guid>
      <description>&lt;p&gt;Like it or not, technical challenges are a common part of today's interview process for developers. &lt;/p&gt;

&lt;p&gt;One of the most common technical challenges you might encounter is sometimes referred to as 'Well Formed Strings'. It challenges you to take a string of assorted brackets "({(([]))})" and validate whether or not the opening brackets are closed in the same order they were opened. &lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Well-Formed Strings

A string of characters like "({12}[34(56){67}])" is said to be well-formed
if every opening bracket (square, curly, or parentheses) has a matching
close AND the closing bracket comes in the opposite order of the opening.*

* Valid: "({12}[34(56){67}])"
* Invalid "({12)"
* Invalid "({12)}"

Write a validator that can determine the well-formed-ness of an input string.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Stacks
&lt;/h2&gt;

&lt;p&gt;This challenge can be solved using a &lt;strong&gt;Stack&lt;/strong&gt;. &lt;br&gt;
Stacks are Last In First Out (LIFO) data structures that follow simple rules. Elements in a stack are added or removed from the top of the stack.  &lt;/p&gt;

&lt;p&gt;You can think of a stack like an empty pringles can. &lt;br&gt;
You start by adding pringles one at a time to the can. When you decide to start removing them, you begin with the pringle at the top. &lt;em&gt;eg: The last pringle you added.&lt;/em&gt;&lt;br&gt;
You keep removing them in order until finally you remove the last pringle, which was the first one you added.&lt;/p&gt;

&lt;p&gt;In our solution we are going to use an Array to signify the stack. &lt;/p&gt;

&lt;h2&gt;
  
  
  Pseudocode
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Start by creating a Hash with Key/Value pairs. Each Key will represent an opening bracket. Each Value will represent the corresponding closing bracket. We will use this to evaluate the characters in the input string. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Next iterate over the input string's characters. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If the Character is an opening bracket (represented by a Key in the valid_pairs hash) then we will &lt;code&gt;push&lt;/code&gt; that Character into our Stack. &lt;/li&gt;
&lt;li&gt;If the Character matches the last character pushed into the stack, then remove the last character in the stack. &lt;/li&gt;
&lt;li&gt;If neither of these are true, but the Character is a closing bracket, then the string is not 'well-formed' and our validation fails. &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;&lt;p&gt;By the end of this process, we should have a Stack that is empty. Since all the matching pairs will have been removed from the stack. If the Stack is Not empty, then we haven't matched all pairs and the string is not 'well-formed'. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Solution
&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input_string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="c1"&gt;# Establish valid key/value pairs #&lt;/span&gt;
  &lt;span class="n"&gt;valid_pairs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s1"&gt;'('&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;')'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="s1"&gt;'{'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'}'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="s1"&gt;'['&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;']'&lt;/span&gt; 
                &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="c1"&gt;# Establish the array which will be our stack #&lt;/span&gt;
  &lt;span class="n"&gt;stack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

  &lt;span class="c1"&gt;# Iterate over each character in the input_string argument #&lt;/span&gt;
  &lt;span class="n"&gt;input_string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;chars&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;character&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;

    &lt;span class="c1"&gt;# If the character is an opening bracket, #&lt;/span&gt;
    &lt;span class="c1"&gt;## represented as one of the 'keys' in the valid_pairs hash ##&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;valid_pairs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has_key?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;character&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="c1"&gt;### Then push that character onto the end of the stack ###&lt;/span&gt;
      &lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;character&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# If the last character on the stack is a key in the valid_pairs hash, # &lt;/span&gt;
    &lt;span class="c1"&gt;## whose matching value is == to the current character ##&lt;/span&gt;
    &lt;span class="k"&gt;elsif&lt;/span&gt; &lt;span class="n"&gt;valid_pairs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;last&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;character&lt;/span&gt;
      &lt;span class="c1"&gt;### Then remove the last character from the stack, ###&lt;/span&gt;
      &lt;span class="c1"&gt;#### since the current character forms a perfect match to the last character ####&lt;/span&gt;
      &lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pop&lt;/span&gt;

    &lt;span class="c1"&gt;# If neither of the above conditions are true, #&lt;/span&gt;
    &lt;span class="c1"&gt;## yet the character is a value in our valid_pairs hash, ##&lt;/span&gt;
    &lt;span class="c1"&gt;### then the character is a closing bracket, ###&lt;/span&gt;
    &lt;span class="c1"&gt;#### that doesn't match an open bracket in our stack ####&lt;/span&gt;
    &lt;span class="k"&gt;elsif&lt;/span&gt; &lt;span class="n"&gt;valid_pairs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has_value?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;character&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="c1"&gt;##### Meaning our string isn't matching and fails #####&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="c1"&gt;# The string is well formed if the stack is left with no characters, # &lt;/span&gt;
  &lt;span class="c1"&gt;## since we removed all matched characters, ##&lt;/span&gt;
  &lt;span class="c1"&gt;### if the stack array isn't empty it means unmatched characters are left ###&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;zero?&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Solution without comments
&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input_string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;valid_pairs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s1"&gt;'('&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;')'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="s1"&gt;'{'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'}'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="s1"&gt;'['&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;']'&lt;/span&gt; 
                &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;stack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

  &lt;span class="n"&gt;input_string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;chars&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;character&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;valid_pairs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has_key?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;character&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;character&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;elsif&lt;/span&gt; &lt;span class="n"&gt;valid_pairs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;last&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;character&lt;/span&gt;
      &lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pop&lt;/span&gt;
    &lt;span class="k"&gt;elsif&lt;/span&gt; &lt;span class="n"&gt;valid_pairs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has_value?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;character&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;zero?&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;By using this method of Key/Value pairs and a First-In-Last-Out Stack that tracks your matches, you could expand the valid_pairs hash to handle all kinds of match validations. &lt;/p&gt;

</description>
      <category>ruby</category>
      <category>techchallenge</category>
      <category>stack</category>
      <category>techinterview</category>
    </item>
  </channel>
</rss>
