Naloge (dodatne)

Najdaljša beseda

Napiši funkcijo najdaljsa(s), ki vrne najdaljšo besedo v nizu s. Pomagajte si z metodo split().

>>> najdaljsa('an ban pet podgan')
'podgan'

Rešitev

def najdaljsa(s):
    naj = ''
    for beseda in s.split():
        if len(beseda) > len(naj):
            naj = beseda
    return naj

Podobnost

Napišite funkcijo podobnost(s1, s2), ki izračuna podobnost med dvema nizoma. Podobnost definirajmo kot število mest v katerih se niza ujemata.

sobota
robot
------
011110 -> 4
>>> podobnost('sobota', 'robot')
4
>>> podobnost('robot', 'sobota')
4

Rešitev

Uporabimo funkcijo zip.

def podobnost(s1, s2):
    stevec = 0
    for c1, c2 in zip(s1, s2):
        if c1 == c2:
            stevec += 1
    return stevec

Ker se v Pythonu vrednosti True in False obnašata kot števili 0 in 1, bi lahko program zapisali tudi takole:

def podobnost(s1, s2):
    stevec = 0
    for c1, c2 in zip(s1, s2):
        stevec += c1 == c2
    return stevec

Seveda se da tudi ta program skrajšati.

def podobnost(s1, s2):
    return sum(c1 == c2 for c1, c2 in zip(s1, s2))

Sumljive besede

Napiši funkcijo sumljive(s), ki vrne seznam vseh sumljivih besed v danem nizu. Beseda je sumljiva, če vsebuje tako črko u kot črko a.

>>> sumljive('Muha pa je rekla: "Tale juha se je pa res prilegla, najlepša huala," in odletela.')
['Muha', 'juha', 'huala,"']

Rešitev

def sumljive(s):
    suspicious = []
    for word in s.split():
        if 'u' in word and 'a' in word:
            suspicious.append(word)
    return suspicious

Vsi

Napišite funkcijo vsi(xs), ki sprejme seznam xs in vrne True, če so vse vrednosti v seznamu resnične. Elementi seznama xs so lahko poljubnega tipa, ne le bool.

>>> vsi([True, True, False])
False
>>> vsi([True, True])
True
>>> vsi([1, 2, 3, 0])
False
>>> vsi(['foo', 42, True])
True
>>> vsi([])
True

Rešitev

def vsi(xs):
    for x in xs:
        if not x:
            return False
    return True

Vsaj eden

Napišite funkcijo vsaj_eden, ki deluje podobno kot vsi, le da vrne True, če je vsaj ena vrednost v seznamu resnična.

>>> vsaj_eden([2, 3, 0])
True
>>> vsaj_eden([])
False

Rešitev

def vsaj_eden(xs):
    for x in xs:
        if x:
            return True
    return False

Multiplikativni range

Napišite funkcijo mrange(start, faktor, dolzina), ki vrne seznam, kjer je vsako naslednje število za faktor večje od prejšnjega. Npr., v seznamu [1, 2, 4, 8, 16] je vsako naslednje število 2-krat večje od prejšnjega.

>>> print(mrange(7, 4, 7))
[7, 28, 112, 448, 1792, 7168, 28672]

Rešitev

def mrange(s, r, l):
    xs = []
    for i in range(l):
        xs.append(s)
        s *= r
    return xs

Vsota seznamov

Podan je seznam seznamov, npr. [[2, 4, 1], [3, 1], [], [8, 2], [1, 1, 1, 1]]. Napiši funkcijo, ki v seznamu vrne vsote vseh elementov v posameznih podseznamih. Za gornji seznam naj funkcija vrne seznam [7, 4, 0, 10, 4], saj je, na primer, 2 + 4 + 1 = 7.

>>> vsota_seznamov([[1, 1, 1], [1, 1]])
[3, 2]
>>> vsota_seznamov([[2, 4, 1], [3, 1], [], [8, 2], [1, 1, 1, 1]])
[7, 4, 0, 10, 4]

Rešitev

def vsota_seznamov(xss):
    vsote = []
    for xs in xss:
        vsota = 0
        for x in xs:
            vsota += x
        vsote.append(vsota)
    return vsote

Ampak zakaj bi pisali na dolgo, če lahko napišemo tako:

def vsota_seznamov(xss):
    return list(map(sum, xss))

Največji podseznam

Podan je podoben seznam kot zgoraj. Napiši funkcijo, ki vrne podseznam z največjo vsoto elementov. Za gornji seznam mora funkcija vrniti [8, 2], saj je to podseznam z največjo vsoto, namreč 10.

>>> najvecji_podseznam([[1, 1, 1], [1, 1]])
[1, 1, 1]
>>> najvecji_podseznam([[2, 4, 1], [3, 1], [], [8, 2], [1, 1, 1, 1]])
[8, 2]

Rešitev

def najvecji_podseznam(xss):
    najvecji = []
    najvecji_vsota = float('-inf')
    for xs in xss:
        vsota = 0
        for x in xs:
            vsota += x
        if vsota > najvecji_vsota:
            najvecji = xs
            najvecji_vsota = vsota
    return najvecji

Pomagamo si lahko tudi s funkcijo iz prejšnje naloge.

def najvecji_podseznam(xss):
    ys = vsota_seznamov(xss)
    najvecji = float('-inf')
    for i, y in enumerate(ys):
        if y > ys[najvecji]:
            najvecji = i
    return xss[najvecji]

Ali krajše.

def najvecji_podseznam(xss):
    return max(xss, key=sum)

Drugi največji

Napiši funkcijo, ki poišče in vrne drugi največji element seznama.

>>> drugi_najvecji([5, 1, 4, 2, 3])
4

Rešitev

def drugi_najvecji(xs):
    prvi = drugi = float('-inf')
    for x in xs:
        if x > prvi:
            drugi = prvi
            prvi = x
        elif x > drugi:
            drugi = x
    return drugi

Lahko pa seznam najprej uredimo, nato pa preberemo predzadnjo vrednost.

def drugi_najvecji(xs):
    return sorted(xs)[-2]

Cezarjeva šifra

Napišite program, ki podan niz zašifrira z uporabo cezarjeve šifre. Preden se lotite naloge, se je morda vredno pozanimati kaj počneta funkciji ord in chr. Predpostavite lahko, da niz s vsebuje le male črke angleške besede in presledke.

>>> cezar('the quick brown fox jumps over the lazy dog')
'wkh txlfn eurzq ira mxpsv ryhu wkh odcb grj'

Rešitev

def cezar(s):
    cipher = ''
    for c in s:
        if 'a' <= c <= 'w':
            cipher += chr(ord(c) + 3)
        elif 'x' <= c <= 'z':
            cipher += chr(ord(c) - 23)
        else:
            cipher += c
    return cipher

Nalogo cezar lahko rešimo tudi s parom funkcij maketrans in translate.

def cezar(s):
    alphabet = 'abcdefghijklmnopqrstuvwxyz'
    trans = str.maketrans(alphabet, alphabet[3:] + alphabet[:3])
    return s.translate(trans)

EMŠO

Napiši funkcijo veljavna, ki preveri pravilnost dane številke EMŠO. Kako je sestavljena pravilna številka EMŠO, je napisano v 4. členu Uredbe o načinu določanja osebne identifikacijske številke. Preveriti morate pravilnost zadnje števke.

>>> veljavna('2902932505526')
True
>>> veljavna('2805985500156')
True
>>> veljavna('2805985505156')
False

Rešitev

def veljavna(emso):
    vsota = 0
    for i, e in zip((7, 6, 5, 4, 3, 2, 7, 6, 5, 4 ,3 ,2, 0), emso):
        vsota += i * int(e)
    ostanek = vsota % 11
    if ostanek == 0:
        return e == str(ostanek)
    else:
        return e == str(11 - ostanek)

Zadnja sprememba: sreda, 16. november 2022, 13.53