diff --git a/day7p1/Makefile b/day7p1/Makefile new file mode 100644 index 0000000..c711967 --- /dev/null +++ b/day7p1/Makefile @@ -0,0 +1,12 @@ +CFLAGS := -Wall -Wextra -std=c17 -D_GNU_SOURCE + +LIBS := glib-2.0 +CFLAGS += $(shell pkg-config --cflags $(LIBS)) +LDLIBS := $(shell pkg-config --libs $(LIBS)) + +.PHONY: all +all: main + +.PHONY: clean +clean: + rm -f main diff --git a/day7p1/input b/day7p1/input new file mode 100644 index 0000000..7155300 --- /dev/null +++ b/day7p1/input @@ -0,0 +1,101 @@ +Step J must be finished before step H can begin. +Step N must be finished before step C can begin. +Step G must be finished before step P can begin. +Step M must be finished before step I can begin. +Step H must be finished before step X can begin. +Step B must be finished before step Y can begin. +Step C must be finished before step L can begin. +Step F must be finished before step I can begin. +Step V must be finished before step O can begin. +Step W must be finished before step Q can begin. +Step E must be finished before step L can begin. +Step U must be finished before step S can begin. +Step D must be finished before step K can begin. +Step Y must be finished before step X can begin. +Step T must be finished before step R can begin. +Step I must be finished before step K can begin. +Step A must be finished before step K can begin. +Step L must be finished before step X can begin. +Step Q must be finished before step S can begin. +Step S must be finished before step O can begin. +Step P must be finished before step Z can begin. +Step X must be finished before step R can begin. +Step Z must be finished before step O can begin. +Step O must be finished before step K can begin. +Step R must be finished before step K can begin. +Step J must be finished before step W can begin. +Step F must be finished before step V can begin. +Step A must be finished before step X can begin. +Step Z must be finished before step K can begin. +Step M must be finished before step O can begin. +Step X must be finished before step K can begin. +Step E must be finished before step K can begin. +Step J must be finished before step K can begin. +Step E must be finished before step Y can begin. +Step B must be finished before step Q can begin. +Step X must be finished before step Z can begin. +Step D must be finished before step L can begin. +Step N must be finished before step I can begin. +Step N must be finished before step B can begin. +Step V must be finished before step A can begin. +Step H must be finished before step R can begin. +Step N must be finished before step L can begin. +Step U must be finished before step O can begin. +Step A must be finished before step O can begin. +Step V must be finished before step Z can begin. +Step O must be finished before step R can begin. +Step Q must be finished before step P can begin. +Step F must be finished before step Q can begin. +Step P must be finished before step R can begin. +Step S must be finished before step X can begin. +Step J must be finished before step E can begin. +Step V must be finished before step P can begin. +Step M must be finished before step D can begin. +Step I must be finished before step S can begin. +Step Q must be finished before step O can begin. +Step M must be finished before step H can begin. +Step W must be finished before step X can begin. +Step D must be finished before step O can begin. +Step X must be finished before step O can begin. +Step Y must be finished before step Z can begin. +Step F must be finished before step L can begin. +Step V must be finished before step T can begin. +Step V must be finished before step E can begin. +Step Y must be finished before step A can begin. +Step I must be finished before step R can begin. +Step L must be finished before step O can begin. +Step U must be finished before step X can begin. +Step Q must be finished before step X can begin. +Step P must be finished before step X can begin. +Step G must be finished before step C can begin. +Step A must be finished before step L can begin. +Step M must be finished before step U can begin. +Step L must be finished before step S can begin. +Step S must be finished before step P can begin. +Step S must be finished before step K can begin. +Step F must be finished before step T can begin. +Step Q must be finished before step K can begin. +Step G must be finished before step M can begin. +Step G must be finished before step F can begin. +Step T must be finished before step Q can begin. +Step F must be finished before step Z can begin. +Step I must be finished before step Z can begin. +Step N must be finished before step X can begin. +Step J must be finished before step F can begin. +Step W must be finished before step E can begin. +Step M must be finished before step Z can begin. +Step G must be finished before step X can begin. +Step V must be finished before step U can begin. +Step P must be finished before step O can begin. +Step U must be finished before step R can begin. +Step G must be finished before step Z can begin. +Step F must be finished before step R can begin. +Step L must be finished before step R can begin. +Step F must be finished before step A can begin. +Step I must be finished before step O can begin. +Step D must be finished before step T can begin. +Step U must be finished before step L can begin. +Step B must be finished before step S can begin. +Step S must be finished before step Z can begin. +Step J must be finished before step N can begin. +Step H must be finished before step T can begin. diff --git a/day7p1/main.c b/day7p1/main.c new file mode 100644 index 0000000..65a6841 --- /dev/null +++ b/day7p1/main.c @@ -0,0 +1,107 @@ +#include + +#include + +struct action { + int id; + GPtrArray *depends; + GPtrArray *required_by; +}; + +void free_action(gpointer data) +{ + struct action *action = (struct action *)data; + g_ptr_array_free(action->depends, TRUE); + g_ptr_array_free(action->required_by, TRUE); + g_free(action); +} + +struct action *get_action(GHashTable *table, int id) +{ + struct action *action = g_hash_table_lookup(table, GINT_TO_POINTER(id)); + if (action) return action; + + action = g_malloc(sizeof(struct action)); + action->depends = g_ptr_array_new(); + action->required_by = g_ptr_array_new(); + action->id = id; + g_hash_table_insert(table, GINT_TO_POINTER(id), action); + return action; +} + +gint compare_action(gconstpointer _a, gconstpointer _b) +{ + struct action *a = *(struct action **)_a; + struct action *b = *(struct action **)_b; + return a->id - b->id; +} + +GHashTable *parse_tree(const char *fname) +{ + FILE *f = fopen(fname, "r"); + if (!f) { + perror(fname); + return NULL; + } + + GHashTable *table = g_hash_table_new_full(NULL, NULL, NULL, free_action); + + char *line = NULL; + size_t line_len = 0; + while (getline(&line, &line_len, f) != -1) { + char depends = 0; + char required_by = 0; + sscanf(line, "Step %c must be finished before step %c can begin.", + &depends, &required_by); + + struct action *dependent = get_action(table, depends); + struct action *required = get_action(table, required_by); + + g_ptr_array_add(dependent->required_by, required); + g_ptr_array_add(required->depends, dependent); + } + + free(line); + fclose(f); + return table; +} + +int main() + +{ + GHashTable *table = parse_tree("input"); + if (!table) return 1; + + GPtrArray *queue = g_ptr_array_new(); + GString *result = g_string_new(NULL); + + // Find items without dependencies + GHashTableIter iter; + gpointer key, value; + g_hash_table_iter_init(&iter, table); + while (g_hash_table_iter_next(&iter, &key, &value)) { + struct action *action = (struct action *)value; + if (action->depends->len == 0) { + g_ptr_array_add(queue, action); + } + } + + while (queue->len) { + g_ptr_array_sort(queue, compare_action); + + struct action *action = g_ptr_array_remove_index_fast(queue, 0); + g_string_append_c(result, action->id); + for (unsigned i = 0; i < action->required_by->len; i++) { + struct action *next = g_ptr_array_index(action->required_by, i); + g_ptr_array_remove_fast(next->depends, action); + if (next->depends->len == 0) g_ptr_array_add(queue, next); + } + } + + puts(result->str); + + g_string_free(result, TRUE); + g_ptr_array_free(queue, TRUE); + g_hash_table_destroy(table); + return 0; +}