Esempio n. 1
0
def get_teams(pref: Preferences, size: int) -> [[str]]:
    """Partitions all the students whose information is in pref into teams of size.

    One of the teams is padded with dummy students, XXX, if there are not enough
    students. Students are picked in a random order and checked if they can work
    with each other. Teaming can fail if the remaining students to be teamed
    cannot work with each other.

    Parameters:
    - pref: contains the students to be teamed and their preferences.

    Returns:
    The list of teams. The list is empty if teaming fails.

    """
    # Get students to be teamed, randomize their order. Initialize dummy student
    # to be used to pad small team.
    students = pref.get_students()
    random.shuffle(students)
    # Initialize the teams and the teamed students so far.
    teams = []
    teamed = set()
    # Make as many teams of size as possible.
    while len(students) >= size:
        # Initialize empty team and add size students who can be teamed
        # together.
        team = []
        for i in range(size):
            idx = len(students) - 1
            while any([not pref.can_team(students[idx], s)
                       for s in team]) and idx >= 0:
                idx -= 1
            # Exit with failure if teaming failed.
            if idx < 0:
                return []
            # Update team, teamed students, and remaining students.
            team.append(students[idx])
            teamed.add(students[idx])
            students.pop(idx)
        # Save team.
        teams.append(team)
    # Exit successfully if all the students have been teamed.
    if len(students) == 0:
        return teams
    # Exit with failure if the remaining students cannot be teamed.
    for src in students:
        if any([not pref.can_team(src, s) for s in students]):
            return []
    # Add team padded with dummy student, and exit successfully.
    team = students + ['XXX'] * (size - len(students))
    teams.append(team)
    return teams