Ken je de Amerikaanse acteur Kevin Bacon1?
Hij is de spreekwoordelijke spin in het web van het spelletje six degrees of Kevin Bacon dat gespeeld wordt met twee of meer spelers. De eerste speler noemt een willekeurige acteur. Daarna noemen de spelers om beurten een acteur die nog niet genoemd werd en die in een film meespeelt samen met de laatste genoemde acteur. Het gezamenlijke doel van alle spelers is om zo snel mogelijk de naam van Kevin Bacon te noemen.
Dit spelletje gaat ervan uit dat alle acteurs die betrokken zijn bij de Hollywood-filmindustrie binnen zes stappen met Kevin Bacon kunnen verbonden worden via hun filmrollen. De naam van het spel is een verwijzing naar de six degrees of separation2 (letterlijk: zes graden van verwijdering): een hypothese die stelt dat elke levende persoon op aarde maximaal zes stappen van elke andere persoon verwijderd is via het netwerk van persoonlijke kennissen: om van de ene persoon naar de andere persoon te komen, zijn er nooit meer dan vijf tussenpersonen nodig. Er is heel wat onderzoek gebeurd om deze hypothese empirisch en theoretisch te onderbouwen.
Het Bacongetal van een acteur is het kleinste aantal stappen dat die de acteur van Kevin Bacon verwijderd is volgens de regels van het spelletje:
Kevin Bacon heeft zelf Bacongetal 0
alle medespelers van Kevin Bacon hebben Bacongetal 1
als het kleinste Bacongetal van alle medespelers van acteur $$\mathcal{X}$$ gelijk is aan $$n$$, dan is het Bacongetal van acteur $$\mathcal{X}$$ gelijk aan $$n+1$$
Hoe hoger het Bacongetal, hoe meer tussenstappen je nodig hebt om in het spelletje tot Kevin Bacon te komen.
Twee acteurs zijn medespelers als ze in minstens één film samen meespelen. De afstand tussen twee acteurs is het kleinste aantal medespeler-stappen tussen beide acteurs. Bijgevolg is de afstand tussen twee medespelers gelijk aan 1 en is het Bacongetal van een acteur de afstand tussen die acteur en Kevin Bacon.
We gebruiken een tekstbestand met de rolverdeling van een aantal films om te bepalen of twee acteurs medespelers zijn en om hun onderlinge afstand te bepalen. Elke regel van zo'n bestand bevat de naam van een film, gevolgd door een verticale streep (|) en de naam van een acteur die in die film meespeelt. Dit voorbeeld bevat de rolverdeling van zeven acteurs die in zes verschillende films meespelen (cast.txt3):
Sleepless in Seattle (1993)|Meg Ryan In the Cut (2003)|Kevin Bacon In the Cut (2003)|Meg Ryan Clockwatchers (1997)|Lisa Kudrow Six of a Kind (1934)|W.C. Fields Apollo 13 (1995)|Tom Hanks You've Got Mail (1998)|Parker Posey Six of a Kind (1934)|George Burns Apollo 13 (1995)|Kevin Bacon You've Got Mail (1998)|Meg Ryan Sleepless in Seattle (1993)|Tom Hanks Clockwatchers (1997)|Parker Posey You've Got Mail (1998)|Tom Hanks
Alle medespelers onder deze zeven acteurs (zwart) zijn met blauwe lijnen met elkaar verbonden in onderstaande figuur, met de naam van de film waarin de acteurs samen meespelen als label bij de lijn (ook in het blauw). De gele ringen — die van binnen naar buiten genummerd worden vanaf 0 — geven aan hoe de afstand tussen twee acteurs $$a_1$$ en $$a_2$$ kan bepaald worden, met Kevin Bacon ($$a_2$$) als voorbeeld. Ring $$n$$ bevat alle acteurs met afstand $$n$$ tot acteur $$a_2$$ ($$n = 0, 1, 2, \ldots$$).
We beginnen bij ring 0 die enkel acteur $$a_2$$ (Kevin Bacon) bevat. Daarna bepalen we van binnen naar buiten de acteurs in de opeenvolgende ringen: ring $$n + 1$$ bevat alle medespelers van de acteurs in ring $$n$$ die zelf niet voorkomen in ringen $$0, 1, 2, \ldots, n$$ ($$n = 0, 1, 2, \ldots$$). We blijven dit herhalen tot we een ring bekomen die acteur $$a_1$$ bevat of tot we een ring bekomen waarin geen acteurs meer zitten. In het eerste geval is het nummer van de ring die acteur $$a_1$$ bevat de gezochte afstand tussen acteurs $$a_1$$ en $$a_2$$. Uit de figuur leiden we bijvoorbeeld af dat de afstand tussen de Amerikaanse actrice Lisa Kudrow4 ($$a_1$$) en Kevin Bacon gelijk is aan 3 (haar Bacongetal). In het tweede geval kunnen de twee acteurs niet met elkaar verbonden worden. Voor de rolverdeling in het gegeven bestand is dit bijvoorbeeld het geval voor George Burns ($$a_1$$) en Kevin Bacon ($$a_2$$), zoals we ook uit de figuur kunnen aflezen.
Definieer een klasse Rollen waarmee kan bepaald worden of acteurs medespelers zijn en wat hun onderlinge afstand is op basis van de rolverdeling in een gegeven bestand. Bij het aanmaken van een rolverdeling (Rollen) moet de locatie (str) van het tekstbestand met rolverdelingen doorgegeven worden. Een rolverdeling $$r$$ (Rollen) moet minstens de volgende methoden ondersteunen:
Een methode films waaraan de naam (str) van een acteur moet doorgegeven worden. De methode moet een verzameling (set) teruggeven met de namen (str) van alle films waarin de acteur meespeelt volgens rolverdeling $$r$$.
Een methode acteurs waaraan de naam (str) van een film moet doorgegeven worden. De methode moet een verzameling (set) teruggeven met de namen (str) van alle acteurs die in de film meespelen volgens rolverdeling $$r$$.
Een methode zijn_medespelers waaraan de namen (str) van twee acteurs $$a_1$$ en $$a_2$$ moeten doorgegeven worden. De methode moet een Booleaanse waarde (bool) teruggeven die aangeeft of $$a_1$$ en $$a_2$$ medespelers zijn volgens rolverdeling $$r$$.
Een methode medespelers waaraan een collectie $$\mathcal{C}$$ (list, tuple of set) met namen (str) van acteurs moet doorgegeven worden. De methode moet een verzameling (set) teruggeven met de namen (str) van alle acteurs die volgens rolverdeling $$r$$ meespelen in minstens één film waarin ook een acteur van collectie $$\mathcal{C}$$ meespeelt. De acteurs uit collectie $$\mathcal{C}$$ zitten dus zelf ook in de verzameling die wordt teruggegeven, tenzij ze in geen enkele film uit rolverdeling $$r$$ meespelen.
Een methode afstand waaraan de naam (str) van een acteur $$a_1$$ moet doorgegeven worden. De functie heeft ook nog een tweede optionele parameter waarde de naam (str) van een tweede acteur $$a_2$$ kan doorgegeven worden (standaardwaarde: Kevin Bacon). Als acteurs $$a_1$$ en $$a_2$$ volgens rolverdeling $$r$$ niet met elkaar kunnen verbonden worden, dan moet de waarde -1 (int) teruggegeven worden. Anders moet de afstand (int) tussen beide acteurs volgens rolverdeling $$r$$ teruggegeven worden.
De tekstbestanden uit deze opgave gebruiken de UTF-8 tekencodering. Dit is ondertussen de standaard tekencodering op de meeste computers (ook op die van Dodona). Als je toch problemen zou ondervinden bij het inlezen van bestanden, dan kan je de tekstcodering ook expliciet meegeven bij het openen van de bestanden: encoding='utf-8'.
In onderstaande voorbeeldsessie gaan we ervan uit dat het tekstbestand cast.txt5 zich in de huidige directory bevindt.
>>> rollen = Rollen('cast.txt6')
>>> rollen.films('Kevin Bacon')
{'Apollo 13 (1995)', 'In the Cut (2003)'}
>>> rollen.acteurs('Apollo 13 (1995)')
{'Kevin Bacon', 'Tom Hanks'}
>>> rollen.zijn_medespelers('Kevin Bacon', 'Tom Hanks')
True
>>> rollen.zijn_medespelers('Kevin Bacon', 'Parker Posey')
False
>>> rollen.medespelers(['Kevin Bacon'])
{'Kevin Bacon', 'Tom Hanks', 'Meg Ryan'}
>>> rollen.medespelers(('Parker Posey', 'George Burns'))
{'George Burns', 'W.C. Fields', 'Tom Hanks', 'Lisa Kudrow', 'Parker Posey', 'Meg Ryan'}
>>> rollen.afstand('Kevin Bacon')
0
>>> rollen.afstand('Tom Hanks')
1
>>> rollen.afstand('Meg Ryan')
1
>>> rollen.afstand('Parker Posey')
2
>>> rollen.afstand('Lisa Kudrow')
3
>>> rollen.afstand('James Purefoy')
-1
>>> rollen.afstand('George Burns')
-1
>>> rollen.afstand('W.C. Fields')
-1
>>> rollen.afstand('George Burns', 'W.C. Fields')
1
Maarten Baes7 — professor in de sterrenkunde aan de Universiteit Gent — heeft een Bacongetal van 5.
Baes speelt de mannelijke hoofdrol als de Belgische sterrenkundige "Koen" in de film Above Us All8 (2014), waarin ook actrice Pearl Davern9 meespeelt. Davern speelt dan weer een kleinere rol in de film Resistance10 (1992) met Lorna Lesley11 in de hoofdrol, die ook de hoofdrol vertolkt in de film Just Out of Reach12 (1979) naast acteur Sam Neill13. Neill is op zijn beurt als "Théo" te zien in de film Angel14 (2007) waarin Michael Fassbender15 in de rol van "Esmé" kruipt. Fassbender heeft zelf Bacongetal 1, mede door zijn rol van "Erik Lensherr" in X-Men: First Class16 (2011) waarin Kevin Bacon17 de rol van "Sebastian Shaw" vertolkt.