From 871c7875ddc4c87edf1febf6d6b18949234a1524 Mon Sep 17 00:00:00 2001 From: alexandre Date: Mon, 8 Apr 2024 21:50:37 +0200 Subject: [PATCH] added is_allowed function --- algorithm.c | 180 +++++++++++++++++++++++++++++++++++++++++++++++++++- main.c | 19 +++++- structure.c | 8 +-- 3 files changed, 200 insertions(+), 7 deletions(-) diff --git a/algorithm.c b/algorithm.c index b638a2d..e2050dd 100644 --- a/algorithm.c +++ b/algorithm.c @@ -1,5 +1,183 @@ #include "display.c" +int get_date_index(creneau* edt, int len_creneau, date d) { + // could be done in log(n), I know + int x = -1; + for(int i = 0; i < len_creneau; i++) { + x = date_dist(edt[i].date, d); + if(x >= 0) { + return i; + } + } + return -1; +} + +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) { + if(last_no_inf != -1 && last_no_inf != 5) { + printf("Invalid rotation of info colles at index %d for group %d\n", i, grp); + return false; + } + last_no_inf = 0; + } else if(last_no_inf > 5) { + printf("Too many 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 + } +*/ + +/* void generate_colles_v1(creneau* edt, int len_edt, int n_groups, colleur* chads, int n_chads) { -} \ No newline at end of file +} +*/ + + + + + + + + + + + + diff --git a/main.c b/main.c index 25aceae..4f9d298 100644 --- a/main.c +++ b/main.c @@ -17,10 +17,23 @@ 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 = {17, 1, 3, 2024}; + date d1 = {18, 12, 2, 2024}; + + //printf("%d\n", date_dist(d1, d1)); + //printf("%d %d %d %d\n", edt[70].date.hour, edt[70].date.day, edt[70].date.month, edt[70].date.year); - print_one_week(rend, edt, 112, d1); + //print_one_week(rend, edt, 112, d1); + + edt[3].group = 1; + edt[3].mat = ENGLISH; + edt[6].group = 1; + edt[6].mat = INFO; + edt[20].group = 1; + edt[20].mat = PHYSICS; + edt[21].group = 1; + edt[21].mat = MATH; + is_allowed_MP2I(edt,len_creneau, 1, d1); /* date d1 = {19, 1, 3, 2024}; @@ -29,6 +42,8 @@ int main() { printf("%d\n", date_dist(d1, d2)); */ + free(edt); + SDL_DestroyRenderer(rend); SDL_DestroyWindow(win); SDL_Quit(); diff --git a/structure.c b/structure.c index f1c0080..de263ea 100644 --- a/structure.c +++ b/structure.c @@ -10,12 +10,13 @@ typedef enum topic {NOTHING, MATH, PHYSICS, ENGLISH, FRENCH, INFO} topic; // colles subjects -typedef struct date {int hour; int day; int month; int year;} date; +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; // 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; // available creneaux for the colleurs @@ -23,9 +24,8 @@ typedef struct colleur {char* name; topic mat; date* disp; int n_disp;} colleur; 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 +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;