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

Z Studia Informatyczne
Przejdź do nawigacjiPrzejdź do wyszukiwania
Kubica (dyskusja | edycje)
Nie podano opisu zmian
Kubica (dyskusja | edycje)
Nie podano opisu zmian
Linia 1: Linia 1:
==Praca domowa==
== Praca domowa ==
* Napisz procedurę <tt>dubluj</tt>, która dubluje elementy listy. Na przykład, <tt>dubluj [1;2;3] = [1;1;2;2;3;3]</tt>.
* Napisz procedurę <tt>dubluj</tt>, która dubluje elementy listy. Na przykład, <tt>dubluj [1;2;3] = [1;1;2;2;3;3]</tt>.
* 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.
* Zadeklaruj wariantowy typ danych reprezentujący abstrakcyjną składnię wyrażeń arytmetycznych. Napisz procedurę obliczającą wartość wyrażenia.


==Ćwiczenia==
== Ćwiczenia ==


Ćwiczenie programistyczne na listy:
Ćwiczenie programistyczne na listy:
* <math>N</math>-ty element listy.
* Zaimplementuj procedurę zwracającą <math>n</math>-ty element listy.
* Lista <math>n</math> pierwszych liczb naturalnych.
* Napisz procedurę tworzącą listę <math>n</math> pierwszych liczb naturalnych.
* Odwrócenie listy <tt>rev</tt>. Wersje o liniowej (z <tt>::</tt>) i kwadratowej (z <tt>@</tt>) złożoności czasowej. Porównać je.
* Zaimplementuj procedurę <tt>rev</tt> odwrócającą listę. (Zwróć uwagę, że rozwiązując to zadanie można korzystać z <tt>::</tt> lub <tt>@</tt>, co daje liniową lub kwadratową złożoność czasową.)
* Sklejanie list <tt>append</tt>. Obliczenie ciągu różnicowego zadanej listy liczb całkowitych.
* Zaimplementuj procedurę <tt>append</tt> sklejającą listy.  
* Obliczenie listy kolejnych ciągów różnicowych zadanej 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 zadanej listy liczb całkowitych.
* Napisz procedurę, której wynikiem jest para: minimum i maksimum elementów z listy. Procedura ta powinna wykonywać jak najmniej porównań (ale bez przeginania).
* Napisz procedurę obliczającą listę kolejnych ciągów różnicowych zadanej listy liczb całkowitych.
 
* Napisz procedurę, której wynikiem jest para: minimum i maksimum elementów z listy. Procedura ta powinna wykonywać co najwyżej <math>\frac{3}{2} n</math> porównań.  
Ćwiczenia na inne struktury danych:
* Napisz procedurę <tt>flatten</tt> rozwijającą listę list do listy elementów.  Na przykład, <tt>flatten [[1; 2]; []; [3; 4; 5]] = [1; 2; 3; 4; 5]</tt>.
* Zdefiniuj typ reprezentujący drzewa o wierzchołkach dowolnego (skończonego stopnia).
* Zdefiniuj trochę procedur operujących na takich drzewach.
* Zdefiniuj typ reprezentujący dni tygodnia, miesiące i datę.
* Zdefiniuj procedurę obliczającą na podstawie daty dzień tygodnia. Możesz założyć, że dana jest procedura <tt>sylwester</tt>, która na podstawie roku określa jakiego dnia tygodnia był Sylwester.
 
Proste ćwiczenia na listy. Można je wykonywać w dwóch wariantach: korzystając ze wzorców, lub z procedur <tt>hd</tt>, <tt>tl</tt> i (zdefiniowanej samemu) <tt>null</tt>.
* Rozwinięcie listy list do listy (<tt>flatten</tt>).
* Napisz procedurę <tt>last</tt>, której wynikiem jest ostatni element listy.  
* Napisz procedurę <tt>last</tt>, której wynikiem jest ostatni element listy.  
* 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>?
Linia 31: Linia 26:
** liczby <math>a</math>, <math>b</math> i <math>c</math> spełniają nierówność trójkąta, czyli <math>c < a + b</math>.
** liczby <math>a</math>, <math>b</math> i <math>c</math> spełniają nierówność trójkąta, czyli <math>c < a + b</math>.
* Zdefiniuj taką funkcję <tt>przedziały:int list <math>\to</math> int*int</tt>, że <tt>przedzialy</tt><math>\ [a_1, \dots, a_n] = (k,l)</math>, gdzie jest to taka para liczb <math>1 \le k \le l \le n</math>, dla której suma <math>a_k + \cdots + a_l</math> jest największa. Oblicz i podaj złożoność Twojego rozwiązania (jako funkcję <math>n</math>).
* Zdefiniuj taką funkcję <tt>przedziały:int list <math>\to</math> int*int</tt>, że <tt>przedzialy</tt><math>\ [a_1, \dots, a_n] = (k,l)</math>, gdzie jest to taka para liczb <math>1 \le k \le l \le n</math>, dla której suma <math>a_k + \cdots + a_l</math> jest największa. Oblicz i podaj złożoność Twojego rozwiązania (jako funkcję <math>n</math>).
Ćwiczenia na inne struktury danych:
* Zdefiniuj typ reprezentujący drzewa o wierzchołkach dowolnego (skończonego stopnia).
* Zdefiniuj trochę procedur operujących na takich drzewach.
* Zdefiniuj typ reprezentujący dni tygodnia, miesiące i datę.
* Zdefiniuj procedurę obliczającą na podstawie daty dzień tygodnia. Możesz założyć, że dana jest procedura <tt>sylwester</tt>, która na podstawie roku określa jakiego dnia tygodnia był Sylwester.


Ćwiczenia na inne struktury danych:
Ćwiczenia na inne struktury danych:
Linia 36: Linia 37:
* 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ł.  
* 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ł.  
* Napisz procedurę, która przekształca dane drzewo binarne w wyważone drzewo binarne, zachowując kolejność elementów w porządku infiksowym.  
* Napisz procedurę, która przekształca dane drzewo binarne w wyważone drzewo binarne, zachowując kolejność elementów w porządku infiksowym.  
* Zaimplementować 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 (jeśli czasu mało).
* Rozszerzyć implementację kolejek o wkładanie i wyjmowanie elementów z obydwu stron.
* Rozszerzyć implementację kolejek o wkładanie i wyjmowanie elementów z obydwu stron.
* Dany jest typ danych reprezentujący (mało efektywnie) liczby naturalne:  <tt>type nat = ZERO | SUCC of nat;;</tt>. Zaimplementuj operacje arytmetyczne na takich liczbach.  
* Dany jest typ danych reprezentujący (mało efektywnie) liczby naturalne:  <tt>type nat = ZERO | SUCC of nat;;</tt>. Zaimplementuj operacje arytmetyczne na takich liczbach.  
* Zaimplementuj takie operacje na zbiorach, jak suma, przecięcie, różnica.
* Zaimplementuj takie operacje na zbiorach, jak suma, przecięcie, różnica.
* Zadeklaruj typ danych reprezentujący abstrakcyjną składnię wyrażeń arytmetycznych. Napisz procedurę obliczającą wartość wyrażenia.

Wersja z 15:07, 24 sie 2006

Praca domowa

  • Napisz procedurę dubluj, która dubluje elementy listy. Na przykład, dubluj [1;2;3] = [1;1;2;2;3;3].
  • 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.
  • Zadeklaruj wariantowy typ danych reprezentujący abstrakcyjną składnię wyrażeń arytmetycznych. Napisz procedurę obliczającą wartość wyrażenia.

Ćwiczenia

Ćwiczenie programistyczne na listy:

  • Zaimplementuj procedurę zwracającą n-ty element listy.
  • Napisz procedurę tworzącą listę n pierwszych liczb naturalnych.
  • Zaimplementuj procedurę rev odwrócającą listę. (Zwróć uwagę, że rozwiązując to zadanie można korzystać z :: lub @, co daje liniową lub kwadratową złożoność czasową.)
  • Zaimplementuj procedurę append sklejającą listy.
  • Ciąg różnicowy ciągu (x1,,xn) to ciąg postaci (x2x1,,xnxn1). Napisz procedurę obliczającą ciąg różnicowy zadanej listy liczb całkowitych.
  • Napisz procedurę obliczającą listę kolejnych ciągów różnicowych zadanej listy liczb całkowitych.
  • Napisz procedurę, której wynikiem jest para: minimum i maksimum elementów z listy. Procedura ta powinna wykonywać co najwyżej 32n porównań.
  • 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].
  • Napisz procedurę last, której wynikiem jest ostatni element listy.
  • 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?
  • Napisz procedurę posumuj, która dla danej niemalejącej listy dodatnich liczb całkowitych (a1an) oblicza listę (b1bn), gdzie bi=k=ainak. (Pamiętaj o tym, że jeśli m>n, k=mnak=0.)
  • Zaimplementuj sortowanie: przez scalanie lub quick-sort.
  • Zaimplementuj pakiet arytmetyczny nieograniczonych liczb całkowitych.
  • Napisz program wybierający większość z listy większościowej; uzasadnij jego poprawność. Uwaga: to zadanie można rozwiązać probabilistycznie: metodą Las Vegas: wylosuj element i sprawdź czy to większość; policz oczekiwaną złożoność,
  • Tomek ma zabawkę, z której wystają drewniane słupki różnej wysokości. Jednym uderzeniem młotka może wbić lub wysunąć wybrany słupek o 1. Napisz procedurę słupki, która dla danej listy początkowych wysokości słupków obliczy minimalną liczbę uderzeń młotka potrzebnych do wyrównania wysokości słupków. Napisz funkcję max_diff : int list int, która dla niepustej listy [x1;;xn] znajdzie maksymalną różnicę xjxi dla 1i<jn. Jaką złożoność ma Twój program.
  • Napisz funkcję 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.
  • Zdefiniuj taką funkcję przedziały:int list int*int, że przedzialy [a1,,an]=(k,l), gdzie jest to taka para liczb 1kln, dla której suma ak++al jest największa. Oblicz i podaj złożoność Twojego rozwiązania (jako funkcję n).

Ćwiczenia na inne struktury danych:

  • Zdefiniuj typ reprezentujący drzewa o wierzchołkach dowolnego (skończonego stopnia).
  • Zdefiniuj trochę procedur operujących na takich drzewach.
  • Zdefiniuj typ reprezentujący dni tygodnia, miesiące i datę.
  • 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.

Ćwiczenia na inne struktury danych:

  • Napisz całe mnóstwo procedur operujących na drzewach. Mogą to być znane Ci operacje dotyczące drzew, lub odpowiedniki operacji na listach.
  • 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ł.
  • Napisz procedurę, która przekształca dane drzewo binarne w wyważone drzewo binarne, zachowując kolejność elementów w porządku infiksowym.
  • Rozszerzyć implementację kolejek o wkładanie i wyjmowanie elementów z obydwu stron.
  • Dany jest typ danych reprezentujący (mało efektywnie) liczby naturalne: type nat = ZERO | SUCC of nat;;. Zaimplementuj operacje arytmetyczne na takich liczbach.
  • Zaimplementuj takie operacje na zbiorach, jak suma, przecięcie, różnica.