====== Den 2 ======= ===== Opakování - úkoly ===== Na vstupu přečtěte celé číslo reprezentující útratu v hospodě v Kč. Vypiště kolik mincí je minimálně potřeba zaplacení účtu, pokud nemůžete platit bankovkami. Vypiště také, které mince to budou. Připomínáme, že české mince mají hodnoty: 1, 2, 5, 10, 20 a 50. Vzorový vstup: Zadejte vasi utratu: 79 Vzorový výstup: Celkem je potreba 5 minci Pocet minci o hodnote 50 Kc: 1 Pocet minci o hodnote 20 Kc: 1 Pocet minci o hodnote 10 Kc: 0 Pocet minci o hodnote 5 Kc: 1 Pocet minci o hodnote 2 Kc: 2 Pocet minci o hodnote 1 Kc: 0 Pokud je zákazník příliš dlouho v hospodě, pokusí se zadat záporné číslo. Všechny podobné situace musíte ve svých kódech ošetřovat a vypsat odpovídající chybovou hlášku. K této úloze se ještě vrátíte později. Zvládnete nevypisovat řádky, pokud by bylo zapotřebí 0 mincí o dané hodnotě? [[courses:pri-bootcamp:solutions:day2#opakovani|Řešení]] ===== For cyklus - teorie ===== Všechny programy, které jsme doposud napsali, proběhly od začátku do konce právě jednou. Někdy se nám ale hodí části programu opakovat a abychom nemuseli příkazy za sebe psát (a nebo kopírovat) můžeme použít //for cyklus//, který n-krát zopakuje zadané příkazy. Ukážeme si to na jednoduchém příkladu vypsání 10x ''Hello Bootcamp!'': for i in range(10): print("Hello Bootcamp!") Všimněte si, že příkaz ''print("Hello Bootcamp!")'' je odsazen (třeba pomocí tabulátoru, nebo pomocí stisknutí mezerníku), čímž Pythonu dává najevo, kde začíná a hlavně končí for-cyklus (jaké příkazy je v //těle for cyklu//), viz: for i in range(10): print("Jsem ve for-cyklu...") print("...ale já už ne.") Pod pokličku fungování for-cyklu můžeme nakouknout následujícím kódem, kdy sledujeme hodnotu //iterační// proměnné ''i'': for i in range(10): print(i) který pod sebe vypíše čísla ''0, 1, ..., 9'', tedy deset čísel začínající nulou a menších než zadané číslo n (v našem případě 10). Pokud bychom nechtěli vypisovat čísla od 0, ale třeba začít od 4 napíšeme: for i in range(4,10): print(i) což pod sebe vypíše čísla ''4, 5, ..., 9''. Všimněte si, že ''for i in range(10):'' je to samé jako ''for i in range(0,10):''. Všimněte si, že ''for i in range(n,m):'' vypíše čísla v polouzavřeném intervalu $ for i in range(0,10,2): print(i) což pod sebe vypíše čísla ''0, 2, 4, 6, 8''. Podobně je možné vyřešit stejné zadání i takto: for i in range(5): print(2*i) jak vidno, k jednomu cíli vede (nejen v programování) vícero cest. Pokud není třeba dokončovat cyklus, ale chcete ho přerušit už dříve, lze po splnění nějaké podmínky použít klíčové slovo ''break''. Opakem ''break'' je ''continue''. ===== For cyklus - úkoly ===== ==== Rozcvička ==== Přečtěte číslo N ze standardního vstupu a poté: - vypište N-krát nějaký text (třeba "Ahoj"). - vypište čísla od 0 do N (vyjma). - vypište čísla od 0 do N (včetně) - vypište sestupně čísla od N do 1. - vypište sestupně čísla od N do 0. [[courses:pri-bootcamp:solutions:day2#rozcvicka|Řešení]] ---- ==== Úkol 0 ==== Přečtěte celé číslo N ze standardního vstupu. Vypiště čísla 1 až N. Vzorový výstup pro ''N=5'': 1 2 3 4 5 [[courses:pri-bootcamp:solutions:day2#ukol_0|Řešení]] ---- ==== Úkol 1 ==== Přečtěte celé číslo N ze standardního vstupu. Vypiště čísla 1 až N. Oddělte je vždy čárkou a mezerou. Pozor, za posledním číslem žádná čárka ani mezera být nemá. Příkaz ''print()'' v základním nastavení vždy zalomí řádek. Pokud chceme pokračovat na stejném řádku musíme přidat parametr: ''end=""'', který Pythonu říká, jak ukončit výpis (v tomto případě s ''""'', tj. prázdným textovým řetězcem). print("abc",end="") Vzorový výstup pro ''N=5'': 1, 2, 3, 4, 5 [[courses:pri-bootcamp:solutions:day2#ukol_1|Řešení]] ---- ==== Úkol 2 ==== Přečtěte celé číslo N ze standartního vstupu. Vypiště čísla od N do 1 sestupně se stejným formátováním. Vzorový výstup pro ''N=5'': 5, 4, 3, 2, 1 [[courses:pri-bootcamp:solutions:day2#ukol_2|Řešení]] ---- ==== Úkol 3 ==== Napište program, který sečte všechna kladná čísla do zadaného čísla (včetně). Zkuste jej modifikovat tak, aby vypsal součet od jednoho zadaného čísla do druhého (včetně). Ověřte, že nebude vadit, pokud zadáte stejná čísla, nebo bude druhé menší než první. [[courses:pri-bootcamp:solutions:day2#ukol_3|Řešení]] ---- ==== Úkol 4 ==== Napište program pro výpočet faktoriálu. Program načte jedno číslo (předpokládejte, že se jedná o přirozené číslo nebo nulu) a následně spočítá a vypíše faktoriál tohoto čísla. Připomeňmě, že faktoriál čísla n je definován takto: * pro přirozené číslo $n \in \mathbb{N}^0$ platí $n! = 1 \cdot 2 \cdot 3 \cdot \dots \cdot n$, * pro $n=0$ platí $n!=1$. Pro ověření správnosti vašeho programu si můžete výsledky zkontrolovat s následujícím seznamem: * 0! = 1 * 1! = 1 * 2! = 2 * 3! = 6 * 4! = 24 * 5! = 120 * 6! = 720 * 7! = 5 040 * 8! = 40 320 * 9! = 362 880 [[courses:pri-bootcamp:solutions:day2#ukol_4|Řešení]] ---- ==== Úkol 5 ==== Napište program, který načte jedno číslo (předpokládejte, že se jedná o přirozené číslo) a vypíše, zda se jedná o prvočíslo. Poznamenejme, že prvočíslo je takové přirozené číslo, které má právě dva dělitele: jedničku a samo sebe. **Tedy číslo jedna není prvočíslo ani složené číslo!** Je vhodné “odchytit” číslo jedna a řešit ho zvlášť. Prvočíselnost u ostatních čísel ověřujeme tak, že zkoušíme, jestli je dané číslo dělitelné některým z čísel mezi jedničkou a daným číslem. Pokud je dělitelné alespoň jedním z nich, tak se nejedná o prvočíslo. To, jestli je číslo A dělitelné číslem B, zjistíte tak, že vypočítáte zbytek po dělení (použijeme tedy operátor %). Pokud je A dělitelné číslem B, pak ''A%B == 0'' je pravdivý výrok. V opačném případě není A dělitelné číslem B. Při zjišťování, zda je číslo n prvočíslo nemusíme zkoušet, zda je dělitelné všemi čísly mezi $1$ a $n$. Úplně stačí zjistit, zda je dělitelné některým z čísel mezi $1$ a $\sqrt(n)$, protože pokud není dělitelné žádným z těchto čísel, pak není dělitelné ani žádným z čísel mezi $\sqrt(n)$ a $n$. Dokážete zdůvodnit proč? [[courses:pri-bootcamp:solutions:day2#ukol_5|Řešení]] ---- ===== Vnořený for cyklus - teorie ===== Uvnitř těla for cyklu mohou být libovolné příkazy (třeba výše použité výpisy podmínky a podobně) a to včetně dalšího for cyklu. V takovém případě hovoříme o vnořeném for cyklu, jehož fungování si můžeme ukázat na následujícím příkladu: for i in range(4): for j in range(i): print(j) print("---") Výstup tohoto programu bude: --- 0 --- 0 1 --- 0 1 2 --- V prvním průběhu vnějšího for cyklu je ''i=0'', tedy vnořený for cyklus neproběhne ani jednou a žádné číslo se nevypíše. V druhém kroku vnějšího for cyklu, kdy je ''i=1'' už vnořený for cyklus proběhne právě jednou a vytiskne se ''0''. Obdobně pak v dalších krocích. ===== Vnořený for cyklus - úkoly ===== ==== Úkol 0 ==== Napiště program, který vezme šířku ''X'' a výšku ''Y'' obdélníku, který vytiskne na příkazovou řádku složený ze znaků ''*''. Ukázkový vstup pro ''X=4'', ''Y=5'': **** **** **** **** **** [[courses:pri-bootcamp:solutions:day2#ukol_01|Řešení]] ---- ==== Úkol 1 ==== Napišta program, který načte šířku ''X'' a výšku ''Y'' souřadnicové sítě a vypíše všechny souřadnice v této síti. Ukázkový vstup pro ''X=4'' a ''Y=5''. [0,0][1,0][2,0][3,0] [0,1][1,1][2,1][3,1] [0,2][1,2][2,2][3,2] [0,3][1,3][2,3][3,3] [0,4][1,4][2,4][3,4] Tento program se vám bude hodit pro lepší vhled do toho, jaké jsou hodnoty proměnných, přes které iterujeí jendotlivé for cykly. Povšimněte si, že nám nevadí, že osa y jde opačným směrem, než jsme zvyklí (tedy shora dolů). [[courses:pri-bootcamp:solutions:day2#ukol_11|Řešení]] ---- ==== Úkol 2 ==== Napiště program, který načte N a vykreslí čtverec složený z ''0'' a pouze na obou diagonálách budou ''1''. Ukázkový vstup pro ''N=5'': 1 0 0 0 1 0 1 0 1 0 0 0 1 0 0 0 1 0 1 0 1 0 0 0 1 Modifikujte program tak, aby místo znaků ''1'' vypisoval znaky ''X'' a místo znaků ''0'' vypisoval mezery '' '' [[courses:pri-bootcamp:solutions:day2#ukol_21|Řešení]] ---- ==== Úkol 3 ==== Napište program, který načte N a (pro ''N=5'') vykreslí obrazec: X X X X X X X X X X X X X X X [[courses:pri-bootcamp:solutions:day2#ukol_31|Řešení]] ---- ==== Úkol 4 ==== S využítím předchozího napište program, který načte N a (pro ''N=5'') vykreslí obrazec: X X X X X X X X X X X X X X X [[courses:pri-bootcamp:solutions:day2#ukol_41|Řešení]] ---- ==== Úkol 5 ==== Napište program, který načte N a (pro ''N=5'') vykreslí obrys čtverce: X X X X X X X X X X X X X X X X [[courses:pri-bootcamp:solutions:day2#ukol_51|Řešení]] ---- ==== Úkol 6 ==== S využítím předchozího napište program, který načte N a vykreslí čtverec s diagonálami (pro ''N=7''): X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X [[courses:pri-bootcamp:solutions:day2#ukol_6|Řešení]] ---- ==== Úkol 7 ==== Modifikujte program na testování prvočíselnosti tak, aby vypsal všechna prvočísla menší než zadané n. [[courses:pri-bootcamp:solutions:day2#ukol_7|Řešení]] ---- ===== Textové řetězce - teorie ===== Textové řetězce se skládají z jednotlivých znaků. Chceme-li získat znak na ''N''-tém místě (//indexu//) v textovém řetezci uloženém v proměnné ''txt'' můžeme použít hranaté závorky: ''txt[N]''. Kupříkladu: txt="uwxyz" s = txt[0] u = txt[1] print(s) print(u) print(s) vypíše: u w u Povšimněte si, že první znak má index ''0''. Délku textového řetezce v proměnné ''txt'' je možné zjistit pomocí ''len(txt)'' ===== Textové řetězce - úkoly ===== ==== Úkol 1 ==== Naprogramujte úlohu, ve které od uživatele přijmete celé číslo a pro větší čitelnost do něj vložíte mezery. | Ukázkové vstupy | Ukázkové výstupy | | 1000000 | 1 000 000 | | 123456789 | 123 456 789 | | 9825 | 9 825 | Ujistěte se, že opravdu jde o celé číslo, ne jiný druh vstupu. Bude se vám hodit operátor modulo, více viz [[courses:pri-bootcamp:01#ukol_31 | úkol z prvního dne]]. ----- Rovnou tiskněte do konzole, neukládejte do paměti [[courses:pri-bootcamp:solutions:day2#ukol_12|Řešení]] ---- ==== Úkol 2 ==== Aby se k reportérům nedostaly choulostivé informace, napište program, který od uživatele načte textový řetězec a nahradí každou cifru za znak ''*''. | Ukázkové vstupy | Ukázkové výstupy | | commit: cb72418f702be7169e81961db5421034fe5a3f61 | commit: cb*****f***be****e****db*******fe*a*f** | | File "", line 5 | File "", line * | | cmake_minimum_required(VERSION 3.16) | cmake_minimum_required(VERSION *.**) | [[courses:pri-bootcamp:solutions:day2#ukol_22|Řešení]] ---- ==== Úkol 3 ==== Napište program, který jako uživatelský vstup vezme text a vrátí počet znaků a slov. Předpokládejme, že každý vstup obsahuje alespoň jedno slovo a slova jsou vždy oddělena jednou mezerou. | Ukázkové vstupy | Ukázkové výstupy | | nejkulaťoulinkatější | znaky: 20, slova: 1 | | Letní programovací Bootcamp FEL ČVUT | znaky: 36, slova: 5 | [[courses:pri-bootcamp:solutions:day2#ukol_32|Řešení]] ---- ==== Úkol 4 ==== Přečtěte binární zápis čísla na vstupu a vypište jeho hodnotu v dekadickém zápise (normální číslo). | Ukázkové vstupy | Ukázkové výstupy | | 10100 | 20 | | 110100 | 52 | Binární zápis z prvního ukázkového vstupu lze číst takto: $1 \cdot 2^4 + 0 \cdot 2^3 + 1 \cdot 2^2 + 0 \cdot 2^1 + 0 \cdot 2^0 = 16 + 4 = 20$ Další rozsáhlejší vodítka k pochopení [[https://algoritmy.net/article/80/Prevod-cisla-mezi-soustavami|zde (cz)]]. [[courses:pri-bootcamp:solutions:day2#ukol_42|Řešení]] ---- ===== Volitelné úkoly ===== ==== Úkol 1 ==== Napište program, který načte přirozené číslo ''n''. Pak tento program vypíše ''n''-tý člen Fibonacciho posloupnosti. Fibonacciho posloupnost je nekonečná posloupnost, pro kterou platí:\\ F(0) = 0\\ F(1) = 1\\ F(N) = F(N-1) + F(N-2)\\ Tedy další členy jsou: \\ F(2) = 1\\ F(3) = 2\\ F(4) = 3\\ F(5) = 5\\ F(6) = 8\\ ...\\ Bližší vysvětlení posloupnosti naleznete [[https://cs.wikipedia.org/wiki/Fibonacciho_posloupnost|zde (cz)]]. [[courses:pri-bootcamp:solutions:day2#ukol_13|Řešení]] ---- ==== Úkol 2 ==== Napište program, který načte dvě přirozená čísla a najde a vytiskne jejich největšího společného dělitele. [[courses:pri-bootcamp:solutions:day2#ukol_23|Řešení]]