#include "display.c" int get_date_index(creneau* edt, int len_creneau, date d) { // could be done in log(n), I know // yields the 1st occurence of d in edt int x = -1; for(int i = 0; i < len_creneau; i++) { x = date_dist(d, edt[i].date); if(x >= 0) { return i; } } return -1; } array get_all_date_index(creneau* edt, int len_edt, date d) { array arr; arr.a = malloc(sizeof(int)*8); arr.memlen = 8; arr.len = 0; int x = -1; int halt = 0; for(int i = 0; i < len_edt-halt; i++) { x = date_dist(d, edt[i].date); if(x == 0) { arr.a[arr.len] = i; arr.len++; } else if(x > 0) { halt = len_edt; } } return arr; } int get_next_friday(creneau* edt, int len_creneau, date d) { // could be done in log(n), I know again int x = -1; for(int i = 0; i < len_creneau; i++) { x = date_dist(d, edt[i].date); //printf("%d\n", x); if(x >= 0 && (i == len_creneau-1 || date_dist(d, edt[i+1].date) - x > 1)) { return i; } } return -1; } int get_fst_offset(creneau* edt, date d) { return (date_dist(edt[0].date, d)); } bool is_allowed_MP2I(creneau* edt, int len_edt, int grp, date end) { /* conditions (AND) : 1) Alternate between physics and english 2) Pattern for math colles is exactly 3-1-3-1-... 3) Between 1 and 2 colles per week and per group (exclusing special colles such as Info) 4) Special colles (aka INFO) at least 1 every 6 weeks */ int end_id = get_next_friday(edt, len_edt, end); // index of first date that is later than end if(end_id == -1) { return true; } //printf("EndId : %d\n", end_id); // 1) PC/AGL alternance int agl = 0; int pc = 0; char has_to_be = 'n'; // 'n' = not set, 'a' = AGL and 'p' = PC for(int i = end_id-1; i >= 0; 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)) { //printf("Checking AGL/PC...\n"); // currently pointed date is the last friday of the week // since we are going down, friday <==> reset variables and check for conflicts if(agl + pc != 1) { printf("Missing english or physics colle at index %d for group %d (found %d)\n", i, grp, agl+pc); return false; } else if(has_to_be == 'p' && pc != 1) { printf("Wrong number of physics colle at index %d for group %d\n", i, grp); return false; } else if(has_to_be == 'a' && agl != 1) { printf("Wrong number of english colle at index %d for group %d\n", i, grp); return false; } if(has_to_be == 'n') { if(agl == 1) { has_to_be = 'p'; } else { has_to_be = 'a'; } } agl = 0; pc = 0; } if(edt[i].group == grp && edt[i].mat == ENGLISH) { agl += 1; } if(edt[i].group == grp && edt[i].mat == PHYSICS) { pc += 1; } } // 2) Math colles int math = 0; int last_no_math = -1; for(int i = end_id-1; i >= 0; 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(math != 0 && math != 1) { printf("Invalid number of math colles at index %d for group %d\n", i, grp); return false; } else if(math == 0) { if(last_no_math != -1 && last_no_math != 3) { printf("Invalid rotation of math colles at index %d for group %d\n", i, grp); return false; } last_no_math = 0; } else if(last_no_math > 3) { printf("Too many math colles at index %d for group %d\n", i, grp); return false; } else { if(last_no_math != -1) { last_no_math += 1; } } math = 0; } if(edt[i].group == grp && edt[i].mat == MATH) { math += 1; } } // 3) Count int n_colles = 0; for(int i = end_id-1; i >= 0; 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(n_colles != 1 && n_colles != 2) { printf("Invalid number of colles at index %d for group %d (found %d)", i, grp, n_colles); return false; } n_colles= 0; } if(edt[i].group == grp) { n_colles++; } } // 4) Info int inf = 0; int last_no_inf = -1; for(int i = end_id-1; i >= 0; 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(inf != 0 && inf != 1) { printf("Invalid number of info colles at index %d for group %d\n", i, grp); return false; } else if(inf == 0) { last_no_inf = 0; } else if(last_no_inf > 5) { printf("Too few info colles at index %d for group %d\n", i, grp); return false; } else { if(last_no_inf != -1) { last_no_inf += 1; } } inf = 0; } if(edt[i].group == grp && edt[i].mat == INFO) { inf += 1; } } return true; } /* for(int i = end_id-1; i >= 0; 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)) { // Check week } // Detect colles } */ int heuristique_MP2I(creneau* edt,int len_edt, int grp, date end) { /* 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; } /* void generate_colles_v1(creneau* edt, int len_edt, int n_groups, colleur* chads, int n_chads) { } */