Skúška 19.1.2023 - Pet detective


V malom mestečku v niektorých domoch chovajú domáce zvieratá. Jedného dňa dostal zvierací detektív informácie o tom, kde v meste videli stratené zvieratá a kam ich treba odviezť. Nasadol do svojho auta, obchádzal uličky mesta, zbieral do auta nájdené zvieratá a pri správnych domoch ich opäť vykladal. Lenže jeho auto nemalo neobmedzenú kapacitu, takže, keď už bolo plné, aj keď na ceste prešiel okolo strateného zvieraťa, nenaložil ho, ale išiel ďalej. Auto budeme riadiť šípkami ('l' pre vľavo, 'p' pre vpravo, 'h' pre hore, 'd' pre dolu), a keď sa v danom smere nebude môcť pohnúť, tak tento príkaz odignoruje.

Zadefinuj triedu PetDetective:

class PetDetective:
    def __init__(self, meno_suboru):
        ...

    def __repr__(self):
        ...

    def kapacita(self, kapa):
        ...

    def zisti(self):
        ...

    def krok(self, smer):
        ...

kde

  • metóda __init__(meno_suboru): prečíta súbor a vytvorí z neho dvojrozmernú hraciu plochu - táto nemusí mať rovnako dlhé riadky;

  • metóda __repr__(): vráti znakový reťazec, ktorý reprezentuje momentálny stav hracej plochy, pričom sa zobrazí aj poloha auta ako '*', medzi riadkami je znak '\n';

  • metóda kapacita(kapa): nastaví kapacitu auta, bez tohto nastavenia by bola kapacita auta 1;

  • metóda zisti(): vráti 2 hodnoty (dvojicu): znakový reťazec s písmenami momentálne naložených zvierat na aute (nezáleží na poradí) a množinu políčok so zvieratami, ktoré sa ešte nenakladali na auto (ako množinu trojíc (písmeno, riadok, stĺpec));

  • metóda krok(smer): pohne auto v jednom zo zadaných smerov ('l' pre vľavo, 'p' pre vpravo, 'h' pre hore, 'd' pre dolu) o jedno políčko, pričom, ak je na danom políčku zviera (písmeno od 'a' po 'z') a kapacita auta to ešte povoľuje, tak ho naloží a z políčka ho odstráni (v hracej ploche ho nahradí znakom '.'), ak je na danom políčku dom (písmeno od 'A' po 'Z') a na aute má príslušné zvieratá, tak zo zoznamu zvierat na aute ich odstráni (písmeno domu v ploche ponechá); ak sa tento príkaz vykonať nedá (políčko je mimo plochy alebo obsahuje medzeru), metóda ho odignoruje; parameter smer môže obsahovať aj celú postupnosť šípok, vtedy auto tieto šípky postupne vykoná, pričom niektoré z nich možno odignoruje (ak sú v smere nepriechodného políčka); metóda vráti 2 hodnoty (dvojicu): počet naozaj vykonaných krokov auta a znakový reťazec s písmenami naložených zvierat na aute (nezáleží na poradí).

Vstupný formát súboru:

  • na začiatku obsahuje popis hracej plochy ako dvojrozmernú tabuľku znakov (riadky nemusia mať rovnakú dĺžku)

  • znaky v tejto hracej ploche majú takýto význam:

    • znak '.' priechodné políčko s cestou

    • znak ' ' nepriechodné políčko

    • znak 'a''z' priechodné políčko so zvieraťom – rovnakých zvierat môže byť aj viac

    • znak 'A''Z' priechodné políčko s domom pre zodpovedajúce zviera (pre príslušné malé písmeno) – domov s rovnakým písmenom môže byť aj viac

  • za popisom hracej plochy je v súbore jeden prázdny riadok;

  • nasledujúci riadok obsahuje dvojicu celých čísel pre riadok a stĺpec políčka s autom;

  • môžeš predpokladať, že súbor je zadaný korektne.

Počítaj s tým, že v ploche sa môže nachádzať aj viac rovnakých zvierat a auto ich zrejme všetky bude prevážať do domu s rovnakým veľkým písmenom (hoci aj domov s týmto písmenom môže byť aj viac). Zrejme závisí od kapacity auta, koľko zvierat sa odvezie naraz. Ak auto vezie viac rovnakých zvierat a príde k príslušnému domu, naraz ich všetky vyloží.

Napríklad, takéto zadanie hracej plochy a polohy auta (súbor subor2.txt):

......a..
a   . . .
..... ..b
.   . . .
B...... A

2 4

reprezentuje takúto plochu:

../../_images/sk2023z3.png

Potom tento test:

if __name__ == '__main__':
    p = PetDetective('subor2.txt')
    #p.kapacita(2)
    print(p)
    print(p.zisti())
    print(p.krok('hhppppppddd'))
    print(p)
    print(p.zisti())
    print(p.krok('dhhlllllhhlllllldddd'))
    print(p)
    print(p.zisti())

vypíše:

......a..
a   . . .
....* ..b
.   . . .
B...... A
('', {('a', 1, 0), ('b', 2, 8), ('a', 0, 6)})
(9, 'a')
.........
a   . . .
..... ..b
.   . . *
B...... A
('a', {('a', 1, 0), ('b', 2, 8)})
(17, '')
.........
a   . . .
..... ...
.   . . .
*...... A
('', {('a', 1, 0)})

Uvedom si, že ak by bola nastavená kapacita auta na 2, tak druhý výpis print(p.zisti()) by vypísal ('a', set()).

Z úlohového servera L.I.S.T. si stiahni kostru programu skuska.py. Pozri si testovacie dáta v súboroch 'subor1.txt', …, ktoré bude používať testovač.

Aby si mohol spúšťať skúškové testy, program ulož do súboru skuska.py. Riešenie (bez dátových súborov) odovzdaj na úlohový server https://list.fmph.uniba.sk/. Tvoj odovzdaný program musí začínať tromi riadkami komentárov:

# 3. skuska: pet detective
# autor: Janko Hraško
# datum: 19.1.2023