Naar jaarlijkse gewoonte scharen de gezinnen van een familie zich rond het haardvuur om Kerstmis te vieren. Op het hoogtepunt van de avond deelt elk familielid een geschenk uit aan een andere familielid, waarbij iedereen één geschenk uitdeelt en iedereen één geschenk ontvangt. Om dat te organiseren, worden er een paar weken voorafgaand aan de festiviteiten kaartjes met alle namen van de familieleden in een grote hoed gestopt en mag iedereen blind één kaartje uit de hoed trekken. Als iemand toevallig zijn eigen naam zou trekken, dan gaan alle kaartjes terug in de hoed, en wordt de procedure herhaald totdat iedereen iemand anders getrokken heeft. Omdat iedereen dit jaar toevallig een kaartje getrokken heeft waarop de naam van iemand van zijn of haar eigen gezin staat, heeft de familie afgesproken om de volgende trekking te blijven herhalen totdat niemand een kaartje getrokken heeft van een eigen gezinslid.

kerstfeestje

Voorbereiding

In de module random wordt een functie shuffle gedefinieerd die de elementen van een gegeven lijst willekeurig door elkaar schudt. Onderstaande sessie illustreert de werking van deze functie. Merk dus op dat de functie shuffle geen nieuwe lijst teruggeeft, maar de elementen in place van plaats verwisselt.

>>> from random import shuffle

>>> lijst = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> shuffle(lijst)
>>> lijst
[2, 7, 8, 9, 3, 6, 1, 5, 4, 10]
>>> shuffle(lijst)
>>> lijst
[8, 10, 6, 7, 4, 2, 9, 3, 5, 1]

Opgave

In deze opgave stellen we een gezin voor als een (bevroren) verzameling van strings, waarbij de strings de namen van de gezinsleden bevatten. Een samenstelling van een familie wordt voorgesteld als een lijst, een tuple of een verzameling van gezinnen. Hierbij mag verondersteld worden dat een familie uit minstens twee gezinnen bestaat, en dat er binnen een familie geen twee personen zijn die dezelfde naam hebben. Voor een gegeven familie wordt een trekking voorgesteld als een dictionary die de namen van alle familieleden één-op-één afbeeldt op de namen van alle familieleden. De naam van elk familielid komt dus juist één keer als sleutel en juist één keer als waarde voor in de dictionary. Deze afbeelding stelt dus voor wie (sleutel in dictionary) een geschenk moet uitdelen aan wie (waarde die correspondeert met sleutel).

Voorbeeld

>>> familie = ({'Alice', 'Bob', 'Cindy'}, {'Dora', 'Eric', 'Felix'})

>>> trekking = {
...   'Alice': 'Bob', 
...   'Cindy': 'Dora', 
...   'Dora': 'Alice', 
...   'Eric': 'Eric', 
...   'Bob': 'Felix', 
...   'Felix': 'Cindy'
... }
>>> isGeldigeTrekking(trekking, familie)
False

>>> trekking = {
...   'Alice': 'Dora', 
...   'Cindy': 'Felix', 
...   'Dora': 'Eric', 
...   'Eric': 'Cindy', 
...   'Bob': 'Alice', 
...   'Felix': 'Bob'
... }
>>> isGeldigeTrekking(trekking, familie)
True
>>> isGeldigeTrekking(trekking, familie, zelfdeGezin=True)
False

>>> trekking = {
...   'Alice': 'Dora', 
...   'Cindy': 'Eric', 
...   'Dora': 'Alice', 
...   'Eric': 'Bob', 
...   'Bob': 'Felix', 
...   'Felix': 'Cindy'
... }
>>> isGeldigeTrekking(trekking, familie)
True
>>> isGeldigeTrekking(trekking, familie, zelfdeGezin=True)
True

>>> maakTrekking(familie)
{
	'Alice': 'Cindy', 
	'Cindy': 'Alice', 
	'Dora': 'Bob', 
	'Eric': 'Dora', 
	'Bob': 'Felix', 
	'Felix': 'Eric'
}

>>> maakGeldigeTrekking(familie)
{
	'Alice': 'Cindy', 
	'Cindy': 'Bob', 
	'Dora': 'Alice', 
	'Eric': 'Felix', 
	'Bob': 'Eric', 
	'Felix': 'Dora'
}
>>> maakGeldigeTrekking(familie, zelfdeGezin=True)
{
	'Alice': 'Felix', 
	'Cindy': 'Eric', 
	'Dora': 'Bob', 
	'Eric': 'Alice', 
	'Bob': 'Dora', 
	'Felix': 'Cindy'
}