From 36ef6a20b6a6d13c7881498c18b4ca601b069a15 Mon Sep 17 00:00:00 2001 From: Isaac Good Date: Sun, 27 Sep 2026 10:12:12 -0700 Subject: [PATCH] [matching-brackets] Add new practice exercise --- config.json | 8 ++ .../matching-brackets/.docs/instructions.md | 5 + .../matching-brackets/.docs/introduction.md | 8 ++ .../matching-brackets/.meta/config.json | 18 +++ .../matching-brackets/.meta/example.gd | 9 ++ .../matching-brackets/.meta/template.j2 | 7 ++ .../matching-brackets/.meta/tests.toml | 70 +++++++++++ .../matching-brackets/matching_brackets.gd | 2 + .../matching_brackets_test.gd | 118 ++++++++++++++++++ 9 files changed, 245 insertions(+) create mode 100644 exercises/practice/matching-brackets/.docs/instructions.md create mode 100644 exercises/practice/matching-brackets/.docs/introduction.md create mode 100644 exercises/practice/matching-brackets/.meta/config.json create mode 100644 exercises/practice/matching-brackets/.meta/example.gd create mode 100644 exercises/practice/matching-brackets/.meta/template.j2 create mode 100644 exercises/practice/matching-brackets/.meta/tests.toml create mode 100644 exercises/practice/matching-brackets/matching_brackets.gd create mode 100644 exercises/practice/matching-brackets/matching_brackets_test.gd diff --git a/config.json b/config.json index e05a153..21683d7 100644 --- a/config.json +++ b/config.json @@ -274,6 +274,14 @@ "practices": [], "prerequisites": [], "difficulty": 2 + }, + { + "slug": "matching-brackets", + "name": "Matching Brackets", + "uuid": "5b341290-4baa-4e11-8b31-0b177a3b025d", + "practices": [], + "prerequisites": [], + "difficulty": 4 } ] }, diff --git a/exercises/practice/matching-brackets/.docs/instructions.md b/exercises/practice/matching-brackets/.docs/instructions.md new file mode 100644 index 0000000..ea17084 --- /dev/null +++ b/exercises/practice/matching-brackets/.docs/instructions.md @@ -0,0 +1,5 @@ +# Instructions + +Given a string containing brackets `[]`, braces `{}`, parentheses `()`, or any combination thereof, verify that any and all pairs are matched and nested correctly. +Any other characters should be ignored. +For example, `"{what is (42)}?"` is balanced and `"[text}"` is not. diff --git a/exercises/practice/matching-brackets/.docs/introduction.md b/exercises/practice/matching-brackets/.docs/introduction.md new file mode 100644 index 0000000..0618221 --- /dev/null +++ b/exercises/practice/matching-brackets/.docs/introduction.md @@ -0,0 +1,8 @@ +# Introduction + +You're given the opportunity to write software for the Bracketeer™, an ancient but powerful mainframe. +The software that runs on it is written in a proprietary language. +Much of its syntax is familiar, but you notice _lots_ of brackets, braces and parentheses. +Despite the Bracketeer™ being powerful, it lacks flexibility. +If the source code has any unbalanced brackets, braces or parentheses, the Bracketeer™ crashes and must be rebooted. +To avoid such a scenario, you start writing code that can verify that brackets, braces, and parentheses are balanced before attempting to run it on the Bracketeer™. diff --git a/exercises/practice/matching-brackets/.meta/config.json b/exercises/practice/matching-brackets/.meta/config.json new file mode 100644 index 0000000..2f62a05 --- /dev/null +++ b/exercises/practice/matching-brackets/.meta/config.json @@ -0,0 +1,18 @@ +{ + "authors": [ + "IsaacG" + ], + "files": { + "solution": [ + "matching_brackets.gd" + ], + "test": [ + "matching_brackets_test.gd" + ], + "example": [ + ".meta/example.gd" + ] + }, + "blurb": "Make sure the brackets and braces all match.", + "source": "Ginna Baker" +} diff --git a/exercises/practice/matching-brackets/.meta/example.gd b/exercises/practice/matching-brackets/.meta/example.gd new file mode 100644 index 0000000..75acfca --- /dev/null +++ b/exercises/practice/matching-brackets/.meta/example.gd @@ -0,0 +1,9 @@ +func is_paired(data: String) -> bool: + var stack = [] + for char in data: + if char in "[({": + stack.append(char) + if char in "])}": + if not stack or stack.pop_back() != {"]": "[", ")": "(", "}": "{"}[char]: + return false + return not stack diff --git a/exercises/practice/matching-brackets/.meta/template.j2 b/exercises/practice/matching-brackets/.meta/template.j2 new file mode 100644 index 0000000..2de124f --- /dev/null +++ b/exercises/practice/matching-brackets/.meta/template.j2 @@ -0,0 +1,7 @@ +{% for case in cases %} +func test_{{ case.func_name }}(solution_script): + var inputs = {{ case.given | togdscript }} + var expected = {{ case.expected }} + return [solution_script.{{ case.property | camel_to_snake }}(inputs), expected] + +{% endfor %} diff --git a/exercises/practice/matching-brackets/.meta/tests.toml b/exercises/practice/matching-brackets/.meta/tests.toml new file mode 100644 index 0000000..35a98a0 --- /dev/null +++ b/exercises/practice/matching-brackets/.meta/tests.toml @@ -0,0 +1,70 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[81ec11da-38dd-442a-bcf9-3de7754609a5] +description = "paired square brackets" + +[287f0167-ac60-4b64-8452-a0aa8f4e5238] +description = "empty string" + +[6c3615a3-df01-4130-a731-8ef5f5d78dac] +description = "unpaired brackets" + +[9d414171-9b98-4cac-a4e5-941039a97a77] +description = "wrong ordered brackets" + +[f0f97c94-a149-4736-bc61-f2c5148ffb85] +description = "wrong closing bracket" + +[754468e0-4696-4582-a30e-534d47d69756] +description = "paired with whitespace" + +[ba84f6ee-8164-434a-9c3e-b02c7f8e8545] +description = "partially paired brackets" + +[3c86c897-5ff3-4a2b-ad9b-47ac3a30651d] +description = "simple nested brackets" + +[2d137f2c-a19e-4993-9830-83967a2d4726] +description = "several paired brackets" + +[2e1f7b56-c137-4c92-9781-958638885a44] +description = "paired and nested brackets" + +[84f6233b-e0f7-4077-8966-8085d295c19b] +description = "unopened closing brackets" + +[9b18c67d-7595-4982-b2c5-4cb949745d49] +description = "unpaired and nested brackets" + +[a0205e34-c2ac-49e6-a88a-899508d7d68e] +description = "paired and wrong nested brackets" + +[1d5c093f-fc84-41fb-8c2a-e052f9581602] +description = "paired and wrong nested brackets but innermost are correct" + +[ef47c21b-bcfd-4998-844c-7ad5daad90a8] +description = "paired and incomplete brackets" + +[a4675a40-a8be-4fc2-bc47-2a282ce6edbe] +description = "too many closing brackets" + +[a345a753-d889-4b7e-99ae-34ac85910d1a] +description = "early unexpected brackets" + +[21f81d61-1608-465a-b850-baa44c5def83] +description = "early mismatched brackets" + +[99255f93-261b-4435-a352-02bdecc9bdf2] +description = "math expression" + +[8e357d79-f302-469a-8515-2561877256a1] +description = "complex latex expression" diff --git a/exercises/practice/matching-brackets/matching_brackets.gd b/exercises/practice/matching-brackets/matching_brackets.gd new file mode 100644 index 0000000..efa87e9 --- /dev/null +++ b/exercises/practice/matching-brackets/matching_brackets.gd @@ -0,0 +1,2 @@ +func is_paired(data: String) -> bool: + pass diff --git a/exercises/practice/matching-brackets/matching_brackets_test.gd b/exercises/practice/matching-brackets/matching_brackets_test.gd new file mode 100644 index 0000000..3e2bfde --- /dev/null +++ b/exercises/practice/matching-brackets/matching_brackets_test.gd @@ -0,0 +1,118 @@ +func test_paired_square_brackets(solution_script): + var inputs = "[]" + var expected = true + return [solution_script.is_paired(inputs), expected] + + +func test_empty_string(solution_script): + var inputs = "" + var expected = true + return [solution_script.is_paired(inputs), expected] + + +func test_unpaired_brackets(solution_script): + var inputs = "[[" + var expected = false + return [solution_script.is_paired(inputs), expected] + + +func test_wrong_ordered_brackets(solution_script): + var inputs = "}{" + var expected = false + return [solution_script.is_paired(inputs), expected] + + +func test_wrong_closing_bracket(solution_script): + var inputs = "{]" + var expected = false + return [solution_script.is_paired(inputs), expected] + + +func test_paired_with_whitespace(solution_script): + var inputs = "{ }" + var expected = true + return [solution_script.is_paired(inputs), expected] + + +func test_partially_paired_brackets(solution_script): + var inputs = "{[])" + var expected = false + return [solution_script.is_paired(inputs), expected] + + +func test_simple_nested_brackets(solution_script): + var inputs = "{[]}" + var expected = true + return [solution_script.is_paired(inputs), expected] + + +func test_several_paired_brackets(solution_script): + var inputs = "{}[]" + var expected = true + return [solution_script.is_paired(inputs), expected] + + +func test_paired_and_nested_brackets(solution_script): + var inputs = "([{}({}[])])" + var expected = true + return [solution_script.is_paired(inputs), expected] + + +func test_unopened_closing_brackets(solution_script): + var inputs = "{[)][]}" + var expected = false + return [solution_script.is_paired(inputs), expected] + + +func test_unpaired_and_nested_brackets(solution_script): + var inputs = "([{])" + var expected = false + return [solution_script.is_paired(inputs), expected] + + +func test_paired_and_wrong_nested_brackets(solution_script): + var inputs = "[({]})" + var expected = false + return [solution_script.is_paired(inputs), expected] + + +func test_paired_and_wrong_nested_brackets_but_innermost_are_correct(solution_script): + var inputs = "[({}])" + var expected = false + return [solution_script.is_paired(inputs), expected] + + +func test_paired_and_incomplete_brackets(solution_script): + var inputs = "{}[" + var expected = false + return [solution_script.is_paired(inputs), expected] + + +func test_too_many_closing_brackets(solution_script): + var inputs = "[]]" + var expected = false + return [solution_script.is_paired(inputs), expected] + + +func test_early_unexpected_brackets(solution_script): + var inputs = ")()" + var expected = false + return [solution_script.is_paired(inputs), expected] + + +func test_early_mismatched_brackets(solution_script): + var inputs = "{)()" + var expected = false + return [solution_script.is_paired(inputs), expected] + + +func test_math_expression(solution_script): + var inputs = "(((185 + 223.85) * 15) - 543)/2" + var expected = true + return [solution_script.is_paired(inputs), expected] + + +func test_complex_latex_expression(solution_script): + var inputs = "\\left(\\begin{array}{cc} \\frac{1}{3} & x\\\\ \\mathrm{e}^{x} &... x^2 \\end{array}\\right)" + var expected = true + return [solution_script.is_paired(inputs), expected]