Avatar of paulfioravanti

paulfioravanti's solution

to Matching Brackets in the Ruby Track

Published at Jul 13 2018 · 0 comments
Instructions
Test suite
Solution

Note:

This solution was written on an old version of Exercism. The tests below might not correspond to the solution code, and the exercise may have changed since this code was written.

Bracket Push

Given a string containing brackets [], braces {}, parentheses (), or any combination thereof, verify that any and all pairs are matched and nested correctly.


For installation and learning resources, refer to the Ruby resources page.

For running the tests provided, you will need the Minitest gem. Open a terminal window and run the following command to install minitest:

gem install minitest

If you would like color output, you can require 'minitest/pride' in the test file, or note the alternative instruction, below, for running the test file.

Run the tests from the exercise directory using the following command:

ruby bracket_push_test.rb

To include color from the command line:

ruby -r minitest/pride bracket_push_test.rb

Source

Ginna Baker

Submitting Incomplete Solutions

It's possible to submit an incomplete solution so you can see how others have completed the exercise.

bracket_push_test.rb

require 'minitest/autorun'
require_relative 'bracket_push'

# Common test data version: 1.5.0 20dd164
class BracketPushTest < Minitest::Test
  def test_paired_square_brackets
    # skip
    assert Brackets.paired?('[]')
  end

  def test_empty_string
    skip
    assert Brackets.paired?('')
  end

  def test_unpaired_brackets
    skip
    refute Brackets.paired?('[[')
  end

  def test_wrong_ordered_brackets
    skip
    refute Brackets.paired?('}{')
  end

  def test_wrong_closing_bracket
    skip
    refute Brackets.paired?('{]')
  end

  def test_paired_with_whitespace
    skip
    assert Brackets.paired?('{ }')
  end

  def test_partially_paired_brackets
    skip
    refute Brackets.paired?('{[])')
  end

  def test_simple_nested_brackets
    skip
    assert Brackets.paired?('{[]}')
  end

  def test_several_paired_brackets
    skip
    assert Brackets.paired?('{}[]')
  end

  def test_paired_and_nested_brackets
    skip
    assert Brackets.paired?('([{}({}[])])')
  end

  def test_unopened_closing_brackets
    skip
    refute Brackets.paired?('{[)][]}')
  end

  def test_unpaired_and_nested_brackets
    skip
    refute Brackets.paired?('([{])')
  end

  def test_paired_and_wrong_nested_brackets
    skip
    refute Brackets.paired?('[({]})')
  end

  def test_paired_and_incomplete_brackets
    skip
    refute Brackets.paired?('{}[')
  end

  def test_too_many_closing_brackets
    skip
    refute Brackets.paired?('[]]')
  end

  def test_math_expression
    skip
    assert Brackets.paired?('(((185 + 223.85) * 15) - 543)/2')
  end

  def test_complex_latex_expression
    skip
    string = '\left(\begin{array}{cc} \frac{1}{3} & x\\ ' +
             '\mathrm{e}^{x} &... x^2 \end{array}\right)'
    assert Brackets.paired?(string)
  end
end
# frozen_string_literal: true

module Brackets
  OPENING_BRACKETS = "([{"
  private_constant :OPENING_BRACKETS
  CLOSING_BRACKETS = ")]}"
  private_constant :CLOSING_BRACKETS
  WHITESPACE = /\s/.freeze
  private_constant :WHITESPACE

  module_function

  def paired?(string)
    string = remove_white_space(string)
    return true if string.empty?

    catch(:halt) do
      string
        .each_char
        .with_object([], &method(:check_pair))
        .empty?
    end
  end

  def remove_white_space(string)
    string.gsub(WHITESPACE, "")
  end
  private_class_method :remove_white_space

  def check_pair(char, acc)
    throw(:halt, false) if
      closing_bracket?(char) && no_matching_opening_bracket?(acc, char)

    acc.push(char) if opening_bracket?(char)
  end
  private_class_method :check_pair

  def closing_bracket?(char)
    CLOSING_BRACKETS.include?(char)
  end
  private_class_method :closing_bracket?

  def no_matching_opening_bracket?(acc, char)
    acc.pop != char.tr(CLOSING_BRACKETS, OPENING_BRACKETS)
  end

  def opening_bracket?(char)
    OPENING_BRACKETS.include?(char)
  end
  private_class_method :opening_bracket?
end

Community comments

Find this solution interesting? Ask the author a question to learn more.

What can you learn from this solution?

A huge amount can be learned from reading other people’s code. This is why we wanted to give exercism users the option of making their solutions public.

Here are some questions to help you reflect on this solution and learn the most from it.

  • What compromises have been made?
  • Are there new concepts here that you could read more about to improve your understanding?