Skúška 2.2.2023 - Separovaný zber¶
V malom mestečku v niektorých domoch separujú odpad. Pracovník komunálnych služieb raz začas so svojim autom obchádza uličky mesta a do auta zbiera vyložené balíky plastových vriec a v príslušných zberných dvoroch ich potom opäť vykladá. Každý zberný dvor zbiera len odpad určitého typu (napríklad, len sklo, alebo len papier, alebo len plasty, …) a preto tu auto vyloží len všetky príslušné balíky. Lenže auto nemá neobmedzenú kapacitu, takže, keď už je plné, aj keď na ceste prejde okolo pripraveného balíka, nenaloží ho, ale ide ď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 SepearovanyZber
:
class SepearovanyZber:
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 auta1
;metóda
zisti()
: vráti 2 hodnoty (dvojicu): znakový reťazec s písmenami práve naložených balíkov na aute (nezáleží na poradí) a množinu políčok s balíkmi, ktoré sa nachádzajú v ploche a ešte sa 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 balík (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 zberný dvor (písmeno od'A'
po'Z'
) a na aute má príslušné balíky, tak zo zoznamu balíkov na aute ich odstráni (písmeno zberného dvora v ploche ponechá); ak sa tento príkaz vykonať nedá (políčko je mimo plochy alebo obsahuje'#'
), 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 počet naozaj vykonaných krokov auta.
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 cestouznak
'#'
nepriechodné políčko
za popisom hracej plochy je v súbore jeden prázdny riadok;
nasledujúce riadky obsahujú popis objektov v hracej ploche:
znak
'@'
počiatočná poloha auta s dvojicou celých čísel pre riadok a stĺpecznak
'a'
až'z'
priechodné políčko s balíkom – rovnakých balíkov v ploche môže byť aj viac - za týmto znakom nasleduje aspoň jedna dvojica celých čísel pre riadok a stĺpecznak
'A'
až'Z'
priechodné políčko so zberným dvorom pre zodpovedajúci typ balíkov (pre príslušné malé písmeno) – zberných dvorov s rovnakým písmenom môže byť aj viac - za týmto znakom nasleduje aspoň jedna dvojica celých čísel pre riadok a stĺpec
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 typov balíkov a auto ich zrejme všetky bude prevážať do zberného dvora s rovnakým veľkým písmenom (hoci aj dvorov s týmto písmenom môže byť aj viac). Zrejme závisí od kapacity auta, koľko balíkov sa odvezie naraz. Ak auto vezie viac rovnakých balíkov a príde k príslušnému dvoru, naraz ich všetky vyloží.
Napríklad, takéto zadanie hracej plochy a polohy auta a ďalších objektov (súbor subor2.txt
):
---------
-###-#-#-
-----#---
-###-#-#-
-------#-
a 0 6 1 0
b 2 8
A 4 8
B 4 0
@ 2 4
reprezentuje takúto plochu:

Potom tento test:
if __name__ == '__main__':
p = SepearovanyZber('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', 0, 6), ('a', 1, 0), ('b', 2, 8)})
9
---------
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:
# 5. skuska: separovany zber
# autor: Janko Hraško
# datum: 2.2.2023