Programowanie funkcyjne/Struktury danych/Ćwiczenia: Różnice pomiędzy wersjami

Z Studia Informatyczne
Przejdź do nawigacjiPrzejdź do wyszukiwania
 
(Nie pokazano 2 pośrednich wersji utworzonych przez tego samego użytkownika)
Linia 93: Linia 93:
Zaimplementuj procedurę zwracającą <math>n</math>-ty element listy.
Zaimplementuj procedurę zwracającą <math>n</math>-ty element listy.
}}
}}
{{rozwiazanie|||
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed"> <div class="mw-collapsible-content" style="display:none">
<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</span>
<div class="mw-collapsible-content" style="display:none">
   '''let rec''' nth l n =
   '''let rec''' nth l n =
     '''match''' l '''with'''
     '''match''' l '''with'''
       h::t ->
       h::t ->
         '''if''' n = 0 '''then''' h '''else''' nth t (n-1);;
         '''if''' n = 0 '''then''' h '''else''' nth t (n-1);;
</div></div>}}
</div></div>


{{cwiczenie|[Lista <math>[0;1;\dots;n]</math>]||
{{cwiczenie|[Lista <math>[0;1;\dots;n]</math>]||
Napisz procedurę tworzącą listę <math>n</math> pierwszych liczb naturalnych.
Napisz procedurę tworzącą listę <math>n</math> pierwszych liczb naturalnych.
}}
}}
{{rozwiazanie|||
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed"> <div class="mw-collapsible-content" style="display:none">
<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</span>
<div class="mw-collapsible-content" style="display:none">
   '''let''' naturalne n =
   '''let''' naturalne n =
     '''let rec''' pom k =
     '''let rec''' pom k =
       '''if''' k >= n '''then''' [] '''else''' k :: pom (k+1)
       '''if''' k >= n '''then''' [] '''else''' k :: pom (k+1)
     '''in''' pom 0;;
     '''in''' pom 0;;
</div></div>}}
</div></div>


{{cwiczenie|[append]||
{{cwiczenie|[append]||
Zaimplementuj procedurę <tt>append</tt> sklejającą listy.  
Zaimplementuj procedurę <tt>append</tt> sklejającą listy.  
}}
}}
{{rozwiazanie|||
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed"> <div class="mw-collapsible-content" style="display:none">
<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</span>
<div class="mw-collapsible-content" style="display:none">
   '''let rec''' append l1 l2 =
   '''let rec''' append l1 l2 =
     '''match''' l1 '''with'''
     '''match''' l1 '''with'''
       []  -> l2 |
       []  -> l2 |
       h::t -> h :: append t l2;;
       h::t -> h :: append t l2;;
</div></div>}}
</div></div>


{{cwiczenie|[ciąg różnicowy]||
{{cwiczenie|[ciąg różnicowy]||
Ciąg różnicowy ciągu <math>(x_1, \dots, x_n)</math> to ciąg postaci <math>(x_2-x_1,\dots,x_n-x_{n-1})</math>. Napisz procedurę obliczającą ciąg różnicowy żądanej listy liczb całkowitych.
Ciąg różnicowy ciągu <math>(x_1, \dots, x_n)</math> to ciąg postaci <math>(x_2-x_1,\dots,x_n-x_{n-1})</math>. Napisz procedurę obliczającą ciąg różnicowy żądanej listy liczb całkowitych.
}}
}}
{{rozwiazanie||1|
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed"> <div class="mw-collapsible-content" style="display:none">
<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</span>
<div class="mw-collapsible-content" style="display:none">
   '''let rec''' roznicowy l =
   '''let rec''' roznicowy l =
     '''match''' l '''with'''
     '''match''' l '''with'''
       h1::(h2::_ '''as''' t) -> (h2-h1) :: roznicowy t |
       h1::(h2::_ '''as''' t) -> (h2-h1) :: roznicowy t |
       _                -> [];;
       _                -> [];;
</div></div>}}
</div></div>


{{rozwiazanie||2|
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed"> <div class="mw-collapsible-content" style="display:none">
<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">
   '''let''' roznicowy l =
   '''let''' roznicowy l =
     '''let rec''' pom a l =
     '''let rec''' pom a l =
Linia 142: Linia 152:
         _                  -> rev a
         _                  -> rev a
     '''in''' pom [] l;;
     '''in''' pom [] l;;
</div></div>}}
</div></div>


{{cwiczenie|[ciąg ciągów różnicowych]||
{{cwiczenie|[ciąg ciągów różnicowych]||
Napisz procedurę obliczającą listę kolejnych ciągów różnicowych zadanej listy liczb całkowitych, tzn.: daną listę, jej ciąg różnicowy, ciąg różnicowy ciągu różnicowego itd.
Napisz procedurę obliczającą listę kolejnych ciągów różnicowych zadanej listy liczb całkowitych, tzn.: daną listę, jej ciąg różnicowy, ciąg różnicowy ciągu różnicowego itd.
}}
}}
{{rozwiazanie|||
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed"> <div class="mw-collapsible-content" style="display:none">
<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</span>
<div class="mw-collapsible-content" style="display:none">
   '''let rec''' roznicowe l =
   '''let rec''' roznicowe l =
     '''if''' l = [] '''then''' [[]] '''else''' l :: roznicowe (roznicowy l);;
     '''if''' l = [] '''then''' [[]] '''else''' l :: roznicowe (roznicowy l);;
</div></div>}}
</div></div>


{{cwiczenie|[minimum-maksimum]||
{{cwiczenie|[minimum-maksimum]||
Linia 160: Linia 172:
Napisz procedurę <tt>last</tt>, której wynikiem jest ostatni element (niepustej) listy.  
Napisz procedurę <tt>last</tt>, której wynikiem jest ostatni element (niepustej) listy.  
}}
}}
{{rozwiazanie|||
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed"> <div class="mw-collapsible-content" style="display:none">
<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</span>
<div class="mw-collapsible-content" style="display:none">
   '''let rec''' last (h::t) =  
   '''let rec''' last (h::t) =  
     '''if''' t = [] '''then''' h '''else''' last t;;
     '''if''' t = [] '''then''' h '''else''' last t;;
</div></div>}}
</div></div>


{{cwiczenie|[<tt>head</tt> i <tt>tail</tt>]||
{{cwiczenie|[<tt>head</tt> i <tt>tail</tt>]||
Napisz procedury <tt>head</tt> i <tt>tail</tt>, które dla zadanej listy <math>l</math> i liczby całkowitej <math>n</math> zwracają pierwsze/ostatnie <math>n</math> elementów listy <math>l</math>. Jeśli lista <math>l</math> ma mniej elementów niż <math>n</math>, to wynikiem powinna być cała lista <math>l</math>. (Nazwy pochodzą od programów <tt>head</tt> i <tt>tail</tt> w Uniksie.) Co jest wynikiem <tt>tail (head l n) 1</tt>?
Napisz procedury <tt>head</tt> i <tt>tail</tt>, które dla zadanej listy <math>l</math> i liczby całkowitej <math>n</math> zwracają pierwsze/ostatnie <math>n</math> elementów listy <math>l</math>. Jeśli lista <math>l</math> ma mniej elementów niż <math>n</math>, to wynikiem powinna być cała lista <math>l</math>. (Nazwy pochodzą od programów <tt>head</tt> i <tt>tail</tt> w Uniksie.) Co jest wynikiem <tt>tail (head l n) 1</tt>?}}
<div class="mw-collapsible mw-made=collapsible mw-collapsed"> <div class="mw-collapsible-content" style="display:none">
<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</span>
<div class="mw-collapsible-content" style="display:none">
   '''let''' head l n =  
   '''let''' head l n =  
     '''let rec''' head_pom l n a =  
     '''let rec''' head_pom l n a =  
Linia 182: Linia 198:
     '''in'''
     '''in'''
       skip l (max (length l - n) 0);;   
       skip l (max (length l - n) 0);;   
</div></div>}}
</div></div>


{{cwiczenie|[sortowanie]||
{{cwiczenie|[sortowanie]||
Linia 193: Linia 209:


{{cwiczenie|[lista większościowa]||
{{cwiczenie|[lista większościowa]||
Lista większościowa to taka lista, na której ponad połowa elementów jest sobie równa, a ich wartość nazywa się właśnie większością. Napisz procedurę wybierającą większość z listy większościowej; uzasadnij jej poprawność.  
Lista większościowa to taka lista, na której ponad połowa elementów jest sobie równa, a ich wartość nazywa się właśnie większością. Napisz procedurę wybierającą większość z listy większościowej; uzasadnij jej poprawność.}}
<div class="mw-collapsible mw-made=collapsible mw-collapsed"> <div class="mw-collapsible-content" style="display:none">
<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</span>
<div class="mw-collapsible-content" style="display:none">
   '''let''' majority l =  
   '''let''' majority l =  
     '''let rec''' scan c k l =  
     '''let rec''' scan c k l =  
Linia 204: Linia 222:
           '''else''' scan c (k-1) t
           '''else''' scan c (k-1) t
   '''in''' scan (hd l) 0 l;;
   '''in''' scan (hd l) 0 l;;
</div></div>}}
</div></div>


{{cwiczenie|[trójki]||
{{cwiczenie|[trójki]||

Aktualna wersja na dzień 13:57, 1 cze 2020

Praca domowa

  • Napisz procedurę dubluj, która dubluje elementy listy, na przykład dubluj [1;2;3] = [1;1;2;2;3;3].
  • Punkty (kratowe) na płaszczyźnie reprezentujemy jako pary liczb całkowitych. Prostokąty o bokach równoległych do osi układu współrzędnych reprezentujemy jako pary punktów: dolny lewy i górny prawy róg. Napisz procedurę, która dla dwóch danych prostokątów wyznacza ich przecięcie. Podaj w jaki sposób reprezentowany jest zbiór pusty.
  • Zadeklaruj wariantowy typ danych reprezentujący abstrakcyjną składnię wyrażeń arytmetycznych. Napisz procedurę obliczającą wartość wyrażenia.

Ćwiczenia

Ćwiczenie [rev]

Zaimplementuj procedurę rev odwracającą listę. (Zwróć uwagę, że rozwiązując to zadanie można korzystać z :: lub @, co daje liniową lub kwadratową złożoność czasową.)

Rozwiązanie nieefektywne, ale proste

Rozwiązanie efektywne

Ćwiczenie [Przeplot list]

Napisz procedurę shuffle: α list → α list → α list, która dla danych dwóch list postaci [x1;x2;;xn] oraz [y1;y2;;ym] wyznaczy listę postaci [x1;y1;x2;y2;]. Jeżeli jedna z list jest dłuższa, to jej końcowe elementy trafiają na koniec listy wyikowej. Na przykład: shuffle [3; 2; 8; 1; 9; 3; 6] [5; 7; 0] = [3; 5; 2; 7; 8; 0; 1; 9; 3; 6].


Ćwiczenie [flatten]

Napisz procedurę flatten rozwijającą listę list do listy elementów. Na przykład, flatten [[1; 2]; []; [3; 4; 5]] = [1; 2; 3; 4; 5].

Rozwiązanie

Ćwiczenie [Średnica drzew]

Dana jest definicja typu: type tree = Node of tree * tree | Leaf. Odległością między dwoma wierzchołkami (Node) w drzewie nazywamy minimalną liczbę krawędzi jakie trzeba przejść z jednego wierzchołka do drugiego. Średnicą drzewa nazwiemy maksymalną odległość między dwoma węzłami (Node) w drzewie. Przyjmujemy, że średnica pustego drzewa (Leaf) jest równa 0. Napisz procedurę srednica: tree -> int, która oblicza średnicę danego drzewa.

Rozwiązanie

Ćwiczenie [Drzewa dowolnego stopnia]

Zdefiniuj typ reprezentujący drzewa o wierzchołkach dowolnego (skończonego) stopnia. Zdefiniuj trochę procedur operujących na takich drzewach, np. procedury wyznaczające listy elementów w porządku prefiksowym i postfiksowym.

Laboratorium

Ćwiczenia programistyczne na listy:

Ćwiczenie [n-ty element listy]

Zaimplementuj procedurę zwracającą n-ty element listy.

Rozwiązanie

Ćwiczenie [Lista [0;1;;n]]

Napisz procedurę tworzącą listę n pierwszych liczb naturalnych.

Rozwiązanie

Ćwiczenie [append]

Zaimplementuj procedurę append sklejającą listy.

Rozwiązanie

Ćwiczenie [ciąg różnicowy]

Ciąg różnicowy ciągu (x1,,xn) to ciąg postaci (x2x1,,xnxn1). Napisz procedurę obliczającą ciąg różnicowy żądanej listy liczb całkowitych.

Rozwiązanie


Rozwiązanie 2

Ćwiczenie [ciąg ciągów różnicowych]

Napisz procedurę obliczającą listę kolejnych ciągów różnicowych zadanej listy liczb całkowitych, tzn.: daną listę, jej ciąg różnicowy, ciąg różnicowy ciągu różnicowego itd.

Rozwiązanie

Ćwiczenie [minimum-maksimum]

Napisz procedurę, której wynikiem jest para: minimum i maksimum elementów z listy. Procedura ta powinna wykonywać co najwyżej 32n porównań.

Ćwiczenie [last]

Napisz procedurę last, której wynikiem jest ostatni element (niepustej) listy.

Rozwiązanie

Ćwiczenie [head i tail]

Napisz procedury head i tail, które dla zadanej listy l i liczby całkowitej n zwracają pierwsze/ostatnie n elementów listy l. Jeśli lista l ma mniej elementów niż n, to wynikiem powinna być cała lista l. (Nazwy pochodzą od programów head i tail w Uniksie.) Co jest wynikiem tail (head l n) 1?

Rozwiązanie

Ćwiczenie [sortowanie]

Zaimplementuj sortowanie: przez scalanie lub quick-sort.

Ćwiczenie [arytmetyka nieograniczonych liczb całkowitych]

Zaimplementuj pakiet arytmetyczny nieograniczonych liczb całkowitych.

Ćwiczenie [lista większościowa]

Lista większościowa to taka lista, na której ponad połowa elementów jest sobie równa, a ich wartość nazywa się właśnie większością. Napisz procedurę wybierającą większość z listy większościowej; uzasadnij jej poprawność.

Rozwiązanie

Ćwiczenie [trójki]

Napisz procedurę trójki:int list -> (int * int * int) list, która dla zadanej listy dodatnich liczb całkowitych, uporządkowanej rosnąco, stworzy listę takich trójek (a,b,c) liczb z danej listy, że:

  • a<b<c,
  • liczby a, b i c spełniają nierówność trójkąta, czyli c<a+b.


Ćwiczenia na inne struktury danych:

Ćwiczenie [arytmetyka liczb wymiernych]

Zaimplementuj arytmetykę liczb wymiernych, reprezentując liczby wymierne jako rekordy złożone z licznika i mianownika. Implementacja może być uproszczona, np. bez skracania ułamków i bez normalizacji znaków.

Ćwiczenie [reprezentacja daty]

Zdefiniuj typ reprezentujący dni tygodnia, miesiące i datę.

Ćwiczenie [dzień tygodnia]

Zdefiniuj procedurę obliczającą na podstawie daty dzień tygodnia. Możesz założyć, że dana jest procedura sylwester, która na podstawie roku określa jakiego dnia tygodnia był Sylwester.

Ćwiczenie [słaby warunek BST]

Napisz procedurę, która dla dowolnego drzewa binarnego poprawia je tak, że spełnia ono słabszą wersję warunku BST: dla dowolnego węzła, lewy syn nie jest większy, a prawy nie jest mniejszy niż węzeł.

Ćwiczenie [wyważanie drzewa BST]

Napisz procedurę, która przekształca dane drzewo binarne w wyważone drzewo binarne, zachowując kolejność elementów w porządku infiksowym.

Ćwiczenie [zbiory jako drzewa BST]

Zaimplementuj takie operacje na zbiorach (reprezentowanych jako drzewa BST) jak suma, przecięcie i różnica.

Ćwiczenie [kolejki dwustronne]

Rozszerz implementację kolejek o wkładanie i wyjmowanie elementów z obydwu stron. Jaką własność powinna zachowywać procedura balance, aby koszt zamortyzowany operacji był stały?

Ćwiczenie [liczby naturalne]

Dany jest typ danych reprezentujący (mało efektywnie) liczby naturalne:
 type nat = ZERO | SUCC of nat;;

Zaimplementuj operacje arytmetyczne na takich liczbach.