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

Z Studia Informatyczne
Przejdź do nawigacjiPrzejdź do wyszukiwania
Dorota (dyskusja | edycje)
Nie podano opisu zmian
m Zastępowanie tekstu – „<math> ” na „<math>”
 
(Nie pokazano 19 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.  
* 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.
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 12: Linia 11:
  &nbsp;&nbsp;&nbsp;&nbsp;fibpom 0 1 n;;
  &nbsp;&nbsp;&nbsp;&nbsp;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?
 


==Ćwiczenia==
==Ćwiczenia==
Linia 19: Linia 19:
Rozwiązaniami poniższych zadań są proste programiki operujące na liczbach całkowitych
Rozwiązaniami poniższych zadań są proste programiki operujące na liczbach całkowitych
(bez rekurencji ogonowej i list):
(bez rekurencji ogonowej i list):
* Napisz procedurę, która sprawdza, czy dana liczba jest pierwsza,
 
* 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.
{{cwiczenie|[<tt>sqrt x</tt>]||
* 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.
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>.
* 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.
}}
* Zaimplementuj kodowanie par liczb całkowitych jako liczby całkowite. To znaczy, napisz procedurę dwuargumentową, która koduje dwie liczby dane jako argumenty w jednej liczbie całkowitej. Dodatkowo napisz dwie procedury, które wydobywają z zakodowanej pary odpowiednio pierwszą i drugą liczbę.
<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 rec''' pom k s =
      '''if''' s > n '''then''' k-1 '''else''' pom (k+1) (s + 2 * k + 1)
    '''in''' pom 0 0;;
</div></div>
 
{{cwiczenie|[Test pierwszości]||
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 rec''' pom a =
      '''if''' a * a > x '''then''' true
      '''else if''' x mod a = 0 '''then''' false
      '''else''' pom (a+1)
    '''in''' (x > 1) && (pom 2);;
</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 ==
{{cwiczenie|[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.
}}
<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 rec''' pom x w =
    '''if''' x = 0 '''then''' w '''else''' pom (x/10) (w*10 + x mod 10)
  '''in'''
    pom n 0;;
</div></div>
 
{{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.
}}
<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''' sumacyfr n a =
      '''if''' n = 0 '''then''' a '''else''' sumacyfr (n / 10) (a + n mod 10)
    '''in'''
      '''if''' x < 10 '''then''' x '''else''' numerologia (sumacyfr x 0);;
</div></div>
 
{{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.
}}
<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 pom''' r1 r2 x =   
      '''if''' x = 0 '''then''' r1 - r2 '''else''' pom (r1 + x mod 10) (r2 + (x / 10) mod 10) (x / 100) 
    '''in'''
      '''let''' r = pom 0 0 x
      '''in'''
        '''if''' r > 10 '''then''' mod11 r
        '''else if''' r < 0 '''then''' 10 - mod11 ((- r) - 1)
        '''else''' r;;
</div></div>
 
{{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ę.
}}
<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''' para a b =
    '''let rec''' pom a b c p =
      '''if''' (a = 0) && (b = 0) '''then''' c
      '''else''' pom (a/10) (b/10) (c + p *(a mod 10) + 10 * p *(b mod 10)) (100*p)
    '''in''' pom a b 0 1;;
 
  '''let''' rzut_x x =
    '''let rec''' pom x p a =
      '''if''' x = 0 '''then''' a
      '''else''' pom (x / 100) (10 * p) (a + (x mod 10) * p)
    '''in''' pom x 1 0;;
 
  '''let''' rzut_y x =
    '''let rec''' pom x p a =
      '''if''' x = 0 '''then''' a
      '''else''' pom (x / 100) (10 * p) (a + ((x/10) mod 10) * p)
    '''in''' pom x 1 0;; 
</div></div>
 
{{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>).
}}
<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 rec''' spr p =
      '''if''' p >= n-1 '''then''' false
      '''else if''' (p * p) mod n = 1 '''then''' true
      '''else''' spr (p+1)
    '''in'''
      spr 2;;
</div></div>

Aktualna wersja na dzień 22:13, 11 wrz 2023

Praca domowa

  • Stopień parzystości liczby całkowitej x to największa taka liczba naturalna i, że x 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: i=1k(2i1)=k2. Wykorzystaj ten fakt do napisania procedury sqrt obliczającej sqrt x =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 n sprawdzi czy pierścień reszt modulo n zawiera nietrywialne pierwiastki z 1 (tj. takie liczby k, k1, kn1, że k21 mod n).

Rozwiązanie