Autorské riešenie
[stiahni py]

  • Počet riešiteľov: 46 / 46 = 100 %

  • Úspešnosť riešenia: 3,11/6 = 51%

Podľa zadania, pre riešenie tejto úlohy potrebujeme poznať staré heslo a minimálnu dĺžku nového hesla. V prípade, že v novom hesle nechceme použiť staré heslo, bude na vstupe prázdny reťazec. Na správne vyriešenie úlohy je potrebné vykonať nasledovné kroky:

  • začnime s novým prázdnym heslom,
  • zistime, či staré heslo obsahuje malé písmeno,
    •  ak nie, do nového hesla náhodne vložíme náhodné malé písmeno,
  • zistime, či staré heslo obsahuje veľké písmeno,
    •  ak nie, do nového hesla náhodne vložíme náhodné veľké písmeno,
  • zistíme, koľko znakov je potrebné do nového hesla doplniť, aby sme dosiahli minimálnu dĺžku,
    •  doplníme požadovaný počet náhodne vybraných malých alebo veľkých písmen,
  • do nového hesla na náhodne miesto vložíme staré heslo.

Všimnime si, že v našom postupe do nového hesla na náhodnú pozíciu pridávame nejaký znak alebo reťazec. Výhodné bude si na túto činnosť vytvoriť pomocnú funkciu. Výsledné riešenie môže vyzerať napr. takto:

import random

def vloz_do_hesla_retazec(heslo, retazec):
    idx = random.randrange(len(heslo) + 1)
    upravene_heslo = heslo[:idx] + retazec + heslo[idx:]
    return upravene_heslo

def generuj_1(min_dlzka, stare_heslo):
    mala_abeceda = 'abcdefghijklmnopqrstuvwxyz'
    velka_abeceda = mala_abeceda.upper()
    obsahuje_male_pismeno = False
    obsahuje_velke_pismeno = False
    heslo = ''

    for znak in stare_heslo:
        if znak.islower():
            obsahuje_male_pismeno = True
        elif znak.isupper():
            obsahuje_velke_pismeno = True

    if not obsahuje_male_pismeno:
        heslo = vloz_do_hesla_retazec(heslo, random.choice(mala_abeceda))
    if not obsahuje_velke_pismeno:
        heslo = vloz_do_hesla_retazec(heslo, random.choice(velka_abeceda))

    chybajuci_pocet_znakov = min_dlzka - len(heslo) - len(stare_heslo)
    for i in range(chybajuci_pocet_znakov):
        heslo = vloz_do_hesla_retazec(heslo, random.choice(mala_abeceda + velka_abeceda))
    heslo = vloz_do_hesla_retazec(heslo, stare_heslo)

    return heslo

Ak budujeme nové heslo postupne ako reťazec máme trochu sťaženú prácu s tým, aby všetky vloženia bolo náhodné. Výhodnejšie by bolo "pozbierať" potrebné znaky/reťazce nového hesla, pomiešať ich a spojiť do výsledku. Toto riešenie zrealizujeme pomocou zoznamov a môže vyzerať nasledovne: 

def generuj_2(min_dlzka, stare_heslo):
    mala_abeceda = 'abcdefghijklmnopqrstuvwxyz'
    velka_abeceda = mala_abeceda.upper()
    obsahuje_male_pismeno = False
    obsahuje_velke_pismeno = False
    casti_hesla = []

    for znak in stare_heslo:
        if znak.islower():
            obsahuje_male_pismeno = True
        elif znak.isupper():
            obsahuje_velke_pismeno = True

    if not obsahuje_male_pismeno:
        casti_hesla.append(random.choice(mala_abeceda))
    if not obsahuje_velke_pismeno:
        casti_hesla.append(random.choice(velka_abeceda))

    chybajuci_pocet_znakov = min_dlzka - len(casti_hesla) - len(stare_heslo)
    for i in range(chybajuci_pocet_znakov):
        casti_hesla.append(random.choice(mala_abeceda + velka_abeceda))
    casti_hesla.append(stare_heslo)
    random.shuffle(casti_hesla)
    heslo = ''.join(casti_hesla)

    return heslo

Vaše zaujímavé riešenia a najčastejšie chyby

  • Pre splnenie podmienok ste menili veľkosť znakov starého hesla. Avšak tým pádom už staré heslo nebolo súčasťou nového hesla.
  • Pri riešení úlohy ste pracovali s konštantnou dĺžkou nového hesla, čím ste nemuseli vytvárať najkratšie možné heslá a mohlo dôjsť k neočakávaným výsledkom.
  • Staré heslo sa nachádzalo vždy na začiatku, prípadne konci nového hesla.
  • K starému heslu sa pripísalo malé a veľké písmeno aj keď to už nebolo potrebné (staré heslo už obsahovalo malé a j veľké písmeno).
  • Pri riešení úlohy ste pracovali s konštantnou dĺžkou nového hesla, čím ste nemuseli vytvárať najkratšie možné heslá.
  • Pri tvorbe nového hesla dopisovali špeciálne znaky ({, #, @, ]...) a čísla.