diff options
| author | Abigail <abigail@abigail.be> | 2021-02-10 19:18:58 +0100 |
|---|---|---|
| committer | Abigail <abigail@abigail.be> | 2021-02-10 19:20:37 +0100 |
| commit | deda23c261ee75dab3b3713ad21e7e4aa4205a3e (patch) | |
| tree | a96cfba4a23028392e1e263f7f8c0c99b39ef12e | |
| parent | 7104bcff280dafd9dce7551e2ed7d7468b943003 (diff) | |
| download | perlweeklychallenge-club-deda23c261ee75dab3b3713ad21e7e4aa4205a3e.tar.gz perlweeklychallenge-club-deda23c261ee75dab3b3713ad21e7e4aa4205a3e.tar.bz2 perlweeklychallenge-club-deda23c261ee75dab3b3713ad21e7e4aa4205a3e.zip | |
C solution for week 99, part 2
| -rw-r--r-- | challenge-099/abigail/README.md | 1 | ||||
| -rw-r--r-- | challenge-099/abigail/c/ch-2.c | 93 |
2 files changed, 94 insertions, 0 deletions
diff --git a/challenge-099/abigail/README.md b/challenge-099/abigail/README.md index 2cf96b11c4..3e98f336de 100644 --- a/challenge-099/abigail/README.md +++ b/challenge-099/abigail/README.md @@ -81,6 +81,7 @@ Output: 3 ### Solutions * [AWK](awk/ch-2.awk) +* [C](c/ch-2.c) * Perl * [Using regular expressions](perl/ch-2.pl) * [Recursive counting](perl/ch-2a.pl) diff --git a/challenge-099/abigail/c/ch-2.c b/challenge-099/abigail/c/ch-2.c new file mode 100644 index 0000000000..9553f698ba --- /dev/null +++ b/challenge-099/abigail/c/ch-2.c @@ -0,0 +1,93 @@ +# include <stdlib.h> +# include <stdio.h> +# include <string.h> + +/* + * See ../README.md + */ + +/* + * Run as: cc -o ch-2.o ch-2.c; ./ch-2.o < input-file + */ + + +/* + * Helper method to allocate memory for a string. + */ +char * malloc_char (size_t size) { + char * string = (char *) malloc (size * sizeof (char)); + if (string == NULL) { + perror (NULL); + exit (1); + } + return (string); +} + +/* + * Recursively count matches: + * - If either the string or the pattern is empty, there are no matches. + * - Else, + count the matches if we don't match at the first character + * if the string. + * + if the first character of the string equals the first + * character of the pattern: + * o add 1 if the pattern is just one character long + * o else, add the number of matches starting from the + * then next character in the string, and the next + * character in the pattern. + */ +int matches (char * string, size_t string_len, + char * pattern, size_t pattern_len) { + if (string_len == 0 || pattern_len == 0) { + return 0; + } + + /* + * Don't match at the beginning + */ + int count = matches (string + 1, string_len - 1, + pattern, pattern_len); + if (string [0] == pattern [0]) { + if (pattern_len == 1) { + count ++; + } + else { + count += matches (string + 1, string_len - 1, + pattern + 1, pattern_len - 1); + } + } + return count; +} + + +/* + * Read input from standard input, assuming one exercise per line. + * Each line consists of a string $S, and a pattern $T, separated + * by whitespace. + */ +int main (void) { + char * line = NULL; + size_t len = 0; + size_t str_len; + + while ((str_len = getline (&line, &len, stdin)) != -1) { + char * string; + char * pattern; + + string = malloc_char (str_len); + pattern = malloc_char (str_len); + + if (sscanf (line, "%s %s", string, pattern) != 2) { + fprintf (stderr, "Could not parse input\n"); + exit (1); + } + + printf ("%d\n", matches (string, strnlen (string, str_len), + pattern, strnlen (pattern, str_len))); + + free (pattern); + free (string); + } + free (line); + + return (0); +} |
