aboutsummaryrefslogtreecommitdiffstats
path: root/cover.c
diff options
context:
space:
mode:
authorThibaut Horel <thibaut.horel@gmail.com>2015-07-02 16:08:10 -0700
committerThibaut Horel <thibaut.horel@gmail.com>2015-07-02 16:08:10 -0700
commit759858311aab27cfb3265835c58a56b612731fb0 (patch)
tree93240f0aa1f45631152eed13e7c8d7c3b4ad91a6 /cover.c
parent0f600a65c7f33986df447c3611909037a6208d71 (diff)
downloadcover-759858311aab27cfb3265835c58a56b612731fb0.tar.gz
First fully working version
Diffstat (limited to 'cover.c')
-rw-r--r--cover.c163
1 files changed, 163 insertions, 0 deletions
diff --git a/cover.c b/cover.c
new file mode 100644
index 0000000..b5b1b9c
--- /dev/null
+++ b/cover.c
@@ -0,0 +1,163 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include "cover.h"
+
+element* insert_element(set* s, int id) {
+ element* el = malloc(sizeof(element));
+ el->id = id;
+ el->set = s;
+ el->prev = el->next = NULL;
+ if (s->head) {
+ el->next = s->head;
+ s->head->prev = el;
+ }
+ s->head = el;
+ return el;
+}
+
+set* new_set(int id) {
+ set* s = malloc(sizeof(set));
+ s->id = id;
+ s->prev = s->next = NULL;
+ s->head = NULL;
+ s->bucket = NULL;
+ return s;
+}
+
+parent* new_parent(element* el) {
+ parent* p = malloc(sizeof(parent));
+ p->pos = el;
+ p->next = NULL;
+ return p;
+}
+
+void insert_parent(parent** parents, element* el) {
+ int id = el->id;
+ parent* p = new_parent(el);
+ if (parents[id]) {
+ p->next = parents[id];
+ }
+ parents[id] = p;
+}
+
+bucket* new_bucket(set* s, int size) {
+ bucket* b = malloc(sizeof(bucket));
+ b->size = size;
+ b->prev = b->next = NULL;
+ b->head = s;
+ s->bucket = b;
+ s->prev = s->next = NULL;
+ return b;
+}
+
+void insert_set(set* s, bucket* b) {
+ s->next = b->head;
+ s->prev = NULL;
+ s->bucket = b;
+ b->head->prev = s;
+ b->head = s;
+}
+
+void remove_bucket(bucket* b) {
+ if (b->prev) {
+ b->prev->next = b->next;
+ }
+ if (b->next) {
+ b->next->prev = b->prev;
+ }
+ free(b);
+}
+
+void detach_set(set* s) {
+ if (s->next) {
+ s->next->prev = s->prev;
+ }
+ if (s->prev) {
+ s->prev->next = s->next;
+ } else {
+ s->bucket->head = s->next;
+ }
+ s->prev = s->next = NULL;
+ s->bucket = NULL;
+}
+
+void attach_set(set* s, int size, bucket* b) {
+ if (b->size == size) {
+ insert_set(s, b);
+ } else {
+ bucket* nb = new_bucket(s, size);
+ nb->prev = b;
+ nb->next = b->next;
+ nb->prev->next = nb;
+ if (nb->next) {
+ nb->next->prev = nb;
+ }
+ }
+}
+
+void demote(set* s) {
+ bucket* b = s->bucket;
+ detach_set(s);
+ int size = b->size - 1;
+ if (size == 0) {
+ free(s);
+ } else if (!b->prev) {
+ bucket* nb = new_bucket(s, size);
+ nb->next = b;
+ b->prev = nb;
+ } else {
+ attach_set(s, size, b->prev);
+ }
+ if (!b->head) {
+ remove_bucket(b);
+ }
+}
+
+void remove_element(element* el) {
+ if (el->next) {
+ el->next->prev = el->prev;
+ }
+ if (el->prev) {
+ el->prev->next = el->next;
+ } else {
+ el->set->head = el->next;
+ }
+ demote(el->set);
+ free(el);
+}
+
+void remove_parents(element* el, parent** parents) {
+ parent* current = parents[el->id];
+ parent* temp;
+ while (current) {
+ temp = current;
+ if (current->pos != el) {
+ remove_element(current->pos);
+ }
+ current = current->next;
+ free(temp);
+ }
+
+}
+
+void greedy(bucket* head, parent** parents) {
+ bucket* b = head;
+ element* current = b->head->head;
+ printf("%d\n", current->set->id);
+ element* temp;
+ while (1) {
+ temp = current;
+ remove_parents(current, parents);
+ if (current->next) {
+ current = current->next;
+ } else if (current->set->next) {
+ current = current->set->next->head;
+ printf("%d\n", current->set->id);
+ } else if (current->set->bucket->prev) {
+ current = current->set->bucket->prev->head->head;
+ printf("%d\n", current->set->id);
+ } else {
+ break;
+ }
+ }
+}