Skip to content

Instantly share code, notes, and snippets.

@imtapps
Last active August 29, 2015 14:24
Show Gist options
  • Save imtapps/3048235ad4fd69430c56 to your computer and use it in GitHub Desktop.
Save imtapps/3048235ad4fd69430c56 to your computer and use it in GitHub Desktop.
Assign seats for roundtable discussions at the customer meeting
"""
Sort customers into random tables
Make sure they do not sit at a table with the same people more than once
* 155 customers
* 20 tables
* 6-8 customers at each table
* 6 rounds of switching tables
=====
To use this just run it until there is only 1 failing test and it fails with "X"... then that output is good
"""
from __future__ import division
from random import shuffle
class Duplicate(Exception):
pass
class Main(object):
def __init__(self, tables, attendees):
self.tables = range(1, tables + 1)
self.attendees = range(1, attendees + 1)
self.rounds = []
shuffle(self.attendees)
@property
def slices(self):
return [8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 6, 6]
@property
def people_per_table(self):
return int(round(len(self.attendees) / len(self.tables)))
def init(self):
current_round = {}
start = 0
for table, peeps in enumerate(self.slices, 1):
end = peeps + start
current_round[table] = self.attendees[start:end]
start = end
self.rounds.append(current_round)
return current_round
def switch(self):
v = 1
while True:
v += 1
attendees = list(self.attendees)
shuffle(attendees)
current_round = self.get_new_round(attendees)
try:
for previous_round in self.rounds:
for x in previous_round.values():
for people in current_round.values():
if len(set(x).intersection(set(people))) > 2:
raise Duplicate
except Duplicate:
continue
break
return current_round
def get_new_round(self, attendees):
current_round = {}
for table, peeps in enumerate(self.slices, 1):
people = []
for i in range(peeps):
if attendees:
people.append(attendees.pop())
current_round[table] = people
return current_round
import unittest
class MainTests(unittest.TestCase):
def test_lots(self):
result = Main(tables=20, attendees=155).init()
self.assertEqual(range(1, 21), result.keys())
for i in range(1, 18):
self.assertEqual(8, len(result[i]))
self.assertEqual(7, len(result[18]))
self.assertEqual(6, len(result[19]))
self.assertEqual(6, len(result[20]))
def test_does_not_duplicate_on_second_round(self):
main = Main(tables=20, attendees=155)
result_one = main.init()
result_two = main.switch()
self.assert_unique(result_one, result_two)
def test_does_not_duplicate_on_third_round(self):
main = Main(tables=20, attendees=155)
result_one = main.init()
result_two = main.switch()
result_three = main.switch()
self.assert_unique(result_one, result_two)
self.assert_unique(result_one, result_three)
self.assert_unique(result_two, result_three)
def test_does_not_duplicate_on_fourth_round(self):
main = Main(tables=20, attendees=155)
result_one = main.init()
result_two = main.switch()
result_three = main.switch()
result_four = main.switch()
self.assert_unique(result_one, result_two)
self.assert_unique(result_one, result_three)
self.assert_unique(result_two, result_three)
self.assert_unique(result_one, result_four)
self.assert_unique(result_two, result_four)
self.assert_unique(result_three, result_four)
def test_does_not_duplicate_on_fifth_round(self):
main = Main(tables=20, attendees=155)
result_one = main.init()
result_two = main.switch()
result_three = main.switch()
result_four = main.switch()
result_five = main.switch()
self.assert_unique(result_one, result_two)
self.assert_unique(result_one, result_three)
self.assert_unique(result_two, result_three)
self.assert_unique(result_one, result_four)
self.assert_unique(result_two, result_four)
self.assert_unique(result_three, result_four)
self.assert_unique(result_one, result_five)
self.assert_unique(result_two, result_five)
self.assert_unique(result_three, result_five)
self.assert_unique(result_four, result_five)
def test_does_not_duplicate_on_sixth_round(self):
main = Main(tables=20, attendees=155)
result_one = main.init()
result_two = main.switch()
result_three = main.switch()
result_four = main.switch()
result_five = main.switch()
result_six = main.switch()
self.assert_unique(result_one, result_two)
self.assert_unique(result_one, result_three)
self.assert_unique(result_two, result_three)
self.assert_unique(result_one, result_four)
self.assert_unique(result_two, result_four)
self.assert_unique(result_three, result_four)
self.assert_unique(result_one, result_five)
self.assert_unique(result_two, result_five)
self.assert_unique(result_three, result_five)
self.assert_unique(result_four, result_five)
self.assert_unique(result_one, result_six)
self.assert_unique(result_two, result_six)
self.assert_unique(result_three, result_six)
self.assert_unique(result_four, result_six)
self.assert_unique(result_five, result_six)
self.display_results(result_one)
self.display_results(result_two)
self.display_results(result_three)
self.display_results(result_four)
self.display_results(result_five)
self.display_results(result_six)
self.fail("X")
def assert_unique(self, first, second):
self.assertEqual(20, len(first))
self.assertEqual(20, len(second))
for table, peeps in first.items():
self.assertGreater(len(peeps), 5)
duplicates = len(list(set(peeps).intersection(set(second[table]))))
self.assertTrue(duplicates <= 2)
def display_results(self, result):
print "=" * 80
for table, peeps in result.items():
print "Table: {} People: {}".format(table, peeps)
if __name__ == '__main__':
unittest.main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment