Fuzbalska lestvica

 

Na evropskem in svetovnem prvenstvu v nogometu so reprezentance razvrščene v skupine po 4 in odigrajo med seboj vsaka z vsemi, torej vsaka 3 tekme, skupaj 6 tekem. Za zmago dobi ekipa 3 točke, za neodločen rezultat eno, ob porazu pa ostane brez točk. Ekipi, ki v skupini zbereta največ točk, se uvrstita v nadaljnje tekmovanje, preostali pa odpotujeta domov.

Vprašajmo se, kakšni so možni točkovni izidi po koncu tekem v skupini. Na misel nam pride, da je eden od možnih izdov osvojenih točk   npr. 9,6,3,0, kar pomeni, da ni bilo nobenega neodločenega rezultata, temveč same zmage,  in da je prva ekipa premagala ostale tri, druga izgubila s prvo, premagala pa ostali, tretje je izgubila z ekipama pred njo, premagala pa zadnjo in nazadnje četrta ekipa je izgubila vse tekme. Pri tem izidu je bilo v skupini razdeljeno maksimalno, 18 točk. Ni pa to edina taka možnost, preostali sta še npr. 9,3,3,3 ali 6,6,6,0.

Drug skrajni primer so sami remiji, torej 3,3,3,3. V tem primeru je bilo v skupini podeljeno minimalno, torej 12 točk.

Zanima nas, koliko je vseh možnih izidov osvojenih točk v skupini po koncu teh tekem. V skupini so 4 ekipe in vsaka igra z vsako, torej je skupaj C_4^2={4 \choose 2}=6 tekem. Ker so na vsaki tekmi tri možnosti izida, je po osnovnem izreku kombinatorike N=^{\left(p\right)}\hspace{-1.8mm} V_6^3=3^6=729 vseh možnosti. A število različnih izidov je dosti manjše, saj moramo odšteti njihove permutacije (npr 0,9,6,3 da isti izid kot 9,6,3,0). Imamo kar zapleten kombinatoričen problem. Namesto da bi ga rešili matematično, raje napišimo program, ki bo simuliral število točk po vseh možnih izidih teh tekem. Najprej sestavimo niz vseh izidov, nato pa izide v njem sortiramo in različne prepišemo v novi niz. V Pythonu gre to skoraj tako kot v slovenščini.

Koda programa zgleda takole:

#Program ugotovi vse različne možnosti osvojitve točk 
#v skupini 4 moštev.
#Medsebojnih tekem je 6, zmagovalec, dobi 3 točke, poraženec 0,
# v primeru
#neodločenega rezultata pa si moštvi razdelita 2 točki.
# V Petruna, junij 2014
x=3
y=0
z=1
izidi=[]
izid2=[]
for i in range(3):    
    for ii in range(3):
        for iii in range(3):
            for i4 in range(3):
                for i5 in range(3):
                    for i6 in range(3):
                        a=0
                        b=0
                        c=0
                        d=0
#simulacija izida na posamezni tekmi
                        if i==0:a=a+x;b=b+y
                        else:
                            if i==1:a=1;b=1
                            else:a=a+y;b=b+x

                        if ii==0:a=a+x;c=c+y
                        else:
                            if ii==1:a=a+1;c=c+1
                            else:a=a+y;c=c+x

                        if iii==0:a=a+x;d=d+y
                        else:
                            if iii==1:a=a+1;d=d+1
                            else:a=a+y;d=d+x   

                        if i4==0:b=b+x;c=c+y
                        else:
                            if i4==1:b=b+1;c=c+1
                            else:b=b+y;c=c+x

                        if i5==0:b=b+x;d=d+y
                        else:
                            if i5==1:b=b+1;d=d+1
                            else:b=b+y;d=d+x    

                        if i6==0:c=c+x;d=d+0
                        else:
                            if i==1:c=c+1;d=d+1
                            else:c=c+0;d=d+x

                        izi=[a,b,c,d]
                        izid=sorted(izi,reverse=True)                    
#tvorimo niz vseh izidov
                        izidi.append(izid)
#izločanje podvojenih
for i in range (len(izidi)):       
    if (izidi[i] not in izid2):
        izid2.append(izidi[i])       
izidis=sorted(izid2,reverse=True)
#računanje vsote točk v skupini
for i in range(len(izid2)):
    vsota=izidis[i][0]+izidis[i][1]+izidis[i][2]+izidis[i][3]
    izidis[i].insert(0,vsota)
#izpis števila vseh različnih možnosti
print "VSEH RAZLIČNIH MOŽNOSTI = ",len(izidis)
izidiss=sorted(izidis,reverse=True)
#izpis vseh različnih možnosti, urejenih po številu doseženih točk v skupini
for i in range(len(izidiss)):
    for j in range(5):
        print izidiss[i][j],"  ",
    print

Rezultat, ki ga dobimo, je naslednji:

18    9    6    3    0   
18    9    3    3    3   
18    6    6    6    0   
18    6    6    3    3   
17    9    6    1    1   
17    9    4    4    0   
17    9    4    3    1   
17    7    7    3    0   
17    7    6    4    0   
17    7    6    3    1   
17    7    4    3    3   
17    6    6    4    1   
17    6    4    4    3   
16    9    4    2    1   
16    7    7    1    1   
16    7    6    2    1   
16    7    5    4    0   
16    7    5    3    1   
16    7    4    4    1   
16    7    4    3    2   
16    6    5    4    1   
16    6    4    4    2   
16    5    4    4    3   
16    4    4    4    4   
15    9    2    2    2   
15    7    5    2    1   
15    7    4    3    1   
15    7    4    2    2   
15    6    5    2    2   
15    5    5    5    0   
15    5    5    4    1   
15    5    5    3    2   
15    5    4    4    2   
15    4    4    4    3   
14    7    3    2    2   
14    5    5    3    1   
14    5    5    2    2   
14    5    4    3    2   
13    5    3    3    2   
12    3    3    3    3

Opazimo torej, da je vseh možnih različnih izidov 40.

Zgornja tabela možnih točkovnih izidov po koncu tekmovanja v skupini pokaže nekaj zanimivosti. Možno je npr. napredovati samo z dvema remijema, ali zapustiti tekmovanje kljub dvem zmagam.  V prvem primeru ima drugovrščena ekipa samo 2 točki, v drugem pa tretjeuvrščena 6 točk (poišči v tabeli ta primera).  Tudi v zadnjem primeru, ko so tekmeci izenačeni, dva nadaljujeta, dva pa končata stekmovanjem.

Vidi se torej, da je kljub točkovanju zelo pomembna tudi sreča.

Nostalgija(2)

Zadnjič sem pisal o tem, kako je Logo kakor feniks ponovno vstal iz pepela, tokrat v preobleki Pythonove želvje grafike. Nekaj preprostih ukazov , pa vam program lahko riše lepe krivulje. Grafika pa lahko postane nekaj posebnega, če pri njenem nastajanju uporabite rekurzijo – programerski prijem, s katerim velik problem razdelite na identične, a nekoliko manjše probleme. Seveda se to da narediti samo pri posebnih problemih. Včasih smo občudovali Hilbertove krivulje, krivulje Sierpinskega, hanojske stolpiče, celo permutacije se dajo programirati rekurzivno. A tokrat (pogled skozi okno pove, da še vedno sneži) si oglejmo Kochovo snežinko.

Koda je naslednja:

#Kochova snežinka, V.Petruna feb.2013
from Tkinter import *
import math
import turtle
a=80
def koch(x,stopnja):
    if stopnja<1:
        turtle.forward(x)
    else:
        koch(x/3,stopnja-1)
        turtle.left(60)
        koch(x/3,stopnja-1)
        turtle.right(120)
        koch(x/3,stopnja-1)        
        turtle.left(60)
        koch(x/3,stopnja-1)
turtle.heading()
turtle.penup()
turtle.setpos(-600,0)
turtle.pendown()
for n in range(5):    
    for i in range(3):        
        koch(243,n)
        turtle.right(120)
    turtle.penup()
    turtle.forward(243)
    turtle.pendown()
mainloop()

Dolžina 243 ni izbrana naključno, saj je to 3^5. Tako se izognemo napaki zaradi necelega deljenja. Program nam ustvari naslednjo risbico