The assignment logic may be used in a planning KoTH, in which a student bot chooses a full permutation from the classes and is awarded points from what preference they get.
Background
In a school, students are signing up for after-school classes. However, the capacity of each class is limited. In order to facilitate class assignment, each student is required to fill in a questionnaire to show his/her preference to the classes by listing all classes in decreasing order of his/her interests.
You are assigned to help assigning classes to them. You want to maximally satisfy their preferences while being fair with the assignment. A student can be assigned with multiple classes.
Challenge
Write a program or function that receives the following input:
- a list of classes with the corresponding capacities; and
- a list of students with their corresponding preference lists,
and output or return either:
- a list of class with the list of students being assigned to that class; or
- a list of students with their assigned classes.
You may use any reasonable alternative format for both input and output, for example, apart from receiving two arrays, you may choose to receive two strings, and especially for the second input (which requires a 2-D array), you may even have an input like this (first level delimiter \n
, second level delimiter space
):
1 2 3 4
4 2 3 1
1 3 2 4
2 3 4 1
3 4 1 2
4 1 2 3
To simplify the challenge, you may assume both classes and students are 0-indexed or 1-indexed. For the use of illustrating the requirements and samples, 1-indexing is used. You may also assume that each preference list is a full permutation of all classes.
The assignment requirements are as follows:
- Fairness: All students must have roughly the same amount of classes assigned to them, that is, for every \$1\le i\le\text{[Number of students]}\$, $$\left|{\text{[Number of classes assigned]}_i-\frac{\sum\text{[Class capacities]}}{\text{[Number of students]}}}\right|<1.$$
- Satisfaction: You should fulfill the preferences as well as possible. Specifically, you should fulfill as much first preferences as possible, then as much second preferences as possible, and so on. In case of having the same preference order, the classes should be assigned on first-come-first-served basis.
The fairness rule should be taken first if it conflicts with the satisfaction rule. Test case 3 is an example of handling such conflicts.
The program should terminate in finite time for all practical sizes of inputs.
Test cases
Test case 1
Input:
classes = [2, 2, 2, 2],
students = [
[1, 2, 4, 3],
[2, 4, 1, 3],
[3, 4, 2, 1],
[4, 3, 2, 1]
]
Output:
classes = [
[1, 3],
[2, 1],
[3, 4],
[4, 2]
],
students = [
[1, 2],
[2, 4],
[3, 1],
[4, 3]
]
Explanation:
- It is clear that all 1st priorities can be fulfilled because all of them are different. So each student gets his 1st priority.
- Student 1 wants Class 2 as his 2nd priority, and Class 2 still has place for him. So he gets Class 2.
- Student 2 wants Class 4 as his 2nd priority, and Class 4 still has place for him. So he gets Class 4.
- Student 3 wants Class 4 as his 2nd priority, but Class 4 is already full. No place for him.
- Student 4 wants Class 3 as his 2nd priority, and Class 3 still has place for him. So he gets Class 3.
- Now each of the students except Student 3 has 2 classes already, so by the rule of fairness they are not considered in the subsequent assignments.
- Only Class 1 has place for Student 3, so he gets his 4th priority.
Test case 2
Input:
classes = [2, 2, 2],
students = [
[3, 1, 2],
[2, 3, 1],
[2, 3, 1],
[3, 2, 1]
]
Output:
classes = [
[1, 2],
[2, 3],
[1, 4]
],
students = [
[3, 1],
[2, 1],
[2],
[3]
]
Explanation:
- It is clear that all 1st priorities can be fulfilled because none of the classes was chosen by 3 or more students as their 1st priorities.
- Student 1 wants Class 1 as his 2nd priority, and Class 1 still has place for him. So he gets Class 1.
- Student 2 wants Class 3 as his 2nd priority, but Class 3 is already full. No place for him.
- Student 3 wants Class 3 as his 2nd priority, but Class 3 is already full. No place for him.
- Student 4 wants Class 2 as his 2nd priority, but Class 2 is already full. No place for him.
- Now Student 1 has 2 classes already, so by the rule of fairness he is not considered in the subsequent assignments.
- Student 2 wants Class 1 as his 3rd priority, and Class 1 still has place for him. So he gets Class 1.
- All classes are already full, so no more seats can be assigned. Students 3 and 4 will only get 1 class each.
Test case 3
Input:
classes = [1, 1, 1, 2],
students = [
[1, 2, 4, 3],
[3, 4, 2, 1],
[2, 4, 3, 1],
[2, 4, 1, 3]
]
Output:
classes = [
[1],
[3],
[2],
[4, 2]
],
students = [
[1],
[3, 4],
[2],
[4]
]
Explanation:
- It is clear that all 1st priorities except for Student 4 can be fulfilled.
- If we ignore Student 4 and proceed to the second round, Student 2 and 3 will occupy the remaining seats and Student 4 will not get a place (which is disallowed by the fairness rule), so the 2nd priority of Student 4 will be considered first. Since Class 4 still has place for him, he gets Class 4.
- Student 1 wants Class 2 as his 2nd priority, but Class 2 is already full. No place for him.
- Student 2 wants Class 4 as his 2rd priority, and Class 4 still has place for him. So he gets Class 4.
- All classes are already full, so no more seats can be assigned. All students get 1 class each, except Student 2, who gets 2 classes.
Test case 4
Input:
classes = [1, 1, 1, 2],
students = [
[1, 2, 4, 3],
[3, 4, 2, 1],
[2, 4, 3, 1],
[2, 1, 3, 4]
]
Output:
classes = [
[1],
[4],
[2],
[2, 3]
],
students = [
[1],
[3, 4],
[4],
[2]
]
Explanation:
- It is clear that all 1st priorities except for Student 4 can be fulfilled.
- If we ignore Student 4 and proceed to the second round, Student 2 and 3 will occupy the remaining seats and Student 4 will not get a place (which is disallowed by the fairness rule), so the 2nd priority of Student 4 will be considered first. However both Classes 1 and 3 are full, he can only get Class 4.
- The remaining place for Class 4 goes to Student 2, and we have 3 1st priorities, 1 2nd priority and 1 4th priority fulfilled.
- But this is not the best. By breaking the first-come-first-served rule for 1st priority, we can get the best - 3 1st priorities and 2 2nd priorities fulfilled.
Winning Condition
This is a code-golf challenge, so the shortest submission for each language wins. Standard loopholes are forbidden.