5. Rekurencja. Przykłady

Podobne dokumenty
4. Funkcje. Przykłady

6. Pętle while. Przykłady

3. Instrukcje warunkowe

Programowanie - wykład 4

7. Pętle for. Przykłady

Algorytmy i struktury danych. Wykład 4

Rekurencja (rekursja)

ALGORYTMY I STRUKTURY DANYCH

8. Wektory. Przykłady Napisz program, który pobierze od użytkownika 10 liczb, a następnie wypisze je w kolejności odwrotnej niż podana.

Wykład 4. Określimy teraz pewną ważną klasę pierścieni.

2. Zmienne i stałe. Przykłady Napisz program, który wypisze na ekran wynik dzielenia 281 i 117 w postaci liczby mieszanej (tj. 2 47/117).

Programowanie strukturalne i obiektowe. Funkcje

Rekurencja. Przygotowała: Agnieszka Reiter

Wstęp do Informatyki zadania ze złożoności obliczeniowej z rozwiązaniami

1. Wypisywanie danych

1. Liczby wymierne. x dla x 0 (wartością bezwzględną liczby nieujemnej jest ta sama liczba)

Algorytmika i programowanie. Wykład 2 inż. Barbara Fryc Wyższa Szkoła Informatyki i Zarządzania w Rzeszowie

Programowanie komputerowe. Zajęcia 1

Podstawy programowania. Wykład: 13. Rekurencja. dr Artur Bartoszewski -Podstawy programowania, sem 1 - WYKŁAD

Programowanie w Baltie klasa VII

Program 14. #include <iostream> #include <ctime> using namespace std;

Przykładowe zadania z teorii liczb

Warunki logiczne instrukcja if

Informacje wstępne #include <nazwa> - derektywa procesora umożliwiająca włączenie do programu pliku o podanej nazwie. Typy danych: char, signed char

Program znajduje największa lub najmniejsza z podanych liczb. Liczby podajemy dopóki nam sie nie znudzi.

1. Napisz program, który wyświetli Twoje dane jako napis Witaj, Imię Nazwisko. 2. Napisz program, który wyświetli wizytówkę postaci:

do instrukcja while (wyrażenie);

Rekurencja. Rekurencja zwana także rekursją jest jedną z najważniejszych metod konstruowania rozwiązań i algorytmów.

for (inicjacja_warunkow_poczatkowych(końcowych); wyrazenie_warunkowe; wyrazenie_zwiekszajace(zmniejszające)) { blok instrukcji; }

Część 4 życie programu

Wstęp do Programowania, laboratorium 02

Wstęp do informatyki- wykład 12 Funkcje (przekazywanie parametrów przez wartość i zmienną)

Zajęcia nr 2 Programowanie strukturalne. dr inż. Łukasz Graczykowski mgr inż. Leszek Kosarzewski Wydział Fizyki Politechniki Warszawskiej

Liczby całkowite i rzeczywiste

Podstawy Programowania Podstawowa składnia języka C++

ALGORYTMY MATEMATYCZNE Ćwiczenie 1 Na podstawie schematu blokowego pewnego algorytmu (rys 1), napisz listę kroków tego algorytmu:

INFORMATYKA Z MERMIDONEM. Programowanie. Moduł 5 / Notatki

Podstawą w systemie dwójkowym jest liczba 2 a w systemie dziesiętnym liczba 10.

Rozwiązanie. #include <cstdlib> #include <iostream> using namespace std;

I. Podstawy języka C powtórka

Zadanie 1. Zmiana systemów. Zadanie 2. Szyfr Cezara. Zadanie 3. Czy liczba jest doskonała. Zadanie 4. Rozkład liczby na czynniki pierwsze Zadanie 5.

Instrukcje sterujące

1. Liczby naturalne, podzielność, silnie, reszty z dzielenia

WHILE (wyrażenie) instrukcja;

Algorytmy w teorii liczb

Zadania do samodzielnego rozwiązania

Pytania sprawdzające wiedzę z programowania C++

Programowanie Obiektowo Zorientowane w języku c++ Przestrzenie nazw

Programowanie komputerowe. Zajęcia 2

Jarosław Wróblewski Matematyka Elementarna, lato 2012/13. W dniu 21 lutego 2013 r. omawiamy test kwalifikacyjny.

Algorytm. a programowanie -

WHILE (wyrażenie) instrukcja;

I - Microsoft Visual Studio C++

WYRAŻENIA ALGEBRAICZNE

Programowanie - instrukcje sterujące

Podstawy programowania 2. Temat: Funkcje i procedury rekurencyjne. Przygotował: mgr inż. Tomasz Michno

PROGRAMOWANIE W C++ ZADANIA

ZADANIE 1. Ważenie (14 pkt)

Funkcje. Deklaracja funkcji. Definicja funkcji. Wykorzystanie funkcji w programie.

void Pobierz(Student &a); void Wypisz(Student a); void Ustaw_zaliczenia(Student t[],int r); void Wypisz_najlepszych(Student t[],int r, float prog);

for (inicjacja_warunkow_poczatkowych; wyrazenie_warunkowe; wyrazenie_zwiekszajace) { blok instrukcji; }

Wstęp do programowania

Jarosław Wróblewski Matematyka Elementarna, zima 2012/13

1 Podstawy c++ w pigułce.

1,3,4,2,3,4,0,1,4,5,0. Wówczas największa suma trzech kolejnych liczb (zaznaczone na czerwono) wynosi:

Wstęp do informatyki- wykład 7

ALGORYTMY Algorytm poprawny jednoznaczny szczegółowy uniwersalny skończoność efektywność (sprawność) zmiennych liniowy warunkowy iteracyjny

Iteracje. Algorytm z iteracją to taki, w którym trzeba wielokrotnie powtarzać instrukcję, aby warunek został spełniony.

Wieczorowe Studia Licencjackie Wrocław, Wykład nr 6 (w oparciu o notatki K. Lorysia, z modyfikacjami) Sito Eratostenesa

Matematyka dyskretna. Andrzej Łachwa, UJ, a/15

C++ w przykładach. Mariusz Różycki Cezary Obczyński

znajdowały się różne instrukcje) to tak naprawdę definicja funkcji main.

Podstawy algorytmiki i programowania - wykład 2 Tablice dwuwymiarowe cd Funkcje rekurencyjne

12. Rekurencja. UWAGA Trzeba bardzo dokładnie ustalić <warunek>, żeby mieć pewność, że ciąg wywołań się zakończy.

Moneta 1 Moneta 2 Kostka O, R O,R 1,2,3,4,5, Moneta 1 Moneta 2 Kostka O O ( )

Schematy blokowe I. 1. Dostępne bloki: 2. Prosty program drukujący tekst.

Liczby rzeczywiste. Działania w zbiorze liczb rzeczywistych. Robert Malenkowski 1

PDF stworzony przez wersję demonstracyjną pdffactory Pro Program 15

2.8. Algorytmy, schematy, programy

Podstawy programowania funkcjonalnego

Podstawowe elementy proceduralne w C++ Program i wyjście. Zmienne i arytmetyka. Wskaźniki i tablice. Testy i pętle. Funkcje.

Zadania język C++ Zad. 1. Napisz program wczytujący z klawiatury wiek dwóch studentów i wypisujący informację o tym, który z nich jest starszy.

Wstęp do Informatyki

Algorytm Euklidesa. Największy wspólny dzielnik dla danych dwóch liczb całkowitych to największa liczba naturalna dzieląca każdą z nich bez reszty.

Mechanizm dziedziczenia

Podzielność liczb przez liczby od 2 do 10 WSTĘP CO TO ZNACZY, ŻE LICZBA JEST PODZIELNA PRZEZ INNĄ LICZBĘ? ZASADY PODZIELNOŚCI

Bukiety matematyczne dla gimnazjum

Wstęp do programowania

C++ wprowadzanie zmiennych

Rekurencja. Przykład. Rozważmy ciąg

Algorytm Euklidesa. Dwie monety - jeden problem. Trochę matematyki 180=36*5 180=60*3

Podstawy programowania. Wykład: 4. Instrukcje sterujące, operatory. dr Artur Bartoszewski -Podstawy programowania, sem 1 - WYKŁAD

2.1. Duszek w labiryncie

LISTA 5. C++ PETLE for, while, do while

Wstęp do informatyki- wykład 6

WYKŁAD 8. Funkcje i algorytmy rekurencyjne Proste przykłady. Programy: c3_1.c..., c3_6.c. Tomasz Zieliński

Listy powiązane zorientowane obiektowo

Wykorzystanie rozkładu liczby na czynniki pierwsze

Opis zagadnieo 1-3. Iteracja, rekurencja i ich realizacja

Transkrypt:

5. Rekurencja Uwaga! W tym rozdziale nie są omówione żadne nowe konstrukcje języka C++. Omówiona jest za to technika wykorzystująca funkcje, która pozwala na rozwiązanie pewnych nowych rodzajów zadań. Przed rozpoczęciem pracy nad tym rozdziałem upewnij się, że rozumiesz funkcje i instrukcje warunkowe. Bez tej wiedzy będziesz mieć problemy ze zrozumieniem materiału zawartego w tym rozdziale. Jeżeli potrzebujesz, rozwiąż więcej zadań z poprzedniego rozdziału. Przykłady 5.1. Napisz program, który będzie w nieskończoność wypisywać kolejne liczby naturalne, począwszy od 0, po jednej liczbie na linię. 1 #include <iostream> 2 using namespace std; 3 4 void wypisznaturalneod(int n) { 5 cout << n << endl; 6 wypisznaturalneod(n+1); 7 } 8 9 int main() { 10 wypisznaturalneod(0); 11 12 return 0; 13 } Uwaga! Program ten nigdy sam nie zakończy swojego działania. Aby zakończyć jego działanie wciśnij kombinację klawiszy Ctrl+C. Rozwiązanie tego zadania może na pierwszy rzut oka wyglądać bardzo nietypowo. Wykorzystuje ono bardzo popularną technikę zwaną rekurencja. W celu wypisania wszystkich kolejnych liczb naturalnych tworzymy funkcję, która pozwoli wypisać nam wszystkie liczby naturalne począwszy od pewnej 31

danej liczby. Funkcja ta, wypisznaturalneod nie zwraca żadnej wartości (wypisuje jedynie liczby), a jako argument przyjmuje początkową liczbę, od której chcemy zacząć wypisywanie. W ciele tej funkcji znajdują się jedynie 2 linie kodu. Pierwsza z nich odpowiada za wypisanie pierwszej z liczb (czyli n, od którego mieliśmy zacząć). Druga linia wywołuje zaś tę samą funkcję, jednak z argumentem o jeden większym, co wypisze na ekran wszystkie pozostałe liczby naturalne, które mamy do wypisania. Rekurencja polega na wywoływaniu funkcji wewnątrz jej własnej definicji. Pozwala to na wielokrotne wykonanie tego samego fragmentu kodu. Funkcję, która wywołuje sama siebie nazywamy rekurencyjna. Funkcje rekurencyjne z reguły podążają za utartym schematem: jeżeli potrafię znaleźć rozwiązanie dla n, to jakie będzie rozwiązanie dla n + 1? 5.2. Napisz program, który będzie odliczać w dół do 0 od pewnej zadanej liczby. Program ma pobrać od użytkownika liczbę n, a następnie wypisać na ekran liczby od n do 0 włącznie, w kolejności malejącej, po jednej liczbie na linię. 1 #include <iostream> 2 using namespace std; 3 4 void odliczod(int n) { 5 if (n < 0) { 6 return; 7 } 8 9 cout << n << endl; 10 odliczod(n-1); 11 } 12 13 int main() { 14 int n; 15 cin >> n; 16 17 odliczod(n); 18 19 return 0; 20 } Program z poprzedniego przykładu nie był zbyt przydatny, jako że nigdy nie kończył swojego działania. Nie posiadał on tzw. podstawy rekurencji, a jedynie krok rekurencyjny. 32

W tym przykładzie chcemy wypisywać kolejno coraz mniejsze liczby, stąd wywołanie w linii 10 zawiera n-1, a nie n+1 jak w poprzednim przykładzie. Tym razem jednak chcemy zakończyć wypisywanie liczb, jeżeli n przekroczy 0. Dlatego oprócz zmiany plusa na minus, do funkcji dodane zostały jeszcze dodatkowe linie kodu (5-7), które sprawdzają czy argument funkcji nie jest ujemny. Jeżeli jest, działanie funkcji jest przerywane, a co za tym idzie, kolejne liczby nie są wypisywane na ekran. Taki warunek nazywamy podstawą rekurencji i z reguły umieszczamy go na samym początku funkcji rekurencyjnej. Uwaga! Warunek w linii 5 moglibyśmy zastąpić przez n == -1 i program działałby wciąż poprawnie. Jednak gdyby ktoś poprosił cię o zmianę tego kodu tak, aby wypisywał co drugą liczbę, konieczna byłaby modyfikacja tego warunku na n == -1 n == -2. Unikaj używania warunków z == lub!= w podstawie rekurencji (a później także w pętlach). Czasem jest to niezbędne, jednak w większości przypadków lepiej jest taki warunek zastąpić przez jedną z nierówności. Całą resztę kodu funkcji rekurencyjnej nazywamy krokiem rekurencji. 5.3. Napisz program, który wypisze kolejne liczby naturalne od a do b włącznie, w kolejności rosnącej, gdzie a i b są dane przez użytkownika. 1 #include <iostream> 2 using namespace std; 3 4 void wypisznaturalne(int start, int koniec) { 5 if (start > koniec) { 6 return; 7 } 8 9 cout << start << endl; 10 wypisznaturalne(start+1, koniec); 11 } 12 13 int main() { 14 int start, koniec; 15 cin >> start >> koniec; 16 17 wypisznaturalne(start, koniec); 18 19 return 0; 20 } 33

Tym razem nasza funkcja rekurencyjna przyjmuje dwa argumenty: granice przedziału, którego elementy mamy wypisać. Zacznijmy od omówienia kroku rekurencji (linie 9-10). Przypomina on rozwiązanie przykładu 5.1. Wypisujemy pierwszą liczbę przedziału, a potem rekurencyjnie wypisujemy całą resztę. Tym razem musimy jednak pamiętać o przekazaniu również drugiego argumentu koniec, który jednak nie zmienia się. Wypisywanie powinno zakończyć się w momencie, kiedy kolejna liczba do wypisania (tj. start) jest większa niż ostatnia liczba, która miała być wypisana (czyli koniec). Stąd podstawa rekurencji (linie 5-7) sprawdza czy start jest większe od koniec i jeżeli tak, to kończy działanie funkcji bez wypisywania żadnej wartości na ekran. Głowna funkcja programu sprowadza się do pobrania od użytkownika dwóch liczb, a następnie przekazania ich do zdefiniowanej już funkcji wypisznaturalne. 5.4. Dana jest plansza o wymiarach 2 n 2 n, gdzie n > 0, z wyciętym jednym z pól, oraz dowolna liczba klocków w kształcie litery L złożonej z 3 kwadratów. W jaki sposób dokładnie przykryć planszę klockami tak, aby żaden klocek nie zakrywał wyciętego pola ani nie wystawał poza planszę? Klocki nie mogą na siebie nachodzić, ale można dowolnie je obracać. Uwaga! Ten przykład nie zawiera kodu, jako że zadanie nie prosi o jego napisanie. Jeżeli czujesz się na siłach, możesz spróbować napisać program, który będzie konstruował i prezentował odpowiedni układ klocków dla danej planszy. Wymaga to jednak nieco wiedzy wykraczającej poza dotychczasowy materiał. Zaczniemy od rozwiązania najprostszego przypadku, gdzie n = 1, czyli plansza ma rozmiar 2 2. Następnie na podstawie prostszych rozwiązań będziemy konstruować rozwiązania dla coraz większych plansz. Przypadek bazowy jest trywialnie prosty. Mamy planszę 2 2 z jednym z pól wyciętym. Cała reszta planszy ma więc dokładnie taki sam kształt jak nasz klocek, a więc wystarczy go tam położyć. Następnie załóżmy, że mamy rozwiązanie dla n i spróbujmy znaleźć rozwiązanie dla n+1. Dzielimy planszę na 4 części: na pół w pionie i w poziomie, otrzymując cztery ćwiartki. 34

Dostajemy więc 4 plansze, każda o rozmiarach 2 n 2 n, a taką potrafimy zapełnić klockami tak, aby dowolne pole pozostało wolne. W jednej z ćwiartek znajduje się pole, które musi pozostać puste, więc zapełniamy ją odpowiednio. Na pozostałych 3 ćwiartkach nie mamy żadnych pól, które powinny pozostać puste. Możemy je sobie wybrać tak, aby w pozostałą lukę dało się umieścić jeszcze jeden klocek. W każdej z tych 3 ćwiartek zostawiamy wolne pole przy samym środku planszy, co da nam lukę w kształcie klocka, którą możemy w prosty sposób zapełnić. Wiemy, że dla dowolnego n da się wypełnić planszę, jeżeli da się to zrobić dla n 1. Wiemy także, że jest to możliwe dla n = 1. Stąd wiemy, że da się to zrobić dla n = 2 (bo da się dla 2 1 = 1), a więc także dla n = 3 (bo da się dla 3 1 = 2) itd. W ten sposób nie tylko udowodniliśmy (przez indukcję), że żądany układ istnieje dla każdego n > 0, ale także znaleźliśmy rekurencyjny sposób na jego skonstruowanie. 35

5.5. Napisz program, który obliczy wartość silni z danej liczby. 1 #include <iostream> 2 using namespace std; 3 4 int silnia(int n) { 5 if (n == 0) { 6 return 1; 7 } 8 9 return n * silnia(n-1); 10 } 11 12 int main() { 13 int n; 14 cin >> n; 15 cout << silnia(n); 16 17 return 0; 18 } Rekurencję spotykamy nie tylko w programowaniu, ale i w matematyce. Niektóre funkcje, jak silnia, zdefiniowane są rekurencyjnie. To znaczy że definicja takiej funkcji odwołuje się do tej właśnie funkcji. Uwaga! Silnia z n (zapisujemy n!) to iloczyn wszystkich kolejnych liczb naturalnych od 1 do n włącznie. Silnia zdefiniowana jest następująco: { 1 gdy n = 0 n! = n (n 1)! gdy n 0 Definicję tę możemy zapisać w C++ w niemal niezmienionej formie, jak widać na przykładzie powyżej. Sprawdzamy najpierw czy n == 0. Jeżeli tak, zwracamy 1, jeżeli nie, zwracamy iloczyn n i silni z n-1. Uwaga! Drugie z wyrażeń return moglibyśmy umieścić w bloku else, jednak nie jest to konieczne. Jeżeli warunek podstawy rekurencji jest spełniony, to i tak program nie dotrze nigdy do kodu kroku rekurencji. 36

5.6. Ile jest liczb naturalnych nie większych od n, które podzielne są przez 5, ale nie są podzielne przez 3? Napisz program, który obliczy wynik dla n danego przez użytkownika. 1 #include <iostream> 2 using namespace std; 3 4 int ileniewiekszych(int n) { 5 if (n < 0) { 6 return 0; 7 } 8 9 if (n % 5 == 0 && n % 3!= 0) { 10 return 1 + ileniewiekszych(n-1); 11 } else { 12 return ileniewiekszych(n-1); 13 } 14 } 15 16 int main() { 17 int n; 18 cin >> n; 19 20 cout << ileniewiekszych(n) << endl; 21 22 return 0; 23 } Przy użyciu rekurencji możemy w łatwy sposób policzyć ile liczb w danym przedziale spełnia pewien warunek. Wystarczy rekurencyjnie przejść kolejno po wszystkich liczbach w przedziale (jak w przykładach 5.1, 5.2 i 5.3) i dla każdej z nich sprawdzić, czy warunek jest spełniony. Jeżeli tak, do ostatecznego wyniku dodajemy 1. Jeżeli nie, nie dodajemy nic. Dokładnie w ten sposób działa krok rekurencyjny funkcji w tym rozwiązaniu. Sprawdzamy czy obecnie rozpatrywana liczba spełnia warunek (linia 9) i dodajemy 1 do wyniku dla liczby o jeden mniejszej (linia 10) lub po prostu zwracamy wynik dla n 1 (linia 12). W podstawie rekurencji sprawdzamy, czy dana liczba jest mniejsza zero. Jeżeli tak, to nie musimy szukać już dalej, jako że interesują nas wyłącznie liczby naturalne, a poniżej 0 ich nie ma, stąd wynik wynosi 0. 37

Pytania 5.1. Co stanie się, jeżeli wywołamy odliczod(-1)? 5.2. Co stanie się, jeżeli wywołamy silnia(-1)? 5.3. Z czego wynika różnica w odpowiedziach na poprzednie dwa pytania? 5.4. Co wypisze na ekran wywołanie silnia(20)? Czy jest to prawidłowy wynik? Jaka jest największa wartość n dla której funkcja z przykładu 5.5 zwróci prawidłowy wynik? Dlaczego dla wartości większych otrzymujemy błędny wynik? 5.5. Czy zmiana typu zwracanego z int na double w funkcji silnia jest dobrym rozwiązaniem problemu z poprzedniego pytania? 5.6. Przeczytaj w internecie o wieżach Hanoi, na przykład na Wikipedii. Opisz własnymi słowami, ale zwięźle, w jaki sposób rekurencyjnie rozwiązać ten problem dla n krążków. Narysuj kolejne kroki dla n = 3. Zadania 5.1. (+50) Napisz program, który wypisze liczby od danego n do 1 włącznie, przy czym każda liczba podzielna przez 3 powinna zostać zastąpiona słowem fizz. 5.2. (+60) Napisz program, który rekurencyjnie obliczy sumę liczb naturalnych od 1 do danego n. Nie używaj wzoru Gaussa (tj. n(n+1) 2 ). 5.3. (+60) Napisz program, który obliczy wartość k-tej potęgi 2, gdzie k jest liczbą naturalną daną jako argument funkcji. Nie używaj cmath. 5.4. (+70) Napisz program, który obliczy wartość k-tej potęgi n, gdzie k i n są danymi liczbami naturalnymi. Nie używaj cmath. 5.5. (+75) Napisz program, który obliczy wartość funkcji Ackermanna A(m, n) zdefiniowanej następująco: n + 1 gdy m = 0 A(m, n) = A(m 1, 1) gdy m > 0 i n = 0 A(m 1, A(m, n 1)) gdy m > 0 i n > 0 5.6. (+70) Napisz program, który pobierze od użytkownika liczbę całkowitą, a następnie wypisze jej cyfry, zaczynając od jedności, po jednej cyfrze na linię. 38

5.7. (+70) Algorytm Euklidesa. Największy wspólny dzielnik (NWD) dwóch liczb to największa taka liczba naturalna, która dzieli bez reszty obie te liczby. Wiemy, że NWD(a, 0) = a oraz że NWD(a, b) = NWD(b, a mod b), gdzie a mod b to reszta z dzielenia a przez b. Napisz program, który znajdzie NWD dwóch danych liczb. 5.8. (+80) Ciąg Collatza zdefiniowany jest następująco: pierwsza liczba ciągu jest dowolną liczbą naturalną. Następnie każda kolejna wartość ciągu obliczana jest na podstawie poprzedniej wedle następującej reguły: jeżeli poprzednia wartość jest parzysta, nowa wartość stanowi jej połowę, w przeciwnym razie jej trzykrotność powiększoną o 1. Przykład. Jeżeli rozpoczniemy od 6 uzyskamy: 6, 3, 10, 5, 16, 8, 4, 2, 1. Napisz program, który dla danego pierwszego elementu ciągu wypisze kolejne elementy tego ciągu aż do napotkania pierwszej jedynki. 5.9. (+60) Napisz funkcję, która policzy wartość n-tej liczby Fibonacciego (F n ). Dla uściślenia: F 0 = 0, F 1 = 1, F n = F n 1 + F n 2. 5.10. (+60) Napisz program, który wypisze kolejne liczby naturalne od a do b włącznie, w kolejności malejącej, gdzie a i b to dane liczby naturalne. 5.11. (+80) Napisz program, który wypisze wszystkie dzielniki danej liczby naturalnej. Podpowiedź: konieczne może być napisanie dwóch funkcji. Jedna z nich przyjmuje dwa argumenty: wartość dzielnej i potencjalnego dzielnika, która rekurencyjnie sprawdza kolejne dzielniki. Druga funkcja przyjmuje tylko jeden argument i wywołuje pierwszą funkcję z danym argumentem i wartością pierwszego potencjalnego dzielnika. 5.12. (+100) Potęgę o wykładniku naturalnym możemy zdefiniować następująco: 1 gdy k = 0 n k = n k 2 n k 2 gdy 2 k n k 1 2 n k 1 2 n gdy 2 k Napisz funkcję, która obliczać będzie potęgi o wykładnikach naturalnych używając tej definicji. Upewnij się, że w każdym przypadku wykonujesz tylko jedno wywołanie rekurencyjne (np. przez zapisanie wyniku w zmiennej). Nie używaj cmath. 5.13. (+60) Ile jest liczb naturalnych mniejszych od n, które podzielne są przez 5, ale nie są podzielne przez 3? Napisz program, który obliczy wynik dla n danego przez użytkownika. 39

5.14. (+80) Jeżeli wypiszemy wszystkie liczby naturalne mniejsze od 10, które są wielokrotnościami 3 lub 5, otrzymamy 3, 5, 6 i 9. Suma tych liczb wynosi 23. Napisz program, który znajdzie sumę wszystkich wielokrotności 3 i 5 poniżej 1000. (Project Euler, zadanie 1) 5.15. (+100) Suma kwadratów pierwszych 10 liczb naturalnych wynosi 1 2 + 2 2 +... + 10 2 = 385 Natomiast kwadrat sumy pierwszych 10 liczb naturalnych wynosi (1 + 2 +... + 10) 2 = 3025 Stąd różnica między sumą kwadratów pierwszych 10 liczb naturalnych a kwadratem ich sumy wynosi 3025 385 = 2640. Znajdź różnicę między sumą kwadratów a kwadratem sumy dla pierwszych 100 liczb naturalnych. Podpowiedź: przydatne będzie tu napisanie więcej niż jednej funkcji. (Project Euler, zadanie 6) 5.16. (+120) Mamy do dyspozycji monety o nominałach 5zł i 2zł. Napisz program, który obliczy minimalną liczbę monet jaka jest niezbędna do wydania reszty w kwocie danej przez użytkownika. Program powinien wypisać słowa nie da się, jeżeli danej kwoty nie da się wydać przy użyciu danych nominałów. Upewnij się, że twój program zwraca prawidłowy wynik dla kwot takich jak 6zł (3 monety) czy 21zł (6 monet). 5.17. (+120) Napisz program, który wypisze na ekran tabliczkę mnożenia do 100. Rozszerzenie 5.1. (+210) Napisz funkcję, która przybliży wartość liczby π ze wzoru Leibniza: π 4 = ( 1) n n=0 2n+1. 5.2. (+340) Napisz funkcję, która obliczy przybliżoną wartość logarytmu naturalnego z danej liczby zmiennoprzecinkowej (double). 5.3. (+550) Zaimplementuj algorytm sortowania przez scalanie. 40