Naloga

Ogrevalna naloga

Napiši program, ki prebere seznam števil in izpiše "Da", če seznam vsebuje tudi kako liho število, in "Ne", če ga ne.

Seznam bo uporabnik podal tako, da bo vpisal zaporedje števil, med katerimi bodo presledki (brez vejic). Seznam boš najpreprosteje prebral (ali prebrala, če si študentka) z

s = [int(x) for x in input("Seznam: ").split()]

Ne sprašuj se (zaenkrat!), kako tole deluje. Pomembno je, da je po tem v spremenljivki s seznam števil.

Obvezna naloga

Mama deli bombone šestim otrokom, ki jih je oštevilčila s številkami od 0 do 5. Zaporedje dajanja bombonov je shranila v seznam. Tako, recimo, [4, 0, 2, 3, 2, 0, 3, 4, 4, 4] pomeni, da je najprej dala bombon četrtemu otroku, nato ničtemu, potem drugemu...

Napiši program, ki prebere seznam otrok (na enak način kot pri ogrevalni nalogi) in izpiše "Da", če so dobili bombone vsi otroci, in "Ne", če je kateri ostal brez. V gornjem primeru bi moral program izpisati "Ne" - vendar samo enkrat, ne dvakrat, čeprav sta brez bombonov dva otroka.

Dodatna naloga

Komaj je mati dobro razdelila bombone, že so jih otroci začeli goltati. Napiši program, ki prebere seznam, po katerem mati deli bombone in seznam, po katerem jih otroci goltajo. Če bi bil seznam, recimo [3, 0, 4, 4, 2, 3, 0, 4], bi to pomenilo, da je najprej pojedel bombon tretji otrok, nato ničti, potem četrti, potem še enkrat četrti, nato drugi otrok...

Program naj pove, kateri otrok prvi ostane brez bombonov. V primeru gornjih dveh seznamov je to otrok 3, saj je prvi ostal brez (obeh) bombonov, ki ju je dobil. Programu ni potrebno kontrolirati, ali sta seznama pravilna, torej, ali res vsebujete samo številke in ali otroci res pojedo samo toliko bombonov, kot jih v resnici imajo.

Podatke preberi z

delitev = [int(x) for x in input("Seznam: ").split()] goltanje = [int(x) for x in input("Goltanje: ").split()]

Rešitev

Ogrevalna naloga

Kot so nas navedla navodila, program začnemo z

s = map(int, input("Seznam: ").split())

Bistvo ogrevalna naloge je fraza "poišči enega", ki jo pogosto srečujemo pri programiranju: imamo seznam (terko, niz, datoteko, karkoli) nekih stvari in zanima nas, ali je med njimi takšna, ki ustreza nekemu pogoju. Ta stvar ima tipično obliko: for in znotraj njega if. V večini jezikov to izpade tako:

je_liho = False for e in s: if e % 2 == 1: je_liho = True if je_liho: print("Je liho") else: print("Ni lihega")

Zelo narobe je pisati tole:

je_liho = False for e in s: if e % 2 == 1: je_liho = True else: je_liho = False

Ne toliko zato, ker je to isto kot

je_liho = False for e in s: je_liho = e % 2 == 1 temveč predvsem zato, ker je to popolnoma narobe, saj v resnici gleda le zadnji element.

Pač pa je lepo, da zanko končamo z break, čim naletimo na prvi element, ki ustreza pogoju, saj tedaj nima več smisla nadaljevati s pregledovanjem. Torej: naredimo enako kot v prvem programu, le še break dopišemo.

je_liho = False for e in s: if e % 2 == 1: je_liho = True break if je_liho: print("Je liho") else: print("Ni lihega")

V Pythonu lahko za zanko dodamo else, ki se izvede, če se zanka ni končala z break, torej lahko program poenostavimo v

for e in s: if e % 2 == 1: print("Je liho") break else: print("Ni lihega")

Tole smo bolj ali manj naredili tudi že na predavanjih; komentarje in svarila si lahko ogledate v zapiskih.

Obvezna naloga

Obvezna naloga je enaka ogrevalni: gremo prek vseh številk otrok od 0 do 5 (for otrok in range(6):) in če katerega od otrok ni na seznamu dobitnikov bombonov (if otrok not in delitev) izpišemo "Ne" in prekinemo zanko, sicer pa izpišemo "Da".

for otrok in range(6): if otrok not in delitev: print("Ne") break else: print("Da")

Vsako reč se da seveda zaplesti. Lahko bi rekli, da v začetku predpostavimo, da noben otrok ni dobil nobenega bombona, potem pa šli prek delitve in pri vsakem, ki dobi bombon, zabeležili, da je dobil bombon. Nato gremo prek tega seznama, da preverimo, ali je v njem kdo, ki je ostal brez bombonov.

ima_bombon = [False] * 6 for otrok in delitev: ima_bombon[otrok] = True for ima in ima_bombon: if not ima: print("Ne") break else: print("Da")

Seznam ima_bombon moramo razumeti takole: ima_bombon[i] bo True, če ima i-ti otrok bombon. V začetku je v seznamu šest False-ov, potem pa gremo prek delitve in na ustreznih mestih pišemo True-je. V drugi zanki preverimo, ali je v seznamu ostal kak False.

Druga rešitev je v resnici boljša, če mama razdeli zelo zelo zelo veliko bombonov zelo zelo velikemu številu otrok.

Lahko pa naredimo še malo drugače: namesto da bi beležili, kdo že ima bombon, preštevamo, koliko bombonov je dobil posamezni otrok. Za to je potrebno le spremeniti prvi kos v

ima_bombon = [0] * 6 for otrok in delitev: ima_bombon[otrok] += 1

Drugi lahko ostane takšen kot prej, saj je not ima isto kot ima == 0.

Dodatna naloga

Dodatno nalogo izpeljemo iz zadnje rešitve. Najprej prištevamo bombone, ki jih otroci dobivajo, nato ponovimo isto, le da bombone odštevamo. Čim ostane kdo brez, povemo, kdo je to in končamo.

ima_bombon = [0] * 6 for otrok in delitev: ima_bombon[otrok] += 1 for otrok in goltanje: ima_bombon[otrok] -= 1 if not ima_bombon[otrok]: print(otrok) break
Zadnja sprememba: sreda, 19. september 2018, 16.23