Rešitve s komentarji
Tule so rešene izpitne naloge. Pri vsaki nalogi sem pokazal nekaj možnih rešitev in premislekov (razen pri tistih, ki so za to preenostavne). Pravilne pa so seveda tudi druge rešitve, ki dajo pravi rezultat. Nekatere od napisanih rešitev očitno presegajo pričakovani nivo znanja. Vsaka naloga pa je, kot boste videli, preprosto rešljiva tudi z osnovnim znanjem.
Izpit je bil v resnici lažji, kot se morda zdi. :)
Starost
Tole ni prehuda umetnost - malo spominja na domačo nalogo z mp3, malo spreminjanja nizov v števila...
Strategija bo preprosta. Najprej bomo izračunali katerega dne, meseca in leta je oseba rojena. Najprej se bomo delali, kot da je rojena leta 1xxx, torej bomo k trem števkam letnice prišteli 1000. Če bo vsota manjša od 1800, bomo dodali še 1000, ter tako poskrbeli za one, rojene po letu 2000. Starost bomo dobili tako, da bomo letnico rojstva odšteli od 2009. Za tiste, ki so rojeni januarja in to 26. ali prej, bomo k starosti dodali še 1.
Bomboni
Začnimo z najpreprostejšo rešitvijo. Recimo, da imamo štiri otroke in tisti, ki ima največ, ima osem bombonov. Ko jih bodo imeli vsi enako, jih bodo torej imeli 32. Recimo, da jih imajo sedaj 23. Koliko jim jih moramo še razdeliti? 32 - 23 = 9, ne? :)
Kakor vidim, je edini lenuh, ki je rešil nalogo na ta nacin, Blaž Šolar. (Bravo!) Vsi drugi pa preveč radi programirate (pohvalno!) in ste nalogo rešili nekako takole.
Veliko pa je tudi bolj zapletenih rešitev, ki ne uporabijo funkcije max
.
Podobna beseda
Tipična rešitev, ki ste jo napisali, je videti nekako takole.
To ne deluje prav: težava je v tem, da enake črke štejemo večkrat. Najpreprostejša rešitev tega problema je uporaba množic. Število skupnih crk je kar enako preseku dveh množic; do preseka pridemo z metodo intersection
ali z operatorjem &
.
Gornja rešitev je nekako tisto, kar sem pričakoval. No, upal. (Niso pa napačne drugacne rešitve, če dajo pravilen rezultat.) Rokohitreci pa vedo, da ima funkcija max
argument key
, s katerim lahko nalogo rešijo kar takole.
Pari števil
Najprej poglejmo, kako dobimo vsoto števk števila. En način je, da si pripravimo pomožno funkcijo, ki kot argument dobi število in kot rezultat vrne vsoto števk, takole.
Številko smo pretvorili v niz. Ko gremo z zanko čez niz, dobivamo posamezne števke, te pretvarjamo nazaj v števila in jih seštevamo.
Gre pa tudi hitreje. Vsoto števk števila i
lahko dobimo preprosto s
sum(int(c) for c in str(i))
ali
sum(map(int, str(i))
Preostanek je preprost: dve zanki, ena od 1 do 100, druga pa od števca prve zanke pa do 1000. Da bi spustili obe zanki do 1000, ni nobene potrebe, saj morajo imeti števila različno število mest, torej mora biti vsaj eno število 100 ali manj. (Čemu pa do 100, ne do 99? Da ne spustimo para 100, 1000! :). Za vsak par preverimo, ali imata razlicno število števk (obe števili pretvorimo v niza in primerjamo njuno dolžino) in enako vsoto. Če to drži, ju dodamo v seznam.
V gornjem primeru smo uporabili pomožno funkcijo vsotaStevk
, enako dobro bi bilo tudi brez nje.
Veliko hitrejše pa je, če uporabimo nekaj trikov. Pripravimo si lahko tabelo, v kateri za vsako številko vnaprej izracunamo vsoto njenih števk. Na kakšen način v spodnji rešitvi zoptimiziramo zanke, pa odkrijte sami.
Takšna rešitev je veliko veliko hitrejša od prve, vendar pri hitrosti pridobimo predvsem po zaslugi shranjenih vsot števk, ne trikov z zankami for
.
Da se bo vedelo, da se da, pa je tu še ena rešitev.
Trgovinski računi
Če sem napisal, da je ves izpit lažji, kot se morda komu zdi, je to še posebej res za zadnjo nalogo. Preprosto beremo vrstice datoteke in jih split
amo s tabulatorjem. Ker sem obljubil, da se tabulator pojavlja le v vrsticah s številkami, je seznam, ki ga dobimo s split
dolg en ali dva niza. Če je dolg dva niza, je drugi niz število. Ta števila seštevamo, dokler ne naletimo na vrstico, v kateri je prvi niz enak skupaj
. Tedaj vrnemo True
, če je vsota enaka drugi številki in False
, če ni. Če besede "skupaj" ni v racunu in se zanka "izteče", pa vrnemo False
.
To je vse.
Vse skupaj
Zberimo skupaj rešitve vseh nalog, se pravi celotnega izpita, kakršne bi lahko napisal študent, ki se ni lotil nekoliko naprednejše snovi, izpeljevanja seznamov in ki se ni domislil kakih posebnih trikov.
Krajša, a ne pretirano svinjska rešitev izpita pa je takšna.