Osnovne, nekoliko okornejše rešitve

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