PALMA junior, Programovanie, ALgoritmy, MAtematika, súťaž pre mladých programátorov v Python-e

 

Autorské riešenie
[stiahni py]

  • Počet riešiteľov: 7 / 11 = 63,6 %

  • Úspešnosť riešenia: 2 / 6 = 33,3 %

Podľa zadania je našou úlohou vytvoriť kód, ktorý dešifruje zadaný reťazec na základe šifrovacích pravidiel, ktoré boli uvedené v zadaní úlohy:

  • Určíme si prirodzené číslo, ktoré bude šifrovacím kľúčom.
  • Znaky v správe, ktoré sú na párnej pozícii cyklicky posunieme o hodnotu kľúča vpravo.
  • Znaky v správe, ktoré sú na nepárnej pozícii cyklicky posunieme o hodnotu kľúča vľavo.
Potrebujeme si preto uvedomiť, že pri dešifrovaní budeme tieto pravidlá aplikovať v opačnom smere. Teda konkrétne:
  • Určíme si prirodzené číslo, ktoré bude šifrovacím kľúčom.
  • Znaky v správe, ktoré sú na párnej pozícii cyklicky posunieme o hodnotu kľúča vľavo.
  • Znaky v správe, ktoré sú na nepárnej pozícii cyklicky posunieme o hodnotu kľúča vpravo.
Mohlo by sa zdať, že vezmeme párne znaky, posunieme ich, vezmeme nepárne znaky a posunieme ich a následne spojíme dokopy. To však nie je až také jednoduché. Potrebujeme si rozdeliť teda správu rozdeliť na znaky na párnych a nepárnych pozíciách a potom samostatne cyklicky posunúť párne znaky doľava a nepárne znaky doprava. Potom musíme tieto párne a nepárne znaky striedavo uložiť do výsledného reťazca.

Výsledný program môže vyzerať nasledovne:

def zrotuj_doprava(znaky, kluc):
    kluc = kluc % len(znaky)
    return znaky[-kluc:] + znaky[:-kluc]
    
def zrotuj_dolava(s, k):
    kluc = kluc % len(znaky)
    return znaky[kluc:] + znaky[:kluc]
    
def desifruj(odpoved, kluc):
    parne_znaky = odpoved[::2]  # Párne indexy (0, 2, 4,...)
    neparne_znaky = odpoved[1::2]  # Nepárne indexy (1, 3, 5,...)

    parne_zrotovane = zrotuj_dolava(parne, kluc)
    neparne_zrotovane = zrotuj_doprava(neparne, kluc)

    desifrovane = ""
    index_parne, index_neparne = 0, 0
    for i in range(len(odpoved)):
        if i % 2 == 0:
            desifrovane += parne_zrotovane[index_parne]
            parne += 1
        else:
            desifrovane += neparne_zrotovane[index_neparne]
            neparne += 1

    return desifrovane

odpoved = RTAKINIOFM  
kluc = 3 
desifrovane = desifruj(odpoved, kluc)
print("Dešifrovaný text:", desifrovane)                

Toto riešenie vieme upraviť aj tak, aby sme využívali iba jednu funkciu namiesto 2 a to tak, že posun budeme volať pomocou opačnej hodnoty kódu, aby sme pomocou neho zistili smer kódovania.

Takto upravený program môže vyzerať nasledovne:

def zrotuj(znaky, kluc)
    if kluc>0:
      kluc = kluc % len(znaky)
    if kluc<0:
      -kluc = -kluc % len(znaky) 
    return s[k:] + s[:k]
    
def desifruj(odpoved, kluc):
    parne_znaky = odpoved[::2]  # Párne indexy (0, 2, 4,...)
    neparne_znaky = odpoved[1::2]  # Nepárne indexy (1, 3, 5,...)

    parne_zrotovane = zrotuj(parne, kluc)
    neparne_zrotovane = zrotuj(neparne, -kluc)

    desifrovane = ""
    index_parne, index_neparne = 0, 0
    for i in range(len(odpoved)):
        if i % 2 == 0:
            desifrovane += parne_zrotovane[index_parne]
            parne += 1
        else:
            desifrovane += neparne_zrotovane[index_neparne]
            neparne += 1

    return desifrovane

odpoved = RTAKINIOFM  
kluc = 3 
desifrovane = desifruj(odpoved, kluc)
print("Dešifrovaný text:", desifrovane)
               

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

Najväčší problém súťažiacim robila manipulácia s reťazcami a dešifrovanie správnym spôsobom. Mali problém s tým určiť správny smer dešifrovania a správne urobiť posun pomocou kľúča. Viacerí nevedeli ako pracovať so znakmi na párnych a nepárnych pozíciach - nevedeli si tento reťazec rozdeliť na párne a nepárne znaky, nevolili vhodné spôsoby na prácu so znakmi a reťazcami.