Kojn
Testi
Naloga
Šahovski konj je žival, ki živi na šahovnici in se premika v obliki črke L. O njegovi pomembnosti priča tudi to, da mu je posvečen poseben članek na Wikipediji. Posvečena mu je tudi ta naloga.
Pri vsaki nalogi, razen pri nalogi za oceno 10, morate obvezno uporabiti funkcijo, ki ste jo napisali pri prejšnji nalogi!
Pri rešitvah smete uporabljati funkciji, ki smo ju napisali na predavanjih:
Za ogrevanje
Napišite funkcijo legalne_koord(x, y)
, ki prejme koordinati polja (x je stolpec, y vrstica) in vrne
True
, če so koordinate pravilne (ob koordinati sta med, vključno, 1 in 8), in False
, če
niso.
Za oceno 6
Napišite funkcijo moznosti(polje)
, ki kot argument dobi polje (v šahovskih koordinatah, npr. "B4")
in kot rezultat vrne seznam polj, na katera lahko s tega polja skoči konj. Polja naj bodo urejena po abecedi. (Namig:
sicer lahko uporabite tudi funkcijo sort
, vendar se ji poskusite izogniti: raje sestavite seznam tako,
da bo urejen.)
Za oceno 7
Napišite funkcijo legalna(polje1, polje2)
, ki za par polj pove, ali konj lahko skoči iz enega
polja na drugo.
Za oceno 8
Napišite funkcijo legalna_pot(pot)
, ki kot argument dobi pot konja (seznam s poljubnim številom
zaporednih polj, po katerih je skakal konj) in vrne True
, če je pot pravilna in False
,
če ni. Predpostaviti smete, da vsebuje seznam vsaj eno polje.
Za oceno 9
Napišite funkcijo obhod(pot)
, ki za podano pot pove, ali vsebuje obhod konja prek vseh polj šahovnice.
Konj se mora gibati pravilno in mora obiskati vsako polje natančno enkrat. Izjema je samo zadnje polje, ki mora biti
enako prvemu.
Več primerov je v testih.
Za oceno 10
Napišite funkcijo razdalje()
, ki vrne število potez, ki ga konj potrebuje, od zgornjega levega
polja do ostalih polj šahovnice. Funkcija mora vrniti takšen niz:
Niz torej predstavlja šahovnico in vsako številka na posameznem polju pove, koliko (najmanj) potez potrebuje konj do posameznega polja.
Niz razbijete v vrstice tako, da na konec vsake vrstice dodate "\n".
Funkcija mora seveda izračuati niz; če ga bo kdo shranil in izpisal, bomo to razumeli kot (blažji) poskus goljufije. Naloge se lahko lotite tako, da najprej premislite, kako bi jo rešili ročno. Vzemite list karirastega papirja, narišite šahovnico in v zgornji levi kvadratek ničlo. Nato v vsa polja, v katera lahko pridete s tega polja, napišete enico. Nato na vsa polja, kjer ste pravkar napisali enico, napišete ...
Ocene 5-9
Rešitve so komajda vredne komentarja. Bistvo naloge ni bilo programiranje zank in pogojev (to naj bi po enem mesecu že nekako znali), temveč spretno klicanje funkcij, ki smo jih že napisali.
Pri nalogi za oceno 5 ste morali znati elegantno zapisati pogoj. Seveda ga je bilo, kot vedno, možno tudi brez potrebe zaplesti.
Rešitev za oceno 6 je bilo mogoče skrajšati z nekaj zvitosti: pripravimo si seznam premikov konja in ga prištejemo k trenutnemu polju, a obdržimo le tiste premike, ki dajo legalno polje. Katero polje je legalno, pa preverimo s funkcijo, ki smo jo napisali za oceno 5.
Daljša različica bi lahko šla takole:
Rešitev za oceno 7 ne bi mogla biti lažja, kot je: skok s polje1
na polje2
je legalen,
če je polje2
na seznamu polj, na katera je mogoče priti s polja polje1
.
Za oceno 8 se je potrebno sprehoditi čez seznam polj in dati funkciji s prejšnje naloge preveriti vsak zaporedni par.
Za nalogo 9 mora biti pot legalna (kar preverimo s funkcijo iz naloge 8), dolga 65 polj, prvo polje mora biti enako zadnjemu, poleg tega pa se nobeno polje ne sme ponoviti - preveriti je potrebno, da se i-to polje ne pojavlja na seznamu prvih i-1 polj.
Za oceno 10
Tole ni najhitrejša, temveč le najbolj razumljiva rešitev. Pokazali bomo tudi precej boljšo.
Najprej sestavimo seznam osmih seznamov, ki vsebujejo po osem številk -1; -1 bo pomenila, da razdalja do tega polja še ni bila izračunana.
Za zgornje levo polje nastavimo, da ga dosežemo v 0 korakih in si zapomnimo, da poznamo razdaljo do enega samega
polja (obiskanih=1
). V naslednjem koraku bomo označili polja, do katerih potrebujemo en skok
(skok=1
). Dokler ne obiščemo vseh 64 polj, ponavljamo naslednje: preletimo vso šahovnico. Če naletimo
na polje, do katerega smo prišli v 0 skokih, zabeležimo, da se do njega pride v enem skoku in povečamo število
obiskanih polj. Ko tako pridemo čez vso šahovnico, gremo čeznjo ponovno: iščemo vsa polja, do katerih smo
prišli v enem skoku in zabeležimo, da do njih pridemo v dveh skokih ... in tako naprej.
Bistveno boljše je tole:
Seznam kandidati
bo vseboval vsa polja, do katerih smo prišli, nismo pa še preiskali poti z njih.
Na začetku označimo, da je pod do A8 (sahovnica[0][0]
) dolga 0 skokov in damo A8 na seznam kandidatov.
Nato ponavljamo zanko, dokler seznam kandidatov ni prazen. S kandidati.pop(0)
poberemo prvega
kandidata in pogledamo, koliko skokov je potrebnih do njega. Preverimo vsa polja, do katerih je možnost skočiti
s "kandidata": če na teh poljih še nismo bili, si zapomnimo, da je pot do njih dolga en skok več kot do
"kandidata" in dodamo to polje med kandidate.
Resne rešitve
Funkcije, ki smo jih napisali tule, so relativno dolge. Če bi šlo zares, bi jih sprogramirali takole.
Pri rešitvi za oceno 10 nam je v nadlego, da funkcija moznosti
dela z nerodnimi
šahovskimi koordinatami. V praksi bi se jim izogibali; tule bomo, da bomo funkcija krajša,
uporabili rešitev s slovarji, ki časovno ni ravno optimalna, je pa lepa.