import itertools
import re
import string
import time
def is_valid(arrangement):
table = arrangement.lower()
return table[0] != table[-1] and not re.search(r'(\w)\1', table)
def permutations(people, preset):
if preset is None:
preset = people[0] + '_' * (len(people) - 1)
unused = [person for person in people if person not in preset]
cases = itertools.permutations(unused)
template = preset.replace('_', '{}')
return (template.format(*p) for p in cases)
def get_valid_seatings(people, preset=None):
if preset is None:
preset = people[0] + '_' * (len(people) - 1)
cases = permutations(people, preset)
return [c for c in cases if is_valid(c)]
def count_seatings(num_couples):
people = string.ascii_lowercase[:num_couples] + string.ascii_uppercase[:num_couples]
return len(get_valid_seatings(people))
for i in range(1, 6):
start = time.time()
seatings = count_seatings(i)
end = time.time()
print('{} couples: {} -- {:0.3f}s'.format(i, seatings, end - start))
# Try one with pre-seatings
couples = 'abcdeABCDE'
impatient = 'a__bc__A__'
start = time.time()
seatings = len(get_valid_seatings(couples, impatient))
end = time.time()
print('4 impatient people: {} -- {:0.3f}s'.format(seatings, end - start))
aW1wb3J0IGl0ZXJ0b29scwppbXBvcnQgcmUKaW1wb3J0IHN0cmluZwppbXBvcnQgdGltZQoKCmRlZiBpc192YWxpZChhcnJhbmdlbWVudCk6CiAgICB0YWJsZSA9IGFycmFuZ2VtZW50Lmxvd2VyKCkKICAgIHJldHVybiB0YWJsZVswXSAhPSB0YWJsZVstMV0gYW5kIG5vdCByZS5zZWFyY2gocicoXHcpXDEnLCB0YWJsZSkKCgpkZWYgcGVybXV0YXRpb25zKHBlb3BsZSwgcHJlc2V0KToKICAgIGlmIHByZXNldCBpcyBOb25lOgogICAgICAgIHByZXNldCA9IHBlb3BsZVswXSArICdfJyAqIChsZW4ocGVvcGxlKSAtIDEpCiAgICB1bnVzZWQgPSBbcGVyc29uIGZvciBwZXJzb24gaW4gcGVvcGxlIGlmIHBlcnNvbiBub3QgaW4gcHJlc2V0XQogICAgY2FzZXMgPSBpdGVydG9vbHMucGVybXV0YXRpb25zKHVudXNlZCkKICAgIHRlbXBsYXRlID0gcHJlc2V0LnJlcGxhY2UoJ18nLCAne30nKQogICAgcmV0dXJuICh0ZW1wbGF0ZS5mb3JtYXQoKnApIGZvciBwIGluIGNhc2VzKQoKCmRlZiBnZXRfdmFsaWRfc2VhdGluZ3MocGVvcGxlLCBwcmVzZXQ9Tm9uZSk6CiAgICBpZiBwcmVzZXQgaXMgTm9uZToKICAgICAgICBwcmVzZXQgPSBwZW9wbGVbMF0gKyAnXycgKiAobGVuKHBlb3BsZSkgLSAxKQogICAgY2FzZXMgPSBwZXJtdXRhdGlvbnMocGVvcGxlLCBwcmVzZXQpCiAgICByZXR1cm4gW2MgZm9yIGMgaW4gY2FzZXMgaWYgaXNfdmFsaWQoYyldCgoKZGVmIGNvdW50X3NlYXRpbmdzKG51bV9jb3VwbGVzKToKICAgIHBlb3BsZSA9IHN0cmluZy5hc2NpaV9sb3dlcmNhc2VbOm51bV9jb3VwbGVzXSArIHN0cmluZy5hc2NpaV91cHBlcmNhc2VbOm51bV9jb3VwbGVzXQogICAgcmV0dXJuIGxlbihnZXRfdmFsaWRfc2VhdGluZ3MocGVvcGxlKSkKCgpmb3IgaSBpbiByYW5nZSgxLCA2KToKICAgIHN0YXJ0ID0gdGltZS50aW1lKCkKICAgIHNlYXRpbmdzID0gY291bnRfc2VhdGluZ3MoaSkKICAgIGVuZCA9IHRpbWUudGltZSgpCiAgICBwcmludCgne30gY291cGxlczoge30gLS0gezowLjNmfXMnLmZvcm1hdChpLCBzZWF0aW5ncywgZW5kIC0gc3RhcnQpKQojIFRyeSBvbmUgd2l0aCBwcmUtc2VhdGluZ3MKY291cGxlcyA9ICdhYmNkZUFCQ0RFJwppbXBhdGllbnQgPSAnYV9fYmNfX0FfXycKc3RhcnQgPSB0aW1lLnRpbWUoKQpzZWF0aW5ncyA9IGxlbihnZXRfdmFsaWRfc2VhdGluZ3MoY291cGxlcywgaW1wYXRpZW50KSkKZW5kID0gdGltZS50aW1lKCkKcHJpbnQoJzQgaW1wYXRpZW50IHBlb3BsZToge30gLS0gezowLjNmfXMnLmZvcm1hdChzZWF0aW5ncywgZW5kIC0gc3RhcnQpKQ==