Krogi z rešitvami
V domači nalogi se bomo ukvarjali s krogi. Vsak krog bo podan s trojko
(terko) (x, y, r), kjer sta x in y koordinati središča, r pa
polmer. Kadar bomo govorili o seznamu krogov, bo to seznam trojk, na primer
[(4, 1, 2), (2, 7, 5)] - to bi pomenilo dva kroga, prvi ima
središče v (4, 1) in polmer 2, drugi pa ima središče v (2, 7) in polmer 5.
Pri reševanju vam bo morda prišlo prav pogledati teste. Krogi a, b, c, d, e, f, g, h, i, j, k, ki se pojavljajo v njih, so postavljeni tako, kot kaže slika.
Pri reševanju domačih nalog priporočam uporabo izpeljanih seznamov. Ni
obvezno, pravilo pa je takšno: kdor vse funkcije napiše z uporabo izpeljanih
seznamov (slovarjev, množic), dobi eno oceno več. Pri tem seveda ni dovolj
zgolj uporabiti izpeljanih seznamov nekje znotraj funkcije: funkcije morajo
dejansko vsebovati zgolj return. Manjša izjema je funkcija
se_sekata, kjer ni nobenih seznamov; le-ta bo očitno napisana
zgolj s formulo (in morda še dvema vrsticama pred njo, da bo formula
preglednejša).
Za oceno 6
Napišite funkcijo radiji(n, minr, maxr), ki vrne seznam z
n naključnimi števili med (vključno) minr in
maxr. Pomagate si lahko s funkcijo random.randint.
Napišite tudi funkcijo krogi(n, maxx, maxy, minr, maxr), ki
vrne seznam naključno razmetanih krogov naključnih velikosti. Njihovi polmeri
morajo biti med minr in
maxr. Krogi morajo biti v celoti znotraj pravokotnika, katerega
levo spodnje oglišče je izhodišče koordinatnega sistema (0, 0), desno zgornje
pa (maxx, maxy). Pozor: testi tega ne preverjajo, vendar mora biti
funkcija napisana tako, da se lahko zgodi tudi, da se krog s polmerom minr
dotika (ko)ordinatne osi ali skrajne desne ali zgornje meje dovoljenega
območja.
Napišite tudi funkcijo ploscina(krogi), ki prejme seznam krogov
in vrne vsoto njihovih ploščin.
Rešitev
Pri rešitvi je nenavadno, da i-ja pravzaprav ne potrebujemo.
Hm, nenavadno? Niti ne. Tudi sicer smo pogosto pisali reči v slogu
for i in range(4):, da bi nekaj štirikrat ponovili.
PyCharm in podobni v takih primerih označijo i in komentirajo,
da smo definirali spremenljivko, ki je nikjer ne uporabimo - kar da je sumljivo.
Če se hočemo izogniti opozorilu, preimenujemo i v _.
Tudi _ je za Python "čisto navadna spremenljivka", okoljem, kot je
PyCharm, pa s takim imenom namignemo, da te spremenljivke v resnici ne
potrebujemo.
Preostali funkciji sta takšni:
Finta prve je, da si koordinat x in y ne izmišljamo kar tako, temveč za
dani polmer. Ko že imamo polmer, vemo, kakšen je interval dovoljenih koordinat.
Če izbiramo števila v tem intervalu se izognemo potrebi po tem, da bi z
if preverjali, ali je krog pravilno postavljen ali ne.
Za oceno 7
Napišite funkcijo se_sekata(krog1, krog2), ki prejme dva kroga
(dve terki s tremi elementi) ter vrne True, če se sekata in
False, če se ne.
Napišite tudi funkcijo seka(krog, krogi), ki vrne
True, če podani krog seka katerega od krogov v seznamu
in False, če ne.
Rešitev
Ob prvi funkciji povejmo, da je lepo, da smo takole razpakirali koordinate
središča in polmer. Tako smo se izognili mukotrpnemu (in napake povzročujočemu)
indeksiranju v slogu (krog1[0] - krog2[1]) ** 2 in tako naprej.
Druga funkcija je klasičen primer za funkcijo any.
Za oceno 8
Napišite funkcijo seka_n(krog, krogi), ki vrne indekse
krogov v seznam krogi, ki jih seka podani krog. (Namig: ne
uporabljajte metode index. Ne bo se obneslo. ;)
Rešitev
Tudi tole je precej klasična zadeva: z enumerate dobimo indekse
in kroge. Seznam sestavimo iz indeksov (i), vendar takšnih, pri
katerih ima krog določeno lepo lastnost (se seka s podanim krogom).
Za oceno 9
Napišite funkcijo sosedi(krogi), ki vrne slovar, katerega
ključi so krogi, vrednosti pa množice krogov, ki jih ta krog seka. Za primer
poglej sliko in teste. Množica naj ne vsebuje tega kroga samega.
Napišite funkcijo sosedi_n(krogi), ki vrne podoben slovar, le
da so ključi in vrednosti indeksi krogov.
Rešitev
Sestavili bomo slovar. Njegovi ključi bodo krogi (krog1) iz
podanega seznama krogov (for krog1 in krogi). Vrednosti bodo
množice vseh krogov, ki sekajo ta krog in niso isti kot ta krog,
{krog2 for krog2 in krogi if se_sekata(krog1, krog2) and krog1 is not krog2}.
Druga funkcija počne isto, le da uporablja enumerate in
sestavlja indekse.
Za oceno 10
Kako priti do ocene 10, piše v uvodu.