Programowanie funkcyjne/Zadania egzaminacyjne: 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
 
(Nie pokazano 1 pośredniej wersji utworzonej przez tego samego użytkownika)
Linia 8: Linia 8:


* Napisz procedurę <tt>przedziały:int list -> int*int</tt>, która dla danej listy <math>[a_1, \dots, a_n]</math> oblicza taką parę liczb <math>(k,l)</math>, <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.
* Napisz procedurę <tt>przedziały:int list -> int*int</tt>, która dla danej listy <math>[a_1, \dots, a_n]</math> oblicza taką parę liczb <math>(k,l)</math>, <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.
* Napisz procedurę <tt>podział: int list -> int list list</tt>, która dla danej listy liczb całkowitych <math>l=[x_1; x_2; \dots; x_n]</math> podzieli ją na listę list <math>[l_1; \dots; l_k]</math>, przy czym:
** <math>l = l_1 @ \dots @ l_k</math>,
** każda z list <math>l_i</math> jest ściśle rosnąca,
** <math>k</math> jest najmniejsze możliwe.
:Przykład:
podział [1;3;0;-2;-2;4;9] = [[1; 3]; [0]; [-2]; [-2;4;9]]
: Rozwiązując to zadanie nie wolno Ci tworzyć żadnych własnych procedur rekurencyjnych, ani używać pętli. Powinieneś natomiast użyć standardowych procedur wyższych rzędów przetwarzających listy.
* Napisz procedurę <tt>podział: int list -> int list list</tt>, która dla danej listy liczb całkowitych <math>l=[x_1; x_2; \dots; x_n]</math> podzieli ją na listę list <math>[l_1; \dots; l_k]</math>, przy czym:
** <math>l = l_1 @ \dots @ l_k</math>,
** dla każdej listy <math>l_i</math> wszystkie elementy na takiej liście są tego samego znaku,
** <math>k</math> jest najmniejsze możliwe.
: Przykład:
podział [1;3;0;-2;-2;-4;9] = [[1; 3]; [0]; [-2;-2;-4]; [9]]
: Rozwiązując to zadanie nie wolno Ci tworzyć żadnych własnych procedur rekurencyjnych, ani używać pętli. Powinieneś natomiast użyć standardowych procedur wyższych rzędów przetwarzających listy.


* Napisz procedurę <tt>podziel: int list -> int list list</tt>, która dla danej listy <math>[a_1; a_2; \dots; a_n]</math> zawierającej permutację zbioru <math>\{1, 2, \dots, n\}</math> znajdzie jej podział na jak najliczniejszą listę list postaci:
* Napisz procedurę <tt>podziel: int list -> int list list</tt>, która dla danej listy <math>[a_1; a_2; \dots; a_n]</math> zawierającej permutację zbioru <math>\{1, 2, \dots, n\}</math> znajdzie jej podział na jak najliczniejszą listę list postaci:
Linia 27: Linia 47:
</math></center>
</math></center>
: Przyjmujemy, że wynikiem dla listy pustej jest lista pusta.
: Przyjmujemy, że wynikiem dla listy pustej jest lista pusta.
: Przykład: <tt>podziel [2; 3; 1; 6; 5; 4; 7; 9; 10; 11; 8] = [[2; 3; 1]; [6; 5; 4]; [7]; [9; 10; 11; 8]]</tt>.
: Przykład:  
 
podziel [2; 3; 1; 6; 5; 4; 7; 9; 10; 11; 8] = [[2; 3; 1]; [6; 5; 4]; [7]; [9; 10; 11; 8]]
 
: Rozwiązując to zadanie powinieneś skorzystać z rekurencji, ale wolno Ci korzystać wyłącznie z rekurencji ogonowej.
: Rozwiązując to zadanie powinieneś skorzystać z rekurencji, ale wolno Ci korzystać wyłącznie z rekurencji ogonowej.


Linia 33: Linia 56:
: Lista list <math>[c_1; \dots; c_k]</math>, gdzie listy <math>c_i</math> dla <math>1 \leq i \leq k</math> reprezentują cykle, reprezentuje permutację złożoną z tych cykli. Możesz założyć, że wszystkie cykle są rozłączne.
: Lista list <math>[c_1; \dots; c_k]</math>, gdzie listy <math>c_i</math> dla <math>1 \leq i \leq k</math> reprezentują cykle, reprezentuje permutację złożoną z tych cykli. Możesz założyć, że wszystkie cykle są rozłączne.
: Przyjmujemy, że dla wartości <math>x</math> nie występujących na żadnej z list <math>c_i</math> wynikiem <tt>buduj_permutacje</tt> <math>[c_0; \dots; c_k]\ x</math> jest <math>x</math>.  W szczególności, przyjmujemy, że pusta lista reprezentuje permutację identycznościową.
: Przyjmujemy, że dla wartości <math>x</math> nie występujących na żadnej z list <math>c_i</math> wynikiem <tt>buduj_permutacje</tt> <math>[c_0; \dots; c_k]\ x</math> jest <math>x</math>.  W szczególności, przyjmujemy, że pusta lista reprezentuje permutację identycznościową.
: Przykład:
   '''let''' p = buduj_permutacje [[2; 1]; [8; 3; 4]; [5; 7; 6; 10]; [11]];;
   '''let''' p = buduj_permutacje [[2; 1]; [8; 3; 4]; [5; 7; 6; 10]; [11]];;
   map p [1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12];;
   map p [1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12];;
Linia 43: Linia 68:
: Napisz procedurę <tt>kompresuj: int list -> int list</tt> kompresującą zadaną listę. Lista wynikowa powinna być oczywiście jak najkrótsza.
: Napisz procedurę <tt>kompresuj: int list -> int list</tt> kompresującą zadaną listę. Lista wynikowa powinna być oczywiście jak najkrótsza.
: Rozwiązując to zadanie nie wolno Ci tworzyć żadnych własnych procedur rekurencyjnych. Powinieneś natomiast użyć procedur wyższych rzędów przetwarzających listy, znanych z wykładów.
: Rozwiązując to zadanie nie wolno Ci tworzyć żadnych własnych procedur rekurencyjnych. Powinieneś natomiast użyć procedur wyższych rzędów przetwarzających listy, znanych z wykładów.
: Przykład: <tt>kompresuj [1; 2; 2; 5; 11; 11; 2] = [1; 6; 9; 42; 3]</tt>.
: Przykład:  
 
kompresuj [1; 2; 2; 5; 11; 11; 2] = [1; 6; 9; 42; 3]
 
* Zdefiniuj w sposób kontynuacyjny procedurę <tt>pierwsze: int -> (int -> 'a) -> 'a</tt>, która dla danej dodatniej liczby całkowitej oblicza sumę liczb pierwszych występujących w jej rozkładzie. Wszelkie procedury pomocnicze powinny również być zdefiniowane w sposób kontynuacyjny.
 
* Napisz procedurę <tt>codrugi: 'a stream -> 'a stream</tt>, która przekształca strumień postaci <math>(s_1; s_2; s_3; s_4; \dots)</math> w strumień postaci <math>(s_1; s_3; s_5; \dots)</math>. Powinna ona działać zarówno dla strumieni skończonych, jak i nieskończonych.
 
* Dany jest nieskończony strumień nieskończonych strumieni <math>s</math>. Zdefiniuj jego ,,przekątną'' <math>p</math>.  


* Zdefiniuj w sposób uwikłany strumień złożony z tych dodatnich liczb całkowitych, które w rozkładzie na czynniki pierwsze mają tylko liczby 2 i 3, oraz rozkładają się na nieparzystą liczbę czynników pierwszych.
* Zdefiniuj w sposób uwikłany strumień złożony z tych dodatnich liczb całkowitych, które w rozkładzie na czynniki pierwsze mają tylko liczby 2 i 3, oraz rozkładają się na nieparzystą liczbę czynników pierwszych.

Aktualna wersja na dzień 18:07, 8 mar 2007

Propozycje zadań egzaminacyjnych:

  • 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.)
  • 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 1ijn. Jaką złożoność ma Twoja procedura?
  • Napisz procedurę przedziały:int list -> int*int, która dla danej listy [a1,,an] oblicza taką parę liczb (k,l), 1kln, dla której suma ak++al jest największa. Oblicz i podaj złożoność Twojego rozwiązania.
  • Napisz procedurę podział: int list -> int list list, która dla danej listy liczb całkowitych l=[x1;x2;;xn] podzieli ją na listę list [l1;;lk], przy czym:
    • Parser nie mógł rozpoznać (błąd składni): {\displaystyle l = l_1 @ \dots @ l_k} ,
    • każda z list li jest ściśle rosnąca,
    • k jest najmniejsze możliwe.
Przykład:
podział [1;3;0;-2;-2;4;9] = [[1; 3]; [0]; [-2]; [-2;4;9]]
Rozwiązując to zadanie nie wolno Ci tworzyć żadnych własnych procedur rekurencyjnych, ani używać pętli. Powinieneś natomiast użyć standardowych procedur wyższych rzędów przetwarzających listy.
  • Napisz procedurę podział: int list -> int list list, która dla danej listy liczb całkowitych l=[x1;x2;;xn] podzieli ją na listę list [l1;;lk], przy czym:
    • Parser nie mógł rozpoznać (błąd składni): {\displaystyle l = l_1 @ \dots @ l_k} ,
    • dla każdej listy li wszystkie elementy na takiej liście są tego samego znaku,
    • k jest najmniejsze możliwe.
Przykład:
podział [1;3;0;-2;-2;-4;9] = [[1; 3]; [0]; [-2;-2;-4]; [9]]
Rozwiązując to zadanie nie wolno Ci tworzyć żadnych własnych procedur rekurencyjnych, ani używać pętli. Powinieneś natomiast użyć standardowych procedur wyższych rzędów przetwarzających listy.
  • Napisz procedurę podziel: int list -> int list list, która dla danej listy [a1;a2;;an] zawierającej permutację zbioru {1,2,,n} znajdzie jej podział na jak najliczniejszą listę list postaci:
[[a1;a2;;ak1];[ak1+1;ak1+2;;ak2];;[akm1+1;akm1+2;;akm]]
taką że:
{a1,a2,,ak1}={1,2,,k1}(równość zbiorów),{ak1+1,ak1+2,,ak2}={k1+1,k1+2,,k2},{akm1+1,akm1+2,,akm}={km1+1,km1+2,,km}
Przyjmujemy, że wynikiem dla listy pustej jest lista pusta.
Przykład:
podziel [2; 3; 1; 6; 5; 4; 7; 9; 10; 11; 8] = [[2; 3; 1]; [6; 5; 4]; [7]; [9; 10; 11; 8]]
Rozwiązując to zadanie powinieneś skorzystać z rekurencji, ale wolno Ci korzystać wyłącznie z rekurencji ogonowej.
  • Napisz procedurę buduj_permutacje: 'a list list -> 'a -> 'a, która przyjmuje permutację w postaci rozkładu na cykle i zwraca ją w postaci procedury. Lista składowa postaci [a1;;an], gdzie aiaj dla 1i<jn, reprezentuje cykl, czyli permutację przeprowadzającą ai na a(imodn)+1 dla 1in. Możesz założyć, że listy składowe są niepuste.
Lista list [c1;;ck], gdzie listy ci dla 1ik reprezentują cykle, reprezentuje permutację złożoną z tych cykli. Możesz założyć, że wszystkie cykle są rozłączne.
Przyjmujemy, że dla wartości x nie występujących na żadnej z list ci wynikiem buduj_permutacje [c0;;ck] x jest x. W szczególności, przyjmujemy, że pusta lista reprezentuje permutację identycznościową.
Przykład:
 let p = buduj_permutacje [[2; 1]; [8; 3; 4]; [5; 7; 6; 10]; [11]];;
 map p [1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12];;
 -: int list = [2; 1; 4; 8; 7; 10; 6; 3; 9; 5; 11; 12]
  • Dana jest lista liczb zmiennopozycyjnych [x1;x2;;xn]. Jej uśrednienie, to lista postaci: [x1+.x22.0;;xn1+.xn2.0]. Uśrednieniem listy jednoelementowej oraz pustej jest lista pusta.
Napisz procedurę usrednienie, która dla danej listy obliczy jej uśrednienie. Rozwiązując to zadanie nie możesz tworzyć procedur rekurencyjnych. Zamiast tego powinieneś skorzystać ze standardowych procedur wyższych rzędów przetwarzających listy.
  • Rozważmy następującą metodę kompresji ciągów liczb całkowitych: Jeżeli w oryginalnym ciągu ta sama liczba powtarza się kilka razy z rzędu, to jej kolejne wystąpienia reprezentujemy za pomocą jednej tylko liczby. Konkretnie, $i$ powtórzeń liczby $k$ reprezentujemy w ciągu skompresowanym jako 2i1(2k1).
Napisz procedurę kompresuj: int list -> int list kompresującą zadaną listę. Lista wynikowa powinna być oczywiście jak najkrótsza.
Rozwiązując to zadanie nie wolno Ci tworzyć żadnych własnych procedur rekurencyjnych. Powinieneś natomiast użyć procedur wyższych rzędów przetwarzających listy, znanych z wykładów.
Przykład:
kompresuj [1; 2; 2; 5; 11; 11; 2] = [1; 6; 9; 42; 3]
  • Zdefiniuj w sposób kontynuacyjny procedurę pierwsze: int -> (int -> 'a) -> 'a, która dla danej dodatniej liczby całkowitej oblicza sumę liczb pierwszych występujących w jej rozkładzie. Wszelkie procedury pomocnicze powinny również być zdefiniowane w sposób kontynuacyjny.
  • Napisz procedurę codrugi: 'a stream -> 'a stream, która przekształca strumień postaci (s1;s2;s3;s4;) w strumień postaci (s1;s3;s5;). Powinna ona działać zarówno dla strumieni skończonych, jak i nieskończonych.
  • Dany jest nieskończony strumień nieskończonych strumieni s. Zdefiniuj jego ,,przekątną p.
  • Zdefiniuj w sposób uwikłany strumień złożony z tych dodatnich liczb całkowitych, które w rozkładzie na czynniki pierwsze mają tylko liczby 2 i 3, oraz rozkładają się na nieparzystą liczbę czynników pierwszych.