Wstęp do programowania / Ćwiczenia 2: Różnice pomiędzy wersjami

Z Studia Informatyczne
Przejdź do nawigacjiPrzejdź do wyszukiwania
Zadania na rekurencje wpisane jakoś
 
(Nie pokazano 125 wersji utworzonych przez 11 użytkowników)
Linia 1: Linia 1:
To są ćwiczenia z rekurencji.
{{powrot|WDP_Wprowadzenie_do_programowania|do modułu Wprowadzenie do programowania}}


Ta strona zawiera podstawowe zadania na tablice.


==Zadanie 1 (Labirynt)==
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
Oglądaj wskazówki i rozwiązania __SHOWALL__<br>
Ukryj wskazówki i rozwiązania __HIDEALL__
</div>
 
 
== Zadanie 1 (Flaga polska)==
Tablica A typu array[1..N] of integer (N > 0) wypełniona zerami i jedynkami reprezentuje ciąg N urn w których znajdują się żetony białe (0) i czerwone (1). Podaj algorytm działania automatu przestawiającego żetony w urnach tak, by najpierw były żetony czerwone, potem białe. Robot może wykonywać dwa rodzaje operacji:
 
*Kol(i) - podaje kolor żetonu w i-tej urnie (1 &le; i &le; n)
*Z(i,j) - zamienia żetony z i-tej i j-tej urny (1 &le; i,j &le; n)
 
Uwagi:
#Operacja Kol jest bardzo kosztowna, więc zależy nam na tym by kolor każdego żetonu był sprawdzany co najwyżej raz. 
#Robot potrafi zapamiętać tylko kilka wartości z przedziału 0..N+1.
#Nie można założyć, że występuje choć jeden żeton w każdym z kolorów.
 
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Wskazówka 1</span>
<div class="mw-collapsible-content" style="display:none">
Należy przesuwać się indeksem c od początku tablicy, zaś indeksem b od końca. Intencją jest utrzymywanie następującego niezmmiennika: wszystkie elementy tablicy o indeksach mniejszych od c są czerwone, zaś wiekszych od b są białe. Indeksy c i b będą się do siebie zbliżać i ostatecznie gdy c będzie równe b, to tablica będzie uporządkowana.</div>
</div>
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie 1</span>
<div class="mw-collapsible-content" style="display:none">
'''program''' FlagaPolska1(N:integer; A:array[1..N] of integer);
//Tablica A jest wypełniona zerami i jedynkami
'''const''' bialy = 0;
      czerwony = 1;
'''var''' b,c : integer;
'''begin'''
  c:=1; b:=n;
  '''while''' c < b '''do'''
    '''if''' Kol(c)=czerwony '''then''' c:=c+1
    '''else''' '''begin'''
      Z(c,b);
      b:=b-1;
    '''end''';
'''end'''.
''Koszt czasowy'': liniowy względem N
 
''Koszt pamięciowy'': stały
</div>
</div>
 
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Wskazówka 2</span>
<div class="mw-collapsible-content" style="display:none">
Rozwiązanie 1 optymalizuje liczbę sprawdzeń kolorów, ale może niepotrzebnie zamieniać białe z białymi. Można tego uniknąć wprowadzając dodatkową pętlę po białych od końca tablicy.</div>
</div>
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie 2</span>
<div class="mw-collapsible-content" style="display:none">
'''program''' FlagaPolska2(N:integer; A:array[1..N] of integer);
//Tablica A jest wypełniona zerami i jedynkami
'''const''' bialy = 0;
      czerwony = 1;
'''var''' b,c : integer;
'''begin'''
  c:=1; b:=n;
  '''while''' c < b '''do'''
    '''if''' Kol(c)=czerwony '''then''' c:=c+1
    '''else''' '''begin'''
      '''while''' Kol(b)=biały '''and''' (c<b) '''do''' b:=b-1; //pętla po białych od końca tablicy
      '''if''' c<b '''then''' '''begin'''
        Z(c,b);
        b:=b-1;
      '''end''';
    '''end''';
'''end'''.
W rozwiązaniu 2 są dwie zagnieżdżone pętle while. Trzeba zwrócić uwagę, że gdyby nie warunek c<b, to w przypadku tablicy zawierającej same białe żetony doszłoby do wyjścia poza zakres (odwołanie do Kol(0)).
 
''Koszt czasowy'': liniowy względem N
 
''Koszt pamięciowy'': stały
</div>
</div>
 
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Wskazówka 3</span>
<div class="mw-collapsible-content" style="display:none">
W Rozwiązaniu 2 można uniknąć zagnieżdżonych while'i, trzeba jednak uważać, aby nie sprawdzać kilka razy koloru tego samego żetonu. </div>
</div>
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie 3</span>
<div class="mw-collapsible-content" style="display:none">
'''program''' FlagaPolska3(N:integer; A:array[1..N] of integer);
//Tablica A jest wypełniona zerami i jedynkami
'''const''' bialy = 0;
      czerwony = 1;
'''var''' b,c,kb,kc : integer;
'''begin'''
  c:=1; kc:=Kol(c);
  b:=n; kb:=Kol(b);
  '''while''' c < b '''do'''
    '''if''' kc=czerwony '''then''' '''begin'''
      c:=c+1;
      kc:=Kol(c);
    '''end'''
    '''else'''
      '''if''' kb=biały '''then''' '''begin'''
        b:=b-1;
        kb:=Kol(b);
      '''end'''
      '''else''' '''begin'''
        Z(c,b);
        c:=c+1;
        b:=b-1;
        '''if''' c < b '''then''' '''begin'''
          kc:=Kol(c);
          kb:=Kol(b);
        '''end;''';
      '''end;'''
'''end'''.
W rozwiązaniu 3 każdy żeton jest sprawdzany co najwyżej raz, a każda zamiana ustawia na dobrych miejscach 2 żetony (inaczej mówiąc, tych żetonów nie trzeba już będzie przestawiać). A więc wszystkich zamian jest co najwyżej N div 2. Alternatywne rozwiązanie, unikające zagnieżdżonych pętli jest poniżej.
 
''Koszt czasowy'': liniowy względem N
 
''Koszt pamięciowy'': stały
</div>
</div>
 
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Wskazówka 4</span>
<div class="mw-collapsible-content" style="display:none">
Alternatywne rozwiązanie, unikające zagnieżdżonych pętli jest poniżej. Tu oba indeksy b i c przesuwają się od początku tablicy a niezmiennikiem jest to, że wszystkie elementy tablicy o indeksach  mniejszych od c są czerwone, zaś te o indeksach większych lub równych c i miejszych od b są białe. </div>
</div>
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie 4</span>
<div class="mw-collapsible-content" style="display:none">
'''program''' FlagaPolska4(N:integer; A:array[1..N] of integer);
//Tablica A jest wypełniona zerami i jedynkami
'''const''' bialy = 0;
      czerwony = 1;
'''var''' b,c : integer;
'''begin'''
  c:=1; b:=1;
  '''while''' c <= N '''do'''
    '''if''' Kol(b)=biały '''then''' b:=b+1
    '''else''' '''begin'''
        Z(c,b);
        b:=b+1;
        c:=c+1;
    '''end''';
'''end'''.
''Koszt czasowy'': liniowy względem N
 
''Koszt pamięciowy'': stały
</div>
</div>


Czy istnieje droga miedzy wskazanymi punktami <math>(x_1,y_1)</math> i
<math>(x_2,y_2)</math> w labiryncie reprezentowanym przez prostokątną
tablicę liczb całkowitych A o rozmiarze n&times;m, zawierająca zera
(droga) i jedynki (ściana)?


<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
'''Wskazówka 1'''
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Ćwiczenie 1</span>
<div class="mw-collapsible-content" style="display:none">
<div class="mw-collapsible-content" style="display:none">
W rozwiązaniu pojawia się funkcja-otoczka, która jako parametry ma
Dla jakich danych algorytm przedstawiony w Rozwiązaniu 4 dokona N-1 zamian?
(przekazywane przez zmienną) tablicę i 4 liczby opisujące początkowy i
</div>
końcowy punkt drogi. Dzięki temu, że otoczka ma jako parametr tablicę,
</div>
właściwa funkcja rekurencyjna już go nie potrzebuje, nie potrzebuje
też parametrów określających punkt docelowy. Otoczka ponadto sprząta
po funkcji rekurencyjnej (usuwa markowanie z tablicy), sprawdza czy
nie startujemy/kończymy na ścianie lub poza tablicą.


Zapis rozwiązania bardzo się upraszcza jeśli założymy, że mamy ścianę
dookoła labiryntu, jest to pewna forma strażnika.


Należy się też zastanowić, co by było, gdyby zamiast usuwać markowanie
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
na końcu w otoczce, usuwać je lokalnie, wychodząc z rekurencji (tzn.
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Ćwiczenie 2</span>
gdy każde wywołanie startując markuje jedno pole i kończąc to pole
<div class="mw-collapsible-content" style="display:none">
odmarkowuje) (dalej by działało, ale z wykładniczym czasem). Należy
Jak trzeba by zmienić powyższe rozwiązania, gdyby zamiana Z(i,j) była dozwolona tylko dla i <> j ?
wspomnieć o liniowym (wgl. wielkości danych, kwadratowym wzgl długości
boku labiryntu) czasie rozwiązania i o innych możliwych rozwiązaniach
(przeszukiwanie wszerz z kolejką).
</div>
</div>
</div>
</div>


==Zadanie 2 (Z górki na pazurki)==
== Zadanie 2 (Flaga trójkolorowa) ==
Dana jest tablica A typu array[1..N] of integer (N > 0). Należy tak poprzestawiać w niej elementy, żeby najpierw były elementy ujemne, potem równe zero, a na końcu dodatnie.


W tablicy liczb całkowitych o rozmiarze n&times;m zapisana jest mapa
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
gór (każdy punkt ma podaną dodatnią wysokość). Sprawdzić, czy da się
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Wskazówka 1</span>
przejść z punktu startowego do docelowego idąc:
<div class="mw-collapsible-content" style="display:none">
* tylko w dół lub po płaskim
Rozwiązanie dla flagi trójkolorowej jest uogólnieniem rozwiązania dla flagi dwukolorowej. Rozwiązanie 1 poniżej jest kombinacją rozwiązań 3 i 4 z zadania 1; zaś Rozwiązanie 2 poniżej jest bezpośrednim uogólnieniem  rozwiązania 4 z zadania 1. Jeśli chodzi o liczbę zamian, to lepsze wydaje się Rozwiązanie 1, gdyż od razu na dobre (ostateczne) miejsca trafiają elementy ujemne i dodatnie.
* tylko w dół
</div>
</div>


<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
'''Wskazówka 1'''
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie 1</span>
<div class="mw-collapsible-content" style="display:none">
<div class="mw-collapsible-content" style="display:none">
W obu wariantach potrzebne jest markowanie (przez negację). W pierwszym zapobiega zapętleniu, w drugim czasowi wykładniczemu. Znów
'''program''' FlagaTrójkolorowa(N:integer; A:array[1..N] of integer);
potrzebna jest funkcja otoczka.
  '''var''' m,r,w,pom : integer;
'''begin'''
  m:=1; r:=1; w:=N;
  '''while''' r <= w '''do'''
    '''if''' A[r]=0 '''then''' r:=r+1 //przedłużamy segment liczb dodatnich
    '''else'''
      '''if''' A[r]<0 '''then''' '''begin'''
        pom:=A[r]; A[r]:=A[m]; A[m]:=pom; //zamieniamy wartości w A[r] i A[m], po zamianie A[r]=0 i A[m] < 0 
        m:=m+1; //więc zwiększamy oba indeksy r i m
        r:=r+1;
      '''end'''
      '''else''' '''begin'''
        pom:=A[r]; A[r]:=A[w]; A[w]:=pom; //zamieniamy wartości w A[r] i A[w]
        w:=w-1; //po zamianie A[w]>0,  ale o A[r] nic nie wiemy
      '''end''';    
'''end'''.
''Koszt czasowy'': liniowy względem N
 
''Koszt pamięciowy'': stały
 
[[pimp:modul2_2_1.html|Wizualizacja]]
 
</div>
</div>
</div>
</div>


==Zadanie 3 (Wieże Hanoi z ograniczeniami)==
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie 2</span>
<div class="mw-collapsible-content" style="display:none">
'''program''' FlagaTrójkolorowa(N:integer; A:array[1..N] of integer);
'''var''' m,r,w,pom : integer;
'''begin'''
  m:=1; r:=1; w:=1;
  '''while''' w <= N '''do'''
    '''if''' A[w]>0 '''then''' w:=w+1 //przedłużamy segment liczb dodatnich
    '''else'''
      '''if''' A[w]=0 '''then''' '''begin'''
        pom:=A[r]; A[r]:=A[w]; A[w]:=pom; //zamieniamy wartości w A[r] i A[w], po zamianie A[r]=0, A[w] >0
        w:=w+1; //więc zwiększamy oba indeksy r i w
        r:=r+1;
      '''end'''
      '''else''' '''begin''' //zamieniamy cyklicznie A[m], A[r] i A[w] jeśli m<>r; wpp zamieniamy A[m] i A[w]
        pom:=A[m];
        A[m]:=A[w];
        '''if''' (m<>r) '''then''' '''begin'''
          A[w]:=A[r];
          A[r]:=pom;
        '''end'''
        '''else''' A[w]:=pom;
        m:=m+1;
        r:=r+1;
        w:=w+1;
      '''end''';
'''end'''.
''Koszt czasowy'': liniowy względem N


Na wykładzie były wieże Hanoi. Ciekawa modyfikacja tego zadania polega na zabronieniu ruchów pomiędzy niektórymi pałeczkami, np. z pierwszej na drugą. Zapisac procedurę realizującą to zadanie przy zabronionych niektórych ruchach.
''Koszt pamięciowy'': stały


[[pimp:modul2_2_2.html|Wizualizacja]]


Uwagi:
</div>
1) Duzo latwiej rozwiazac to zadanie przy powyzszym sformułowaniu, niz
</div>
gdy powie
    sie ze zabroniony jest konkretny ruch (np. 1-> 2).
2) Kiedy to zadanie ma jeszcze rozwiazanie (gdy na kazda wieze i z
kazdej wiezy
    istnieje co najmniej jeden dozwolony ruch).
3) Jak reprezentowac dozwolone ruchy (TDozwRuchow = array[1..3, 1..3] of
boolean,
    przekatna nie ma znaczenia).
4) Znow konieczna jest otoczka (dostarcza srodowisko pamietajace
dozwolone ruchy,
    sprawdza czy w ogole istnieje rozwiazanie).
5) Algorytm:


    type Paleczki = 1..3;
== Zadanie 3 (Najdłuższe plateau) ==
Napisz program znajdujący w zadanej tablicy A typu array[1..N] of integer, N > 0,  długość najdłuższego stałego segmentu (spójnego fragmentu tablicy).


    procedure Hanoi(Ile: integer; Skad, Dokad: Paleczki; Dozw:
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
TDozwRuchow);
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Wskazówka 1</span>
      {...}
<div class="mw-collapsible-content" style="display:none">
      procedure Rob(Skad, Dokad, Pom: Paleczki; Ile: Integer);
Zadanie to można rozwiązać używając dwóch pętli; zewnętrznej (po możliwych początkach segmentu) i wewnętrznej (w której szukamy końca segmentu stałego).
      begin
</div>
        {Pom oczywiscie jest rowne 6 - skad - dokad, ale chyba z
</div>
parametrem jest czytelniej}
        if Ile > 0 then
        begin
          if Dozw[Skad, Dokad]
          then
            begin
                Rob(Skad, Pom, Dokad, Ile-1);
                Przenies(Skad,Dokad);
                Rob(Pom, Dokad, Skad, Ile-1);
            end
          else
            begin
                Rob(Skad, Dokad, Pom, Ile-1);
                Przenies(Skad, Pom);
                Rob(Dokad, Skad, Ile-1);
                Przenies(Pom, Dokad);
                Rob(Skad, Dokad, Ile-1);
            end
      end;
  begin {Otoczka}
    ...
  end;


6) Jaki przypadek jest najgorszy i ile trzeba wykonac ruchow (gdy
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
przerwane jest polaczenie
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiąznie 1</span>
    Skad-Dokad w obie strony, 3^ile-1)
<div class="mw-collapsible-content" style="display:none">
'''program''' NajdłuższePlateau1(N:integer; A:array[1..N] of integer);
'''var''' l,p,w,maks: integer;
  koniec:boolean;
'''begin'''
  l:=1; w:=A[l]; maks:=1;
  '''while''' l < N '''do''' '''begin'''
    p:=l+1; koniec:=false;
    '''while''' (p <= N) '''and''' ('''not''' koniec) '''do''' //dopóki jesteśmy w tablicy i poruszamy się wewnątrz segmentu stałego
      '''if''' A[p]=w '''then''' p:=p+1
      '''else''' koniec:=true;
    maks:=max(maks, p-l); //poprawiamy maks
    l:=p;
    '''if''' l <= N '''then''' w:=A[l]; //ustawiamy nowy początek segmentu
  '''end''';
  '''end'''.
''Koszt czasowy'': liniowy względem N


==Zadanie 4 (Nawroty)==
''Koszt pamięciowy'': stały
Napisz procedure znajdujaca wszystkie takie rozstawienia 8 hetmanow na
szachownicy, by
zadne dwa hetmany sie nie atakowaly.


(rozwiazanie jest ladnie opisane w duzym Wirthcie 155-160, pamitamy w
[[pimp:modul2_3_1.html|Wizualizacja]]
tablicach logicznych
zajetosc kolumn i obu rodzai przekatnych, kolejnego hetmana ustawiamy w
kolejnym
wierszu jesli sie da, jesli nie wracamy). Oczywiscie lepiej uogolnic na
N hetmanow na szachownicy
N*N.


</div>
</div>


==Zadanie 5 (Mnozenie wielomianow stopnia n-1)==
Dane sa dwie tablice (array[0..n-1] of real) reprezentujace dwa
wielomiany. Nalezy obliczyc iloczyn tych
wielomianow metoda dziel-i-zwyciezaj. Zakladamy, ze N jest potega
dwojki.


Rozw.
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
Zamiast rozwiazania naiwnego wymagajacego n^2 mnozen zrobmy troche
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Wskazówka 2</span>
lepsze
<div class="mw-collapsible-content" style="display:none">
(aczkolwiek nie najlepsze) polegajace na podzieleniu wielomianow na
Dokładnie to samo rozwiązanie można zapisać używając jednej pętli.
dwie czesci. Caly pomysl polega na spostrzezeniu, ze jesli zadane
</div>
wielomiany p(x) i q(x) podzielimy na dolna i gorna czesc (p(x) =
</div>
p_l(x) + p_h(x)*x^(n/2) i analogicznie q(x)), to ich iloczyn mozna
zapisac tak:
r_l(x)+(r_m(x)-r_l(x)-r_h(x))*x^(n/2)+r_h(x)*x^n, gdzie
r_l(x) = p_l(x)*q_l(x)
r_h(x) = p_h(x)*q_h(x)
r_m(x) = (p_h(x)+p_l(x))*(q_h(x)+q_l(x))
Czyli potrzebujemy 3 mnozen o polowe mniejszych wielomianow. W sumie
uzyskamy liczbe mnozen rzedu n^lg3. Szczegoly mozna znalezc w Sedgewick


  Algorithms in C++ 527-530 (lub tegoz autora Algorithms in *)
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiąznie 2</span>
<div class="mw-collapsible-content" style="display:none">
'''program''' NajdłuższePlateau2(N:integer; A:array[1..N] of integer);
'''var''' w,p,dl,maks: integer;
  koniec:boolean;
  '''begin'''
  w:=A[1]; dl:=1; maks:=1;
  '''for''' p:=2 '''to''' N '''do''' '''begin'''
    '''if''' A[p]=w '''then''' dl:=dl+1
    '''else''' '''begin'''
      maks:=max(maks, dl);
      w:=A[p];
      dl:=1;
    '''end''';
  '''end''';
  maks:=max(maks, dl);
'''end'''.
''Koszt czasowy'': liniowy względem N


''Koszt pamięciowy'': stały


[[pimp:modul2_3_2.html|Wizualizacja]]


Uwagi ogolne:
</div>
- zwrocmy uwage na kolejnosc wyliczania wyrazen logicznych: standard
</div>
Pascala jej nie definiuje,
  zatem AND moze byc liczony tak, ze najpierw liczy sie _oba_ argumenty
a dopiero potem podaje wynik
  (nie mozna zakladac krotkiego liczenia od lewej do prawej). Przy
wywolaniach rekurencyjnych
  to wazne szczegolnie, bo nie chodzi tylko (czy az) o poprawnosc (if
(i>1) and (tab[i]<>x) jest bledem)
  ale o efektywnosc (if droga(i-1,j) or droga(i+1,j) or ... jest
nieefektywne).
- podkreslmy wage procedur otoczek: pozwalaja uzytkownikowi i nam
widziec nasze procedury z takimi parametrami
  jakie sa potrzebne.




==Zadanie 6 (Parser)==
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
Dla zadanej poniżej gramatyki języka programowania (będącego uproszczoną
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Ćwiczenie 1</span>
wersją Pascala) napisz metodą zejść rekurencyjnych zestaw procedur weryfikujących
<div class="mw-collapsible-content" style="display:none">
poprawność programów zapisanych w tym języku. W przypadku napotkania
Czy przedostatnia linia programu w Rozwiązaniu 2 jest potrzebna? Co by było, gdyby jej nie było?
błędu należy wypisać stosowny komunikat i zakończyć działanie. Należy założyć
</div>
istnienie procedury GetSym(Symbol), która daje kolejny symbol (identyfikator,
</div>
liczbę, operator (:=,<,>,<=,>=,=,<>),  separator (;, ., (, ) ) z wejścia. Należy także
zaprojektować odpowiedni typ danych do pamiętania symboli wejściowych.


Gramatyka:
===Inna wersja zadania===
W opisie gramatyki występują następujące symbole:
A co byłoby gdyby tablica była posortowana ?
  <nieterminal>
  terminal
  { coś }                                      wielokrotne (być może 0-krotne) wystąpienie cosia
  ->                                              rozdziela lewą część produkcji od prawej
  |                                                rozdziela poszczególne produkcje
Jest to trochę roszerzona (o {}) gramatyka bezkontekstowa.


<program> -> <dekl> begin <ciąg instrukcji> end .
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<ciąg instrukcji> -> <instrukcja> { ; <instrukcja>}
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Wskazówka 3</span>
<deklaracja> -> var <zmienna> {, <zmienna>} ;
<div class="mw-collapsible-content" style="display:none">
<instrukcja> ->  
Podczas przechodzenia tablicy indeksem i od lewej do prawej, zmiana maks - dotychczas odnalezionej wartości najdłuższego plateau - zachodzi tylko wtedy gdy A[i] wydłuża ostatnie plateau do długości maks+1. Ponieważ tablica jest posortowana, wystarczy porównywać wartości A[i] i A[i-maks]. 
  while <warunek> do <instrukcja>                            |
</div>
          if <warunek> then <instrukcja> else <instrukcja>  |
</div>
          begin <ciąg instrukcji> end                                      |
  <zmienna> := <wyrażenie>
<warunek> -> <składnik> {and <składnik>}
<składnik> -> <czynnik> {or <czynnik>}
<czynnik> -> true | false | not <czynnik> | <wyrażenie> <oprel> <wyrażenie> | ( <warunek> )
<wyrażenie> -> <zmienna> | <liczba>
<oprel> -> < | <= | > | >= | <> | =


<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiąznie 3</span>
<div class="mw-collapsible-content" style="display:none">
'''program''' NajdłuższePlateau3(N:integer; A:array[1..N] of integer);
'''var''' i,maks: integer;
'''begin'''
  maks:=1;
  '''for''' i:=2 '''to''' N '''do'''
    '''if''' A[i]=A[i-maks] '''then''' maks:=maks+1;
'''end'''.
''Koszt czasowy'': liniowy względem N


Rozw.
''Koszt pamięciowy'': stały
  W tym zadaniu chodzi o przećwiczenie metody zejść rekurencyjnych (była na wykładzie). Niestety
 
  na razie nie mamy dostatecznie ciekawych typów danych, żeby móc zapamiętać strukturę danych
[[pimp:modul2_3_3.html|Wizualizacja]]
  programu (i np. po tem go wykonywać). Tym nie mniej zadanie jest pouczające. Typ danych który
 
  ma być wymyślony to rekord z wariantami. Można uatrakcyjnić to zadanie każąc sprawdzać, czy każda
</div>
  użyta zmienna była wcześniej zadeklarowana i czy nie była deklarowana kilkakrotnie (tablica
</div>
  napisów).
 
== Zadanie 4 (Segment o maksymalnej sumie) ==
Napisz program znajdujący w zadanej tablicy A typu array[1..N] of integer, N > 0, maksymalną sumę segmentu (spójnego fragmentu tablicy). Przyjmujemy, że segment pusty ma sumę 0.
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Wskazówka 1</span>
<div class="mw-collapsible-content" style="display:none">
Najprostsze rozwiązanie to dla wszystkich możliwych segmentów policzyć ich sumę.
</div>
</div>
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie 1</span>
<div class="mw-collapsible-content" style="display:none">
'''program''' SegmentOMaksymalnejSumie1(N:integer; A:array[1..N] of integer);
'''var''' l,p,j,suma,maks: integer;
'''begin'''
  maks:=0;
  '''for''' l:=1 '''to''' N '''do''' '''begin''' //wybieramy początek segmentu
    '''for''' p:=l '''to''' N '''do''' '''begin''' //wybieramy koniec
      suma:=0;
      '''for j:=l '''to''' p '''do''' suma:=suma+A[j]; //liczymy sumę
      maks:=max(maks,suma);
    '''end''';
  '''end''';
'''end'''.
''Koszt czasowy'': sześcienny względem N
 
''Koszt pamięciowy'': stały
 
[[pimp:modul2_4_1.html|Wizualizacja]]
 
</div>
</div>
 
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Wskazówka 2</span>
<div class="mw-collapsible-content" style="display:none">
W powyższym rozwiązaniu sumę pewnych segmentów liczy się wiele razy. Lepiej dla danego początku l obliczać po kolei sumy coraz dłuższych segmentów zaczynających sie w l.
</div>
</div>
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie 2</span>
<div class="mw-collapsible-content" style="display:none">
'''program''' SegmentOMaksymalnejSumie2(N:integer; A:array[1..N] of integer);
'''var''' l,p,suma, maks: integer;
'''begin'''
  maks:=0;
  '''for''' l:=1 '''to''' N '''do''' '''begin'''
    suma:=0;
    '''for''' p:=l '''to''' N '''do''' '''begin'''
      suma:=suma+A[p];
      maks:=max(maks,suma);
    '''end''';
  '''end''';
'''end'''.
''Koszt czasowy'': kwadratowy względem N
 
''Koszt pamięciowy'': stały
 
[[pimp:modul2_4_2.html|Wizualizacja]]
 
</div>
</div>
 
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Wskazówka 3</span>
<div class="mw-collapsible-content" style="display:none">
Niech Pref(i) oznacza sumę elemetów tablicy od 1 do i włącznie. Suma segmentu od l do p to oczywiście Pref(p) - Pref(l-1). Maksymalną sumę segmentu kończącego się w p uzyskamy odejmując od Pref(p) minimalne Pref(i) gdzie i przebiega [1..p].
</div>
</div>
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie 3</span>
<div class="mw-collapsible-content" style="display:none">
'''program'''  SegmentOMaksymalnejSumie3(N:integer; A:array[1..N] of integer);
'''var''' mini_pref,biez_pref,maks,i: integer;
'''begin'''
  maks:=0;
  mini_pref:=0;
  biez_pref:=0;
  '''for''' i:=1 '''to''' N '''do''' '''begin'''
    biez_pref:=biez_pref+A[i];
    mini_pref:=min(mini_pref,biez_pref);
    maks:=max(maks, biez_pref-mini_pref);
  '''end''';
'''end'''.
''Koszt czasowy'': liniowy względem N
 
''Koszt pamięciowy'': stały
 
[[pimp:modul2_4_3.html|Wizualizacja]]
 
</div>
</div>
 
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Wskazówka 4</span>
<div class="mw-collapsible-content" style="display:none">
Poniższe rozwiązanie opiera się na spostrzeżeniu, że jeśli suma pewnego segmentu o początku w l i końcu w p jest ujemna, lub nawet równa zero, to nie ma sensu tego segmentu przedłużać. Co więcej, wszystkie segmenty o początkach pomiędzy l i p będą podsegmentami tego dotychczas rozpatrywanego, więc nie ma sensu ich rozważać przy poszukiwaniu segmentu o maksymalnej sumie. Jedyną sensowną możliwością jest rozpatrywanie segmentów które zaczynają się od p+1. 
</div>
</div>
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie 4</span>
<div class="mw-collapsible-content" style="display:none">
'''program'''  SegmentOMaksymalnejSumie4(N:integer; A:array[1..N] of integer);
'''var''' l,p,i,maks,suma: integer;
  '''begin'''
  l:=1;
  p:=1;
  suma:=0; 
  maks:=0;
  while p <= N '''do'''
    '''if''' suma+A[p] <= 0 '''then''' '''begin'''
      l:=p+1;
      suma:=0;
      p:=l;
    '''end'''
    '''else''' '''begin'''
      suma:=suma+A[p];
      maks:=max(maks,suma);
      p:=p+1;
    '''end''';
'''end'''.
W powyższym programie suma=A[l]+...+A[p-1] i jest to największa suma kończąca się na p-1 (przyjmując, że suma pustego ciągu też kończy się na p-1).
 
Ponieważ jest to rozwiązanie działające w czasie liniowym od N (p zwiększa się w każdym obrocie pętli) a wszystkich segmentów jest kwadratowo wiele, powstaje wątpliwość czy przypadkiem nie omijamy
segmentu o maksymalnej sumie. To trzeba by udowodnić. Temat ten będzie poruszany w module o niezmiennikach i logice Hoare'a.
 
''Koszt czasowy'': liniowy względem N
 
''Koszt pamięciowy'': stały
 
[[pimp:modul2_4_4.html|Wizualizacja]]
 
</div>
</div>
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie 5</span>
<div class="mw-collapsible-content" style="display:none">
Poniżej znajduje się inaczej (zwięźlej) zapisane Rozwiązanie 4. W tym rozwiązaniu nie odwołujemy się bezpośrednio do początku i końca aktualnego segmentu, a tylko do jego sumy (biez).
'''program'''  SegmentOMaksymalnejSumie5(N:integer; A:array[1..N] of integer);
'''var''' i,biez,maks: integer;
'''begin'''
  maks:=0;
  biez:=0;
  '''for''' i:=1 '''to''' N '''do''' '''begin'''
    biez:=max(0,biez+A[i]);
    maks:=max(maks, biez);
  '''end''';
'''end'''.
''Koszt czasowy'': liniowy względem N
 
''Koszt pamięciowy'': stały
 
[[pimp:modul2_4_5.html|Wizualizacja]]
 
</div>
</div>
 
== Zadanie 5 (Część wspólna zbiorów) ==
Dane są dwie tablice A i B typu array[1..N] of integer, N > 0. Obie są
posortowane rosnąco. Należy traktując A i B jako reprezentacje dwóch
zbiorów wypisać (operacją write) część wspólną tych zbiorów.
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Wskazówka 1</span>
<div class="mw-collapsible-content" style="display:none">
Będziemy przesuwać się po tablicach od prawej do lewej indeksami ia i ib. Za każdym obrotem pętli przesuwamy ten indeks pod którym jest miejsza wartość, lub oba gdy mają takie same wartości. 
</div>
</div>
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiąznie 1</span>
<div class="mw-collapsible-content" style="display:none">
'''program''' CzęśćWspólna(N:integer; A,B:array[1..N] of integer);
//Tablice A i B są posortowane rosnąco
'''var''' ia,ib: integer;
'''begin'''
  ia:=1; ib:=1;
  '''while''' (ia <= N) '''and''' (ib <= N) '''do'''
    '''if''' A[ia] < B[ib] '''then''' ia:=ia+1
    '''else'''
      '''if''' A[ia] > B[ib] '''then''' ib:=ib+1
      '''else''' '''begin'''
          write(A[ia], ' ');
          ia:=ia+1;
          ib:=ib+1;
      '''end''';
'''end'''.
''Koszt czasowy'': liniowy względem N
 
''Koszt pamięciowy'': stały
 
[[pimp:modul2_5_1.html|Wizualizacja]]
 
</div>
</div>
 
== Zadanie 6 (Suma zbiorów) ==
Dane są dwie tablice A i B typu array[1..N] of integer, N > 0. Obie są
posortowane rosnąco. Należy traktując A i B jako reprezentacje dwu
zbiorów wypisać (operacją write) sumę tych zbiorów.
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Wskazówka 1</span>
<div class="mw-collapsible-content" style="display:none">
Dopóki istnieją elementy w obu tablicach, przesuwamy się tak, jak przy obliczaniu części wspólnej, potem obługujemy końcówki tablic.
</div>
</div>
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie 1</span>
<div class="mw-collapsible-content" style="display:none">
'''program''' Suma(N:integer; A,B:array[1..N] of integer);
//Tablice A i B są posortowane rosnąco
'''var''' ia,ib: integer;
'''begin'''
  ia:=1; ib:=1;
  '''while''' (ia <= N) '''and''' (ib <= N) '''do''' //dopóki są elementy w obu tablicach
    '''if''' A[ia] < B[ib] '''then''' '''begin'''
      write(A[ia], ' ');
      ia:=ia+1;
    '''end'''
    '''else'''
      '''if''' A[ia] > B[ib] '''then''' '''begin'''
        write(B[ib], ' ');
        ib:=ib+1;
      '''end'''
      '''else''' '''begin'''
        write(A[ia], ' ');
        ia:=ia+1;
        ib:=ib+1;
      '''end''';
  '''for''' ia:=ia '''to''' N '''do''' write(A[ia], ' '); //obsługa końcówki A
  '''for''' ib:=ib '''to''' N '''do''' write(B[ib], ' '); //obsługa końcówki B
'''end'''.
''Koszt czasowy'': liniowy względem N
 
''Koszt pamięciowy'': stały
 
[[pimp:modul2_6_1.html|Wizualizacja]]
 
</div>
</div>
 
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Ćwiczenie 1</span>
<div class="mw-collapsible-content" style="display:none">
Z dwóch pętli while obsługujących końcówki tablic A i B w Rozwiązaniu 1 wykona się co najwyżej jedna. W jakich sytuacjach nie wykona się żadna z nich ?
</div>
</div>
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Wskazówka 2</span>
<div class="mw-collapsible-content" style="display:none">
Można próbować modyfikować rozwiązanie zadania o części wspólnej, tak by oddać analogię między sumą i częścią wspólną zbiorów. Prowadziłoby to do warunku (ia <= N) or (ib <= N) w głównej pętli while.  Trzeba jednak na nowo zdefiniować co to znaczy, że pod danym indeksem jest mniejsza wartość niż pod innym indeksem, w sytuacji gdy jeden z tych indeksów może być większy od N.
</div>
</div>
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie 2</span>
<div class="mw-collapsible-content" style="display:none">
'''program''' Suma(N:integer; A,B:array[1..N] of integer);
//Tablice A i B są posortowane rosnąco
'''var''' ia,ib: integer;
'''function''' mniejsze(ia,ib: integer):boolean; //funkcja porównująca wartości w ia i ib
'''begin'''
  mniejsze:=false;
  '''if''' (ib > N) '''and''' (ia <= N) '''then'''  mniejsze:=true
  '''else''' '''if''' (ib <= N) '''and''' (ia <= N) '''then''' 
    '''if''' A[ia] < B[ib] '''then''' mniejsze:=true
'''end''';   
'''begin''' //główny program
  ia:=1;
  ib:=1;
  '''while''' (ia <= N) '''or''' (ib <= N) '''do'''
    '''if''' mniejsze(ia,ib) '''then''' '''begin'''
      write(A[ia], ' ');
      ia:=ia+1;
    '''end'''
    '''else'''
      '''if''' mniejsze(ib,ia) '''then''' '''begin'''
        write(B[ib], ' ');
        ib:=ib+1;
      '''end'''
      '''else''' '''begin'''
          write(A[ia], ' ');
          ia:=ia+1;
          ib:=ib+1;
      '''end''';
'''end'''.
''Koszt czasowy'': liniowy względem N
 
''Koszt pamięciowy'': stały
 
[[pimp:modul2_6_2.html|Wizualizacja]]
 
</div>
</div>
 
== Zadanie 7 (Podciąg) ==
Dane są dwie tablice A typu array[1..N] of integer i B typu array[1..M] of integer, N, M > 0. Napisz program sprawdzający, czy A jest podciągiem B (tzn. czy istnieje funkcja f, rosnąca, z 1..N w 1..M, t. ze A[i]=B[f(i)]).
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Wskazówka 1</span>
<div class="mw-collapsible-content" style="display:none">
Każdy element tablicy A musi odnaleźć swoją kopię w tablicy B. Przechodząc tablicę A od lewej do prawej i szukamy odpowiednika A[i] w części B, która jeszcze nie została odwiedzona. 
</div>
</div>
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie 1</span>
<div class="mw-collapsible-content" style="display:none">
'''program''' Podciąg(N,M:integer; A:array[1..N] of integer; B:array[1..M] of integer);
'''var''' ia,ib: integer;
    istnieje: boolean;
  '''begin'''
  '''if''' N > M '''then''' istnieje:=false //bo funkcja f miała być rosnąca
  '''else''' '''begin'''
    ia:=1;ib:=1;
    '''while''' (ia <= N) '''and''' (ib <= M) '''do'''
      '''if''' A[ia] <> B[ib] '''then''' ib:=ib+1
      '''else''' '''begin'''
        ia:=ia+1;
        ib:=ib+1;
      '''end''';
    istnieje:=(ia>N);
    '''if''' istnieje '''then''' write('Tablica A jest podciągiem tablicy B');
  '''end''';
'''end'''.
''Koszt czasowy'': liniowy względem N+M
 
''Koszt pamięciowy'': stały
 
[[pimp:modul2_7_1.html|Wizualizacja]]
 
</div>
</div>
 
== Zadanie 8 (Odwracanie tablicy) ==
Dana tablica A typu array[0..N-1] of integer, N > 1. Napisz program odwracający kolejność elementów w A.
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Wskazówka 1</span>
<div class="mw-collapsible-content" style="display:none">
Należy zamienić element 0 z N-1, 1 z N-2 itd.
</div>
</div>
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie 1</span>
<div class="mw-collapsible-content" style="display:none">
'''program''' Odwracanie1(N:integer; A:array[0..N-1] of integer);
'''var''' l,pom: integer;
'''begin'''
  l:=0;
  '''while''' l < (N div 2) '''do''' '''begin'''
    pom:=A[l];
    A[l]:=A[N-1-l];
    A[N-1-l]:=pom;
    l:=l+1;
  '''end''';
'''end'''.
''Koszt czasowy'': liniowy względem N
 
''Koszt pamięciowy'': stały
 
[[pimp:modul2_8_1.html|Wizualizacja]]
 
</div>
</div>
 
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Wskazówka 2</span>
<div class="mw-collapsible-content" style="display:none">
To samo co w Rozwiązaniu 1 można zrobić używjąc dwóch indeksów l i p na oznaczenie elemnetów z lewej i prawej strony tablicy. W ten sposób na pewno nie pomylimy się wyliczając element, z którym ma się zamienić l (czy to N-1-l, N-l, N-(l+1) itp.) i warunek w while.
</div>
</div>
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie 2</span>
<div class="mw-collapsible-content" style="display:none">
'''program''' Odwracanie2(N:integer; A:array[0..N-1] of integer);
'''var''' l,p,pom: integer;
'''begin'''
  l:=0; p:=N-1;
  '''while''' l < p '''do''' '''begin'''
    pom:=A[l];
    A[l]:=A[p];
    A[p]:=pom;
    l:=l+1;
    p:=p-1;
  '''end''';
'''end'''.
''Koszt czasowy'': liniowy względem N
 
''Koszt pamięciowy'': stały
 
[[pimp:modul2_8_2.html|Wizualizacja]]
 
Można też odwracać jedynie część tablicy, pomiędzy indeksami l i p. Zapiszmy to w formie procedury
'''procedure''' OdwracanieTablicy(var A: array[0..N-1] of integer; l,p:integer);
'''var''' pom: integer;
'''begin'''
  '''while''' l < p '''do''' '''begin'''
    pom:=A[l];
    A[l]:=A[p];
    A[p]:=pom;
    l:=l+1;
    p:=p-1;
  '''end''';
'''end'''.
</div>
</div>
 
== Zadanie 9 (Przesunięcie cykliczne) ==
Dana tablica A typu array[0..N-1] of integer, N > 1, i liczba naturalna k > 1. Napisz program realizujący przesunięcie cykliczne w prawo o k pól, czyli przesuwający zawartość pola A[i] na A[(i+k) mod N] dla każdego i < N.
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Wskazówka 1</span>
<div class="mw-collapsible-content" style="display:none">
Najprościej rozwiązać to zadanie używając dodatkowej pamięci rozmiaru N.
</div>
</div>
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie 1</span>
<div class="mw-collapsible-content" style="display:none">
'''program''' Przesuń1(N,k:integer; A:array[0..N-1] of integer);
'''var''' i: integer;
  P: array[0..N-1] of integer;
'''begin'''
  '''for''' i:=0 '''to''' N-1 '''do''' P[(i+k) '''mod''' N]:=A[i];
  '''for''' i:=0 '''to''' N-1 '''do''' A[i]:=P[i];
'''end'''.
''Koszt czasowy'': liniowy względem N
 
''Koszt pamięciowy'': liniowy względem N
 
[[pimp:modul2_9_1.html|Wizualizacja]]
 
</div>
</div>
 
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Wskazówka 2</span>
<div class="mw-collapsible-content" style="display:none">
Można też skorzystać z rozkładu permutacji na cykle. Długość każdego takiego cyklu wynosi N/nwd(N,k), a na dodatek pierwsze nwd(N,k) elementów tablicy należy do różnych cykli. Dodatkowym kosztem jest oczywiście obliczenie nwd.
</div>
</div>
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie 2</span>
<div class="mw-collapsible-content" style="display:none">
'''program''' Przesuń2(N,k:integer; A:array[0..N-1] of integer);
// k > 1
'''var''' dl_cyklu,ile_cykli: integer;
'''begin'''
  ile_cykli:=nwd(N,k);
  dl_cyklu:=N/nwd(N,k);
  '''for''' i:=0 '''to''' ile_cykli-1 '''do''' '''begin'''
    akt:=A[i];       //na akt zapamiętujemy wartość do przesunięcia
    nast:=(i+k) '''mod''' N;                //obliczamy dla niej nowe miejsce nast
    '''for''' j:=1 '''to''' dl_cyklu '''do''' '''begin'''
      pom:=A[nast];       //wstawiamy akt na A[nast]
      A[nast]:=akt;
      akt:=pom;                       //to co tam było, będzie nowym akt
      nast:=(nast+k) '''mod''' N;            //obliczamy nowe nast
    '''end''';
  '''end''';
'''end'''.
''Koszt czasowy'': liniowy względem N + [[koszt nwd]]
 
''Koszt pamięciowy'': stały
</div>
</div>
 
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Wskazówka 3</span>
<div class="mw-collapsible-content" style="display:none">
Można też zauważyć, że przesunięcie cykliczne o k w prawo można zrealizować poprzez trzy odwrócenia pewnych segmentów tablicy.
</div>
</div>
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie 3</span>
<div class="mw-collapsible-content" style="display:none">
'''program''' Przesun3(N,k:integer; A:array[0..N-1] of integer);
// k > 1
'''begin'''
  OdwracanieTablicy(A,0,N-k-1);
  OdwracanieTablicy(A,N-k,N-1);
  OdwracanieTablicy(A,0,N-1);
'''end'''.
Procedura OdwracanieTablicy pochodzi z Zadania 8. Poprawność tego rozwiązania można uzasadnić poniższym rysunekiem. W pierwszej linii jest oryginalna tablica, a w kolejnych tablica po kolejnych wywołaniach procedury OdwracanieTablicy.
  a(0)    a(1)    ...        ...    a(N-k-1) a(N-k)    ...        a(N-1)
a(N-k-1) a(N-k-2)  ...        ...    a(0)    a(N-k)    ...        a(N-1)
a(N-k-1) a(N-k-2)  ...        ...    a(0)    a(N-1)    ...        a(N-k)
  a(N-k)  a(N-k+1)  ... a(N-1) a(0)    ...    ...      a(N-k-2)  a(N-k-1)
 
''Koszt czasowy'': liniowy względem N
 
''Koszt pamięciowy'': stały
 
[[pimp:modul2_9_3.html|Wizualizacja]]
 
</div>
</div>
 
== Zadanie 10 (Następna permutacja) ==
Tablica A typu array[1..N] of integer, N > 0, zawiera pewną permutację liczb 1.. N. Napisz program wpisujący do A następną leksykograficznie [[permutację]]. Zakładamy, że permutacja w A nie jest ostatnia leksykograficznie.
 
'''Przykład''' Dla N=3 kolejne permutacje w [[porządku leksykograficznym]] wyglądają następująco:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Wskazówka 1</span>
<div class="mw-collapsible-content" style="display:none">
Zastanów się, która część tablicy pozostanie taka sama w następnej permutacji.
</div>
</div>
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiąznie 1</span>
<div class="mw-collapsible-content" style="display:none">
'''program''' NastępnaPermutacja(N:integer; A:array[1..N] of integer);
//Permutacja zapisana w A nie jest ostatnia leksykograficznie
'''var''' i,k,pom: integer;
'''begin'''
  i:=N-1;
  '''while''' A[i] > A[i+1] '''do''' i:=i-1;
  k:=N;
  '''while''' A[k] < A[i] '''do''' k:=k-1;
  pom:=A[i];
  A[i]:=A[k];
  A[k]:=pom;
  OdwracanieTablicy(A,i+1,N);
  '''end''';
  '''end'''.
Procedura OdwracanieTablicy pochodzi z Zadania 8.
 
Najpierw szukamy od tyłu pierwszego elementu, takiego że A[i] < A[i+1] (tu korzystamy z założenia, że to nie ostatnia permutacja), potem szukamy na prawo od i najmniejszego większego od niego elementu k (uwaga: dużo wygodniej to robić od prawej strony!), potem zamieniamy te elementy i odwracamy kolejność elementów na prawo od i.
 
''Koszt czasowy'': liniowy względem N
 
''Koszt pamięciowy'': stały
 
[[pimp:modul2_10_1.html|Wizualizacja]]
 
</div>
</div>
 
== Zadanie 11 (Segment o danej sumie)  ==
Tablica A typu array[1..N] of integer, N > 0,  zawiera tylko liczby dodatnie. Napisz program, który dla danego W typu integer sprawdza, czy w A istnieje segment o sumie W (czyli czy istnieją l, p takie, że W<math>=A[l]+...+A[p-1]</math>).
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Wskazówka 1</span>
<div class="mw-collapsible-content" style="display:none">
Podobnie jak w zadaniu o segmencie o maksymalnej sumie można dla
danego początku l obliczać po kolei sumy coraz dłuższych segmentów zaczynających się w l.
</div>
</div>
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie 1</span>
<div class="mw-collapsible-content" style="display:none">
'''program''' SegmentODanejSumie1(N,W:integer; A:array[1..N] of integer);
//Tablica A zawiera tylko liczby dodatnie
'''var''' l,p,suma: integer;
    znalezione: boolean;
'''begin'''
  '''if''' W < 0 '''then''' znalezione:=false
  '''else''' '''begin'''
    l:=1;
    znalezione:=false;
    '''while''' (l <= N) and (not znalezione) '''do''' '''begin'''
      p:=l;
      suma:=0;
      '''while''' (p <=  N) and (suma < W) '''do''' '''begin'''
          suma:=suma+A[p];
          p:=p+1;
      '''end'''; 
      znalezione:=(suma=W);
      l:=l+1;
    '''end''';  //while
  '''end''';  //else
  '''if''' znalezione '''then''' write('W tablicy A istnieje segment o sumie W');
'''end'''.
''Koszt czasowy'': kwadratowy względem N
 
''Koszt pamięciowy'': stały
 
[[pimp:modul2_11_1.html|Wizualizacja]]
 
</div>
</div>
 
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Wskazówka 2</span>
<div class="mw-collapsible-content" style="display:none">
Podobnie jak w zadaniu o segmencie o maksymalnej sumie, możliwe też jest rozwiązanie o liniowym koszcie czasowym.
</div>
</div>
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie 2</span>
<div class="mw-collapsible-content" style="display:none">
'''program''' SegmentODanejSumie2(N,W:integer; A:array[1..N] of integer);
//Tablica A zawiera tylko liczby dodatnie
'''var''' l,p,suma: integer;
    znalezione: boolean;
'''begin'''
  '''if''' W < 0 '''then''' znalezione:=false
  '''else''' '''begin'''
    l:=1; p:=1;
    suma:=0;
    '''while''' (suma <> W) '''and''' (p <= N) '''do'''
      '''if''' suma < W '''then''' '''begin''' //jeśli suma jest za mała, to przesuwamy prawy koniec segmentu
        suma:=suma+A[p];
        p:=p+1;
      '''end'''
      '''else''' '''begin''' //jeśli za duża, to przesuwamy lewy koniec segmentu
        suma:= suma-A[l];
        l:=l+1;
      '''end''';
    '''while''' (suma > W) '''do''' '''begin'''          //jeśli suma nadal za duża, to próbujemy ją zmniejszyć
      suma:= suma-A[l];
      l:=l+1;
    '''end''';
    znalezione:=(suma=W);
  '''end''';  //else
  '''if''' znalezione '''then''' write('W tablicy A istnieje segment o sumie W');
'''end'''.
Ponieważ jest to rozwiązanie działające w czasie liniowym od N (l+p zwiększa się w każdym obrocie pętli), a wszystkich segmentów jest kwadratowo wiele, powstaje wątpliwość, czy przypadkiem nie omijamy
segmentu o maksymalnej sumie. To trzeba by udowodnić. Wrócimy do tego problemu w module o niezmiennikach i logice Hoare'a.
 
''Koszt czasowy'': liniowy względem N
 
''Koszt pamięciowy'': stały
 
[[pimp:modul2_11_2.html|Wizualizacja]]
 
</div>
</div>
 
== Zadanie 12 (Głosowanie większościowe) ==
Dana jest tablica A typu array[1..N] of integer, N > 0. Sprawdź, czy jest w niej element wystepujący więcej niż N/2 razy i jeśli tak - wskaż go.
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Wskazówka 1</span>
<div class="mw-collapsible-content" style="display:none">
Najprościej jest dla każdego elementu policzyć liczbę wystąpień w tablicy. Jest to oczywiście rozwiązanie o kwadratowym koszcie czasowym.
</div>
</div>
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiąznie 1</span>
<div class="mw-collapsible-content" style="display:none">
'''program''' Głosowanie1(N:integer; A:array[1..N] of integer);
{Program wypisuje wartość tego elementu, który występuje ponad połowę
razy, o ile taki istnieje, lub komunikat, że takiego elementu nie ma}
'''var''' i,j,ile,indeks_lidera: integer;
  '''begin'''
  i:=1;
  indeks_lidera:=0; {Zero oznacza, że lidera jeszcze nie znaleźliśmy}
  '''while''' (i < (N+1) div 2) '''and''' (indeks_lidera=0) '''do''' '''begin'''
    ile:=0;
    '''for j:=i '''to''' N '''do''' if A[i]=A[j] '''then''' ile:=ile+1;
    {Tutaj zaczynamy od i, bo nie ma sensu zaczynać wcześniej. I tak, jeśli istnieje lider,
      to będzie wykryty przy pierwszym jego wystąpieniu}
    '''if''' (ile >= N div 2 + 1) '''then''' indeks_lidera:=i
    '''else''' i:=i+1
  '''end''';
  '''if''' indeks_lidera <> 0 '''then''' write('Liderem jest: ', A[indeks_lidera])
  '''else''' write('Nie ma lidera')
'''end'''.
Ponieważ lider musi mieć co najmiej N div 2 + 1 wystąpień w tablicy, to wystarczy go szukać na ((N+1) div 2) pierwszych pozycjach tablicy A.
 
''Koszt czasowy'': kwadratowy względem N
 
''Koszt pamięciowy'': stały
 
[[pimp:modul2_12_1.html|Wizualizacja]]
 
</div>
</div>
 
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Wskazówka 2</span>
<div class="mw-collapsible-content" style="display:none">
To zadanie ma też (piękne) rozwiązanie liniowe. Składa się ono z dwóch faz. W pierwszej wyznaczamy takie kand, że jeśli jest lider, to jest nim kand; w drugiej (banalnej) sprawdzamy, czy kand wygrał.
</div>
</div>
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie 2</span>
<div class="mw-collapsible-content" style="display:none">
'''program''' Głosowanie2(N:integer; A:array[1..N] of integer);
'''var''' ile,i,kand,lider: integer;
'''begin'''
  kand:=A[1]; //szukamy kandydata na lidera
  ile := 1;
  '''for''' i:=2 '''to''' N '''do''' '''begin'''
    '''if''' A[i]=kand '''then''' ile:=ile+1
    '''else'''
      '''if''' ile > 0 '''then''' ile:=ile-1
      '''else''' '''begin'''
        kand:=A[i];
        ile:=1;
      '''end''';
  '''end''';
  ile:=0; //sprawdzamy, czy kandydat jest liderem
  '''for''' i:=1 '''to''' N '''do'''
    '''if''' A[i]=kand '''then''' ile:=ile+1;
  '''if''' (ile >= (N div 2 + 1)) '''then''' '''begin'''
    lider:=kand;
    write('Liderem jest: ', kand);
  '''end'''
  '''else'''
    lider:=0;
  '''end'''.
''Koszt czasowy'': liniowy względem N
 
''Koszt pamięciowy'': stały
 
[[pimp:modul2_12_2.html|Wizualizacja]]
 
</div>
</div>
 
== Zadanie 13 (Arytmetyka liczb wielocyfrowych) ==
Liczby wielocyfrowe będą reprezentowane w tablicach typu liczba=array[0..N-1] of integer, N > 1, w taki sposób, że najmniej znacząca cyfra jest pod indeksem 0. Rozpatrujemy liczby przy podstawie b > 1. Napisz procedury obliczające:
# sumę liczb A i B do C. Jeśli wynik nie zmieści się w C, to wartość C nie ma znaczenia. Zmienna przepełnienie wskazuje czy do niego doszło czy nie.
# różnicę A i B do C. Jeśli wynik miałby byc liczbą ujemną, to wartość C nie ma znaczenia. Zmienna ujemny wskazuje jaki jest znak wyniku.
# iloczyn A i B do C (C powinno być tablicą dwa razy dłuższą niż A i B, żeby móc pomieścić wynik).
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie 1</span>
<div class="mw-collapsible-content" style="display:none">
'''const''' N=100;
  b=10;
'''type''' liczba = array[0..N-1] of integer;
  dwa_liczba = array[0..2*N-1] of integer;
 
Poniżej treści procedur Suma, Roznica, Iloczyn:
'''procedure''' Suma(A,B:liczba, var C:liczba, var przepełnienie:boolean);
//Sumujemy liczby zapisane w A i B do C; zmienna przepełnienie staje się true, gdy wynik nie mieści się w C.
'''var''' p: integer;
'''begin'''
  p:=0;
  '''for''' i:=0 '''to''' N-1 '''do''' '''begin'''
    C[i]:=A[i]+B[i]+p;
    '''if''' C[i] >= b '''then''' '''begin'''
      C[i]:=C[i]-b;
      p:=1;
    '''end'''
    '''else''' p:=0;
  '''end''';
  przepełnienie:=(p=1);
'''end''';
''Koszt czasowy'': liniowy względem N
 
''Koszt pamięciowy'': stały
'''procedure''' Różnica(A,B:liczba, var C:liczba, var ujemny:boolean);
//Odejmujemy od liczby zapisanej w A liczbę z B. Wynik zapisujemy w C, zmienna ujemny informuje o znaku wyniku.
'''var''' p: integer;
'''begin'''
  p:=0;
  '''for''' i:=0 '''to''' N-1 '''do''' '''begin'''
    C[i]:=(A[i]-p)-B[i];
    '''if''' C[i] < 0 '''then''' '''begin'''
      C[i]:=C[i]+b;
      p:=1;
    '''end'''
    '''else''' p:=0;
  '''end''';
  ujemny:=(p=1);
'''end''';
''Koszt czasowy'': liniowy względem N
 
''Koszt pamięciowy'': stały
  '''procedure''' Iloczyn(A,B:liczba, var C:dwa_liczba);
//Iloczyn liczb zapisanych w A i B zapisujemy w C.  
'''var''' p,i,j: integer;
'''begin'''
  p:=0;
  '''for''' i:=0 '''to''' 2*N-1 '''do''' C[i]:=0;
  '''for''' i:=0 '''to''' N-1 '''do''' '''begin'''
    '''for''' j:=0 '''to''' N-1 '''do''' '''begin'''
      w:=A[i]*B[j]+p+C[i+j];
      C[i+j]:=w '''mod''' b;
      p:=w '''div''' b;
    '''end''';
    C[i+N]:=p;
    p:=0;
  '''end''';
'''end''';
''Koszt czasowy'': kwadratowy względem N
 
''Koszt pamięciowy'': stały
</div>
</div>

Aktualna wersja na dzień 13:18, 28 maj 2020

<<< Powrót do modułu Wprowadzenie do programowania

Ta strona zawiera podstawowe zadania na tablice.

Oglądaj wskazówki i rozwiązania __SHOWALL__
Ukryj wskazówki i rozwiązania __HIDEALL__


Zadanie 1 (Flaga polska)

Tablica A typu array[1..N] of integer (N > 0) wypełniona zerami i jedynkami reprezentuje ciąg N urn w których znajdują się żetony białe (0) i czerwone (1). Podaj algorytm działania automatu przestawiającego żetony w urnach tak, by najpierw były żetony czerwone, potem białe. Robot może wykonywać dwa rodzaje operacji:

  • Kol(i) - podaje kolor żetonu w i-tej urnie (1 ≤ i ≤ n)
  • Z(i,j) - zamienia żetony z i-tej i j-tej urny (1 ≤ i,j ≤ n)

Uwagi:

  1. Operacja Kol jest bardzo kosztowna, więc zależy nam na tym by kolor każdego żetonu był sprawdzany co najwyżej raz.
  2. Robot potrafi zapamiętać tylko kilka wartości z przedziału 0..N+1.
  3. Nie można założyć, że występuje choć jeden żeton w każdym z kolorów.


Wskazówka 1

Rozwiązanie 1


Wskazówka 2

Rozwiązanie 2


Wskazówka 3

Rozwiązanie 3


Wskazówka 4

Rozwiązanie 4


Ćwiczenie 1


Ćwiczenie 2

Zadanie 2 (Flaga trójkolorowa)

Dana jest tablica A typu array[1..N] of integer (N > 0). Należy tak poprzestawiać w niej elementy, żeby najpierw były elementy ujemne, potem równe zero, a na końcu dodatnie.

Wskazówka 1

Rozwiązanie 1

Rozwiązanie 2

Zadanie 3 (Najdłuższe plateau)

Napisz program znajdujący w zadanej tablicy A typu array[1..N] of integer, N > 0, długość najdłuższego stałego segmentu (spójnego fragmentu tablicy).

Wskazówka 1

Rozwiąznie 1


Wskazówka 2

Rozwiąznie 2


Ćwiczenie 1

Inna wersja zadania

A co byłoby gdyby tablica była posortowana ?

Wskazówka 3

Rozwiąznie 3

Zadanie 4 (Segment o maksymalnej sumie)

Napisz program znajdujący w zadanej tablicy A typu array[1..N] of integer, N > 0, maksymalną sumę segmentu (spójnego fragmentu tablicy). Przyjmujemy, że segment pusty ma sumę 0.

Wskazówka 1

Rozwiązanie 1


Wskazówka 2

Rozwiązanie 2


Wskazówka 3

Rozwiązanie 3


Wskazówka 4

Rozwiązanie 4

Rozwiązanie 5

Zadanie 5 (Część wspólna zbiorów)

Dane są dwie tablice A i B typu array[1..N] of integer, N > 0. Obie są posortowane rosnąco. Należy traktując A i B jako reprezentacje dwóch zbiorów wypisać (operacją write) część wspólną tych zbiorów.

Wskazówka 1

Rozwiąznie 1

Zadanie 6 (Suma zbiorów)

Dane są dwie tablice A i B typu array[1..N] of integer, N > 0. Obie są posortowane rosnąco. Należy traktując A i B jako reprezentacje dwu zbiorów wypisać (operacją write) sumę tych zbiorów.

Wskazówka 1

Rozwiązanie 1


Ćwiczenie 1

Wskazówka 2

Rozwiązanie 2

Zadanie 7 (Podciąg)

Dane są dwie tablice A typu array[1..N] of integer i B typu array[1..M] of integer, N, M > 0. Napisz program sprawdzający, czy A jest podciągiem B (tzn. czy istnieje funkcja f, rosnąca, z 1..N w 1..M, t. ze A[i]=B[f(i)]).

Wskazówka 1

Rozwiązanie 1

Zadanie 8 (Odwracanie tablicy)

Dana tablica A typu array[0..N-1] of integer, N > 1. Napisz program odwracający kolejność elementów w A.

Wskazówka 1

Rozwiązanie 1


Wskazówka 2

Rozwiązanie 2

Zadanie 9 (Przesunięcie cykliczne)

Dana tablica A typu array[0..N-1] of integer, N > 1, i liczba naturalna k > 1. Napisz program realizujący przesunięcie cykliczne w prawo o k pól, czyli przesuwający zawartość pola A[i] na A[(i+k) mod N] dla każdego i < N.

Wskazówka 1

Rozwiązanie 1


Wskazówka 2

Rozwiązanie 2


Wskazówka 3

Rozwiązanie 3

Zadanie 10 (Następna permutacja)

Tablica A typu array[1..N] of integer, N > 0, zawiera pewną permutację liczb 1.. N. Napisz program wpisujący do A następną leksykograficznie permutację. Zakładamy, że permutacja w A nie jest ostatnia leksykograficznie.

Przykład Dla N=3 kolejne permutacje w porządku leksykograficznym wyglądają następująco:

1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1

Wskazówka 1

Rozwiąznie 1

Zadanie 11 (Segment o danej sumie)

Tablica A typu array[1..N] of integer, N > 0, zawiera tylko liczby dodatnie. Napisz program, który dla danego W typu integer sprawdza, czy w A istnieje segment o sumie W (czyli czy istnieją l, p takie, że W=A[l]+...+A[p1]).

Wskazówka 1

Rozwiązanie 1


Wskazówka 2

Rozwiązanie 2

Zadanie 12 (Głosowanie większościowe)

Dana jest tablica A typu array[1..N] of integer, N > 0. Sprawdź, czy jest w niej element wystepujący więcej niż N/2 razy i jeśli tak - wskaż go.

Wskazówka 1

Rozwiąznie 1


Wskazówka 2

Rozwiązanie 2

Zadanie 13 (Arytmetyka liczb wielocyfrowych)

Liczby wielocyfrowe będą reprezentowane w tablicach typu liczba=array[0..N-1] of integer, N > 1, w taki sposób, że najmniej znacząca cyfra jest pod indeksem 0. Rozpatrujemy liczby przy podstawie b > 1. Napisz procedury obliczające:

  1. sumę liczb A i B do C. Jeśli wynik nie zmieści się w C, to wartość C nie ma znaczenia. Zmienna przepełnienie wskazuje czy do niego doszło czy nie.
  2. różnicę A i B do C. Jeśli wynik miałby byc liczbą ujemną, to wartość C nie ma znaczenia. Zmienna ujemny wskazuje jaki jest znak wyniku.
  3. iloczyn A i B do C (C powinno być tablicą dwa razy dłuższą niż A i B, żeby móc pomieścić wynik).

Rozwiązanie 1