Created
December 19, 2020 18:50
-
-
Save fniessink/3570a2c0857c40a5195affdee7ff2df2 to your computer and use it in GitHub Desktop.
Create speed date schedules with multiple rounds and tables
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import random | |
from itertools import zip_longest | |
from pprint import pprint | |
def grouper(iterable, n, fillvalue=None): | |
"""Collect data into fixed-length chunks or blocks""" | |
# grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx" | |
args = [iter(iterable)] * n | |
return zip_longest(*args, fillvalue=fillvalue) | |
class Person: | |
def __init__(self, name): | |
self.name = name | |
self.met = set() | |
def __repr__(self): | |
return self.name | |
def __eq__(self, other): | |
return self.name == other.name | |
def __hash__(self): | |
return hash(self.name) | |
def meet(self, others): | |
self.met |= set([person for person in others if person != self]) | |
def real_people(people): | |
return [person for person in people if not person.name.startswith("Dummy")] | |
nr_seats = 4 # Seats per table | |
nr_rounds = 3 | |
people = [ | |
Person("Alexander"), Person("Betty"), Person("Charles"), Person("Diana"), Person("Edward"), | |
Person("Francine"), Person("Gerald"), Person("Hetty"), Person("Ian"), Person("John")] | |
best_score = 0 | |
experiment = 0 | |
for index in range(len(people) % nr_seats): | |
people.append(Person(f"Dummy {index+1}")) | |
while True: | |
experiment += 1 | |
rounds = [random.sample(people, len(people)) for round in range(nr_rounds)] | |
for person in people: | |
person.met = set() | |
seating = [] # List of rounds | |
for round_nr, round in enumerate(rounds): | |
seating.append([]) # Add an empty round | |
for table_nr, table in enumerate(grouper(round, nr_seats)): | |
persons = real_people(table) | |
seating[-1].append(persons) # Add the table | |
for person in persons: | |
person.meet(persons) | |
if (score := sum([len(person.met) for person in people])) >= best_score: | |
best_score = score | |
print(f"Experiment {experiment} scores {score}, seating:") | |
pprint(seating) | |
print([f"{p.name}: {len(p.met)}" for p in real_people(people)]) | |
print() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment