Gra będzie się składać z dwóch aplikacji. Zadaniem użytkownika pierwszej z nich jest odpowiedzenie na proste pytanie, czy z trzech odcinków o podanych długościach (wylosowanych przez duszka) można zbudować trójkąt. Duszek powinien sprawdzić odpowiedź i wyświetlić odpowiedni komunikat.

W drugiej aplikacji duszek postawi przed użytkownikiem trudniejsze zadanie. Odcinków będzie więcej, trzeba odpowiedzieć na pytanie, czy z każdych trzech odcinków można zbudować trójkąt. Twoim zadaniem będzie oprogramować działania duszka, który sprawdza odpowiedź użytkownika. Działanie przykładowej aplikacji możesz obejrzeć na poniższym filmie.

RS4TBPErlNR45
Przedstawienie działania przykładowej aplikacji. Pojawiają się długości odcinków, a obok nich pytanie w dymku Czy z każdych trzech odcinków o podanych długościach można zbudować trójkąt?. Na górze znajdują się przyciski TakNie.

Aby wykonać to ćwiczenie, ważna jest znajomość podstaw obsługi środowiska Scratch oraz wiadomości z matematykiD18lmDeFHwiadomości z matematyki. Jeśli nie masz doświadczenia z tym językiem, zachęcamy do zapoznania się z materiałem Wprowadzenie do programu ScratchDUVRjOY3CWprowadzenie do programu Scratch.

Przydatna może się okazać również wiedza z materiałów Od problemu do algorytmuD10Ja0fSgOd problemu do algorytmu oraz Od algorytmu do programuD11xliCilOd algorytmu do programu.

W obu aplikacjach wykorzystywane jest jedno proste tło składające się z dwóch części (w różnych kolorach). W górnej części znajdują się duszki – przyciski, w dolnej duszek, który sprawdza i informuje o poprawności odpowiedzi.

Skorzystaj z poniższego notatnika do zapisania swoich uwag.

R78T3CLwaa5XF
Źródło: GroMar, licencja: CC BY 3.0.
Ćwiczenie 1

Przygotuj tło do aplikacji. Może być bardziej rozbudowane graficznie, według twojego pomysłu. Następnie załaduj je do nowego projektu w środowisku Scratch.

R5veDfBleKYdD
Ćwiczenie 1
Jak wczytać tło do projektu w programie Scratch? Zaznacz prawidłową odpowiedź.
Źródło: GroMar, licencja: CC BY 3.0.
Ćwiczenie 2

Przygotuj dwa duszki: przycisk Tak oraz przycisk Nie. Następnie załaduj je do wcześniej utworzonego projektu. Domyślnie niech przyciski będą ukryte. Utwórz także trzy zmienne do pamiętania długości odcinków.

RxzNWW9H9z7jO
Ćwiczenie 2
Możliwe odpowiedzi: 1. Należy przeciągnąć przygotowaną grafikę i upuścić nad otwartym oknem programu Scratch., 2. W prawym dolnym rogu należy wybrać opcję "Wczytaj tło", następnie wybrać plik z przygotowaną grafiką., 3. W lewym dolnym rogu należy wybrać opcję "Wczytaj tło", następnie wybrać plik z przygotowaną grafiką.
Źródło: GroMar, licencja: CC BY 3.0.

Przygotowujemy pierwszą aplikację

Ćwiczenie 3

Określ, jakie działania powinny być wykonane po uruchomieniu aplikacji, czyli kliknięciu w zieloną flagę, do momentu kiedy wymagana będzie akcja użytkownika. Przygotuj właściwy skrypt.

RzrLMNWjxpUjF
Ćwiczenie 3
Zadaniem duszka jest wylosowanie trzech długości boków trójkąta, a następnie zadanie użytkownikowi pytania, czy można zbudować z tych odcinków trójkąt. Ustaw w odpowiedniej kolejności polecenia takiego skryptu.
Źródło: GroMar, licencja: CC BY 3.0.

Należy zadbać o komunikację pomiędzy duszkami. Duszek odpowiedzialny za sprawdzenie odpowiedzi musi wiedzieć, w który przycisk kliknął użytkownik. W Scratchu do komunikacji pomiędzy duszkami można wykorzystać komunikaty. Więcej informacji o nadawaniu i odbieraniu komunikatów znajdziesz po kliknięciu w poniższą zakładkę.

1
Nadawanie i odbieranie komunikatów

Nadawanie i odbieranie komunikatów umożliwia porozumiewanie się pomiędzy duszkami, a także sceną. W ten sposób jeden duszek może uruchomić skrypty innych duszków lub sceny. Trzy bloczki związane z nadawaniem i odbieraniem komunikatów znajdują się w grupie Zdarzenia. Nowy komunikat można zdefiniować i nadać przy pomocy jednego z dwóch bloczków:

Nazwę nadawanego komunikatu można wybrać z listy rozwijalnej lub zdefiniować nowy komunikat przy pomocy opcji Nowa wiadomość dostępnej po rozwinięciu listy.

RkGimheCcEnbx
Blok nadaj komunikat… z kategorii Zdarzenia z rozwiniętą listą opcji
Źródło: GroMar, licencja: CC BY 3.0.

Wyświetlone będzie wówczas okno dialogowe, w którym należy podać nazwę nowego komunikatu.

R1AyakowBzaq4
Okno dialogowe w programie Scratch do tworzenia nowej wiadomości
Źródło: GroMar, licencja: CC BY 3.0.

Po nadaniu komunikatu (wykonaniu bloczka nadaj lub nadaj i czekaj) uruchamiane są automatycznie skrypty zaczynające się od bloczka kiedy otrzymam (nazwa komunikatu).

RUaJwRiriyACV
Blok Kiedy otrzymam… z kategorii Zdarzenia
Źródło: GroMar, licencja: CC BY 3.0.

Działanie skryptu, który nadał komunikat jest kontynuowane równolegle (blok nadaj) lub wstrzymane do czasu zakończenia działania wszystkich skryptów odbierających ten komunikat (blok nadaj i czekaj).
Przykład:

Rf9K11qXukSUV
Przykładowe skrypty z nadawaniem i odbieraniem komunikatu
Źródło: GroMar, licencja: CC BY 3.0.
R1FJ8Lrao1C5L
Działanie skryptu łapania myszy
Źródło: GroMar, licencja: CC BY 3.0.
Ćwiczenie 4

Przygotuj skrypty dla przycisków, które będą nadawały odpowiednie komunikaty.

Ćwiczenie 5

Przygotuj skrypty dla duszka sprawdzającego odpowiedź, reagujące na otrzymanie komunikatów taknie. Zawrzyj w nich komunikat dla duszków - przycisków, informujący o zakończeniu sprawdzania (przyciski należy ukryć).

Ćwiczenie 6

Przygotuj skrypty pokazujące przyciski na początku głównego programu oraz skrypty ukrywające przyciski po otrzymaniu komunikatu koniec.

Projektujemy drugą aplikację

Do stworzenia drugiej aplikacji powinieneś posiadać wiedzę z poniższych zagadnień:

  1. Tworzenie i wykorzystywanie (np. zamienianie elementów miejscami) list w środowisku Scratch. Informacje na ten temat możesz znaleźć w rozwijanej liście, która znajduje się poniżej.

    1
    Listy

    Często zachodzi potrzeba przechowania większej liczby danych. Niewygodne staje się wówczas pamiętanie ich w pojedynczych zmiennych, szczególnie gdy pełnią podobną rolę. Lepiej pamiętać je pod jedną nazwą, a wszystkie dane ponumerować zaczynając od 1. Dostęp do pojedynczego elementu możliwy jest wtedy za pośrednictwem indeksu (numeru elementu). W Scratchu służą do tego listy.

    Przykład
    Przykład

    Rzucamy wielokrotnie sześcienną kostką do gry. Chcemy policzyć, ile razy wypadły poszczególne liczby oczek. Można utworzyć sześć zmiennych odpowiednio do przechowywania liczby wystąpień jednego oczka, dwóch oczek, itd. Lepiej jednak utworzyć sześcioelementową listę. Liczba oczek będzie w takim przypadku indeksem (numerem elementu). Symbolicznie indeks będziemy podawać w nawiasach kwadratowych:

    Stworzymy listę o nazwie: Wyniki. Wtedy oznaczenie np. Wyniki[2] - wskazywać będzie drugi element listy, czyli informację ile razy wypadły dwa oczka.

    Listę, podobnie jak pojedynczą zmienną, można utworzyć w kategorii Zmienne. Należy kliknąć w przycisk Stwórz listę, w polu edycyjnym wpisać nazwę nowotworzonej listy (można także wybrać, czy będzie dostępna dla wszystkich duszków, czy tylko jednego) i zatwierdzić przyciskiem OK.

    R1cEIGZcmMfPV
    Okno tworzenia nowej listy
    Źródło: GroMar, licencja: CC BY 3.0.

    Po utworzeniu listy w kategorii Dane pojawią się nowe bloczki umożliwiające operacje na liście. Dostępne opcje możesz podejrzeć na poniższej ilustracji.

    R15eicq2iid8L
    Wersja alternatywna: Zrzut ekranu przedstawia fragment okna do zarządzania blokami w Scratch. Ekran jest podzielony na dwie główne sekcje: wybór kategorii bloków oraz samą sekcję bloków. Po lewej stronie widoczna jest lista dostępnych kategorii bloków, z których wybrana jest opcja Zmienne. Po prawej stronie umieszczone są dostępne bloki, które zostały stworzone w kontekście listy. W górnej części prawego obszaru znajduje się przycisk Stwórz listę do tworzenia nowych list. Niżej wyróżnione są dostępne listy z polem wyboru ich widoczności na scenie. Poniżej list widoczne są bloki służące do zarządzania listami, gdzie dostępnych jest jedenaście opcji. 1. Nazwa listy Blok reprezentujący listę z podaną nazwą i polem do zaznaczania widoczności listy na scenie., 2. Dodaj () do () Dodaje nowy element na koniec listy., 3. Usuń () z () Usuwa element od podanym indeksie z wybranej listy i zmniejsza indeks kolejnych elementów o 1., 4. Usuń wszystko z () Usuwa wszystkie elementy z listy., 5. Wstaw () na () pozycji z () Dodaje element na wybraną pozycję (indeks) i zwiększa indeks kolejnych elementów na liście., 6. Zamień () z () na () Podmienia element na wybranej liście na inny element., 7. Element () z () Zwraca wartość podanego elementu z wybranej listy., 8. Pozycja () na liście () Zwraca indeks podanego elementu z wybranej listy., 9. Długość () Przechowuje informacje o liczbie elementów w wybranej liście., 10. () zawiera () ? Zwraca wartość prawda lub fałsz w zależności, czy wybrana lista zawiera podany element., 11. Pokaż listę () Wyświetla wybraną listę na scenie aplikacji., 12. Ukryj listę () Ukrywa wybraną listę na scenie aplikacji.
    Bloki dostępne po utworzeniu listy
    Źródło: GroMar, licencja: CC BY 3.0.

    Zrzut ekranu przedstawia fragment okna do zarządzania blokami w Scratch. Ekran jest podzielony na dwie główne sekcje: wybór kategorii bloków oraz samą sekcję bloków. Po lewej stronie widoczna jest lista dostępnych kategorii bloków, z których wybrana jest opcja „Zmienne”. Po prawej stronie umieszczone są dostępne bloki, które zostały stworzone w kontekście listy. W górnej części prawego obszaru znajduje się przycisk „Stwórz listę” do tworzenia nowych list. Niżej wyróżnione są dostępne listy z polem wyboru ich widoczności na scenie. Poniżej list widoczne są bloki służące do zarządzania listami, gdzie dostępnych jest 11 opcji.

    Listą możesz także zarządzać z poziomu sceny Scratch. Zapoznaj się z poniższą ilustracją interaktywną, aby zrozumieć działanie poszczególnych funkcji.

    R126B2PeQY8RV
    Wersja alternatywna: Zrzut ekranu przedstawiający tabelę „Wyniki ”. Na pierwszym miejscu znajduje się wartość 1, na drugim wartość 2. Zaznaczone są elementy - nazwa listy „Wyniki” - jest to unikalna etykieta, która identyfikuje i umożliwia operacje na danym zbiorze danych. Dzięki niej możemy manipulować elementami listy w programie. 1. Nazwa listy Jest to unikalna etykieta (nazwa), która identyfikuje i umożliwia operacje na danym zbiorze danych. Dzięki niej możemy manipulować elementami listy w programie., 2. Indeks elementu Numer pozycji, na której znajduje się dany element w liście. Indeksy w środowisku Scratch zaczynają się od 1, więc pierwszy element listy ma indeks 1, drugi element ma indeks 2 i tak dalej. Dzięki indeksom możemy jednoznacznie zidentyfikować i manipulować poszczególnymi elementami w liście., 3. Element listy Wartość lub dane, które są przechowywane wewnątrz listy. Może to być liczba, tekst lub inny typ danych, a każdy element ma przypisaną swoją pozycję w liście, zwaną indeksem., 4. Przycisk X Po jego kliknięciu wskazany element na liście zostanie usunięty i indeksy pozostałych elementów zostaną dostosowane do nowej długości listy., 5. Przycisk + Umożliwia wstawienie nowego elementu na końcu listy., 6. Długość tablicy Oznacza liczbę elementów znajdujących się w danej liście., 7. Znak = Po najechaniu na niego kursorem myszy zmieni się ikona kursora i możliwe będzie dostosowanie wielkości okna listy na scenie w Scratch.
    Obiekt Lista w środowisku Scratch
    Źródło: GroMar, licencja: CC BY 3.0.

    Zrzut ekranu przedstawiający tabelę Wyniki. Na pierwszym miejscu znajduje się wartość 1, na drugim wartość 2.  Zaznaczone są elementy - Nazwa listy „Wyniki” - Jest to unikalna etykieta, która identyfikuje i umożliwia operacje na danym zbiorze danych. Dzięki niej możemy manipulować elementami listy w programie.

    Jeżeli elementami listy mają być liczby, możesz wprowadzić je do listy na różne sposoby. Jednym z nich jest wylosowanie liczby z określonego zakresu za pomocą bloku losuj liczbę od ... do ..., a następnie dodanie wylosowanej liczby do listy.

    R1NhMF3UIBtP0
    Przykładowy skrypt na dodanie losowej liczby z przedziału <1, 10> do listy
    Źródło: GroMar, licencja: CC BY 3.0.

    Innym sposobem jest zapytanie użytkownika skryptu, jaką liczbę chce wprowadzić do listy, a następnie dodanie podanej odpowiedzi do listy.

    RzNn2uALSgeyP
    Przykładowy skrypt na dodanie podanej przez użytkownika liczby do listy
    Źródło: GroMar, licencja: CC BY 3.0.

    Istnieje wiele sposobów, aby dodać liczbę do listy w Scratch, a te przedstawione są tylko częścią z nich. Wybierz ten, który najlepiej odpowiada twoim potrzebom.

    Ważne!

    Dobrą praktyką jest usuwanie wszystkich elementów listy na początku skryptu. Unikniesz wtedy pozostałości po poprzednich uruchomieniach skryptu, które mogłyby wywołać niepożądane efekty.

    Lista może być widoczna na scenie lub ukryta. Widoczność można zmieniać edycyjnie zaznaczając/odznaczając znacznik przy liście

    R8Ieq14gGnK9V
    Obszar do zmiany widoczności listy na scenie aplikacji Scratch
    Źródło: GroMar, licencja: CC BY 3.0.

    lub programowo, przy pomocy bloczków:

1

⠀⠀ 2. Definiowanie i wykorzystywanie nowych bloków w środowisku Scratch.

Często bardziej złożony problem warto podzielić na podproblemy i zapisać je w postaci oddzielnych bloków. Więcej informacji na temat tworzenia bloków w Scratch znajdziesz po rozwinięciu poniższej zakładki.

1
Tworzenie bloków w Scratch

W celu utworzenia nowego bloku należy przejść do kategorii Moje bloki. Następnie kliknąć przycisk Utwórz blok, w polu edycyjnym wpisać jego nazwę i zatwierdzić przyciskiem OK. W obszarze skryptów pojawi się nowy blok, pod który można podczepić inne bloki rozwiązujące podproblem.

Przykład 1

Duszek ma narysować kilka obróconych kwadratów. Wygodnie będzie zdefiniować własny blok rysujący pojedynczy kwadrat.

R7OSvOAq0YO1P
Przykładowy skrypt realizujący powtarzanie zdefiniowanego własnego bloku w języku Scratch.
Źródło: GroMar, licencja: CC BY 3.0.

Na poniższym filmie możesz obejrzeć, jak utworzyć i wykorzystać własny blok.

R3CPUgu511yAY
Film przedstawia Tworzenie i wykorzystanie własnego bloku.

Własne bloki mogą mieć też parametry, analogicznie jak w przypadku wielu standardowych bloczków (np. w bloczku przesuń podajesz, o ile kroków duszek ma się przemieścić).

Przykład 2

Duszek ma rysować mniejsze i większe kwadraty. Parametrem dla bloku rysującego kwadrat będzie więc długość boku. Jeśli blok jest już zdefiniowany, wystarczy kliknąć w niego prawym przyciskiem myszy i wybrać z menu kontekstowego Edycja, a następnie Dodaj dane wejściowe (liczba lub tekst). Jeśli dopiero tworzymy nowy blok, po podaniu jego nazwy należy od razu zaznaczyć opcję Dodaj dane wejściowe (tekst lub liczba). W kolejny krokach trzeba:

  • wpisać nazwę parametru,

  • zatwierdzić przyciskiem OK.

Żeby wykorzystać parametr należy przeciągnąć go z bloczka rozpoczynającego definicję nowego bloku do instrukcji, w której chcemy go użyć.

RFTiyFZZ2bwk4
Przykładowy skrypt realizujący instrukcję z wykorzystaniem parametru w języku Scratch
Źródło: GroMar, licencja: CC BY 3.0.

Na poniższym filmie możesz obejrzeć, jak utworzyć i wykorzystać własny blok z parametrem.

R1J8LK1HWSP21
Film przedstawia Tworzenie i wykorzystanie własnego bloku z parametrem.
min_max

⠀⠀ 3. Znajdowanie najmniejszego i największego elementu (np. listy).

Więcej informacji na ten temat znajdziesz w ćwiczeniu dodatkowym po rozwinięciu listy.

1
Ćwiczenie dodatkowe

Zapisz w postaci listy kroków algorytm znajdowania najmniejszej liczby na liście. Możesz przygotować także prostą aplikację, w której jest losowana lista dziesięciu liczb, a następnie duszek znajduje najmniejszą liczbę na liście i wyświetla ją w dymku komiksowym.

⠀⠀ 4. Zamiana elementów listy.

Więcej informacji na ten temat znajdziesz w ćwiczeniu dodatkowym po rozwinięciu listy.

1
Ćwiczenie dodatkowe

Popraw tak rozwiązanie poprzedniego ćwiczenia dodatkowego, aby najmniejsza liczba została ustawiona na pierwszym miejscu listy. Nie możesz jednak zgubić żadnego elementu (np. elementu, który pierwotnie był na pierwszym miejscu).

⠀   5. Sortowanie elementów (np. listy). ⠀⠀

Sortowanie to jeden z podstawowych problemów informatycznych. Istnieje wiele algorytmów sortowania, jedne działają szybciej, inne wolniej. W tym podrozdziale poznasz jedną z nich i wykorzystasz w tworzonej aplikacji. W przyszłości, jeśli będziesz kontynuować swoją przygodę z algorytmami, poznasz także inne i porównasz ich efektywność.

sortowanie_przez_wybieranie
1
Algorytm sortowania przez wybieranie

Liczby na liście mają być ustawione od najmniejszej do największej, a więc w pierwszym kroku można znaleźć liczbę najmniejszą i zamienić ją z pierwszym elementem listy. W kolejnym kroku postępujemy analogicznie poszukując liczby najmniejszej poczynając od drugiego elementu, następnie od trzeciego, itd. Powtarzamy więc wybieranie i ustawianie liczby najmniejszej n-1 razy (jak zostaje jedna liczba, to znajduje się już na właściwym miejscu, ciąg złożony z jednego elementu jest uporządkowany).

Przykład 1
Przykład 1

W poniższym filmie przedstawiono kolejne kroki porządkowania następującego zestawu liczb: 8, 5, 1, 9, 3. Kolorem zielonym zaznaczone są liczby już ustawione, kolorem żółtym kolejne znalezione minimum, a czerwonym miejsce, na którym zostanie ustawione.

REHJjrBB8hYYO
Animacja prezentuje działanie sortowania przez wybieranie. W pierwszym kroku szukana jest najmniejsza liczba, a następnie zamieniana z pierwszym elementem listy. W kolejnym kroku szukana jest najmniejsza wartość, począwszy od drugiego elementu, później od trzeciego i tak aż do posortowania wszystkich liczb.

Zapis algorytmu sortowania przez wybieranie w postaci listy kroków:

Dane:
n – liczba elementów listy,
L – lista liczb.

Wynik:
L – uporządkowana niemalejąco lista liczb.

  1. Powtarzaj dla kolejnych wartości zmiennej i od 1 do n - 1:
    1.1. Ustaw wartość zmiennej m na i.
    1.2. Powtarzaj dla kolejnych wartości zmiennej j od i + 1 do n:
     ⠀1.2.1. Jeżeli element na pozycji jL < element na pozycji mL to ustaw wartość zmiennej m na j.
    1.3. Zamień element na pozycji iL z elementem na pozycji mL.

⠀  

Ćwiczenie 7

Utwórz listę do przechowywania długości odcinków (np. o nazwie Odcinki) oraz zmienną (np. o nazwie n), w której będzie przechowywana liczba losowanych odcinków.

Skrypty dla przycisków będą analogiczne jak w poprzedniej aplikacji. Zmienią się dla duszka sprawdzającego odpowiedź, ponieważ inny będzie algorytm sprawdzenia odpowiedzi użytkownika oraz zastosowane struktury danych (zamiast trzech pojedynczych zmiennych lista).

Ćwiczenie 8

Przygotuj skrypt, uruchamiany po kliknięciu w zieloną flagę, losujący najpierw liczbę odcinków, a potem ich długości.

Ćwiczenie 9

Określ jak sprawdzić, czy z każdych trzech odcinków można zbudować trójkąt. Spróbuj znaleźć więcej niż jedną propozycję rozwiązania tego problemu.

Ćwiczenie 10

Utwórz skrypt (nowy blok) sortujący listę odcinków zgodnie z algorytmem przez wybieraniealgorytmem przez wybieranie. Pamiętaj o utworzeniu wszystkich niezbędnych zmiennych.

Ćwiczenie 11

Zmodyfikuj skrypt początkowy oraz skrypty uruchamiane po otrzymaniu komunikatów taknie. Duszek zadający pytanie powinien najpierw posortować wylosowane odcinki.

Znajdujemy dwa najkrótsze odcinki i najdłuższy

Podstawowa wersja gry już działa. W poniższych ćwiczeniach będziemy ją poprawiać, czyli tworzyć inną wersję.

Żeby stwierdzić, czy z każdej trójki odcinków można zbudować trójkąt, nie trzeba porządkować odcinków według ich długości. Wystarczy znaleźć dwa najkrótsze odcinki oraz najdłuższy, czyli dwie liczby najmniejsze i największą. Możesz doprowadzić do sytuacji, że dwie najmniejsze liczby znajdą się na dwóch pierwszych miejscach, a największa na ostatniej. Możesz także znaleźć ich wartości wykorzystując trzy pomocnicze zmienne.

Ćwiczenie 12

Utwórz trzy pomocnicze zmienne, w których zapamiętasz poszukiwane liczby.

Ćwiczenie 13

Zastanów się, jakie nadać wartości początkowe zmiennym min1, min2 i max. Przygotuj pomocniczy skrypt nadający im wartości początkowe.

Ćwiczenie 14

Zapisz w postaci listy kroków algorytm znajdowania dwóch wartości najmniejszych i największej.

Do zapisania listy kroków możesz wykorzystać poniższy notatnik.

R1MVrV482jjJJ
Miejsce, w którym można wpisać tekst
Notatnik
Źródło: GroMar, licencja: CC BY 3.0.
Ćwiczenie 15

Utwórz nowy blok znajdujący dwie wartości najmniejsze i największą zgodnie z algorytmem z poprzedniego ćwiczenia.

Pamiętaj o dostosowaniu skryptów wywoływanych jako reakcja na nadanie komunikatów taknie, oraz skryptu początkowego.

Zadania uzupełniające

Ćwiczenie 16

Przygotuj aplikację, w której losowana jest lista liczb. Następnie niech duszek poprosi o podanie liczby i sprawdzi, czy ona występuje na liście.

Ćwiczenie 17

Przygotuj podobną aplikację, jak w poprzednim ćwiczeniu, ale po wylosowaniu posortuj listę. Zastanów się, czy wyszukując liczbę w posortowanej liście można zastosować inny algorytm, który wykona mniej operacji.

zlozonosc_obliczeniowa