Programowanie funkcyjne/Model obliczeń/Ćwiczenia: Różnice pomiędzy wersjami
m Zastępowanie tekstu – „<math> ” na „<math>” |
|||
(Nie pokazano 9 wersji utworzonych przez 4 użytkowników) | |||
Linia 1: | Linia 1: | ||
== | == Praca domowa == | ||
*Porównaj <tt>foldr</tt> i <tt>foldl</tt>. Która z nich jest ogonowa? | * Porównaj <tt>foldr</tt> i <tt>foldl</tt>. Która z nich jest ogonowa? | ||
* | * Zaimplementuj potęgowanie liczb -- ogonowo, raz o złożoności liniowej, a raz o złożoności logarytmicznej. | ||
== Ćwiczenia == | |||
{{cwiczenie|[Złożoność rekurencji ogonowej]|| | |||
Rozważ standardowe procedury przetwarzania list: <tt>length</tt>, <tt>map</tt>, <tt>append</tt>,<tt>rev</tt>. | |||
Czy w ich przypadku definicja ogonowa zmniejsza złożoność pamięciową? | |||
}} | |||
{{cwiczenie|[Potęgowanie funkcji]|| | |||
Potęgowanie funkcji -- najpierw liniowe, potem logarytmiczne, ale obie wersje z rekurencją ogonową. | |||
Rozrysuj w jaki sposób oblicza się:}} | |||
iterate 2 ('''function''' x -> x * (x+1)) 2 | iterate 2 ('''function''' x -> x * (x+1)) 2 | ||
iterate 3 ('''function''' x -> x * (x+1)) 1 | iterate 3 ('''function''' x -> x * (x+1)) 1 | ||
==Laboratorium== | (w zależności od wersji, cierpliwości i powierzchni tablic :-). | ||
W przypadku wersji logarytmicznej, procedura wynikowa jest | |||
obliczana w czasie logarytmicznym, ale ona sama działa w czasie liniowym. | |||
== Laboratorium == | |||
<center><math> [[a_1; a_2; \dots; a_{k_1}]; [a_{{k_1}+1}; a_{{k_1}+2}; \dots; a_{k_2}]; \dots; [a_{{k_{m-1}}+1}; a_{{k_{m-1}}+2}; \dots; a_{k_m}]] </math>,</center><br/> | {{cwiczenie|[Sześciany]|| | ||
Napisz procedurę <tt>sześciany : int -> int list</tt> taką, że wynikiem <tt>sześciany n</tt> jest lista postaci <math>[1^3; 2^3; \dots; n^3]</math>. | |||
Rozwiązując to zadanie: | |||
* możesz korzystać wyłącznie z rekurencji ogonowej, | |||
* jedyne operacje na liczbach, z jakich możesz korzystać to: <tt>+</tt>, <tt>-</tt> oraz porównywanie | |||
* skorzystaj z tożsamości: | |||
** <math>(n+1)^3 = n^3 + 3n^2 + 3n +1</math>, | |||
** <math>(n+1)^2 = n^2 + 2n + 1</math>. | |||
Twoje rozwiązanie powinno działać w czasie <math>\Theta(n)</math>. | |||
}} | |||
{{cwiczenie|[Podział permutacji]|| | |||
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: | |||
<center><math>[[a_1; a_2; \dots; a_{k_1}]; [a_{{k_1}+1}; a_{{k_1}+2}; \dots; a_{k_2}]; \dots; [a_{{k_{m-1}}+1}; a_{{k_{m-1}}+2}; \dots; a_{k_m}]]</math>,</center><br/> | |||
taką, że:<br/> | |||
<center><math>\begin{matrix} | <center><math>\begin{matrix} | ||
\{a_1, a_2, \dots, a_{k_1}\} & = &\{1, 2, \dots, k_1\} | \{a_1, a_2, \dots, a_{k_1}\} & = &\{1, 2, \dots, k_1\} & \mbox{(równość zbiorów)}, \\ | ||
\{a_{{k_1}+1}, a_{{k_1}+2}, \dots, a_{k_2}\} & = &\{k_1+1, k_1+2, \dots, k_2\},\\ | \{a_{{k_1}+1}, a_{{k_1}+2}, \dots, a_{k_2}\} & = &\{k_1+1, k_1+2, \dots, k_2\},\\ | ||
& \vdots & \\ | & \vdots & \\ | ||
Linia 25: | Linia 45: | ||
\end{matrix}</math></center> | \end{matrix}</math></center> | ||
<br/> | <br/> | ||
Przyjmujemy, że wynikiem dla listy pustej jest lista pusta. | |||
Przykład: | |||
<math>\texttt{\mbox{podziel}} [2; 3; 1; 6; 5; 4; 7; 9; 10; 11; 8] = [[2; 3; 1]; [6; 5; 4]; [7]; [9; 10; 11; 8]]</math>, | |||
<math>\texttt{\mbox{podziel}} [3;4;1;2] = [[3;4;1;2]]</math>. | |||
Rozwiązując to zadanie powinieneś skorzystać z rekurencji, ale wolno Ci korzystać wyłącznie z rekurencji ogonowej. | |||
}} |
Aktualna wersja na dzień 22:17, 11 wrz 2023
Praca domowa
- Porównaj foldr i foldl. Która z nich jest ogonowa?
- Zaimplementuj potęgowanie liczb -- ogonowo, raz o złożoności liniowej, a raz o złożoności logarytmicznej.
Ćwiczenia
Ćwiczenie [Złożoność rekurencji ogonowej]
Rozważ standardowe procedury przetwarzania list: length, map, append,rev. Czy w ich przypadku definicja ogonowa zmniejsza złożoność pamięciową?
Ćwiczenie [Potęgowanie funkcji]
Potęgowanie funkcji -- najpierw liniowe, potem logarytmiczne, ale obie wersje z rekurencją ogonową.
Rozrysuj w jaki sposób oblicza się:iterate 2 (function x -> x * (x+1)) 2 iterate 3 (function x -> x * (x+1)) 1
(w zależności od wersji, cierpliwości i powierzchni tablic :-). W przypadku wersji logarytmicznej, procedura wynikowa jest obliczana w czasie logarytmicznym, ale ona sama działa w czasie liniowym.
Laboratorium
Ćwiczenie [Sześciany]
Napisz procedurę sześciany : int -> int list taką, że wynikiem sześciany n jest lista postaci . Rozwiązując to zadanie:
- możesz korzystać wyłącznie z rekurencji ogonowej,
- jedyne operacje na liczbach, z jakich możesz korzystać to: +, - oraz porównywanie
- skorzystaj z tożsamości:
- ,
- .
Twoje rozwiązanie powinno działać w czasie .
Ćwiczenie [Podział permutacji]
Napisz procedurę podziel : int list -> int list list, która dla danej listy zawierającej permutację zbioru znajdzie jej podział na jak najliczniejszą listę list postaci:
taką, że:
Przyjmujemy, że wynikiem dla listy pustej jest lista pusta.
Przykład: , .
Rozwiązując to zadanie powinieneś skorzystać z rekurencji, ale wolno Ci korzystać wyłącznie z rekurencji ogonowej.