mid-kid
6 years ago
3 changed files with 240 additions and 0 deletions
@ -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 |
@ -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. |
@ -0,0 +1,127 @@ |
|||||
|
#include <stdio.h> |
||||
|
|
||||
|
#include <glib.h> |
||||
|
|
||||
|
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); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
struct action *workers[5] = {0}; |
||||
|
unsigned workers_time[5] = {0}; |
||||
|
unsigned working = 0; |
||||
|
unsigned time = 0; |
||||
|
|
||||
|
do { |
||||
|
g_ptr_array_sort(queue, compare_action); |
||||
|
while (queue->len && working < 5) { |
||||
|
struct action *action = g_ptr_array_remove_index(queue, 0); |
||||
|
workers[working] = action; |
||||
|
workers_time[working++] = action->id - 'A' + 1 + 60; |
||||
|
} |
||||
|
|
||||
|
for (unsigned i = 0; i < working; i++) { |
||||
|
if (--workers_time[i] != 0) continue; |
||||
|
|
||||
|
struct action *action = workers[i]; |
||||
|
memmove(workers + i, workers + i + 1, sizeof(struct action *) * (5 - i - 1)); |
||||
|
memmove(workers_time + i, workers_time + i + 1, sizeof(unsigned) * (5 - i - 1)); |
||||
|
working--; |
||||
|
i--; |
||||
|
|
||||
|
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); |
||||
|
} |
||||
|
} |
||||
|
time++; |
||||
|
} while (queue->len || working); |
||||
|
|
||||
|
puts(result->str); |
||||
|
printf("%u\n", time); |
||||
|
|
||||
|
g_string_free(result, TRUE); |
||||
|
g_ptr_array_free(queue, TRUE); |
||||
|
g_hash_table_destroy(table); |
||||
|
return 0; |
||||
|
} |
Loading…
Reference in new issue