# tomboland's solution

## to Matching Brackets in the OCaml Track

Published at Oct 01 2019 · 0 comments
Instructions
Test suite
Solution

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

## Getting Started

1. For library documentation, follow Useful OCaml resources.

## Running Tests

A Makefile is provided with a default target to compile your solution and run the tests. At the command line, type:

make


## Submitting Incomplete Solutions

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

## Feedback, Issues, Pull Requests

The exercism/ocaml repository on GitHub is the home for all of the Ocaml exercises.

If you have feedback about an exercise, or want to help implementing a new one, head over there and create an issue or submit a PR. We welcome new contributors!

## Source

Ginna Baker

### test.ml

open Base
open OUnit2
open Matching_brackets

let ae exp got _test_ctxt =
assert_equal exp got ~printer:Bool.to_string

let tests = [
"paired square brackets" >::
ae true (are_balanced "[]");
"empty string" >::
ae true (are_balanced "");
"unpaired brackets" >::
ae false (are_balanced "[[");
"wrong ordered brackets" >::
ae false (are_balanced "}{");
"wrong closing bracket" >::
ae false (are_balanced "{]");
"paired with whitespace" >::
ae true (are_balanced "{ }");
"partially paired brackets" >::
ae false (are_balanced "{[])");
"simple nested brackets" >::
ae true (are_balanced "{[]}");
"several paired brackets" >::
ae true (are_balanced "{}[]");
"paired and nested brackets" >::
ae true (are_balanced "([{}({}[])])");
"unopened closing brackets" >::
ae false (are_balanced "{[)][]}");
"unpaired and nested brackets" >::
ae false (are_balanced "([{])");
"paired and wrong nested brackets" >::
ae false (are_balanced "[({]})");
"paired and incomplete brackets" >::
ae false (are_balanced "{}[");
"too many closing brackets" >::
ae false (are_balanced "[]]");
"math expression" >::
ae true (are_balanced "(((185 + 223.85) * 15) - 543)/2");
"complex latex expression" >::
ae true (are_balanced "\\left(\\begin{array}{cc} \\frac{1}{3} & x\\\\ \\mathrm{e}^{x} &... x^2 \\end{array}\\right)");
]

let () =
run_test_tt_main ("matching-brackets tests" >::: tests)
open Base
open Batteries

type bracket_type = Parens | Square | Braces
type orientation = Opening | Closing

let bracket_type_from_char = function
| '(' -> Some (Parens, Opening)
| ')' -> Some (Parens, Closing)
| '[' -> Some (Square, Opening)
| ']' -> Some (Square, Closing)
| '{' -> Some (Braces, Opening)
| '}' -> Some (Braces, Closing)
| _ -> None

let check_next_char (b : bracket_type list option) (c : char) = match b, c with
| None, _ -> None
| (Some []), c -> (match bracket_type_from_char c with
| Some (btype, Opening) -> Some [btype]
| Some (_, Closing) -> None
| None -> Some [])
| Some (h :: t), c -> (match bracket_type_from_char c with
| Some (btype, Opening) -> Some (btype :: h :: t)
| Some (btype, Closing) -> if (phys_equal btype h) then Some t else None
| None -> Some (h :: t))

let are_balanced s =
let res = List.fold_left check_next_char (Some []) (String.to_list s) in
match res with
| Some [] -> true
| _ -> false