Last active
November 11, 2018 21:41
-
-
Save xfbs/66ee09fd0fe6249f9a83ca950a0cc614 to your computer and use it in GitHub Desktop.
Program to count identifiers.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CFLAGS += $(shell pkg-config --cflags glib-2.0) | |
LDFLAGS += $(shell pkg-config --libs glib-2.0) | |
all: task |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdbool.h> | |
#include <string.h> | |
#include <glib.h> | |
#include <assert.h> | |
// read a single line from input. | |
GString *get_line() { | |
// read line | |
char *line = NULL; | |
size_t line_length; | |
getline(&line, &line_length, stdin); | |
// truncate newline | |
g_strstrip(line); | |
return g_string_new(line); | |
} | |
// check if the next word on the input is a valid identifier. | |
bool is_identifier(const char *word) { | |
// compile the regular expression | |
const GRegex *regex = g_regex_new("^[a-zA-Z_][a-zA-Z0-9_]*$", G_REGEX_OPTIMIZE, 0, NULL); | |
return g_regex_match(regex, word, 0, NULL); | |
} | |
// counts the unique identifiers in a list of words. | |
int count_identifiers(gchar **words) { | |
// find identifiers. by using a hash table, we know that repeated identifiers | |
// are only counted once. | |
GHashTable *identifiers = g_hash_table_new(g_str_hash, g_str_equal); | |
for(size_t pos = 0; words[pos]; ++pos) { | |
if(is_identifier(words[pos])) { | |
g_hash_table_insert(identifiers, words[pos], NULL); | |
printf("identifier: '%s'\n", words[pos]); | |
} | |
} | |
// find out how many unique identifiers there are | |
int count = g_hash_table_size(identifiers); | |
g_hash_table_destroy(identifiers); | |
return count; | |
} | |
// read a single line from the input, parse it, and return the number of | |
// identifiers found on it. | |
int parse_line() { | |
// read a single line from input and split into words. | |
GString *line = get_line(); | |
gchar **words = g_strsplit(line->str, " ", 0); | |
int count = count_identifiers(words); | |
free(g_string_free(line, false)); | |
g_strfreev(words); | |
return count; | |
} | |
// tests to make sure everything works as intended | |
void test() { | |
assert(is_identifier("Identifier9_")); | |
assert(is_identifier("ALLCAPS")); | |
assert(is_identifier("allsmall")); | |
assert(is_identifier("________")); | |
assert(is_identifier("i1431")); | |
assert(!is_identifier("------")); | |
assert(!is_identifier("9gag")); | |
// you can add more tests here to make sure the functions work. | |
} | |
int main(int argc, char *argv[]) { | |
test(); | |
// parse data until it's empty. | |
while(!feof(stdin)) { | |
printf("found %i identifiers.\n", parse_line()); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment