using PureFun
using PureFun.Linked: List
The balanced parentheses problem:
Given a string s containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid.
An input string is valid if:
- Open brackets must be closed by the same type of brackets.
- Open brackets must be closed in the correct order.
So, for example:
()
: valid()[]{}
: valid(]
: invalid{[}
]: invalid{[{()}]}
: valid
we start with some helper functions:
isopening(char) = char ∈ [ '(', '{', '[' ]
isclosing(char) = char ∈ [ ')', '}', ']' ]
function bracketmatch(b1, b2)
b1 == '(' && b2 == ')' ||
b1 == '{' && b2 == '}' ||
b1 == '[' && b2 == ']'
end;
For the main logic, we traverse the characters of the input string, keeping track of any unclosed open brackets we've seen on a stack. If we encounter a closing bracket, we check whether it closes the most recent opening bracket, and if it does we continue to match the previous opening bracket.
function balanced(chars, opens)
isempty(chars) && return isempty(opens)
c, rest... = chars
isopening(c) ?
balanced(rest, c ⇀ opens) :
valid(opens, c) && balanced(rest, popfirst(opens))
end
valid(opens, c) = !isempty(opens) && bracketmatch(opens[1], c);
We can overload balanced
to do the initial setup:
balanced(input) = balanced(input, empty(List(input)));
let's see how it works:
test_data = ["()", "()[]{}", "(]", "{[}]", "{[{()}]}"]
expected = [true, true, false, false, true]
actual = map(balanced, test_data)
all(actual .== expected)
true
This page was generated using Literate.jl.