Autorské riešenie
[stiahni [imp][py]]

  • Počet riešiteľov: 7 / 7 = 100,0 %

  • Úspešnosť riešenia:  6,7 / 8 = 83,9 %

Našou úlohou je určiť v akom stave bude kocka (jej horná stena) po zadanej postupnosti prevalení z počiatočného stavu. Najprv sa pozrime, ako sa zmení jej stav po jednom prevalení z počiatočného stavu.

prevalenia kocky v styroch smeroch

Aby sme vedeli popísať zmenu stavu kocky po každom prevaleni je vhodné si označiť jej stav ako šesticu s hodnotami počtu bodov na jednotlivých stenách v určitom poradí, napr. (horná, predná, pravá, ľavá, zadná, dolná).

Po prevalení dopredu sa zmení stav kocky na: (predná, dolná, pravá, ľavá, horná, zadná)

Po prevalení vzad sa zmení stav kocky na: (zadná, horná, pravá, ľavá, dolná, predná)

Po prevalení vľavo sa zmení stav kocky na: (pravá, predná, dolná, horná, zadná, ľavá)

Po prevalení vpravo sa zmení stav kocky na: (ľavá, predná, horná, dolná, zadná, pravá)

Ak si šesticu hodnôt predstavujúcu stav kocky uložíme do premennej kocka typu zoznam (s prvkami kocka[0] až kocka[5] v jazyku Python), po jej prevalení v jednotlivých smeroch sa jej stav z aktuálneho stavu zmení nasledovne:

Po prevalení dopredu: [kocka[1], kocka[5], kocka[2], kocka[3], kocka[0], kocka[4]]

Po prevalení vzad: [kocka[4], kocka[0], kocka[2], kocka[3], kocka[5], kocka[1]]

Po prevalení vľavo: [kocka[2], kocka[1], kocka[5], kocka[0], kocka[4], kocka[3]]

Po prevalení vpravo: [kocka[3], kocka[1], kocka[0], kocka[5], kocka[4], kocka[2]]

Vytvoríme funkcia tah, ktorá pre aktuálny stav kocky uložený v parametri kocka a zadaný smer prevalenia uložený v parametri smer vypočíta jej nový stav. Funkcia tah uvedená v jazyku Python môže vyzerať nasledovne:

def tah(kocka, smer):
    """ Vrati upraveny zoznam kocka podla smeru zadaneho prevalenia
    :param kocka: 6-prvkovy zoznam kocka s ciselnymi hodnotami pred zadanym prevalenim kocky
    :type  kocka: list
    :param smer: jedna zo 4 hodnot prevalenia kocky {'d', 'v', 'l', 'p'}
    :type  smer: str
    :rtype: list
    """
    if smer == 'd':  # dopredu
        return [kocka[1], kocka[5], kocka[2], kocka[3], kocka[0], kocka[4]]
    elif smer == 'v':  # vzad
        return [kocka[4], kocka[0], kocka[2], kocka[3], kocka[5], kocka[1]]
    elif smer == 'l':  # vlavo
        return [kocka[2], kocka[1], kocka[5], kocka[0], kocka[4], kocka[3]]
    elif smer == 'p':  # vpravo
        return [kocka[3], kocka[1], kocka[0], kocka[5], kocka[4], kocka[2]]

Napokon vytvoríme funkciu tahy, ktorá pre zadaný počiatočný stav kocky uložený v parametri kocka a zadanú postupnosť prevalení uoženú v parametri smery vypočíta aktuálny stav kocky a vypíše jeho nultý prvok kocka[0], čo je hodnota zobrazená na hornej stene kocky. Funkcia tahy uvedená v jazyku Python môže vyzerať nasledovne:

def tahy(kocka, smery):
    """ Vrati nultu poziciu zoznamu kocka po prevaleniach uvedenych v zozname smery
    :param kocka: 6-prvkovy zoznam kocka s pociatocnymi ciselnymi hodnotami
    :type  kocka: list
    :param smery: zoznam smerov prevalovania kocky
    :type  smery: list
    :rtype: int
    """
    for smer in smery:
        kocka = tah(kocka, smer)
    return kocka[0]

Kompletný zápis algoritmu riešenia úlohy zapísaný v jazyku Python môže vyzerať nasledovne:

def tah(kocka, smer):
    """ Vrati upraveny zoznam kocka podla smeru zadaneho prevalenia
    :param kocka: 6-prvkovy zoznam kocka s ciselnymi hodnotami pred zadanym prevalenim kocky
    :type  kocka: list
    :param smer: jedna zo 4 hodnot prevalenia kocky {'d', 'v', 'l', 'p'}
    :type  smer: str
    :rtype: list
    """
    if smer == 'd':  # dopredu
        return [kocka[1], kocka[5], kocka[2], kocka[3], kocka[0], kocka[4]]
    elif smer == 'v':  # vzad
        return [kocka[4], kocka[0], kocka[2], kocka[3], kocka[5], kocka[1]]
    elif smer == 'l':  # vlavo
        return [kocka[2], kocka[1], kocka[5], kocka[0], kocka[4], kocka[3]]
    elif smer == 'p':  # vpravo
        return [kocka[3], kocka[1], kocka[0], kocka[5], kocka[4], kocka[2]]


def tahy(kocka, smery):
    """ Vrati nultu poziciu zoznamu kocka po prevaleniach uvedenych v zozname smery
    :param kocka: 6-prvkovy zoznam kocka s pociatocnymi ciselnymi hodnotami
    :type  kocka: list
    :param smery: zoznam smerov prevalovania kocky
    :type  smery: list
    :rtype: int
    """
    for smer in smery:
        kocka = tah(kocka, smer)
    return kocka[0]


print(tahy([0, 1, 2, 3, 4, 5], ['d', 'p', 'v', 'l']))
print(tahy([0, 1, 2, 3, 4, 5], ['l', 'd', 'p', 'v']))
print(tahy([0, 1, 2, 3, 4, 5], ['p', 'd', 'l', 'v']))
print(tahy([0, 1, 2, 3, 4, 5], ['v', 'p', 'd', 'l']))

Zápis algoritmu riešenia úlohy uvedený v jazyku Imagine Logo sa líši od zápisu v jazyku Python len v posune indexov v premennej kocka na: kocka[1] až kocka[6], keďže v Imagine Logu sa indexuje od 1 a v Pythone od 0. Kompletný zápis riešenia úlohy v Imagine Logo môže vyzerať nasledovne:

 ;Imagine Logo
viem tah :kocka :smer ; Vráti upravený zoznam :kocka podľa smeru zadaneho prevalenia :smer akJe :smer [ d [ urobTu "kocka_nova (zoznam prvok 2 :kocka prvok 6 :kocka prvok 3 :kocka prvok 4 :kocka prvok 1 :kocka prvok 5 :kocka) ] v [ urobTu "kocka_nova (zoznam prvok 5 :kocka prvok 1 :kocka prvok 3 :kocka prvok 4 :kocka prvok 6 :kocka prvok 2 :kocka) ] l [ urobTu "kocka_nova (zoznam prvok 3 :kocka prvok 2 :kocka prvok 6 :kocka prvok 1 :kocka prvok 5 :kocka prvok 4 :kocka) ] p [ urobTu "kocka_nova (zoznam prvok 4 :kocka prvok 2 :kocka prvok 1 :kocka prvok 6 :kocka prvok 5 :kocka prvok 3 :kocka) ] ] výsledok :kocka_nova koniec viem tahy :kocka :smery ; Vráti prvú pozíciu zoznamu :kocka po prevaleniach uvedenych v zozname :smery prePrvky "smer :smery [ urobTu "kocka tah :kocka :smer ] výsledok prvý :kocka koniec viem start píš tahy [0 1 2 3 4 5] [d p v l] píš tahy [0 1 2 3 4 5] [l d p v] píš tahy [0 1 2 3 4 5] [p d l v] píš tahy [0 1 2 3 4 5] [v p d l] koniec

Skutočnosť, že súčet počtov bodiek na protiľahlých stenách kocky je stále rovnaký, sme využili len v rozbore úlohy, nie v zápise algoritmu riešenia. Niektorí súťažiacich využili túto skutočnosť vo svojich riešeniach.

V programoch sme uviedli riešenia štyroch konkrétnych prípadov prevalenia kocky na pôvodné miesto na podložke. Je zaujímavé (možno aj prekvapivé), že sme dostali štyri rôzne výsledky. Pre ďalšie skúmanie si môžme položiť otázky, napr. "Existujú postupnosti prevalení kocky končiace na jej pôvodnom mieste na podložke, ktorých výsledkom sú postupne všetky hodnoty kocky? Ak áno, aké najkratšie sú tieto postupnosti?".

Táto súťažná úloha je zameraná na dôslednú analýzu problému, na použitie stratégie dekompozície riešenia problému do riešenia podproblémov, na precvičenie použitia procedúr, resp. funkcií s parametrami, príkazov vetvenia a opakovania a prácu s údajovým typom zoznam.

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

Do riešenia tejto úlohy sa zapojilo 7 tímov z kategórie EXPERT, z toho 3 tímy riešili úlohu v jazyku Python a 4 tímy v jazyku Imagine Logo. Plný počet bodov získali až 4 tímy, dva z nich (oravskalesna1 a seda eminencia) vyriešili úlohu pre ľubovoľne zadaný počiatočný stav kocky, čo bolo nad rámec zadania úlohy. Všetky riešenia boli originálne, v niektorých súťažiaci použili šesťprvkový, v iných dvoj-, troj,. či štvorprvkový zoznam, resp. 2, 3, či 4 premenné na zaznamenanie stavu kocky. 

V riešeniach sme zaregistrovali nasledovné nedostatky:

  • v troch súťažných riešeniach nebol dôsledne urobený rozbor úlohy, čoho dôsledkom bol rovnaký výsledok pre postupnosti prevalení [dopredu vpravo dozadu vľavo] a [vpravo dopredu vľavo dozadu], čo nie je správne,

  • použitie menej efektívnych konštrukcií príkazov vetvenia, napr. postupnosť 6 nevnorených príkazov IF, či vnorených IF-ELSE príkazov, čo sa dalo zapísať pomocou príkazu IF-ELIF-ELIF-...-ELSE, resp. AKJE v jazyku Imagine Logo,

  • v dvoch riešeniach namiesto vrátenia výsledku funkcie vypisovali výsledok.