def iclear(x):
for i in range(len(x)):
x[i] = 0
def skritopis(s):
if not s:
return s
ns = s[0]
for i in range(1, len(s)):
if not s[i].isalpha() or not s[i-1].isalpha():
ns += s[i]
return ns
def presledki(s):
odvecnih = presledkov = 0
for i in range(len(s)-2):
if s[i] == " " and s[i+1] != " ":
presledkov += 1
if s[i] == " " and s[i+1] == " " and s[i+2] != " ":
odvecnih += 1
if not presledkov:
return 0
return odvecnih / presledkov
def rime(pesmica):
dodeljene = {}
rima = ''
for line in pesmica.split("\n"):
zadnja_beseda = line.split(" ")[-1]
if not zadnja_beseda:
continue
zlog = zadnja_beseda.split("-")[-1].strip(" .,:;)?!")
if zlog not in dodeljene:
dodeljene[zlog] = "ABCDEFGHIJKLMNOPRSTUVZ"[len(dodeljene)]
rima += dodeljene[zlog]
return rima
def turnir(tekmovalci):
while len(tekmovalci) > 1:
novi_tekmovalci = []
for i in range(0, len(tekmovalci), 2):
if (len(tekmovalci[i]) + len(tekmovalci[i + 1])) % 2 == 0:
novi_tekmovalci.append(tekmovalci[i])
else:
novi_tekmovalci.append(tekmovalci[i+1])
tekmovalci = novi_tekmovalci
return tekmovalci[0]
class Oseba:
def __init__(self, ime, priimek, spol, emso):
self.ime = ime
self.priimek = priimek
self.spol = spol
self.emso = emso
def preveri_emso(self):
dnevi = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
dan, mesec = int(self.emso[:2]), int(self.emso[2:4])
if not (1 <= mesec <= 12 and 1 <= dan <= 31):
return False
if dan > dnevi[mesec - 1]:
return False
if self.spol != ('Z' if self.emso[9] >= '5' else 'M'):
return False
ctl = sum(int(e) * i for e, i in zip(self.emso, [7, 6, 5, 4, 3, 2, 7, 6, 5, 4, 3, 2]))
return (ctl + int(self.emso[-1])) % 11 == 0
V obvezni nalogi z napadalnimi kraljicami je bilo potrebno spremeniti [0] v [-1]. Tisti,
ki ste domačo nalogo reševali na grši način, ne takšen, kot je bilo predpisano, pa ste morali obrniti seznam
(z reversed ali [::-1]) in vrniti prvi element).
Rešitev obvezne naloge z vektorji ni najbolj elegantna; kdor je bil na predavanjih in sledil (ali bral zapiske),
jo je lahko rešil na način, ki je napisan spodaj.
V nalogi Skritopis prepisujemo stari niz v novega, pri čemer obdržimo prve znak, poleg tega pa vse
ne-črke in vse črke, pred katerimi so nečrke.
Naloga Prepresledki ji je na nek način podobna. Ko štejemo potrebne presledke, štejmo le zadnjega izmed
zaporednih presledkov - torej tistega, ki mu ne sledi drug presledek. Ko štejemo večkratne presledke povečamo števec
le pri zadnjih dveh - gledamo torej, koliko je parov presledkov, ki jim ne sledi nov presledek. Rešitev je duhamorna
in niti ne povsem pravilna (obstaja primer, ki pa ga testi ne odkrijejo, ko ne deluje). Služi naj predvsem kot še en
dokaz, kako koristno se je naučiti regularne izraze (glej rešitev spodaj!)
Rime so vaja iz razbijanja nizov (tega smo počeli dovolj!), predvsem pa telovadba s slovarjem (tudi tega nam
ni manjkalo!).
Turnir je algoritmično najzahtevnejša naloga, saj - v preprosti različici, kakršna je gornja - zahteva dvojno zanko.
Zanka while gre prek krogov turnirja, for pa prek parov tekmovalcev. Znotraj for
v seznam zlagamo tiste, ki so se uvrstili v drugi krog. Nekateri ste namesto dvojne zanke uporabljali rekurzijo: to je
v načelu slabša rešitev, vendar sem je zelo vesel!
Naloga z EMŠO zahteva, da znate sestaviti metodo in postaviti nekaj pogojev ter izračunati kontrolno vsoto. Slednje
je mogoče najti v starih vajah, pa tudi letos ste na vajah računali kontrolno vsoto ISBN, kar je precej podobna reč.
Elegantnejše rešitve
Elegantnejše rešitve dokazujejo: da se splača brati rešitve domačih nalog (iclear), da so regularni izrazi
koristna reč in je škoda, da vas je prav na teh predavanjih precej manjkalo (skritopis, presledki), da ve asistent
Žbontar za kako eksotično metodo nizov (splitlines), s katero lahko privarčuje kako vrstico (rime) ter da je doc. Demšar
perverznež (turnir).
def iclear(x):
x[:] = [0]*len(x)
def skritopis(s):
import re
return re.sub("\w+", lambda mo: mo.group()[0], s)
def presledki(s):
import re
return len(re.findall("\s\s+", s)) / (len(re.findall("\s+", s)) or 1)
def rime(pesmica):
dodeljene = {}
rima = ''
for line in pesmica.splitlines():
zlog = line.split(" ")[-1].split("-")[-1].strip(" .,:;)?!")
if zlog not in dodeljene:
dodeljene[zlog] = chr(ord("A") + len(dodeljene))
rima += dodeljene[zlog]
return rima
def turnir(x):
while len(x) > 1:
o1, o2 = x.pop(0), x.pop(0)
x.append([o1, o2][len(o1+o2) % 2])
return x[0]
class Oseba:
def __init__(self, ime, priimek, spol, emso):
self.ime = ime
self.priimek = priimek
self.spol = spol
self.emso = emso
def preveri_emso(self):
dnevi = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
dan, mesec = int(self.emso[:2]), int(self.emso[2:4])
if not (1 <= mesec <= 12 and 1 <= dan <= 31):
return False
if dan > dnevi[mesec - 1]:
return False
if self.spol != ('Z' if self.emso[9] >= '5' else 'M'):
return False
ctl = sum(int(e) * i for e, i in zip(self.emso, list(range(7, 1))*2))
return (ctl + int(self.emso[-1])) % 11 == 0
Последна промена: четврток, 9 февруари 2012, 23:37