Programowanie funkcyjne/Podstawy/Ćwiczenia: Różnice pomiędzy wersjami
m Zastępowanie tekstu – „<math> ” na „<math>” |
|||
(Nie pokazano 5 wersji utworzonych przez 2 użytkowników) | |||
Linia 1: | Linia 1: | ||
==Praca domowa== | ==Praca domowa== | ||
* Stopień parzystości liczby całkowitej <math>x</math> to największa taka liczba naturalna <math> i</math>, że <math>x</math> dzieli się przez 2<sup>i</sup>. Liczby nieparzyste mają stopień parzystości 0, liczby 2 i -6 mają stopień parzystości 1, a liczby 4 i 12 mają stopień parzystości 2. Przyjmujemy, że 0 ma stopień parzystości -1. Napisz procedurę <tt>parzystość</tt> wyznaczającą stopień parzystości danej liczby całkowitej. | * Stopień parzystości liczby całkowitej <math>x</math> to największa taka liczba naturalna <math>i</math>, że <math>x</math> dzieli się przez 2<sup>i</sup>. Liczby nieparzyste mają stopień parzystości 0, liczby 2 i -6 mają stopień parzystości 1, a liczby 4 i 12 mają stopień parzystości 2. Przyjmujemy, że 0 ma stopień parzystości -1. Napisz procedurę <tt>parzystość</tt> wyznaczającą stopień parzystości danej liczby całkowitej. | ||
* Udowodnij, że dla każdego naturalnego <tt>n</tt>, <tt>fib n</tt> jest równe <tt>n</tt>-tej liczbie Fibonacciego. Podaj specyfikację dla <tt>fibpom</tt> i udowodnij ją przez indukcję. | * Udowodnij, że dla każdego naturalnego <tt>n</tt>, <tt>fib n</tt> jest równe <tt>n</tt>-tej liczbie Fibonacciego. Podaj specyfikację dla <tt>fibpom</tt> i udowodnij ją przez indukcję. | ||
Linia 11: | Linia 11: | ||
fibpom 0 1 n;; | fibpom 0 1 n;; | ||
* Forma specjalna <tt>let-in</tt> jest tylko lukrem syntaktycznym i może być rozwinięta do <math>\lambda </math>-abstrakcji. W jaki sposób? | * Forma specjalna <tt>let-in</tt> jest tylko lukrem syntaktycznym i może być rozwinięta do <math>\lambda</math>-abstrakcji. W jaki sposób? | ||
Linia 21: | Linia 21: | ||
{{cwiczenie|[<tt>sqrt x</tt>]|| | {{cwiczenie|[<tt>sqrt x</tt>]|| | ||
Sumy kolejnych liczb nieparzystych dają kwadraty kolejnych liczb naturalnych, zgodnie ze wzorem: <math>\sum_{i=1}^k (2 i - 1) = k^2</math>. Wykorzystaj ten fakt do napisania procedury <tt>sqrt</tt> obliczającej <tt>sqrt x</tt> <math> = \left\lfloor \sqrt{x} \right\rfloor</math>. | Sumy kolejnych liczb nieparzystych dają kwadraty kolejnych liczb naturalnych, zgodnie ze wzorem: <math>\sum_{i=1}^k (2 i - 1) = k^2</math>. Wykorzystaj ten fakt do napisania procedury <tt>sqrt</tt> obliczającej <tt>sqrt x</tt> <math>= \left\lfloor \sqrt{x} \right\rfloor</math>. | ||
}} | }} | ||
<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''' sqrt n = | '''let''' sqrt n = | ||
'''let rec''' pom k s = | '''let rec''' pom k s = | ||
'''if''' s > n '''then''' k-1 '''else''' pom (k+1) (s + 2 * k + 1) | '''if''' s > n '''then''' k-1 '''else''' pom (k+1) (s + 2 * k + 1) | ||
'''in''' pom 0 0;; | '''in''' pom 0 0;; | ||
</div></div> | </div></div> | ||
{{cwiczenie|[Test pierwszości]|| | {{cwiczenie|[Test pierwszości]|| | ||
Napisz procedurę, która sprawdza, czy dana liczba jest pierwsza. | Napisz procedurę, która sprawdza, czy dana liczba jest pierwsza. | ||
}} | }} | ||
<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''' isprime x = | '''let''' isprime x = | ||
'''let rec''' pom a = | '''let rec''' pom a = | ||
Linia 40: | Linia 44: | ||
'''else''' pom (a+1) | '''else''' pom (a+1) | ||
'''in''' (x > 1) && (pom 2);; | '''in''' (x > 1) && (pom 2);; | ||
</div></div>}} | </div></div> | ||
{{cwiczenie|[Zera silni]|| | |||
Napisz procedurę <tt>zera_silni : int -> int</tt>, która dla danej dodatniej liczby całkowitej ''n'' obliczy ile zer znajduje się na końcu zapisu dziesiętnego liczby ''n!''. | |||
}} | |||
== Laboratorium == | == Laboratorium == | ||
Linia 46: | Linia 54: | ||
Napisz procedurę, która przekształca daną liczbę w taką, w której cyfry wystepują w odwrotnej kolejności, np. 1234 jest przekształcane na 4321. | Napisz procedurę, która przekształca daną liczbę w taką, w której cyfry wystepują w odwrotnej kolejności, np. 1234 jest przekształcane na 4321. | ||
}} | }} | ||
<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''' odwroc n = | '''let''' odwroc n = | ||
'''let rec''' pom x w = | '''let rec''' pom x w = | ||
Linia 52: | Linia 62: | ||
'''in''' | '''in''' | ||
pom n 0;; | pom n 0;; | ||
</div></div> | </div></div> | ||
{{cwiczenie|[Numerologia]|| | {{cwiczenie|[Numerologia]|| | ||
Napisz procedurę, która sprawdza, czy dana liczba jest podzielna przez 9 w następujący sposób: jedyne liczby jednocyforwe podzielne przez 9 to 9 i 0; reszta z dzielenia liczby wielocyforwej przez 9 jest taka sama, jak reszta dzielenia sumy jej cyfr przez 9; jeśli suma cyfr jest wielocyfrowa, to całość powtarzamy, aż do uzyskania liczby jednocyfrowej. | Napisz procedurę, która sprawdza, czy dana liczba jest podzielna przez 9 w następujący sposób: jedyne liczby jednocyforwe podzielne przez 9 to 9 i 0; reszta z dzielenia liczby wielocyforwej przez 9 jest taka sama, jak reszta dzielenia sumy jej cyfr przez 9; jeśli suma cyfr jest wielocyfrowa, to całość powtarzamy, aż do uzyskania liczby jednocyfrowej. | ||
}} | }} | ||
<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''' numerologia x = | '''let rec''' numerologia x = | ||
'''let rec''' sumacyfr n a = | '''let rec''' sumacyfr n a = | ||
Linia 63: | Linia 75: | ||
'''in''' | '''in''' | ||
'''if''' x < 10 '''then''' x '''else''' numerologia (sumacyfr x 0);; | '''if''' x < 10 '''then''' x '''else''' numerologia (sumacyfr x 0);; | ||
</div></div> | </div></div> | ||
{{cwiczenie|[Reszta modulo 11]|| | {{cwiczenie|[Reszta modulo 11]|| | ||
Napisz procedurę, która sprawdza czy dana liczba jest podzielna przez 11 w następujący sposób: sumujemy cyfry liczby znajdujące się na parzystych pozycjach, oraz te na nieparzystych pozycjach, różnica tych dwóch liczb przystaje modulo 11 do wyjściowej liczby; krok ten należy powtarzać aż do uzyskania liczby jednocyfrowej. | Napisz procedurę, która sprawdza czy dana liczba jest podzielna przez 11 w następujący sposób: sumujemy cyfry liczby znajdujące się na parzystych pozycjach, oraz te na nieparzystych pozycjach, różnica tych dwóch liczb przystaje modulo 11 do wyjściowej liczby; krok ten należy powtarzać aż do uzyskania liczby jednocyfrowej. | ||
}} | }} | ||
<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''' mod11 x = | '''let rec''' mod11 x = | ||
'''let rec pom''' r1 r2 x = | '''let rec pom''' r1 r2 x = | ||
Linia 78: | Linia 92: | ||
'''else if''' r < 0 '''then''' 10 - mod11 ((- r) - 1) | '''else if''' r < 0 '''then''' 10 - mod11 ((- r) - 1) | ||
'''else''' r;; | '''else''' r;; | ||
</div></div> | </div></div> | ||
{{cwiczenie|[Kodowanie par liczb]|| | {{cwiczenie|[Kodowanie par liczb]|| | ||
Zaimplementuj kodowanie par liczb naturalnych jako liczby naturalne. To znaczy, napisz procedurę dwuargumentową, która otrzymawszy dwie liczby naturalne zakoduje je w jednej liczbie naturalnej. Dodatkowo napisz dwie procedury, które wydobywają z zakodowanej pary odpowiednio pierwszą i drugą liczbę. | Zaimplementuj kodowanie par liczb naturalnych jako liczby naturalne. To znaczy, napisz procedurę dwuargumentową, która otrzymawszy dwie liczby naturalne zakoduje je w jednej liczbie naturalnej. Dodatkowo napisz dwie procedury, które wydobywają z zakodowanej pary odpowiednio pierwszą i drugą liczbę. | ||
}} | }} | ||
<div class="mw-collapsible mw-made=collapsible mw-collapsed"> | |||
'''let | <span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie</span> | ||
'''let rec''' pom a b c = | <div class="mw-collapsible-content" style="display:none"> | ||
'''let''' para a b = | |||
'''let rec''' pom a b c p = | |||
'''if''' (a = 0) && (b = 0) '''then''' c | '''if''' (a = 0) && (b = 0) '''then''' c | ||
'''else''' pom (a/10) (b/10) ( | '''else''' pom (a/10) (b/10) (c + p *(a mod 10) + 10 * p *(b mod 10)) (100*p) | ||
'''in''' pom a b 0;; | '''in''' pom a b 0 1;; | ||
'''let''' | '''let''' rzut_x x = | ||
'''let rec''' pom p a = | '''let rec''' pom x p a = | ||
'''if''' | '''if''' x = 0 '''then''' a | ||
'''else''' pom ( | '''else''' pom (x / 100) (10 * p) (a + (x mod 10) * p) | ||
'''in''' pom | '''in''' pom x 1 0;; | ||
'''let''' | '''let''' rzut_y x = | ||
'''let rec''' pom p | '''let rec''' pom x p a = | ||
'''if''' | '''if''' x = 0 '''then''' a | ||
'''else''' pom ( | '''else''' pom (x / 100) (10 * p) (a + ((x/10) mod 10) * p) | ||
'''in''' pom | '''in''' pom x 1 0;; | ||
</div></div> | </div></div> | ||
{{cwiczenie|[Nietrywialne pierwiastki z 1]|| | {{cwiczenie|[Nietrywialne pierwiastki z 1]|| | ||
Napisz procedurę, która dla danej liczby <math>n</math> sprawdzi czy pierścień reszt modulo <math>n</math> zawiera nietrywialne pierwiastki z 1 (tj. takie liczby <math>k</math>, <math>k \neq 1</math>, <math>k \neq n-1</math>, że <math>k^2 \equiv 1\ \mod\ n</math>). | Napisz procedurę, która dla danej liczby <math>n</math> sprawdzi czy pierścień reszt modulo <math>n</math> zawiera nietrywialne pierwiastki z 1 (tj. takie liczby <math>k</math>, <math>k \neq 1</math>, <math>k \neq n-1</math>, że <math>k^2 \equiv 1\ \mod\ n</math>). | ||
}} | }} | ||
<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''' pierwiastki n = | '''let''' pierwiastki n = | ||
'''let rec''' spr p = | '''let rec''' spr p = | ||
Linia 114: | Linia 132: | ||
'''in''' | '''in''' | ||
spr 2;; | spr 2;; | ||
</div></div> | </div></div> |
Aktualna wersja na dzień 22:13, 11 wrz 2023
Praca domowa
- Stopień parzystości liczby całkowitej to największa taka liczba naturalna , że dzieli się przez 2i. Liczby nieparzyste mają stopień parzystości 0, liczby 2 i -6 mają stopień parzystości 1, a liczby 4 i 12 mają stopień parzystości 2. Przyjmujemy, że 0 ma stopień parzystości -1. Napisz procedurę parzystość wyznaczającą stopień parzystości danej liczby całkowitej.
- Udowodnij, że dla każdego naturalnego n, fib n jest równe n-tej liczbie Fibonacciego. Podaj specyfikację dla fibpom i udowodnij ją przez indukcję.
let fib n = let rec fibpom a b n = if n = 0 then a else fibpom b (a + b) (n - 1) in fibpom 0 1 n;;
- Forma specjalna let-in jest tylko lukrem syntaktycznym i może być rozwinięta do -abstrakcji. W jaki sposób?
Ćwiczenia
W przypadku zajęć laboratoryjnych należy najpierw zapoznać studentów ze środowiskiem i uruchamianiem Ocamla.
Rozwiązaniami poniższych zadań są proste programiki operujące na liczbach całkowitych (bez rekurencji ogonowej i list):
Ćwiczenie [sqrt x]
Sumy kolejnych liczb nieparzystych dają kwadraty kolejnych liczb naturalnych, zgodnie ze wzorem: . Wykorzystaj ten fakt do napisania procedury sqrt obliczającej sqrt x .
Rozwiązanie
Ćwiczenie [Test pierwszości]
Napisz procedurę, która sprawdza, czy dana liczba jest pierwsza.
Rozwiązanie
Ćwiczenie [Zera silni]
Napisz procedurę zera_silni : int -> int, która dla danej dodatniej liczby całkowitej n obliczy ile zer znajduje się na końcu zapisu dziesiętnego liczby n!.
Laboratorium
Ćwiczenie [Odwracanie liczb]
Napisz procedurę, która przekształca daną liczbę w taką, w której cyfry wystepują w odwrotnej kolejności, np. 1234 jest przekształcane na 4321.
Rozwiązanie
Ćwiczenie [Numerologia]
Napisz procedurę, która sprawdza, czy dana liczba jest podzielna przez 9 w następujący sposób: jedyne liczby jednocyforwe podzielne przez 9 to 9 i 0; reszta z dzielenia liczby wielocyforwej przez 9 jest taka sama, jak reszta dzielenia sumy jej cyfr przez 9; jeśli suma cyfr jest wielocyfrowa, to całość powtarzamy, aż do uzyskania liczby jednocyfrowej.
Rozwiązanie
Ćwiczenie [Reszta modulo 11]
Napisz procedurę, która sprawdza czy dana liczba jest podzielna przez 11 w następujący sposób: sumujemy cyfry liczby znajdujące się na parzystych pozycjach, oraz te na nieparzystych pozycjach, różnica tych dwóch liczb przystaje modulo 11 do wyjściowej liczby; krok ten należy powtarzać aż do uzyskania liczby jednocyfrowej.
Rozwiązanie
Ćwiczenie [Kodowanie par liczb]
Zaimplementuj kodowanie par liczb naturalnych jako liczby naturalne. To znaczy, napisz procedurę dwuargumentową, która otrzymawszy dwie liczby naturalne zakoduje je w jednej liczbie naturalnej. Dodatkowo napisz dwie procedury, które wydobywają z zakodowanej pary odpowiednio pierwszą i drugą liczbę.
Rozwiązanie
Ćwiczenie [Nietrywialne pierwiastki z 1]
Napisz procedurę, która dla danej liczby sprawdzi czy pierścień reszt modulo zawiera nietrywialne pierwiastki z 1 (tj. takie liczby , , , że ).
Rozwiązanie