Autor: Dondu
W wrześniu 2013r. zorganizowaliśmy zawody w programowaniu wirtualnego robota. Wykorzystaliśmy darmową wersję bardzo fajnego i darmowego do użytku domowego programu RoboMind.
Zasady, zadanie oraz trasę do pokonania podaliśmy w zawiadomieniu o zawodach.
Wystartowało 12 uczestników. Poniżej przedstawiamy Zwycięski program oraz pozostałe.
Trasa wyglądała tak:
a należało przenieść przedmiot z punktu A do B, poruszając się po białej i czarnej trasie. Dodatkowym zadaniem było zamalować na biało trasę czarną .
Dla przypomnienia kryteria zostały określone następująco:
Oceniane są według kolejności:
- poprawne wykonanie zadania,
- samodzielność programu w podejmowaniu decyzji na podstawie obserwacji otoczenia przez robota,
- najkrótszy program,
- używanie procedur (funkcji),
- "poprawność programistyczna".
Nie poprawialiśmy składni programów, bo było to zadaniem autorów, dlatego też niektóre z poniższych programów, miałyby znacznie mniej linii, gdyby zostały sformatowane jak program Szymona Kempnego.
Michał Wójcik - Zwycięzca!
Zwycięski program, to jego dzieło. Zawiera 38 linii programu - właściwie nie ma czego komentować :)
Wystarczy popatrzeć i zrozumieć:
powtórz { jeżeli(zPrzoduCzarne){ malujBiały naprzód(1) } wPrzeciwnymRazie jeżeli(lewoCzarne){ malujBiały wLewo naprzód(1) } wPrzeciwnymRazie jeżeli(prawoCzarne){ malujBiały wPrawo naprzód(1) } wPrzeciwnymRazie jeżeli(lewoBiałe){ wLewo naprzód(1) } wPrzeciwnymRazie jeżeli(zPrzoduBiałe){ naprzód(1) } wPrzeciwnymRazie jeżeli(prawoBiałe){ wPrawo naprzód(1) } wPrzeciwnymRazie jeżeli(zPrzoduNadajnik){ podnieś wPrawo przestańMalować } wPrzeciwnymRazie jeżeli(zPrzoduPrzeszkoda){ wstecz(1) odłóż zakończ } }
Wynik pracy jego programu wraz ze statystykami:
Szymon Kempny
Powinien był wygrać, ale ... robot po zjechaniu z czarnej trasy jako jedyny pojechał z powrotem na start i stamtąd dopiero na metę. Uznaliśmy więc, że nie możemy go nagrodzić a szkoda, ponieważ zwierał jedynie 33 linie programu (po usunięciu komentarzy) i ładnie używał funkcji (procedur).
szukajDrogi() procedura szukajDrogi() { #Jeździj dopóki nie natrafisz na czarną drogę powtórzDopóki(nie(lewoCzarne) i nie(prawoCzarne)) { jedź() } #Znalazłeś czarną drogę - po krórej stronie? jeżeli(lewoCzarne) { wLewo() } jeżeli(prawoCzarne) { wPrawo() } szukajSkarbu() } procedura jedź() { #Jeździj po białym polu, wrazie czego skręć jeżeli(zPrzoduBiałe() lub zPrzoduCzarne()) { naprzód(1) } wPrzeciwnymRazie jeżeli(prawoBiałe() lub prawoCzarne()) { wPrawo() } wPrzeciwnymRazie jeżeli(lewoBiałe() lub lewoCzarne()) { wLewo() } wPrzeciwnymRazie { #Jeśli trafisz w ślepy zaułek - zawróć powtórz(2) { wLewo() } } } procedura szukajSkarbu() { powtórzDopóki(nie(zPrzoduPrzeszkoda)) { jeżeli(zPrzoduCzarne()) { naprzód(1) } wPrzeciwnymRazie jeżeli(prawoCzarne()) { wPrawo() } wPrzeciwnymRazie jeżeli(lewoCzarne()) { wLewo() } } #Nasz skarb? Mega! Podnieś go i szukaj mety. Nie zapomnij przestać malować podnieś() malujBiały() #Zamaluj drogę, żeby nikt jej nie znalazł szukajMety() } procedura szukajMety() { #Jeśli trafisz na miejsce z przeszkodami dookoła - jesteś na mecie powtórzDopóki(nie(zPrzoduPrzeszkoda) | nie(PrawoPrzeszkoda) | nie(lewoPrzeszkoda)) { #Poprawia bug gdzie przejeżdża na skróty jeżeli(zPrzoduCzarne() i lewoCzarne()) { wLewo() } jedź() } #Zrób miejsce na skarb i go odstaw wstecz(1) odłóż() }
Dlatego też jego statystyka ucierpiała mocno w zakresie pokonanej trasy oraz rozglądania się robota:
Michał Sobolewski
Poprawnie napisany program zajmujący 53 linie:
procedure moveWhite() { if(frontIsWhite & leftIsWhite) { left forward(1) } else if(leftIsWhite & ~frontIsWhite) { left forward(1) } else if(frontIsWhite) { forward(1) } else if(rightIsWhite) { right } } procedure moveBlack() { if(frontIsBlack) { forward(1) } else if(leftIsBlack & ~frontIsBlack) { left } else if(rightIsBlack & ~frontIsBlack) { right } } repeat() { if(leftIsBlack | rightIsBlack | frontIsBlack) { left forward(1) paintWhite repeatWhile(~rightIsBeacon & ~frontIsBeacon & ~leftIsBeacon) { moveBlack } stopPainting pickUp right repeat() { if(frontIsObstacle & leftIsObstacle & rightIsObstacle) { backward(1) putDown end } else { moveWhite } } } else { moveWhite } }
... i jego statystyki:
Anna Maria Rafał
Jedyna niewiasta broniąca honoru żeńskiej części programistów, za co należą się wielkie brawa! Program równorzędny pod względem ilości linii (55 po usunięciu komentarzy) z Patrykiem Jastrzębskim (patrz kolejny zawodnik), ale statystyki znacznie od niego lepsze:
powtórz{ jeżeli(lewoCzarne()){ sledzCzarne() } wPrzeciwnymRazie{ sledzBiale() } } procedura obrot{ wPrawo wPrawo } procedura odlozenie{ obrot naprzód(1) obrot odłóż } procedura sledzBiale(){ jeżeli(lewoBiałe){ wLewo naprzód(1) } wPrzeciwnymRazie jeżeli(prawoBiałe i nie zPrzoduBiałe){ wPrawo naprzód(1) } wPrzeciwnymRazie jeżeli(zPrzoduBiałe){ naprzód(1) } wPrzeciwnymRazie jeżeli(zPrzoduPrzeszkoda){ odlozenie zakończ } } procedura sledzCzarne(){ jeżeli(zPrzoduCzarne){ naprzód(1) malujBiały sledzCzarne() } wPrzeciwnymRazie jeżeli(prawoCzarne){ wPrawo sledzCzarne() } wPrzeciwnymRazie jeżeli(lewoCzarne){ wLewo sledzCzarne() } wPrzeciwnymRazie jeżeli(zPrzoduNadajnik){ podnieś obrot przestańMalować } }
... i wynik pracy programu:
Patryk Jastrzębski
Patryk napisał program program równorzędny pod względem ilości linii (55) z Anną, ale jego działanie nie jest tak dobra jak Anny. Duży plus za komentarz!:
#Autor: Patryk Jastrzębski #E-mail: sirsmark@wp.pl #Program wykorzystuje ogólnikową koncepcje algorytmów mrówkowych. #Priorytetem do pokonywania drogi jest trasa czarnego koloru (zupełnie jak feromony u mrówek) #Drugorzędną sprawą jest trasa biała. Program zakończy się gdy odniesie na miejsce "radar". #Procedury: #---------------------------------------- procedura ruchBialy() { #procedura realizuje ruch po białej trasie jeżeli(lewoBiałe) { wLewo naprzód(1) } wPrzeciwnymRazie jeżeli(zPrzoduBiałe) { naprzód(1) } wPrzeciwnymRazie jeżeli(prawoBiałe) { wPrawo naprzód(1) } } #---------------------------------------- procedura ruchCzarny() { #procedura realizuje ruch po czarnej trasie (priorytetowej) jeżeli(zPrzoduCzarne) { naprzód(1) } wPrzeciwnymRazie jeżeli(prawoCzarne) { wPrawo naprzód(1) } wPrzeciwnymRazie jeżeli(lewoCzarne) { wLewo naprzód(1) } } #---------------------------------------- #Główna pętla programu: #---------------------------------------- powtórz{ #kolejność ma znaczenie, czarna trasa jest priorytetowa! jeżeli(zPrzoduCzarne | lewoCzarne | prawoCzarne) { malujBiały() ruchCzarny() } wPrzeciwnymRazie jeżeli(zPrzoduBiałe | lewoBiałe | prawoBiałe) { przestańMalować() ruchBialy() } wPrzeciwnymRazie { jeżeli(zPrzoduNadajnik) { podnieś() } jeżeli (zPrzoduPrzeszkoda) { północ(1) południe(0) odłóż() zakończ } wPrzeciwnymRazie { północ(0) } } }
.. wynik:
Paweł Matyszok
Całkiem fajnie napisany program:
procedure followBlackTrack() { repeatWhile(not (frontIsBeacon() or frontIsWhite())) { if(rightIsBlack() and not frontIsBlack()) { right() } else if (leftIsBlack()) { if (frontIsBlack()) { left() if (not leftIsWhite()) { right() } } else { left() } } forward(1) } } procedure doBlackTrack() { followBlackTrack() pickUp() left() left() paintWhite() followBlackTrack() stopPainting() } repeatWhile(not frontIsObstacle()) { repeat() { if (leftIsBlack()) { left() doBlackTrack() } if (leftIsWhite() and not frontIsWhite()) { left() } else if(rightIsWhite() and not frontIsWhite()) { right() } if(frontIsObstacle()) { break } forward(1) } } backward(1) putDown()
... i wynik:
Michał Telesz
Także przyzwoicie i czytelnie:
powtórz { jeżeli(zPrzoduBiałe i nie(lewoCzarne) i nie(prawoCzarne)) { naprzód(1) } wPrzeciwnymRazie jeżeli(lewoCzarne lub prawoCzarne) { poszukuj() } wPrzeciwnymRazie jeżeli(lewoBiałe) { wLewo } wPrzeciwnymRazie jeżeli(prawoBiałe) { wPrawo } wPrzeciwnymRazie jeżeli(zPrzoduPrzeszkoda) { wstecz(1) odłóż zakończ } } #Procedura wykonywana po spotkaniu czarnej linii. Poszukiwania przesyłki procedura poszukuj() { powtórz { jeżeli(zPrzoduNadajnik) { podnieś wróćIMaluj() przerwij } jeżeli(zPrzoduCzarne) { naprzód(1) } wPrzeciwnymRazie jeżeli(prawoCzarne) { wPrawo } wPrzeciwnymRazie jeżeli(lewoCzarne) { wLewo } } } #Przesyłka znaleziona. Wracamy i zamalowujemy procedura wróćIMaluj() { wLewo wLewo malujBiały powtórz{ jeżeli(zPrzoduBiałe) { przestańMalować przerwij } jeżeli(zPrzoduCzarne i nie(lewoCzarne) i nie(prawoCzarne)) { naprzód(1) } wPrzeciwnymRazie jeżeli(prawoCzarne) { wPrawo jeżeli(lewoCzarne) { naprzód(1) } } wPrzeciwnymRazie jeżeli(lewoCzarne) { wLewo jeżeli(prawoCzarne) { naprzód(1) } } } }
... i wynik:
Konrad Laskowski
Konrad jako jeden z dwóch zawodników, zauważył, że nie trzeba dojeżdżać do końca, by stwierdzić, że należy postawić przedmiot :-)
Niestety program, który nadesłał, przyszedł w takiej formie jak poniżej, a szkoda, bo może miałby szansę być wysoko :)
powtórzDopóki(nie lewoCzarne ){ jeżeli(zPrzoduBiałe ){ naprzód(1) }wPrzeciwnymRazie{ jeżeli(lewoBiałe ){ wLewo }wPrzeciwnymRazie{ wPrawo } } } powtórzDopóki(nie zPrzoduNadajnik ){ jeżeli(zPrzoduCzarne ){ naprzód(1) }wPrzeciwnymRazie{ jeżeli(prawoCzarne ){ wPrawo }wPrzeciwnymRazie{wLewo } } } jeżeli(zPrzoduNadajnik ){podnieś wPrawo} powtórzDopóki(nie zPrzoduBiałe ){ malujBiały jeżeli(zPrzoduCzarne i nie lewoCzarne ){ naprzód(1) }wPrzeciwnymRazie{ jeżeli(prawoCzarne ){ wPrawo }wPrzeciwnymRazie{ wLewo } } } jeżeli(zPrzoduBiałe){ naprzód(1) } jeżeli(zPrzoduBiałe){ przestańMalować } powtórzDopóki(nie lewoPrzeszkoda lub nie PrawoPrzeszkoda ){ jeżeli(zPrzoduBiałe ){ naprzód(1) }wPrzeciwnymRazie{ jeżeli(lewoBiałe ){ wLewo }wPrzeciwnymRazie{ wPrawo } } } jeżeli(lewoPrzeszkoda lub PrawoPrzeszkoda lub zPrzoduBiałe) { odłóż } zakończ
... i jego wynik:
Patryk Basiak
Patryk także zauważył, że do końca trasy nie trzeba dojeżdżać.
SzukajCzarnejŚcieżki() SzukajPrzedmiotu() ZanieśPrzedmiot() zakończ procedura IdźJeżeliWidziszCzarne(){ jeżeli(zPrzoduCzarne){ naprzód(1) IdźJeżeliWidziszCzarne() } wPrzeciwnymRazie jeżeli(lewoCzarne){ wLewo() naprzód(1) IdźJeżeliWidziszCzarne() } wPrzeciwnymRazie jeżeli(prawoCzarne){ wPrawo() naprzód(1) IdźJeżeliWidziszCzarne() } } procedura IdźJeżeliWidziszBiałe(){ jeżeli(lewoBiałe){ wLewo() naprzód(1) } wPrzeciwnymRazie jeżeli(zPrzoduBiałe){ naprzód(1) } wPrzeciwnymRazie jeżeli(prawoBiałe){ wPrawo() naprzód(1) } } procedura WeźPrzedmiotJeżeliGoWidzisz(){ jeżeli(zPrzoduNadajnik){ podnieś() wLewo() wLewo() } wPrzeciwnymRazie jeżeli(lewoNadajnik){ wLewo() podnieś() wLewo() } wPrzeciwnymRazie jeżeli(prawoNadajnik){ wPrawo() podnieś() wPrawo() } } procedura SzukajCzarnejŚcieżki(){ powtórzDopóki(nie lewoCzarne & nie prawoCzarne & nie zPrzoduCzarne){ IdźJeżeliWidziszBiałe() } } procedura SzukajPrzedmiotu(){ malujBiały() IdźJeżeliWidziszCzarne() WeźPrzedmiotJeżeliGoWidzisz() przestańMalować() } procedura ZanieśPrzedmiot(){ powtórzDopóki(nie lewoPrzeszkoda | nie PrawoPrzeszkoda){ IdźJeżeliWidziszBiałe() } odłóż() }
... wynik:
Maciej Gad
Maciej niestety poległ podczas powrotu z czarnej trasy na pętli, którą przejechał na wprost:
procedura krokBiałąDrogą(){ jeżeli(zPrzoduBiałe()){ naprzód(1) } wPrzeciwnymRazie{ jeżeli(prawoBiałe()){ wPrawo() naprzód(1) } wPrzeciwnymRazie{ jeżeli(lewoBiałe()){ wLewo() naprzód(1) } wPrzeciwnymRazie { wPrawo() krokBiałąDrogą() } } } } procedura krokCzarnąDrogą(){ jeżeli(zPrzoduCzarne()){ naprzód(1) } wPrzeciwnymRazie{ jeżeli(lewoCzarne()){ wLewo() naprzód(1) } wPrzeciwnymRazie{ jeżeli(prawoCzarne()){ wPrawo() naprzód(1) } } } } procedura jedźBiałąDrogą(){ krokBiałąDrogą() powtórz(){ jeżeli(lewoPrzeszkoda() i PrawoPrzeszkoda() i zPrzoduPrzeszkoda()){ wstecz(1) odłóż() zakończ } jeżeli((nie lewoCzarne()) i (nie prawoCzarne()) i (nie zPrzoduCzarne())){ krokBiałąDrogą() } wPrzeciwnymRazie { przerwij } } } procedura podoszenie(){ podnieś() przestańMalować() } procedura jedźCzarąDrogąDoNadajnika(){ krokCzarnąDrogą() krokCzarnąDrogą() malujBiały() powtórz(){ jeżeli(zPrzoduNadajnik()){ podoszenie() przerwij } wPrzeciwnymRazie { jeżeli(lewoNadajnik()){ wLewo() podoszenie() przerwij } wPrzeciwnymRazie { jeżeli(prawoNadajnik()){ wPrawo() podoszenie() przerwij } } } krokCzarnąDrogą() } } procedura drogaNaZachód(){ malujBiały() naprzód(1) przestańMalować() naprzód(1) zachód(1) } jedźBiałąDrogą() jedźCzarąDrogąDoNadajnika() jedźBiałąDrogą() drogaNaZachód() jedźBiałąDrogą()
... wynik:
Marcin Smałz
Marcin za bardzo rozbił program na funkcje, co w realnych projektach jest często pożądaną cechą, ale niepotrzebnie utworzył np. procedurę jedźProsto(), która wykonuje tylko jedną czynność:
procedura ruchWLewo() { wLewo naprzód(1) } procedura ruchWPrawo() { wPrawo naprzód(1) } procedura jedźProsto() { naprzód(1) } procedura szukajSzarego() { jeżeli(lewoCzarne) { ruchWLewo() malujSzare() } wPrzeciwnymRazie { zwroć } } procedura malujSzare() { malujBiały powtórzDopóki(zPrzoduCzarne lub prawoCzarne lub lewoCzarne) { jeżeli (zPrzoduCzarne) { jedźProsto() } wPrzeciwnymRazie jeżeli (prawoCzarne) { ruchWPrawo() } wPrzeciwnymRazie { ruchWLewo() } } przestańMalować sprawdźŁadunek() } procedura sprawdźŁadunek { jeżeli(zPrzoduNadajnik) { podnieś wLewo wLewo } } procedura pokonajTrase { szukajSzarego() jeżeli(zPrzoduBiałe) { jeżeli(lewoBiałe){ ruchWLewo() } wPrzeciwnymRazie { jedźProsto() } } wPrzeciwnymRazie jeżeli(lewoBiałe) { ruchWLewo() } wPrzeciwnymRazie { ruchWPrawo() } jeżeli(zPrzoduPrzeszkoda i lewoPrzeszkoda i PrawoPrzeszkoda) { wstecz(1) odłóż zakończ } } powtórz{ pokonajTrase() }
... i wynik:
Wojciech Urban
Także przejrzyście i fajnie opisany, choć najdłuższy z przesłanych:
powtórz{ #pętla głowna programu sprawdź_kolor() sprawdź_nadajnik() odłóż_nadajnik() ruch() } procedura sprawdź_kolor() #procedura sprawdzająca czy w okolicy nie { #ma jakiegoś czarnego pola do zamalowanie powtórz() #zapętlona zeby od razu zamalowywac całą ścieżkę { jeżeli(zPrzoduCzarne) { naprzód(1) malujBiały() } wPrzeciwnymRazie jeżeli(prawoCzarne) { wPrawo() naprzód(1) malujBiały() } wPrzeciwnymRazie jeżeli(lewoCzarne) { wLewo() naprzód(1) malujBiały() } wPrzeciwnymRazie { przestańMalować() # zakończenie pętli gdy z zadnej przerwij # strony nie ma nic czarnego } } } procedura sprawdź_nadajnik() #procedura szukania nadajnika, w razie co { #podniesie go z kazdej strony, chyba jeżeli(zPrzoduNadajnik) #że, znajdował sie z miejsca z którego { #robot nadjechał(z tyłu) podnieś() } wPrzeciwnymRazie jeżeli(lewoNadajnik) { wLewo() podnieś() wPrawo() } wPrzeciwnymRazie jeżeli(prawoNadajnik) { wPrawo() podnieś() wLewo() } } procedura odłóż_nadajnik() #procedura odkładajaca nadajnik w miejscu { # z trzech stron otoczonym przeszkodą jeżeli(zPrzoduPrzeszkoda i lewoPrzeszkoda i PrawoPrzeszkoda) { # jedynym takim miejscem na białej ścieżce wstecz(1) # jest zadany punkt B odłóż() jeżeli(zPrzoduNadajnik) # warunek zabezpieczający robota przed { # zakonczoniem pracy przed odniesieniem nadajnika zakończ } wPrzeciwnymRazie # jeżeli robot nie oodłóżył nadajnika bo go nie miał { # to po prostu zawróci wPrawo wPrawo } } } procedura ruch() { jeżeli(lewoBiałe) { wLewo() naprzód(1) } wPrzeciwnymRazie jeżeli (zPrzoduBiałe) { naprzód(1) } wPrzeciwnymRazie jeżeli (prawoBiałe) { wPrawo() naprzód(1) } wPrzeciwnymRazie { wPrawo() wPrawo() } }
... wynik:
Komentarze - dyskusja
Zapraszam do dyskusji o zawodach jak i algorytmach zaprezentowanych przez poszczególnych zawodników. Są one bardzo różne, i mają zalety choć nie zawsze zgodne z oczekiwaniami określonymi w regulaminie zawodów, to jednak w realnych warunkach często stosowane.
Na pewno w kolejnym konkursie jeszcze dokładniej określimy wytyczne, by nie było wątpliwości. Co jeszcze mamy zmienić?
Przegapiłem fajną imprezę. Kiedy planujecie kolejne zawody?
OdpowiedzUsuńJeśli będzie zainteresowanie, to możemy pomyśleć nad kolejnymi :-)
UsuńEh, szkoda że o tym nie wiedziałem...
UsuńCzekam na następne zawody :)
Nie miałem pojęcia, że taki fajny program istnieje! Także proszę o zrobienie jeszcze jednych zawodów, ale najwcześniej za tydzień, bo chciałbym się przygotować.
OdpowiedzUsuńDla zwyciężcy wielkie brawa za pomysł i wykonanie, natomiast mógłby jeszcze kod skrócić o 2 linie:) Troszeczkę inne podejście zastosowałem od początku i to mnie zgubiło w ilości procedur.
OdpowiedzUsuńTa przerwa pomiędzy czarną a białą linią mogła być zamalowana?
OdpowiedzUsuńOgólnie trochę szkoda że nie wysłałem swojego rozwiązania, raz że zamalowałem tą przerwę ,
dwa myślałem że ogólnie moje rozwiązanie jest za słabe. Teraz widzę że chyba nie było aż tak źle, no i mój kod ma 24 linijki :) Ale mówi się trudno i na przyszłość nie ma się co tak wstydzić.
http://zapodaj.net/eba83fa7ccaec.jpg.html
Nie było jasno sprecyzowane, czy może być zamalowana, czy też nie, stąd nie braliśmy tego pod uwagę.
UsuńNaprawdę nie ma czego się wstydzić, każdy z nas kiedyś zaczynał i także pisał "straszne" programy. Ja nie byłem wyjątkiem, a i teraz czasami łapię się za głowę jak patrzę na swój program po jakimś czasie :-)
Wklej proszę swój program w komentarzu. Dorzucimy go poza konkursem.
Proszę bardzo:
Usuńprocedura p(){
jeżeli(lewoBiałe lub lewoCzarne)
{wLewo
naprzód(1)
}
wPrzeciwnymRazie jeżeli(zPrzoduBiałe lub zPrzoduCzarne)
{naprzód(1)
}wPrzeciwnymRazie jeżeli(prawoBiałe lub prawoCzarne)
{
wPrawo
naprzód(1)
}wPrzeciwnymRazie{
wstecz(1)
odłóż
zakończ
}
}
powtórz{p
jeżeli(zPrzoduNadajnik){podnieś
wPrawo
wPrawo
malujBiały
}
}
Niestety, ale Twój algorytm popełnia błąd na pętli na czarnym fragmencie trasy, jadąc po przedmiot. W tym samym miejscu co program Macieja skraca sobie drogę z tym że w odwrotnym kierunku. Zaznaczyłem, to na grafice Maciej.
UsuńNo tak za bardzo skupiłem się na tym żeby przeniósł przedmiot i zamalował czarną linię ale teraz doczytałem że "poruszając się po białej i czarnej trasie". Przepraszam mój błąd.
UsuńMam nadzieję że zorganizujecie jeszcze takie zawody bo to fajne wyzwanie i każdy może spróbować nawet jeżeli nie ma dużego doświadczenia w programowaniu.
Nie masz za co przepraszać :-)
UsuńJeżeli będzie zainteresowanie, to zorganizujemy.