Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

C matching brackets #265

Merged
merged 3 commits into from
Sep 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions c/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,4 @@
- [all-your-base](./all-your-base/README.md)
- [roman-numerals](./roman-numerals/README.md)
- [prime-factors](./prime-factors/README.md)
- [matching-brackets](./matching-brackets/README.md)
28 changes: 28 additions & 0 deletions c/matching-brackets/.exercism/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"authors": [
"vlzware"
],
"contributors": [
"h-3-0",
"patricksjackson",
"QLaille",
"ryanplusplus",
"sjwarner",
"wolf99"
],
"files": {
"solution": [
"matching_brackets.c",
"matching_brackets.h"
],
"test": [
"test_matching_brackets.c"
],
"example": [
".meta/example.c",
".meta/example.h"
]
},
"blurb": "Make sure the brackets and braces all match.",
"source": "Ginna Baker"
}
1 change: 1 addition & 0 deletions c/matching-brackets/.exercism/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"track":"c","exercise":"matching-brackets","id":"20f7030b2e6a4a5ab3671ceeec4c60d4","url":"https://exercism.org/tracks/c/exercises/matching-brackets","handle":"vpayno","is_requester":true,"auto_approve":false}
64 changes: 64 additions & 0 deletions c/matching-brackets/HELP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Help

## Running the tests

Get the first test compiling, linking and passing by following the [three rules of test-driven development][3-tdd-rules].

The included makefile can be used to create and run the tests using the `test` task.

```console
$ make test
```

Create just the functions you need to satisfy any compiler errors and get the test to fail.
Then write just enough code to get the test to pass.
Once you've done that, move onto the next test.

As you progress through the tests, take the time to refactor your implementation for readability and expressiveness and then go on to the next test.

Try to use standard C99 facilities in preference to writing your own low-level algorithms or facilities by hand.

[3-tdd-rules]: https://blog.cleancoder.com/uncle-bob/2014/12/17/TheCyclesOfTDD.html

## Submitting your solution

You can submit your solution using the `exercism submit matching_brackets.c matching_brackets.h` command.
This command will upload your solution to the Exercism website and print the solution page's URL.

It's possible to submit an incomplete solution which allows you to:

- See how others have completed the exercise
- Request help from a mentor

## Need to get help?

If you'd like help solving the exercise, check the following pages:

- The [C track's documentation](https://exercism.org/docs/tracks/c)
- The [C track's programming category on the forum](https://forum.exercism.org/c/programming/c)
- [Exercism's programming category on the forum](https://forum.exercism.org/c/programming/5)
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)

Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.

Make sure you have read the [C track-specific documentation][c-track] on the Exercism site.
This covers the basic information on setting up the development environment expected by the exercises.

## Submitting Incomplete Solutions

If you are struggling with a particular exercise, it is possible to submit an incomplete solution so you can see how others have completed the exercise.

## Resources

To get help if having trouble, you can use the following resources:

- [StackOverflow][] can be used to search for your problem and see if it has been answered already. You can also ask and answer questions.
- [CPPReference][] can be used to look up information on C concepts, operators, types, standard library functions and more.
- [TutorialsPoint][] has similar content as CPPReference in its C programming section.
- [The C Programming][K&R] book by K&R is the original source of the language and is still useful today.

[c-track]: https://exercism.org/docs/tracks/c
[stackoverflow]: http://stackoverflow.com/questions/tagged/c
[cppreference]: https://en.cppreference.com/w/c
[tutorialspoint]: https://www.tutorialspoint.com/cprogramming/
[K&R]: https://www.amazon.com/Programming-Language-2nd-Brian-Kernighan/dp/0131103628/
33 changes: 33 additions & 0 deletions c/matching-brackets/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Matching Brackets

Welcome to Matching Brackets on Exercism's C Track.
If you need help running the tests or submitting your code, check out `HELP.md`.

## Instructions

Given a string containing brackets `[]`, braces `{}`, parentheses `()`, or any combination thereof, verify that any and all pairs are matched and nested correctly.
The string may also contain other characters, which for the purposes of this exercise should be ignored.

## Source

### Created by

- @vlzware

### Contributed to by

- @h-3-0
- @patricksjackson
- @QLaille
- @ryanplusplus
- @sjwarner
- @wolf99

### Based on

Ginna Baker

### My Solution

- [my solution](./matching_brackets.c)
- [run-tests](./run-tests-c.txt)
12 changes: 12 additions & 0 deletions c/matching-brackets/compile_commands.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[
{
"directory": "/home/vpayno/git_vpayno/exercism-workspace/c/matching-brackets",
"command": "/usr/bin/cc -DEXERCISM_RUN_ALL_TESTS --coverage -g -Wall -Wextra -Wpedantic -Werror -std=c99 -lm -o tests.out -c test-framework/unity.c -c matching-brackets_test.c",
"file": "/home/vpayno/git_vpayno/exercism-workspace/c/matching-brackets/matching-brackets_test.c"
},
{
"directory": "/home/vpayno/git_vpayno/exercism-workspace/c/matching-brackets",
"command": "/usr/bin/cc -DEXERCISM_RUN_ALL_TESTS --coverage -g -Wall -Wextra -Wpedantic -Werror -std=c99 -lm -fsanitize=address -fno-common -fno-omit-frame-pointer -o memcheck.out -c test-framework/unity.c -c matching-brackets.c",
"file": "/home/vpayno/git_vpayno/exercism-workspace/c/matching-brackets/matching-brackets.c"
}
]
7 changes: 7 additions & 0 deletions c/matching-brackets/compile_flags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
-std=c99
-g
-Wall
-Wextra
-Wpedantic
-Werror
-Wmissing-declarations
37 changes: 37 additions & 0 deletions c/matching-brackets/makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
### If you wish to use extra libraries (math.h for instance),
### add their flags here (-lm in our case) in the "LIBS" variable.

LIBS = -lm

###
CFLAGS = -std=c99
CFLAGS += -g
CFLAGS += -Wall
CFLAGS += -Wextra
CFLAGS += -pedantic
CFLAGS += -Werror
CFLAGS += -Wmissing-declarations
CFLAGS += -DUNITY_SUPPORT_64 -DUNITY_OUTPUT_COLOR

ASANFLAGS = -fsanitize=address
ASANFLAGS += -fno-common
ASANFLAGS += -fno-omit-frame-pointer

.PHONY: test
test: tests.out
@./tests.out

.PHONY: memcheck
memcheck: ./*.c ./*.h
@echo Compiling $@
@$(CC) $(ASANFLAGS) $(CFLAGS) test-framework/unity.c ./*.c -o memcheck.out $(LIBS)
@./memcheck.out
@echo "Memory check passed"

.PHONY: clean
clean:
rm -rf *.o *.out *.out.dSYM

tests.out: ./*.c ./*.h
@echo Compiling $@
@$(CC) $(CFLAGS) test-framework/unity.c ./*.c -o tests.out $(LIBS)
66 changes: 66 additions & 0 deletions c/matching-brackets/matching_brackets.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#include "matching_brackets.h"

bool is_paired(const char *input) {
char brackets[100] = {0};
usize_t counter = 0;

char *input_ptr = (char *)input;

while (*input_ptr != '\0') {
if (!bracket_either(*input_ptr)) {
input_ptr++;
continue;
}

if (bracket_open(*input_ptr)) {
brackets[counter++] = *input_ptr;

input_ptr++;
continue;
}

if (bracket_close(*input_ptr)) {
if (counter == 0) {
return false;
}

if (!bracket_match(brackets[counter - 1], *input_ptr)) {
return false;
}

counter--;
}

input_ptr++;
}

return counter == 0 ? true : false;
}

bool bracket_match(char open_bracket, char close_bracket) {
if (open_bracket == '[' && close_bracket == ']') {
return true;
}

if (open_bracket == '(' && close_bracket == ')') {
return true;
}

if (open_bracket == '{' && close_bracket == '}') {
return true;
}

return false;
}

bool bracket_open(char bracket) {
return bracket == '[' || bracket == '(' || bracket == '{';
}

bool bracket_close(char bracket) {
return bracket == ']' || bracket == ')' || bracket == '}';
}

bool bracket_either(char bracket) {
return bracket_open(bracket) || bracket_close(bracket);
}
14 changes: 14 additions & 0 deletions c/matching-brackets/matching_brackets.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#ifndef MATCHING_BRACKETS_H
#define MATCHING_BRACKETS_H

#include <stdbool.h>

typedef unsigned int usize_t;

bool is_paired(const char *input);
bool bracket_match(char open_bracket, char close_bracket);
bool bracket_open(char bracket);
bool bracket_close(char bracket);
bool bracket_either(char bracket);

#endif
120 changes: 120 additions & 0 deletions c/matching-brackets/run-tests-c.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
Running automated test file(s):


===============================================================================

Running: make clean
rm -rf *.o *.out *.out.dSYM

real 0m0.004s
user 0m0.002s
sys 0m0.001s

===============================================================================

Running: make test | ansifilter
Compiling tests.out
test_matching_brackets.c:133:test_paired_square_brackets:PASS
test_matching_brackets.c:134:test_empty_string:PASS
test_matching_brackets.c:135:test_unpaired_brackets:PASS
test_matching_brackets.c:136:test_wrong_ordered_brackets:PASS
test_matching_brackets.c:137:test_wrong_closing_bracket:PASS
test_matching_brackets.c:138:test_paired_with_whitespace:PASS
test_matching_brackets.c:139:test_partially_paired_brackets:PASS
test_matching_brackets.c:140:test_simple_nested_brackets:PASS
test_matching_brackets.c:141:test_several_paired_brackets:PASS
test_matching_brackets.c:142:test_paired_and_nested_brackets:PASS
test_matching_brackets.c:143:test_unopened_closing_brackets:PASS
test_matching_brackets.c:144:test_unpaired_and_nested_brackets:PASS
test_matching_brackets.c:145:test_paired_and_wrong_nested_brackets:PASS
test_matching_brackets.c:146:test_paired_and_wrong_nested_brackets_but_innermost_are_correct:PASS
test_matching_brackets.c:147:test_paired_and_incomplete_brackets:PASS
test_matching_brackets.c:148:test_too_many_closing_brackets:PASS
test_matching_brackets.c:149:test_early_unexpected_brackets:PASS
test_matching_brackets.c:150:test_early_mismatched_brackets:PASS
test_matching_brackets.c:151:test_math_expression:PASS
test_matching_brackets.c:152:test_complex_latex_expression:PASS

-----------------------
20 Tests 0 Failures 0 Ignored
OK

real 0m0.116s
user 0m0.088s
sys 0m0.028s

===============================================================================

Running: make memcheck | ansifilter
Compiling memcheck
test_matching_brackets.c:133:test_paired_square_brackets:PASS
test_matching_brackets.c:134:test_empty_string:PASS
test_matching_brackets.c:135:test_unpaired_brackets:PASS
test_matching_brackets.c:136:test_wrong_ordered_brackets:PASS
test_matching_brackets.c:137:test_wrong_closing_bracket:PASS
test_matching_brackets.c:138:test_paired_with_whitespace:PASS
test_matching_brackets.c:139:test_partially_paired_brackets:PASS
test_matching_brackets.c:140:test_simple_nested_brackets:PASS
test_matching_brackets.c:141:test_several_paired_brackets:PASS
test_matching_brackets.c:142:test_paired_and_nested_brackets:PASS
test_matching_brackets.c:143:test_unopened_closing_brackets:PASS
test_matching_brackets.c:144:test_unpaired_and_nested_brackets:PASS
test_matching_brackets.c:145:test_paired_and_wrong_nested_brackets:PASS
test_matching_brackets.c:146:test_paired_and_wrong_nested_brackets_but_innermost_are_correct:PASS
test_matching_brackets.c:147:test_paired_and_incomplete_brackets:PASS
test_matching_brackets.c:148:test_too_many_closing_brackets:PASS
test_matching_brackets.c:149:test_early_unexpected_brackets:PASS
test_matching_brackets.c:150:test_early_mismatched_brackets:PASS
test_matching_brackets.c:151:test_math_expression:PASS
test_matching_brackets.c:152:test_complex_latex_expression:PASS

-----------------------
20 Tests 0 Failures 0 Ignored
OK
Memory check passed

real 0m0.141s
user 0m0.100s
sys 0m0.042s

===============================================================================

Running: clang-format-16 -style=file -i ./matching_brackets.c ./test_matching_brackets.c ./matching_brackets.h

real 0m0.024s
user 0m0.011s
sys 0m0.013s

===============================================================================

Running: ../../.github/citools/cpp/clang-check
Running: clang-check-16 --analyze ./matching_brackets.h

real 0m0.024s
user 0m0.011s
sys 0m0.013s


real 0m0.026s
user 0m0.012s
sys 0m0.014s

===============================================================================

Running: ../../.github/citools/cpp/clang-tidy | head -n 100
4 warnings generated.
Suppressed 4 warnings (4 in non-user code).
Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.

real 0m0.030s
user 0m0.020s
sys 0m0.010s
Running: clang-tidy-16 ./matching_brackets.h


real 0m0.032s
user 0m0.021s
sys 0m0.012s

===============================================================================

Loading