#include #include #include #include #include #include "structure.h" //static int width = 1200; //static int height = 900; int date_dist(date d1, date d2) { /* returns distance between d1 and d2 in days if d2 is sooner than d1, it will return -1 */ if(d2.month == d1.month && d2.year == d1.year) { if(d2.day < d1.day) { return -1; } return d2.day - d1.day; } else { int is_31 = 0; if(d1.month == 1 || d1.month == 3 || d1.month == 5 || d1.month == 7 || d1.month == 8 || d1.month == 10 || d1.month == 12) { is_31 = 1; } else { is_31 = (d1.month == 2)*(-2) + (d1.month == 2 && d1.year%4 == 0 && d1.year%100 != 0); } if(d2.month - d1.month < 0 && d2.year <= d1.year) { return -1; } else if(d2.month - d1.month == 1 && d2.year == d1.year) { return d2.day + (30 + is_31 - d1.day); } else { date copy; copy.day = d1.day; copy.month = d1.month; copy.year = d1.year; copy.month = (copy.month + 1); if(copy.month == 13) { copy.month = 1; copy.year += 1; } return (30 + is_31 + date_dist(copy, d2)); } } } bool is_sorted(creneau* edt, int len) { for(int i = 1; i < len; i++) { if(date_dist(edt[i-1].date, edt[i].date) == -1) { printf("Anomaly detected at lane %d (dates are not sorted in ascending order) : \n", i); printf("%d %d %d %d\n", edt[i-1].date.hour, edt[i-1].date.day, edt[i-1].date.month, edt[i-1].date.year); printf("%d %d %d %d\n", edt[i].date.hour, edt[i].date.day, edt[i].date.month, edt[i].date.year); printf("%d %d %d %d\n", edt[i+1].date.hour, edt[i+1].date.day, edt[i+1].date.month, edt[i+1].date.year); return false; } } printf("No problem detected\n"); return true; } creneau* import_creneaux(char* filename, int size) { // import creneau data from a file // see file.txt for an example FILE* ptr = fopen(filename, "r"); char c = fgetc(ptr); creneau* edt = malloc(sizeof(creneau)*size); int i = 0; int to_fill = 0; int buffer = 0; while(c != EOF && c != '$') { if((int)(c) >= 48 && (int)(c) <= 57) { buffer *= 10; buffer += (int)(c) - 48; } else { if(to_fill == 0) { //printf("%d\n", i); edt[i].date.hour = buffer; edt[i].group = 0; edt[i].name = malloc(sizeof(char)*35); edt[i].name[0] = 'n'; edt[i].name[1] = 'o'; edt[i].name[2] = 'n'; edt[i].name[3] = 'e'; edt[i].name[4] = '\0'; edt[i].namelen = 4; edt[i].mat = NOTHING; edt[i].salle.building = 'N'; edt[i].salle.id = 0; edt[i].length = 1; } else if(to_fill == 1) { edt[i].date.day = buffer; } else if(to_fill == 2) { edt[i].date.month = buffer; } else if(to_fill == 3) { edt[i].date.year = buffer; } else { edt[i].length++; } to_fill++; buffer = 0; if(c == '\n') { i++; to_fill = 0; } } c = fgetc(ptr); } fclose(ptr); if(!is_sorted(edt, size)) { assert(0); } return edt; } bool str_equal(char* s1, char* s2) { // note : s1 and s2 must be valid strings (aka have \0 at the end) if((int)(s1[0]) == 0 || (int)(s2[0]) == 0) { return ((int)(s1[0]) == 0 && (int)(s2[0]) == 0); } else if(s1[0] != s2[0]) { return false; } return str_equal(&s1[1], &s2[1]); } void str_copy(char* src, int l1, char* dest) { /* put the word length as l1, \0 NOT included in l1 */ for(int i = 0; i < l1; i++) { dest[i] = src[i]; } dest[l1] = '\0'; } colleur* import_colleurs(char* filename, int n_colleurs, int max_available) { /* file has the following format : name mat dates (date*) - name2 mat2 dates2 - name3 ... $ */ FILE* ptr = fopen(filename, "r"); char c = fgetc(ptr); // {char* name; int namelen; topic mat; date* disp; int n_disp;} colleur* res = malloc(sizeof(colleur)*n_colleurs); char* word = malloc(sizeof(char)*30); int wordlen = 0; int buffer = 0; int date_ptr = 0; int current = 0; // 0 = name, 1 = mat, 2+ = dates int colleur_ptr = 0; while(c != EOF && c != '$') { if(c == '\n') { if(current == 0) { word[wordlen] = '\0'; res[colleur_ptr].name = malloc(sizeof(char)*30); str_copy(word, wordlen, res[colleur_ptr].name); res[colleur_ptr].namelen = wordlen; } else if(current == 1) { if(word[0] == 'M') { // math res[colleur_ptr].mat = MATH; } else if(word[0] == 'P') { // physics res[colleur_ptr].mat = PHYSICS; } else if(word[0] == 'E') { // english res[colleur_ptr].mat = ENGLISH; } else if(word[0] == 'I') { // info res[colleur_ptr].mat = INFO; } else { word[wordlen] = '\0'; printf("Wait that's illegal (%s)\n", word); assert(0); } res[colleur_ptr].disp = malloc(sizeof(date)*max_available); } else { res[colleur_ptr].disp[current-2].year = buffer; } current++; wordlen = 0; buffer = 0; date_ptr = 0; } else if(c == '+') { res[colleur_ptr].n_disp = current-2; current = 0; colleur_ptr++; c = fgetc(ptr); // always a '\n', this to avoid some seg fault } else { if(current <= 1) { word[wordlen] = c; wordlen++; } else { if((int)(c) >= 48 && (int)(c) <= 57) { buffer *= 10; buffer += (int)(c) - 48; } else { if(date_ptr == 0) { res[colleur_ptr].disp[current-2].hour = buffer; } else if(date_ptr == 1) { res[colleur_ptr].disp[current-2].day = buffer; } else if(date_ptr == 2) { res[colleur_ptr].disp[current-2].month = buffer; } else { printf("Oh no (%d)\n", date_ptr); assert(0); } buffer = 0; date_ptr++; } } } //printf("%c", c); c = fgetc(ptr); } // {char* name; int namelen; topic mat; date* disp; int n_disp;} printf("Successfully imported colleurs\n"); fclose(ptr); free(word); return res; } date increment_date(date d, int inc) { int remaining = inc; date res = d; int delta_day = 0; while(remaining > 0) { res.day++; delta_day = (res.month == 1 || res.month == 3 || res.month == 5 || res.month == 7 || res.month == 8 || res.month == 10 || res.month == 12) - 2*(res.month == 2) + (res.month == 2 && res.year%4 == 0 && res.year%100 != 0); // sweet jesus if(res.day > 30 + delta_day) { res.day = 1; if(res.month == 12) { res.month = 1; res.year++; } else { res.month++; } } remaining--; } return res; } creneau* import_creneaux_oneweek(char* filename, int len_file, int n_weeks) { // import creneau data from a file then copy paste it for specified amount of weeks FILE* ptr = fopen(filename, "r"); char c = fgetc(ptr); creneau* edt = malloc(sizeof(creneau)*len_file*n_weeks); int i = 0; int to_fill = 0; int buffer = 0; while(c != EOF && c != '$') { if((int)(c) >= 48 && (int)(c) <= 57) { buffer *= 10; buffer += (int)(c) - 48; } else { if(to_fill == 0) { //printf("%d\n", i); edt[i].date.hour = buffer; edt[i].group = 0; edt[i].name = malloc(sizeof(char)*35); edt[i].name[0] = 'n'; edt[i].name[1] = 'o'; edt[i].name[2] = 'n'; edt[i].name[3] = 'e'; edt[i].name[4] = '\0'; edt[i].namelen = 4; edt[i].mat = NOTHING; edt[i].salle.building = 'N'; edt[i].salle.id = 0; edt[i].length = 1; } else if(to_fill == 1) { edt[i].date.day = buffer; } else if(to_fill == 2) { edt[i].date.month = buffer; } else if(to_fill == 3) { edt[i].date.year = buffer; } else { edt[i].length++; } to_fill++; buffer = 0; if(c == '\n') { i++; to_fill = 0; } } c = fgetc(ptr); } fclose(ptr); for(int k = 1; k < n_weeks; k++) { for(int i = 0; i < len_file; i++) { edt[k*len_file+i].date = increment_date(edt[i].date, 7*k); edt[k*len_file+i].group = 0; edt[k*len_file+i].name = malloc(sizeof(char)*35); edt[k*len_file+i].name[0] = 'n'; edt[k*len_file+i].name[1] = 'o'; edt[k*len_file+i].name[2] = 'n'; edt[k*len_file+i].name[3] = 'e'; edt[k*len_file+i].name[4] = '\0'; edt[k*len_file+i].namelen = 4; edt[k*len_file+i].mat = NOTHING; edt[k*len_file+i].salle.building = 'N'; edt[k*len_file+i].salle.id = 0; edt[k*len_file+i].length = edt[i].length; } } /*for(int k = 0; k < len_file*n_weeks; k++) { printf("%d %d %d %d %d %d\n", edt[k].date.hour, edt[k].date.day, edt[k].date.month, edt[k].date.year, edt[k].group, (int)(edt[k].mat)); }*/ if(!is_sorted(edt, n_weeks*len_file)) { assert(0); } printf("Imported creneaux successfully\n"); return edt; } void expand(colleur* guy, int id, int n_weeks) { int len_1st = guy[id].n_disp; date* new = malloc(sizeof(date)*len_1st*n_weeks); for(int b = 0; b < len_1st; b++) { new[b] = guy[id].disp[b]; } for(int week = 1; week < n_weeks; week++) { for(int i = 0; i < len_1st; i++) { new[week*len_1st+i] = increment_date(guy[id].disp[i], 7*week); } } free(guy[id].disp); guy[id].n_disp *= n_weeks; guy[id].disp = new; } colleur* import_colleurs_oneweek(char* filename, int n_colleurs, int n_weeks, int len_oneweek) { // same as before, but each colleur only set his/her creneaux for the 1st week FILE* ptr = fopen(filename, "r"); char c = fgetc(ptr); // {char* name; int namelen; topic mat; date* disp; int n_disp;} colleur* res = malloc(sizeof(colleur)*n_colleurs); char* word = malloc(sizeof(char)*30); int wordlen = 0; int buffer = 0; int date_ptr = 0; int current = 0; // 0 = name, 1 = mat, 2+ = dates int colleur_ptr = 0; while(c != EOF && c != '$') { if(c == '\n') { if(current == 0) { word[wordlen] = '\0'; res[colleur_ptr].name = malloc(sizeof(char)*30); str_copy(word, wordlen, res[colleur_ptr].name); res[colleur_ptr].namelen = wordlen; } else if(current == 1) { if(word[0] == 'M') { // math res[colleur_ptr].mat = MATH; } else if(word[0] == 'P') { // physics res[colleur_ptr].mat = PHYSICS; } else if(word[0] == 'E') { // english res[colleur_ptr].mat = ENGLISH; } else if(word[0] == 'I') { // info res[colleur_ptr].mat = INFO; } else { word[wordlen] = '\0'; printf("Wait that's illegal (%s)\n", word); assert(0); } res[colleur_ptr].disp = malloc(sizeof(date)*len_oneweek); } else { res[colleur_ptr].disp[current-2].year = buffer; } current++; wordlen = 0; buffer = 0; date_ptr = 0; } else if(c == '+') { res[colleur_ptr].n_disp = current-2; current = 0; colleur_ptr++; c = fgetc(ptr); // always a '\n', this to avoid some seg fault } else { if(current <= 1) { word[wordlen] = c; wordlen++; } else { if((int)(c) >= 48 && (int)(c) <= 57) { buffer *= 10; buffer += (int)(c) - 48; } else { if(date_ptr == 0) { res[colleur_ptr].disp[current-2].hour = buffer; } else if(date_ptr == 1) { res[colleur_ptr].disp[current-2].day = buffer; } else if(date_ptr == 2) { res[colleur_ptr].disp[current-2].month = buffer; } else { printf("Oh no (%d)\n", date_ptr); assert(0); } buffer = 0; date_ptr++; } } } //printf("%c", c); c = fgetc(ptr); } // {char* name; int namelen; topic mat; date* disp; int n_disp;} for(int c = 0; c < n_colleurs; c++) { expand(res, c, n_weeks); } fclose(ptr); free(word); printf("Imported colleurs with no problems\n"); return res; } int str_to_int(char* s) { char c = 'e'; int i = 0; int buffer = 0; while(c != '\0') { c = s[i]; buffer *= 10; if((int)(c) >= 48 && (int)(c) <= 57) { buffer += (int)(c)-48; } i++; } return buffer/10; }