Alright, hier zijn m'n kansberekeningen voor de liederen. Ik zet het in een spoiler met daaronder de tl;dr.
Vreemd genoeg lijken m'n eigen berekeningen overeen te komen met m'n Java simulatie tot op het punt waarop de eigenlijke kansen worden uitgerekend, maar vanaf dan niet meer. Het aantal mogelijke combinaties voor een gegeven aantal wolven, gedeeld door het aantal mogelijke combinaties in totaal, lijkt niet de feitelijke kans te zijn.
- Spoiler:
Om te beginnen, tijdens nacht 2 waren er nog 10 spelers (dit was de nacht nadat Sylvysprit eruit werd gestemd), evenals tijdens nacht 3 (de nacht na de gelijkstand in stemmen). Dit maakt de berekeningen wat gemakkelijker. We kunnen geloof ik wel aannemen dat het spel begon met minder dan 5 daders. 4 of 3 daders als begingetal lijkt me het meest waarschijnlijk. Aangezien Sylvysprit een dader bleek te zijn, ga ik m'n berekeningen doen voor 3 of 2 resterende daders.
Lied 1 (nacht 2)
10 spelers
6 namen in het lied
Het aantal combinaties van 6 uit 10 is 10!/((10-6)!*6!)
= 210
Als we het aantal daders d noemen, dan is het aantal combinaties ZONDER dader het aantal combinaties van 6 uit 10-d, ofwel
(10-d)!/((10-d-6)!*6!)
Voor d = 3 geeft dit 7
Voor d = 2 geeft dit 28
Aangezien er minstens 1 dader in het lied moet zitten, is het aantal mogelijke combinaties in het lied dus 210 - 7 voor d = 3 en 210 - 28 voor d = 2.
Case d = 3
Aantal mogelijke combinaties = 203
Wat is het aantal mogelijke combinaties met precies 1 dader in het lied? Dat is het aantal combinaties van 5 spelers uit 7, vermenigvuldigd met het aantal mogelijke keuzes voor dader (=3). De reden hiervoor is dat we naast de dader nog 5 spelers in het lied zouden moeten hebben, en als dat allemaal geen daders zijn hebben we keuze uit 10 - d ofwel 7 spelers. Voor de ene dader zijn er 3 mogelijke keuzes.
Dus dat wordt
(7!/((7-5)!*5!))*3
= 21*3
= 63
Voor precies 2 daders in het lied moeten we het aantal combinaties van 4 spelers uit 7 vermenigvuldigen met het aantal manieren om 2 daders uit 3 te kiezen (=3)
Dat geeft
(7!/((7-4)!*4!))*3
= 35*3
= 105
Het aantal manieren om alle drie de daders in het lied te hebben is de combinatie van 3 spelers uit 7.
7!/((7-3)!*3!)
= 35
Ik zou denken dat als we deze aantallen delen door de 203 mogelijke combinaties krijgen we de kans op elk aantal. Alleen lijkt dat niet zo te zijn. Ik denk dat ik iets over het hoofd zie inzake hoe bovenstaande getallen tot de eigenlijke kans leiden.
Case d = 2
Aantal mogelijke combinaties = 182
Aantal mogelijke combinaties met 1 dader in het lied = aantal mogelijke keuzes van 5 spelers uit 8 onschuldigen vermenigvuldigd met 2 (aantal keuzes voor dader).
(8!/((8-5)!*5!))*2
= 56*2
= 112
Aantal mogelijke combinaties met 2 daders in het lied = aantal mogelijke keuzes van 4 spelers uit 8 onschuldigen.
8!/((8-4)!*4!)
= 70
Lied 2
10 spelers
5 namen in het lied
Het aantal combinaties van 5 uit 10 is 10!/((10-5)!*5!)
= 252
Het aantal combinaties ZONDER dader is het aantal combinaties van 5 uit 10-d, ofwel
(10-d)!/((10-d-5)!*5!)
Voor d = 3 geeft dit 21
Voor d = 2 geeft dit 56
Aangezien er minstens 1 dader in het lied moet zitten, is het aantal mogelijke combinaties in het lied dus 252 - 21 voor d = 3 en 252 - 56 voor d = 2.
Case d = 3
Aantal mogelijke combinaties = 231
Het aantal mogelijke combinaties met 1 dader in het lied is het aantal combinaties van 4 spelers uit 7, vermenigvuldigd met het aantal mogelijke keuzes voor dader (=3).
(7!/((7-4)!*4!))*3
= 35*3
= 105
Voor precies 2 daders in het lied moeten we het aantal combinaties van 3 spelers uit 7 vermenigvuldigen met het aantal manieren om 2 daders uit 3 te kiezen (=3).
(7!/((7-3)!*3!))*3
= 35*3
= 105
Het aantal manieren om alle drie de daders in het lied te hebben is de combinatie van 2 spelers uit 7.
7!/((7-2)!*2!)
= 21
Case d = 2
Aantal mogelijke combinaties = 196
Aantal mogelijke combinaties met 1 dader in het lied = aantal mogelijke keuzes van 4 spelers uit 8 onschuldigen vermenigvuldigd met 2 (aantal keuzes voor dader).
(8!/((8-4)!*4!))*2
= 70*2
= 140
Aantal mogelijke combinaties met 2 daders in het lied = aantal mogelijke keuzes van 3 spelers uit 8 onschuldigen.
8!/((8-3)!*3!)
= 56
TD;DR + conclusies volgen nu.
Indien we uitgaan van 3 resterende daders in nachten 2 en 3 zijn de kansen als volgt, zoals uit simulaties blijkt:
Kans op 1 dader in lied 1 ~ 17%
Kans op 2 daders lied 1 ~ 56%
Kans op 3 daders in lied 1 ~ 27%
Kans op 1 dader in lied 2 ~ 28%
Kans op 2 daders lied 2 ~ 56%
Kans op 3 daders in lied 2 ~ 16%
Indien we uitgaan van 2 resterende daders in nachten 2 en 3 zijn de kansen als volgt:
Kans op 1 dader in lied 1 ~ 44%
Kans op 2 daders in lied 1 ~ 56%
Kans op 1 dader in lied 2 ~ 56%
Kans op 2 daders in lied 2 ~ 44%
Wat is nu de kans dat dezelfde 2 daders in beide liederen voorkomen?
De volgende kansen moeten daarvoor worden opgeteld voor d = 3:
1) De kans dat er 3 daders zaten in lied 1 vermenigvuldigd met de kans dat er 2 daders zaten in lied 2.
2) De kans dat er 2 daders zaten in lied 1 vermenigvuldigd met de kans dat er 3 daders zaten in lied 2.
3) De kans dat er 2 daders zaten in lied 1 vermenigvuldigd met de kans dat er 2 daders zaten in lied 2, gedeeld door 3 (omdat het dezelfde moeten zijn).
Dus voor d = 3 krijgen we:
0,27*0,56 + 0,56*0,16 + 0,56*0.56/3
= 0,3453
~ 34,5%
Voor d = 2 is het eenvoudiger:
0,56*0,44
= 0,2464
~ 24,5%
Zoals je kan zien zijn in beide gevallen de kansen minder groot dan je zou denken. Natuurlijk zijn er hier bepaalde aannames die mogelijk verkeerd zijn. Zo is dit berekend op basis van het idee dat de dader die zeker in een lied moet zitten willekeurig is uitgekozen (dus niet noodzakelijk hetzelfde in beide liederen) en dat de resterende spelers willekeurig zijn uitgekozen, ongeacht of daar daders tussen zitten of niet.
Waar het op neer komt is dat de kans dat twee dezelfde daders in de twee liederen zouden voorkomen minder groot is dan dat dit niet het geval is. Dat ik en Remilia~ dus allebei twee keer voorkomen is GEEN goede reden om ervan uit te gaan dat we beiden dader zouden zijn.
Uitrekenen wat de kans is dat Remilia~ geen dader is, gegeven dat ik dat niet zou zijn, is een pak complexer en helaas heb ik daar nu de tijd niet meer voor. M'n stem blijft nu op
Remilia~ staan. Ik kan 's avonds misschien nog effe op m'n phone checken wat de stand van zaken is, mocht er iets drastisch gebeuren, maar ik kan het niet verzekeren.
Hierbij nog het Java programma waarmee ik bovenstaande heb gesimuleerd en laten berekenen:
- Spoiler:
- Code:
package wolvengriffier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.TreeSet;
public class WolvenGriffier {
public static void main(String[] args) {
final Random rand = new Random();
final int playerCount = 10;
final int wolfCount = 3;
final Set<Player> players;
final Set<Player> wolves;
{
final Set<Player> tempPlayers = new HashSet<Player>();
final Set<Player> tempWolves = new HashSet<Player>();
for(int i = 1; i <= playerCount; ++i) {
boolean isWolf = i <= wolfCount;
final Player player = new Player(isWolf, (char)((int)'A' + i));
tempPlayers.add(player);
if(isWolf)
tempWolves.add(player);
}
players = Collections.unmodifiableSet(tempPlayers);
wolves = Collections.unmodifiableSet(tempWolves);
assert players.containsAll(wolves);
}
final int simulations = 1000000;
int success = 0;
int[] wolvesSong1 = new int[wolfCount+1];
Arrays.fill(wolvesSong1, 0);
int[] wolvesSong2 = new int[wolfCount+1];
Arrays.fill(wolvesSong2, 0);
final Set<String> fingerPrints1 = new HashSet<String>();
final Set<String> fingerPrints2 = new HashSet<String>();
Set[] citizenPrintCombinations1 = new HashSet[wolfCount+1];
Set[] citizenPrintCombinations2 = new HashSet[wolfCount+1];
Set[] fingerPrintCombinations1 = new HashSet[wolfCount+1];
Set[] fingerPrintCombinations2 = new HashSet[wolfCount+1];
for(int i = 0; i < wolfCount + 1; ++i) {
citizenPrintCombinations1[i] = new HashSet<String>();
citizenPrintCombinations2[i] = new HashSet<String>();
fingerPrintCombinations1[i] = new HashSet<String>();
fingerPrintCombinations2[i] = new HashSet<String>();
}
for(int i = 0; i < simulations; ++i) {
//Song 1
final Set<Player> chosenPlayers1;
final Set<Player> chosenWolves1;
{
final Set<Player> chosenPlayers = new HashSet<Player>();
final Set<Player> chosenWolves = new HashSet<Player>();
//Randomly choosing a wolf
final List<Player> wolfList = new ArrayList<Player>(wolves);
final Player chosenWolf = wolfList.get(rand.nextInt(wolfCount));
chosenPlayers.add(chosenWolf);
chosenWolves.add(chosenWolf);
//Making a set of players without the chosen wolf
final Set<Player> playerSet = new HashSet<Player>(players);
playerSet.remove(chosenWolf);
assert playerSet.size() == playerCount - 1;
//Making a list of the remaining players and shuffling it
final List<Player> playerList = new ArrayList<Player>(playerSet);
Collections.shuffle(playerList);
//Getting the remaining chosen ones
for(int j = 0; j < 5; ++j) {
final Player player = playerList.remove(0);
chosenPlayers.add(player);
if(player.isWolf())
chosenWolves.add(player);
}
chosenPlayers1 = Collections.unmodifiableSet(chosenPlayers);
chosenWolves1 = Collections.unmodifiableSet(chosenWolves);
}
//Song 2
final Set<Player> chosenPlayers2;
final Set<Player> chosenWolves2;
{
final Set<Player> chosenPlayers = new HashSet<Player>();
final Set<Player> chosenWolves = new HashSet<Player>();
//Randomly choosing a wolf
final List<Player> wolfList = new ArrayList<Player>(wolves);
final Player chosenWolf = wolfList.get(rand.nextInt(wolfCount));
chosenPlayers.add(chosenWolf);
chosenWolves.add(chosenWolf);
//Making a set of players without the chosen wolf
final Set<Player> playerSet = new HashSet<Player>(players);
playerSet.remove(chosenWolf);
assert playerSet.size() == playerCount - 1;
//Making a list of the remaining players and shuffling it
final List<Player> playerList = new ArrayList<Player>(playerSet);
Collections.shuffle(playerList);
//Getting the remaining chosen ones
for(int j = 0; j < 4; ++j) {
final Player player = playerList.remove(0);
chosenPlayers.add(player);
if(player.isWolf())
chosenWolves.add(player);
}
chosenPlayers2 = Collections.unmodifiableSet(chosenPlayers);
chosenWolves2 = Collections.unmodifiableSet(chosenWolves);
}
wolvesSong1[chosenWolves1.size()]++;
wolvesSong2[chosenWolves2.size()]++;
boolean hit = true;
hit &= chosenWolves1.size() > 1;
hit &= chosenWolves2.size() > 1;
hit &= !(chosenWolves1.size() > 2 && chosenWolves2.size() > 2);
hit &= chosenWolves1.containsAll(chosenWolves2) || chosenWolves2.containsAll(chosenWolves1);
if(hit)
success++;
final String fingerPrint1 = getFingerPrint(chosenPlayers1);
fingerPrints1.add(fingerPrint1);
fingerPrintCombinations1[chosenWolves1.size()].add(fingerPrint1);
final String fingerPrint2 = getFingerPrint(chosenPlayers2);
fingerPrints2.add(fingerPrint2);
fingerPrintCombinations2[chosenWolves2.size()].add(fingerPrint2);
final Set<Player> citizens1 = new HashSet<Player>(chosenPlayers1);
final Set<Player> citizens2 = new HashSet<Player>(chosenPlayers2);
citizens1.removeAll(chosenWolves1);
citizens2.removeAll(chosenWolves2);
final String citizenprint1 = getFingerPrint(citizens1);
final String citizenprint2 = getFingerPrint(citizens2);
citizenPrintCombinations1[chosenWolves1.size()].add(citizenprint1);
citizenPrintCombinations2[chosenWolves2.size()].add(citizenprint2);
}
double sum1 = 0;
double sum2 = 0;
System.out.println("Song 1 statistics");
System.out.println("-----------------");
for(int i = 0; i < wolvesSong1.length; ++i) {
sum1 += (double)wolvesSong1[i]/(double)simulations;
System.out.println("" + i + " wolves: " + wolvesSong1[i] + "; probability " + (double)wolvesSong1[i]/(double)simulations);
System.out.println("" + i + " wolves: " + fingerPrintCombinations1[i].size() + " combinations of players found");
System.out.println("" + i + " wolves: " + citizenPrintCombinations1[i].size() + " combinations of citizens found");
}
System.out.println("");
System.out.println("Song 2 statistics");
System.out.println("-----------------");
for(int i = 0; i < wolvesSong2.length; ++i) {
sum2 += (double)wolvesSong2[i]/(double)simulations;
System.out.println("" + i + " wolves: " + wolvesSong2[i] + "; probability " + (double)wolvesSong2[i]/(double)simulations);
System.out.println("" + i + " wolves: " + fingerPrintCombinations2[i].size() + " combinations of players found");
System.out.println("" + i + " wolves: " + citizenPrintCombinations2[i].size() + " combinations of citizens found");
}
System.out.println("");
System.out.println("Number of unique combinations for song 1: " + fingerPrints1.size());
System.out.println("Number of unique combinations for song 2: " + fingerPrints2.size());
System.out.println("");
System.out.println(sum1);
System.out.println(sum2);
System.out.println("");
System.out.println("Number of times same two wolves appeared twice: " + success + "; probability " + (double)success/(double)simulations);
}
private static class Player implements Comparable<Player> {
final boolean isWolf;
final char identifier;
Player(boolean isWolf, char identifier) {
this.isWolf = isWolf;
this.identifier = identifier;
}
public boolean isWolf() {
return isWolf;
}
public char getIdentifier() {
return identifier;
}
@Override
public int compareTo(Player o) {
return o.identifier - identifier;
}
}
private static String getFingerPrint(final Set<Player> players) {
StringBuilder fingerPrint = new StringBuilder();
final TreeSet<Player> ordered = new TreeSet<Player>(players);
for(Player p : ordered) {
fingerPrint.append(p.getIdentifier());
}
return fingerPrint.toString();
}
}