Autorské riešenie
[stiahni]

  • Počet riešiteľov: 5 / 7= 71%

  • Úspešnosť riešenia: 1.4 / 5= 28 %

Našou úlohou je zo zadaného textového reťazca vytvoriť nový reťazec, ktorý bude obsahovať všetky znaky pôvodného reťazca, len spoluhlásky budú uvedené v opačnom poradí.

Úlohu môžme riešiť aspoň dvoma spôsobmi:

  1. dvojprechodovo - najprv zistíme pozície samohlások v pôvodnom texte, potom v novom texte umiestňujeme spoluhlásky na prehodené pozície,
  2. jednoprechodovo - prechádzame textovým reťazcom naraz spredu aj zozadu, ak narazíme na spoluhlásky, tak ich vymeníme.

Pri obidvoch uvedených spôsoboch je užitočné uložiť všetky spoluhlásky do jednej premennej, ktorú budeme používať pri zisťovaní, či práve prečítaný znak je spoluhláskou:

viem start
  urob "spoluhlasky "bcčdďfghjklľĺmnňpqrŕsštťvwxzžBCČDĎFGHJKLĽĹMNŇPQRŔSŠTŤVWXZŽ
koniec

V dvojprechodovom riešení v prvom prechode zadaným reťazcom (napr. "maledivy) vytvoríme zoznam obsahujúci pozície spoluhlások (napr. [1 3 5 7]) a zoznam spoluhlások na daných pozíciách, ale v opačnom poradí (napr. [v d l m]). Programový kód tejto časti, so zadaným reťazcom v premennej "povodny a výslednými zoznamami v premenných "spoluhlaskyZtextu a "pozicieSpoluhlasok, môže vyzerať, napr. takto:

...
  urobTu "spoluhlaskyZtextu  []
  urobTu "pozicieSpoluhlasok []
  prePrvky "znak :povodny [   
    ak prvok? :znak :spoluhlasky [
      urobTu "spoluhlaskyZtextu  vlozPr :znak :spoluhlaskyZtextu
      urobTu "pozicieSpoluhlasok vlozPo počítadlo :pozicieSpoluhlasok
    ] 
  ]
...

V druhom prechode najprv do premennej "zasifrovany uložíme obsah premennej "povodny, následne postupne zameníme na spoluhláskových pozíciach zozbierané spoluhlásky, s tým, že budeme skracovať zoznam spoluhlások aj zoznam ich pozícii. Programový kód tejto časti môže vyzerať, napr. takto:

...
  urobTu "zasifrovany :povodny   
  kým [nieJe prázdny? :spoluhlaskyZtextu][
    urobTu "zasifrovany nahrad (prvý :pozicieSpoluhlasok)
   :                           zasifrovany (prvý :spoluhlaskyZtextu)
    urobTu "spoluhlaskyZtextu  bezPr :spoluhlaskyZtextu
    urobTu "pozicieSpoluhlasok bezPr :pozicieSpoluhlasok
  ]
...

Kompletná procedúra zasifruj1 využívajúca v grafickom rozhraní textové polia textPôvodný a textZašifrovaný môže vyzerať, napr. takto:

viem zasifruj1
  urobTu "povodny textPôvodný'hodnota
  urobTu "spoluhlaskyZtextu []
  urobTu "pozicieSpoluhlasok []
  prePrvky "znak :povodny [
    ak prvok? :znak :spoluhlasky [
      urobTu "spoluhlaskyZtextu vložPr :znak :spoluhlaskyZtextu
      urobTu "pozicieSpoluhlasok vložPo počítadlo :pozicieSpoluhlasok
    ]
  ]

  urobTu "zasifrovany :povodny
  kým [nieJe prázdny? :spoluhlaskyZtextu][
    urobTu "zasifrovany nahraď (prvý :pozicieSpoluhlasok)
                               :zasifrovany (prvý :spoluhlaskyZtextu)
    urobTu "spoluhlaskyZtextu bezPr :spoluhlaskyZtextu
    urobTu "pozicieSpoluhlasok bezPr :pozicieSpoluhlasok
  ]
  textZašifrovaný'nechHodnota :zasifrovany
koniec

Druhý prechod môžeme urobiť aj tak, že najprv nastavíme premennú "zasifrovany na prázdny reťazec a prejdeme celým zadaným reťazcom od prvej po poslednú pozíciu. Na pozíciách spoluhlások postupne pripájame k výslednému reťazcu "zasifrovany spoluhlásku z otočeného zoznamu a na ostatných pozíciach pôvodný znak. Kompletná procedúra zasifruj2 využívajúca v grafickom rozhraní textové polia textPôvodný a textZašifrovaný môže vyzerať, napr. takto:

viem zasifruj2
  urobTu "povodny textPôvodný'hodnota
  urobTu "spoluhlaskyZtextu []
  urobTu "pozicieSpoluhlasok []
  prePrvky "znak :povodny [
    ak prvok? :znak :spoluhlasky [
      urobTu "spoluhlaskyZtextu vložPr :znak :spoluhlaskyZtextu
      urobTu "pozicieSpoluhlasok vložPo počítadlo :pozicieSpoluhlasok
    ]
  ]

  urobTu "zasifrovany " 
  preCisla "pocitadlo ![1 (počet :povodny)][
    ak2 prvok? :pocitadlo :pozicieSpoluhlasok [
      urobTu "zasifrovany vložPo prvý :spoluhlaskyZtextu :zasifrovany
      urobTu "spoluhlaskyZtextu bezPr :spoluhlaskyZtextu
    ][
      urobTu "zasifrovany vložPo (prvok :pocitadlo :povodny) :zasifrovany
    ]  
  ]
  textZašifrovaný'nechHodnota :zasifrovany
koniec

Jednoprechodové riešenie úlohy využíva premenné "dolna a "horna na označenie aktuálnych pozícii spoluhlások v textovom reťazci a premenné "znakD? a "znakH? na zaregistrovanie, že práve čítaný znak zľava, resp. sprava je spoluhláskou. Výsledná jednoprechodová procedúra zasifruj3 môže vyzerať, napr. takto:

viem zasifruj3
  urobTu "text textPôvodný'hodnota
  urobTu "dolna 1
  urobTu "horna počet :text
  urobTu "znakD? "nie
  urobTu "znakH? "nie
  kým [:dolna<:horna][
    urobTu "znakD prvok :dolna :text
    ak2 (prvok? :znakD :spoluhlasky)[
      urobTu "znakD? "áno
    ][
      urobTu "dolna :dolna+1
    ]
    urobTu "znakH prvok :horna :text
    ak2 (prvok? :znakH :spoluhlasky)[
      urobTu "znakH? "áno
    ][
      urobTu "horna :horna-1
    ]
    ak (zároveň :znakD? :znakH?) [
      urobTu "text vymena :text :dolna :horna
      urobTu "dolna :dolna+1
      urobTu "horna :horna-1
      urobTu "znakD? "nie
      urobTu "znakH? "nie
    ]
  ]
  textZašifrovaný'nechHodnota :text
koniec

Na výmenu dvoch znakov na vybraných pozíciách v zadanom reťazci použijeme vlastnú funkciu (operáciu) vymena, ktorej kód je uvedený nižšie:

viem vymena :textik :poz1 :poz2
  urobTu "pomocny prvok :poz1 :textik
  urobTu "textik nahraď :poz1 :textik (prvok :poz2 :textik)
  urobTu "textik nahraď :poz2 :textik :pomocny
  výsledok :textik
koniec

Táto súťažná úloha je zameraná na použitie stratégie riešenia rozlož problém do podproblémov, vytvorenie vlastného šifrovacieho algoritmu, prácu so zoznamami, použitie príkazov opakovania a vetvenia.

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

Do riešenia tejto úlohy pre kategóriu PROFÍK sa zapojilo 5 zo 7 tímov, ale len tím Bubáci v. 3 ju vyriešil správne a navyše uviedol cez 50 palindrómov. Celkový priemer úspešnosti odovzdaných riešení bol 1,4 bodu z maximálneho počtu 5 bodov (28,0% úspešnosť).

V úspešnom riešení autori netestovali veľké spoluhlásky, čo by v iných programovacích prostrediach bolo nekompletné riešenie. Zauímavosťou je, že program Imagine Logo síce rozlišuje kódy znakov, ale nerozlišuje "príbuzné" znaky, napr. znaky l, ĺ, ľ, L, Ĺ, Ľ. Jedinou výhodou tohto nerozlišovania je používanie príkazov s diakritkou aj bez nej, napr. vľavo a vlavo.

V jednom započatom a nekompletnom riešení sme ocenili slovný popis postupu riešenia úlohy.