diff --git a/algorithm.c b/algorithm.c index 32dc491..be1ab4f 100644 --- a/algorithm.c +++ b/algorithm.c @@ -64,7 +64,7 @@ bool is_allowed_MP2I(creneau* edt, int len_edt, int grp, date end) { return true; } - printf("EndId : %d\n", end_id); + //printf("EndId : %d\n", end_id); // 1) PC/AGL alternance int agl = 0; @@ -182,16 +182,127 @@ bool is_allowed_MP2I(creneau* edt, int len_edt, int grp, date end) { } */ -int heuristique(creneau* edt,int len_edt, int grp, date end) { +int heuristique_MP2I(creneau* edt,int len_edt, int grp, date end) { /* - - Both colles end at 7PM : -10 - - Having the same colleur two weeks in a row : -45 - - Having the same colleur at a 3w interval : -25 - - Having the same colleur at a 4w interval : -10 - - Two colles the same day : -20 - - Same date over 2 weeks : -10 - */ - return 0; + A - Both colles end at 7PM : -10 + B - Having the same colleur two weeks in a row : -45 + C - Having the same colleur at a 3w interval : -25 + D - Having the same colleur at a 4w interval : -10 + E - Two colles the same day : -20 + F - Same date over 2 weeks : -10 + */ + int end_id = get_next_friday(edt, len_edt, end); // index of first date that is later than end + + if(end_id == -1) { + return 0; + } + int score = 0; + int halt = 0; + int remaining = 2; + creneau* temp = malloc(sizeof(creneau)*16); + int len_temp = 0; + + //printf("EndId : %d\n", end_id); + + // A - Colles 7PM (-10) + // Check for current week only + bool _7pm_1 = false; + bool _7pm_2 = false; + for(int i = end_id-1; i >= 0+halt; i--) { + if(i == 0 || (date_dist(edt[0].date, edt[i].date)%7 == 4 && date_dist(edt[0].date, edt[i+1].date)%7 != 4)) { + score -= 10*(_7pm_1 && _7pm_2); + halt = end_id-1; + } + if(edt[i].group == grp && edt[i].date.hour == 18) { + //printf("E\n"); + _7pm_2 = _7pm_1; + _7pm_1 = true; + } + } + halt = 0; + len_temp = 0; + + // B, C and D : same colleur 2/3/4times in a row (-45) + // 4-week check + remaining = 4; + for(int i = end_id-1; i >= 0+halt; i--) { + if(i == 0 || (date_dist(edt[0].date, edt[i].date)%7 == 4 && date_dist(edt[0].date, edt[i+1].date)%7 != 4)) { + remaining -= 1; + if(remaining == 0 || i == 0) { + bool b = false; + int dist = 0; + for(int j = 0; j < len_temp; j++) { + for(int k = j+1; k < len_temp; k++) { + b = str_equal(temp[j].name, temp[k].name); + if(b && !(str_equal(temp[j].name, ""))) { + dist = date_dist(temp[k].date, temp[j].date); + if(dist < 7) { + score -= 45; + } else if(dist < 14) { + score -= 20; + } else if(dist < 21) { + score -= 10; + } + } + } + } + halt = end_id-1; + } + } + if(edt[i].group == grp) { + temp[len_temp] = edt[i]; + len_temp++; + } + } + halt = 0; + len_temp = 0; + + // E - 2 colles the same day (-20) + // single-week check + for(int i = end_id-1; i >= 0+halt; i--) { + if(i == 0 || (date_dist(edt[0].date, edt[i].date)%7 == 4 && date_dist(edt[0].date, edt[i+1].date)%7 != 4)) { + if(len_temp >= 2) { + score -= 20*(temp[0].date.day == temp[1].date.day); + } + halt = end_id-1; + } + if(edt[i].group == grp) { + temp[len_temp] = edt[i]; + len_temp++; + } + } + halt = 0; + len_temp = 0; + + // F - Same over 2 weeks (-10) + // 2-week check + remaining = 2; + for(int i = end_id-1; i >= 0+halt; i--) { + if(i == 0 || (date_dist(edt[0].date, edt[i].date)%7 == 4 && date_dist(edt[0].date, edt[i+1].date)%7 != 4)) { + remaining -= 1; + if(remaining == 0 || i == 0) { + int dist = 0; + for(int j = 0; j < len_temp; j++) { + for(int k = j+1; k < len_temp; k++) { + dist = date_dist(temp[k].date, temp[j].date); + if(dist == 7 && temp[k].date.hour == temp[j].date.hour) { + score -= 20; + } + } + } + halt = end_id-1; + } + } + if(edt[i].group == grp) { + temp[len_temp] = edt[i]; + len_temp++; + } + } + halt = 0; + len_temp = 0; + + free(temp); + return score; } /* diff --git a/main.c b/main.c index 2bb1212..38ec149 100644 --- a/main.c +++ b/main.c @@ -3,6 +3,7 @@ // gcc -g -Wall -Wextra -Wpedantic main.c -lSDL2 -lSDL2_image -lm -o main int main() { + printf("Starting\n"); if (SDL_Init(SDL_INIT_EVERYTHING) != 0) { printf("error initializing SDL: %s\n", SDL_GetError()); } @@ -17,7 +18,7 @@ int main() { //printf("%d %d %d %d\n", edt[10].date.hour, edt[10].date.day, edt[10].date.month, edt[10].date.year); - date d1 = {18, 12, 2, 2024}; + date d1 = {18, 14, 2, 2024}; //printf("%d\n", date_dist(d1, d1)); @@ -25,18 +26,20 @@ int main() { //print_one_week(rend, edt, 112, d1); - /* - edt[6].group = 1; - edt[6].mat = INFO; + + edt[9].group = 1; + edt[9].mat = INFO; + edt[9].name = "Rapin"; edt[20].group = 1; edt[20].mat = PHYSICS; - edt[1].group = 1; - edt[1].mat = ENGLISH; + edt[13].group = 1; + edt[13].mat = ENGLISH; + edt[13].name = "Rapin"; edt[21].group = 1; edt[21].mat = MATH; - is_allowed_MP2I(edt,len_creneau, 1, d1); - */ - + if(is_allowed_MP2I(edt,len_creneau, 1, d1)) { + printf("Score : %d\n", heuristique_MP2I(edt, 112, 1, d1)); + } /* date d1 = {19, 1, 3, 2024}; diff --git a/structure.c b/structure.c index 8a191b5..5dd35f2 100644 --- a/structure.c +++ b/structure.c @@ -13,12 +13,12 @@ typedef enum topic {NOTHING, MATH, PHYSICS, ENGLISH, FRENCH, INFO} topic; typedef struct date {int hour; int day; int month; int year;} date; /* format is {hour, day, month, year} */ // nothing to say here -typedef struct creneau {date date; int group; char* name; topic mat;} creneau; +typedef struct creneau {date date; int group; char* name; int namelen; topic mat;} creneau; // one créneau de colle // /!\ creneau has to be sorted by ascending dates // with edt being a creneau*, it is required to have edt[0] be a Monday and edt[len(edt)-1] has to be a Friday -typedef struct colleur {char* name; topic mat; date* disp; int n_disp;} colleur; +typedef struct colleur {char* name; int namelen; topic mat; date* disp; int n_disp;} colleur; // available creneaux for the colleurs typedef struct array {int* a; int len; int memlen;} array; @@ -91,7 +91,9 @@ creneau* import_creneaux(char* filename, int size) { if(to_fill == 0) { edt[i].date.hour = buffer; edt[i].group = 0; - edt[i].name = "empty"; + edt[i].name = malloc(sizeof(char)*35); + edt[i].name[0] = '\0'; + edt[i].namelen = 0; edt[i].mat = NOTHING; } else if(to_fill == 1) { edt[i].date.day = buffer; @@ -119,11 +121,19 @@ creneau* import_creneaux(char* filename, int size) { } bool str_equal(char* s1, char* s2) { - // note : s1 and s2 must be valid strings (aka have (int)(0) at the end) + // 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 */ + for(int i = 0; i < l1; i++) { + dest[i] = src[i]; + } + dest[l1] = '\0'; } \ No newline at end of file