Skip to content

Instantly share code, notes, and snippets.

@pepasflo
Created May 15, 2018 16:43
Show Gist options
  • Save pepasflo/9afd1f8510bb4f14b98173cc7959cd57 to your computer and use it in GitHub Desktop.
Save pepasflo/9afd1f8510bb4f14b98173cc7959cd57 to your computer and use it in GitHub Desktop.
#include <stddef.h> // uint32_t, etc
#include <assert.h>
#include <stdlib.h> // malloc, etc
struct appointment_t_ {
uint32_t start;
uint32_t end;
};
typedef struct appointment_t_ appointment_t;
struct list_t_ {
appointment_t *data;
struct list_t_ *next;
};
typedef struct list_t_ list_t;
void terrible_sort(list_t *l) {
list_t *sorted = NULL;
list_t *a = l;
while (a != NULL) {
list_t *min = a;
list_t *prev_min = NULL;
list_t *b = a->next;
list_t *prev_b = a;
// find the minimum item
while (b != NULL) {
if (b->data->start < min->data->start) {
min = b;
prev_min = prev_b;
}
prev_b = b;
b = b->next;
}
// append the minimum item to the sorted list
if (sorted == NULL) {
sorted = min;
} else {
sorted->next = min;
sorted = sorted->next;
}
prev_min = min;
a = a->next;
}
l = sorted;
}
void collapse(list_t *l) {
list_t *a = l;
while (a != NULL) {
list_t *b = a->next;
while (b != NULL) {
if (b->data->start <= a->data->end) {
a->data->end = b->data->end;
a->next = b->next;
free(b->data);
free(b);
}
b = b->next;
}
a = a->next;
}
}
void hical(list_t *l) {
terrible_sort(l);
collapse(l);
}
// A single appointment. This should do nothing.
void test0() {
appointment_t *a = malloc(sizeof(appointment_t));
a->start = 0;
a->end = 1;
list_t *l = malloc(sizeof(list_t));
l->data = a;
l->next = NULL;
hical(l);
assert(l != NULL);
assert(l->data != NULL);
assert(l->data->start == 0);
assert(l->data->end == 1);
assert(l->next == NULL);
}
// Two non-overlapping appointments. This should do nothing.
void test1() {
appointment_t *a = malloc(sizeof(appointment_t));
a->start = 0;
a->end = 1;
appointment_t *b = malloc(sizeof(appointment_t));
b->start = 2;
b->end = 3;
list_t *l = malloc(sizeof(list_t));
l->data = a;
l->next = malloc(sizeof(list_t));
l->next->data = b;
l->next->next = NULL;
hical(l);
assert(l != NULL);
assert(l->data != NULL);
assert(l->data->start == 0);
assert(l->data->end == 1);
assert(l->next != NULL);
assert(l->next->data != NULL);
assert(l->next->data->start == 2);
assert(l->next->data->end == 3);
assert(l->next->next == NULL);
}
// Two adjacent appointments. This should be reduced to one appointment.
void test2() {
appointment_t *a = malloc(sizeof(appointment_t));
a->start = 0;
a->end = 1;
appointment_t *b = malloc(sizeof(appointment_t));
b->start = 1;
b->end = 2;
list_t *l = malloc(sizeof(list_t));
l->data = a;
l->next = malloc(sizeof(list_t));
l->next->data = b;
l->next->next = NULL;
hical(l);
assert(l != NULL);
assert(l->data != NULL);
assert(l->data->start == 0);
assert(l->data->end == 2);
assert(l->next == NULL);
}
// Two overlapping appointments. This should be reduced to one appointment.
void test3() {
appointment_t *a = malloc(sizeof(appointment_t));
a->start = 0;
a->end = 2;
appointment_t *b = malloc(sizeof(appointment_t));
b->start = 1;
b->end = 3;
list_t *l = malloc(sizeof(list_t));
l->data = a;
l->next = malloc(sizeof(list_t));
l->next->data = b;
l->next->next = NULL;
hical(l);
assert(l != NULL);
assert(l->data != NULL);
assert(l->data->start == 0);
assert(l->data->end == 3);
assert(l->next == NULL);
}
int main() {
test0();
test1();
test2();
test3();
return 0;
}
test: hical
./hical
hical: hical.c
gcc -Wall -Werror -o hical hical.c
clean:
rm -f hical
.PHONY: test clean
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment