Govorice
Naloga
V nalogi bomo delali s slovarji, v katerih je zabeleženo, kdo hodi v kateri krožek. Če, recimo, Ana hodi na dramsko skupino in matematični krožek, Berta na dramsko skupino in elementarno geometrijo, Cilka pa na matematični krožek, plezanje in pevski zbor, bo to zapisano takole:
Ključi slovarja so torej imena učencev, vrednosti pa so množice imen krožkov.
(V testih je bo nekoliko poenostavljeno; testi so narejeni tako, da hodi,
recimo, A na krožke a, b, c in B na krožke a, b, d. Ker se vašemu učitelju ne
tipka več, kot je potrebno, tega ne zapiše z
{"A": {"a", "b", "c"}, "B": {"a", "b", "d"}}, temveč kot
{"A": set("abc"), "B": set("abd")}. Povem, da boste znali brati
teste in razumeli, v kakšnem primeru vaš program ne deluje. Če bi prišlo do
česa takšnega, seveda.)
Ogrevanje: Znanci
Napišite funkcijo znanci(krozki), ki vrne množico vseh parov
učencev, ki se srečujejo na kakem krožku. V gornjem primeru mora
{("Ana", "Berta"), ("Berta", "Ana"), ("Ana", "Cilka"), ("Cilka", "Ana")}.
Ana in Berta se namreč srečujeta v dramski skupini, Ana in Cilka pa na
matematičnem krožku.
Obvezna naloga: Govorica
Po šoli krožijo govorice. Ker učenci med poukom seveda ne klepetajo
(tega se naučijo šele kasneje, na faksu), na hodnikih pa so itak tiho, se lahko
govorica širi le na krožku). Napišite funkcijo
govorica(pot, krozki), ki dobi pot govorice in seznam krožkov.
Vrniti mora True, če je pot možna in False, če ni.
Pot je podana kot seznam imen. Možna je, če gre le prek parov, ki se
srečujejo. Tako je pot ["Berta", "Ana", "Cilka"] možna, saj
Berta lahko pove Ani in Ana Cilki. Potem ["Berta", "Cilka", "Ana"]
pa ni možna, saj se Berta in Cilka ne srečujeta na nobenem krožku.
Dodatna naloga: najkrajša pot
Napišite funkcijo najkrajsa_pot(oseba1, oseba2, krozki), ki
vrne najkrajšo pot med dvema osebama.
Namig: poženite naslednji program in razmislite, ali si lahko kaj pomagate
s funkcijo permutations.
Disclaimer: najkrajše poti se sicer iščejo drugače in veliko hitrejše. Kako, boste izvedeli v tretjem letniku.
Rešitev
Rešitev ogrevalne in obvezne naloge (predvsem slednje!) je smešno kratka.
Za rešitev prve je potrebno znati napisati zanko znotraj zanke. Gremo prek vseh oseb in njenih krožkov ter za vsako osebo (in njene krožke) prek vseh drugih oseb. Če ne gre za isto osebo in če imata kak skupen krožek (kar preverimo tako, da izračunamo presek krožkov in se prepričamo, da ta ni prazen -- prazne množice so neresnične, neprazne pa resnične), dodamo par v množico.
Da naženemo zanko for prek parov, uporabimo
krozki.items().
V obvezni nalogi se moramo spomniti dveh trikov. Prvi je trik z
zipom. Vzamemo pot in pot[1:], torej
seznam in taisti seznam brez prvega elementa. Če seznama zazipamo skupaj,
dobimo seznam parov -- ničti in prvi element, prvi in drugi, drugi in tretji...
Iz tega seznama parov naredimo množico parov. To je torej množica vseh parov,
prek katerih je šla govorica. Če je ta množica podmnožica množice znancev,
je pot govorice možna.
Rešitev, ki je manj imenitna od zgornje, je takšna:
Za začetek spravimo množico znancev v znanstva - da je ne bomo
kasneje računali za vsak par posebej. Nato gremo prek vseh parov oseb, ki
nastopajo v poti (pridelamo jih enako kot prej). Če kak par ni v množici
znanstva, vrnemo False. Če se zanka izteče, ne da
bi naleteli na kak tak par, vrnemo True.
Še malo manj ugledna rešitev ne uporablja zipa. Takšnih je
bilo največ; njihovi avtorji so si sami krivi, če se jim je zdela naloga
težka (ehm, razen, če v prvem semestru niste spoznali zipa; v tem
primeru se lahko zdaj veselite, da ga poznate ;).
Kmalu bomo znali napisati obe funkciji še krajše. Takšna bo celotna rešitev ogrevalne in obvezne naloge.
Dodatna naloga
Namig je predlagal uporabo funkcije permutations. Kdor si jo je
ogledal, je videl, da vrne vse izbore določenega števila elementov iz podanega
seznama. Nalogo torej lahko rešimo tako, da poskušamo vse poti od dolžine 0
(saj je vseeno...) do števila oseb, zgradimo vsa možna zaporedja in za vsako
preverimo, ali predstavlja veljavno pot. Funkcija vrne prvo pot, ki je veljavna.
Če veljavne poti ni, ne bo vrnila ničesar. Tudi prav.
Algoritmi za iskanje najkrajših poti (recimo tisti v Garminu) seveda ne delujejo tako. Že pri desetih osebah obstaja 10!, to je 3628800 različnih kombinacij. Pri sto osebah (ali krajih) je kombinacij
in pri 1000 krajih (kar niti slučajno ne pokrije Slovenije!) jih je
To je kar veliko. Kako v resnici delujejo programi za iskanje najkrajših poti, boste izvedeli v tretjem letniku.