Skip to content

Commit 6b51caa

Browse files
Add matching-brackets
1 parent 7c6f713 commit 6b51caa

File tree

13 files changed

+3669
-0
lines changed

13 files changed

+3669
-0
lines changed

config.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,14 @@
263263
"prerequisites": [],
264264
"difficulty": 5
265265
},
266+
{
267+
"slug": "matching-brackets",
268+
"name": "Matching Brackets",
269+
"uuid": "9fd84688-1a9e-4ac6-b474-91063f321d04",
270+
"practices": [],
271+
"prerequisites": [],
272+
"difficulty": 6
273+
},
266274
{
267275
"slug": "pascals-triangle",
268276
"name": "Pascal's Triangle",
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Instructions
2+
3+
Given a string containing brackets `[]`, braces `{}`, parentheses `()`, or any combination thereof, verify that any and all pairs are matched and nested correctly.
4+
Any other characters should be ignored.
5+
For example, `"{what is (42)}?"` is balanced and `"[text}"` is not.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Introduction
2+
3+
You're given the opportunity to write software for the Bracketeer™, an ancient but powerful mainframe.
4+
The software that runs on it is written in a proprietary language.
5+
Much of its syntax is familiar, but you notice _lots_ of brackets, braces and parentheses.
6+
Despite the Bracketeer™ being powerful, it lacks flexibility.
7+
If the source code has any unbalanced brackets, braces or parentheses, the Bracketeer™ crashes and must be rebooted.
8+
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™.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"authors": [
3+
"keiravillekode"
4+
],
5+
"files": {
6+
"solution": [
7+
"matching_brackets.s"
8+
],
9+
"test": [
10+
"matching_brackets_test.c"
11+
],
12+
"example": [
13+
".meta/example.s"
14+
]
15+
},
16+
"blurb": "Make sure the brackets and braces all match.",
17+
"source": "Ginna Baker"
18+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
.text
2+
.globl is_paired
3+
4+
/*
5+
| Register | Usage | Type | Description |
6+
| -------- | ------------ | ------- | -------------------------------- |
7+
| `a0` | input | address | null-terminated string |
8+
| `a1` | temporary | address | input pointer |
9+
| `t0` | temporary | address | original stack pointer |
10+
| `t1` | temporary | byte | input character |
11+
| `t2` | temporary | byte | opening character |
12+
| `t3` | temporary | byte | closing character |
13+
*/
14+
15+
/* extern int is_paired(const char *value); */
16+
is_paired:
17+
move t0, sp
18+
move a1, a0
19+
j read
20+
21+
loop:
22+
li t2, '[' /* '[' is the expected opening character */
23+
li t3, ']' /* when closing character ']' is found */
24+
beq t1, t3, close
25+
26+
li t2, '{' /* '{' is the expected opening character */
27+
li t3, '}' /* when closing character '}' is found */
28+
beq t1, t3, close
29+
30+
li t2, '(' /* '(' is the expected opening character */
31+
li t3, ')' /* when closing character ')' is found */
32+
beq t1, t3, close
33+
34+
li t2, '['
35+
beq t1, t2, open
36+
37+
li t2, '{'
38+
beq t1, t2, open
39+
40+
li t2, '('
41+
beq t1, t2, open
42+
43+
read:
44+
lb t1, 0(a1) /* Load a character, */
45+
addi a1, a1, 1 /* Increment the pointer */
46+
bnez t1, loop /* if not end of string, continue loop. */
47+
48+
restore:
49+
sltu a0, sp, t0
50+
xori a0, a0, 1 /* Check if all brackets have matched. */
51+
move sp, t0 /* Restore original stack pointer. */
52+
53+
return:
54+
ret
55+
56+
open:
57+
add sp, sp, -8 /* Push character onto the stack */
58+
sb t2, 0(sp)
59+
j read
60+
61+
close:
62+
sltu a0, sp, t0 /* Set a0 to 1 if there are open brackets, otherwise 0. */
63+
beqz a0, return /* If there are no open brackets, return. */
64+
65+
lb t1, 0(sp) /* Read the top opening bracket. */
66+
bne t1, t2, restore /* If different from expected, restore stack and report no match. */
67+
68+
addi sp, sp, 8 /* Pop opening character from stack. */
69+
j read
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# This is an auto-generated file.
2+
#
3+
# Regenerating this file via `configlet sync` will:
4+
# - Recreate every `description` key/value pair
5+
# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications
6+
# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)
7+
# - Preserve any other key/value pair
8+
#
9+
# As user-added comments (using the # character) will be removed when this file
10+
# is regenerated, comments can be added via a `comment` key.
11+
12+
[81ec11da-38dd-442a-bcf9-3de7754609a5]
13+
description = "paired square brackets"
14+
15+
[287f0167-ac60-4b64-8452-a0aa8f4e5238]
16+
description = "empty string"
17+
18+
[6c3615a3-df01-4130-a731-8ef5f5d78dac]
19+
description = "unpaired brackets"
20+
21+
[9d414171-9b98-4cac-a4e5-941039a97a77]
22+
description = "wrong ordered brackets"
23+
24+
[f0f97c94-a149-4736-bc61-f2c5148ffb85]
25+
description = "wrong closing bracket"
26+
27+
[754468e0-4696-4582-a30e-534d47d69756]
28+
description = "paired with whitespace"
29+
30+
[ba84f6ee-8164-434a-9c3e-b02c7f8e8545]
31+
description = "partially paired brackets"
32+
33+
[3c86c897-5ff3-4a2b-ad9b-47ac3a30651d]
34+
description = "simple nested brackets"
35+
36+
[2d137f2c-a19e-4993-9830-83967a2d4726]
37+
description = "several paired brackets"
38+
39+
[2e1f7b56-c137-4c92-9781-958638885a44]
40+
description = "paired and nested brackets"
41+
42+
[84f6233b-e0f7-4077-8966-8085d295c19b]
43+
description = "unopened closing brackets"
44+
45+
[9b18c67d-7595-4982-b2c5-4cb949745d49]
46+
description = "unpaired and nested brackets"
47+
48+
[a0205e34-c2ac-49e6-a88a-899508d7d68e]
49+
description = "paired and wrong nested brackets"
50+
51+
[1d5c093f-fc84-41fb-8c2a-e052f9581602]
52+
description = "paired and wrong nested brackets but innermost are correct"
53+
54+
[ef47c21b-bcfd-4998-844c-7ad5daad90a8]
55+
description = "paired and incomplete brackets"
56+
57+
[a4675a40-a8be-4fc2-bc47-2a282ce6edbe]
58+
description = "too many closing brackets"
59+
60+
[a345a753-d889-4b7e-99ae-34ac85910d1a]
61+
description = "early unexpected brackets"
62+
63+
[21f81d61-1608-465a-b850-baa44c5def83]
64+
description = "early mismatched brackets"
65+
66+
[99255f93-261b-4435-a352-02bdecc9bdf2]
67+
description = "math expression"
68+
69+
[8e357d79-f302-469a-8515-2561877256a1]
70+
description = "complex latex expression"
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
AS = /usr/bin/riscv64-linux-gnu-as
2+
CC = /usr/bin/riscv64-linux-gnu-gcc
3+
4+
CFLAGS = -g -Wall -Wextra -pedantic -Werror
5+
LDFLAGS =
6+
7+
ALL_LDFLAGS = -pie -Wl,--fatal-warnings
8+
9+
ALL_CFLAGS = -std=c99 -fPIE $(CFLAGS)
10+
ALL_LDFLAGS += $(LDFLAGS)
11+
12+
C_OBJS = $(patsubst %.c,%.o,$(wildcard *.c))
13+
AS_OBJS = $(patsubst %.s,%.o,$(wildcard *.s))
14+
ALL_OBJS = $(filter-out example.o,$(C_OBJS) $(AS_OBJS) vendor/unity.o)
15+
16+
CC_CMD = $(CC) $(ALL_CFLAGS) -c -o $@ $<
17+
18+
all: tests
19+
qemu-riscv64 -L /usr/riscv64-linux-gnu ./$<
20+
21+
tests: $(ALL_OBJS)
22+
@$(CC) $(ALL_CFLAGS) $(ALL_LDFLAGS) -o $@ $(ALL_OBJS)
23+
24+
%.o: %.s
25+
@$(AS) -o $@ $<
26+
27+
%.o: %.c
28+
@$(CC_CMD)
29+
30+
vendor/unity.o: vendor/unity.c vendor/unity.h vendor/unity_internals.h
31+
@$(CC_CMD)
32+
33+
clean:
34+
@rm -f *.o vendor/*.o tests
35+
36+
.PHONY: all clean
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.text
2+
.globl is_paired
3+
4+
is_paired:
5+
ret
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
#include "vendor/unity.h"
2+
3+
extern int is_paired(const char *value);
4+
5+
void setUp(void) {
6+
}
7+
8+
void tearDown(void) {
9+
}
10+
11+
void test_paired_square_brackets(void) {
12+
TEST_ASSERT_TRUE(is_paired("[]"));
13+
}
14+
15+
void test_empty_string(void) {
16+
TEST_IGNORE();
17+
TEST_ASSERT_TRUE(is_paired(""));
18+
}
19+
20+
void test_unpaired_brackets(void) {
21+
TEST_IGNORE();
22+
TEST_ASSERT_FALSE(is_paired("[["));
23+
}
24+
25+
void test_wrong_ordered_brackets(void) {
26+
TEST_IGNORE();
27+
TEST_ASSERT_FALSE(is_paired("}{"));
28+
}
29+
30+
void test_wrong_closing_bracket(void) {
31+
TEST_IGNORE();
32+
TEST_ASSERT_FALSE(is_paired("{]"));
33+
}
34+
35+
void test_paired_with_whitespace(void) {
36+
TEST_IGNORE();
37+
TEST_ASSERT_TRUE(is_paired("{ }"));
38+
}
39+
40+
void test_partially_paired_brackets(void) {
41+
TEST_IGNORE();
42+
TEST_ASSERT_FALSE(is_paired("{[])"));
43+
}
44+
45+
void test_simple_nested_brackets(void) {
46+
TEST_IGNORE();
47+
TEST_ASSERT_TRUE(is_paired("{[]}"));
48+
}
49+
50+
void test_several_paired_brackets(void) {
51+
TEST_IGNORE();
52+
TEST_ASSERT_TRUE(is_paired("{}[]"));
53+
}
54+
55+
void test_paired_and_nested_brackets(void) {
56+
TEST_IGNORE();
57+
TEST_ASSERT_TRUE(is_paired("([{}({}[])])"));
58+
}
59+
60+
void test_unopened_closing_brackets(void) {
61+
TEST_IGNORE();
62+
TEST_ASSERT_FALSE(is_paired("{[)][]}"));
63+
}
64+
65+
void test_unpaired_and_nested_brackets(void) {
66+
TEST_IGNORE();
67+
TEST_ASSERT_FALSE(is_paired("([{])"));
68+
}
69+
70+
void test_paired_and_wrong_nested_brackets(void) {
71+
TEST_IGNORE();
72+
TEST_ASSERT_FALSE(is_paired("[({]})"));
73+
}
74+
75+
void test_paired_and_wrong_nested_brackets_but_innermost_are_correct(void) {
76+
TEST_IGNORE();
77+
TEST_ASSERT_FALSE(is_paired("[({}])"));
78+
}
79+
80+
void test_paired_and_incomplete_brackets(void) {
81+
TEST_IGNORE();
82+
TEST_ASSERT_FALSE(is_paired("{}["));
83+
}
84+
85+
void test_too_many_closing_brackets(void) {
86+
TEST_IGNORE();
87+
TEST_ASSERT_FALSE(is_paired("[]]"));
88+
}
89+
90+
void test_early_unexpected_brackets(void) {
91+
TEST_IGNORE();
92+
TEST_ASSERT_FALSE(is_paired(")()"));
93+
}
94+
95+
void test_early_mismatched_brackets(void) {
96+
TEST_IGNORE();
97+
TEST_ASSERT_FALSE(is_paired("{)()"));
98+
}
99+
100+
void test_math_expression(void) {
101+
TEST_IGNORE();
102+
TEST_ASSERT_TRUE(is_paired("(((185 + 223.85) * 15) - 543)/2"));
103+
}
104+
105+
void test_complex_latex_expression(void) {
106+
TEST_IGNORE();
107+
TEST_ASSERT_TRUE(is_paired("\\left(\\begin{array}{cc} \\frac{1}{3} & x\\\\ \\mathrm{e}^{x} &... x^2 \\end{array}\\right)"));
108+
}
109+
110+
int main(void) {
111+
UNITY_BEGIN();
112+
RUN_TEST(test_paired_square_brackets);
113+
RUN_TEST(test_empty_string);
114+
RUN_TEST(test_unpaired_brackets);
115+
RUN_TEST(test_wrong_ordered_brackets);
116+
RUN_TEST(test_wrong_closing_bracket);
117+
RUN_TEST(test_paired_with_whitespace);
118+
RUN_TEST(test_partially_paired_brackets);
119+
RUN_TEST(test_simple_nested_brackets);
120+
RUN_TEST(test_several_paired_brackets);
121+
RUN_TEST(test_paired_and_nested_brackets);
122+
RUN_TEST(test_unopened_closing_brackets);
123+
RUN_TEST(test_unpaired_and_nested_brackets);
124+
RUN_TEST(test_paired_and_wrong_nested_brackets);
125+
RUN_TEST(test_paired_and_wrong_nested_brackets_but_innermost_are_correct);
126+
RUN_TEST(test_paired_and_incomplete_brackets);
127+
RUN_TEST(test_too_many_closing_brackets);
128+
RUN_TEST(test_early_unexpected_brackets);
129+
RUN_TEST(test_early_mismatched_brackets);
130+
RUN_TEST(test_math_expression);
131+
RUN_TEST(test_complex_latex_expression);
132+
return UNITY_END();
133+
}

0 commit comments

Comments
 (0)