so one thing i could do is use branch and bound to identify all the valid combinations of blocks for courses (each has a LocalTime for start and end as well as a DayOfWeek) and then sort the solutions by taking points off for being in unfortunate times or so
BUT the first step is greedy in a way that it does not allow exercise blocks to potentially overlap
so if i do allow exercise blocks to overlap.. and then sort by demerits i could get there without libraries