pathterminuspages/brkmnd.dk/aboutcontactabout me

Terninger og tilfældigheder

12-06-2015

Jeg sad og sumpede lidt over vejret tidligere da jeg så kom i tanke om et terningspil en af mine venner engang lavede til en fest – altså programmerede. OK, det burde være lige til at lave, tænkte jeg, og gik i gang med at undersøge funktioner til at genere tilfældige tal i JS. Der er selvfølgelig sådan en funktion. I JavaScript er der en gruppe objekter der hedder Math, og i den er der funktionen random. Fedt!
Random genererer et tilfældigt tal i mellem 0 og 1, formelt et tal t i mængden: $$T = {t \in \mathbb{R} | 0 \le t \lt 1}$$

Det jeg skulle bruge, var et tilfældigt heltal i intervallet et til seks, altså i mængden: $$N = {n \in N | 1 \le n \le 6}$$

På siden hvor jeg fandt koden, skriver de at man feks. kan generere et tilfældigt tal mellem 1 og 10 ved at gange det tilfældige tal der først genereres, med 10. Derefter er der tre funktioner i Math objektet, en der runder ned til nærmeste heltal, en der runder op til nærmeste heltal, og en der runder ned eller op alt afhængigt af hvad der er nærmest. Eksempelvis returnerer den første 4 ved både tallet 4,3 og 4,9. Den funktion der runder op, returnerer 5 i begge tilfælde, og den sidste funktion returnerer hhv. 4 og 5. Ideen er nu at generere et tal mellem 0 og 0,999... herefter skal det tal så ganges med 10, det bliver altså et tal mellem 0 og 9,999... hvorefter det skal rundes ned til nærmeste heltal som er et heltal i intervallet [0;9] – det skal så plusses med én, og vi har et tilfældigt heltal i intervallet [1;10]. Voila.

Jeg er ikke specielt glad for statistik og tilfældigheder og den slags. Jeg synes på en måde at verden er tilfældig nok uden at man undersøger den. Derfor blev jeg glad da jeg fandt ud af at JS kan klare det at generere tilfældigheder for mig. Mit problem var så bare at tilpasse dem til en terning.

Først tænkte jeg at jeg kunne gøre noget i stil med det eksempel jeg fandt på siden med koden. Jeg kunne gange med seks og derefter runde resultatet ned osv. Problemet er bare at når man runder ned i sekstabellen, får det nogle uheldige konsekvenser. Hvis vi nu tænker os tilbage til folkeskolen og de små tabeller, er det så ikke noget med at sekstabellen går: 6, 12, 18, 24, 30, 36, 42, 48, 54, 60. Jo. Hvis vi feks. runder alle elementerne i sekstabellen ned til nærmeste tier, bliver rækken til: 0, 10, 10, 20, 30, 30, 40, 40, 50, 60. Der er altså to muligheder for at ramme elementerne 10, 30 og 40, hvor der kun er én mulighed for at ramme 0, 20, 50 og 60. Umiddelbart ikke så godt.

Min anden idé, der faktisk var den første, var bare at trække tilfældige tal der var større end 6, fra 10. Derudover brugte jeg algoritmen fra før: jeg gangede med 10, rundede ned, lagde til, og hvis tallet var større en 6, blev det trukket fra 10. Feks. giver 7 så 3 retur, 9 giver 1 osv. Problemet med denne model er bare at der kun er de tre muligheder 7, 8 og 9 at trække fra ti. Det resulterer i mulighederne 3, 2 og 1. Da de tre tal allerede indgår i intervallet [1;6], er der altså to muligheder for at få en af de tre tal hvor der kun er 1 mulighed for at få et af tallene i intervallet [4;6]. No cigar.

Fucking tilfældigheder! Min tredje idé, som så blev den endelige, var og er at dele mængden T der udgør intervallet [0;1[, op i tre. Jeg skal altså bruge en funktion der tillordner værdier til ethvert element t fra T og ind i en ny mængde der består af intervallet [1,6] ∈ ℕ. Funktionen kalder jeg for F(x), og den ser sådan her ud: $$ F(t,y) = \begin{cases} y & 0 \le t \lt 1 / 3 \\ y + 2 & 1 / 3 \le t \lt 2 / 3 \\ y + 4 & 2 / 3 \le t \lt 1 \end{cases} $$

Hvor t er et tilfældigt element i intervallet [0,10[ ∈ ℝ og y er endnu et tilfældigt tal der skal generes i intervallet [1,2] ∈ ℕ. F er altså af to tilfældige variable.

Nu ligner det noget. For at nå enden af dette tilfældige projekt skal der nu bare generes to tilfældige variable t og y. Den første variabel, t, er ligeudad landevejen simpelthen et random tal der ikke skal gøres andet ved end generes. Den anden variabel, y, generes ved at trække et tilfældigt tal [0,1[ ∈ ℝ fra 2 hvorefter resultatet rundes op eller ned til nærmeste. Jeg endte altså med en funktion F og en funktion tilfTal:

function tilfTal() { // Laver to tilfaeldigt tal t og y var t = Math.random(); var y = Math.round(2 - Math.random()); return F(t,y); } function F(t,y) { // Tilordner et tal fra maengden [0,1] i de reelle tal og over i maengden [1,6] i de naturlige tal. if(0 <= t && t < 1/3) { return y; } else if(1/3 <= t && t < 2/3) { return y + 2; } else if(2/3 <= t && t < 1) { return y + 4; } }

Læg specielt mærke til hvor meget kodefunktionen ligner definitionen ovenover. Meget smukt!

Såfremt t og y genereres helt tilfældigt i deres respektivt defineret interval, klarer F resten af arbejdet. Den sender simpelthen bare værdierne over i en seksidet terning.

En detalje I kan tage med på casionet, er det kombinatoriske aspekt af terningkast. Hvis I har set filmen Lucky number Slevin, ved I at der held forbundet med Slevin fordi Slevin rimer på seven. Hvis vi undersøger samtlige kombinationer af udfald af kast med to terninger, får vi 6^2 = 6 ⋅ 6 = 36 forskellige. Dette kaldes en permutation hvilket betyder at en etter og en toer ikke er det samme som en toer og en etter. Når vi ser på terningkast på denne måde, bliver det måske klart at ligemeget hvad vi slår med den første terning, er der altid 1/6 mulighed for at slå syv i alt da vi højst kan slå seks ad gangen. Derimod kan vi ikke slå otte hvis vi slår en etter i første kast. Vi kan heller ikke slå seks (sammenlagt) hvis vi slår en sekser i første huk.
Ud af de 36 forskellige slag vi kan slå, kan vi feks. slå en sekser på følgende måder: 3 + 3, 2 + 4, 1 + 5 plus omvendt rækkefølge. Hvis vi siger der er 1/6 chance for at slå hvert af tallene, er der altså kun 5/6 chance for at slå noget i første slag der kan resultere i seks, hvorimod det er uundgåeligt at slå noget der ikke kan resultere i syv sammenlagt. Da to terninger tit kastet samtidig, er forholdet nok symmetrisk på en eller anden måde. Pointen er i hvert fald at chancen for at slå syv med to terninger må være større end noget andet udfald. Hvis jeg ikke var sådan en travl mand, lavede jeg nok en algoritme til at teste mine terninger for at se om de giver ordentlige udfald. Men det må blive en anden gang.

Indtil da kan I spille lidt tilfældige terninger.