785/2894

Céčko --> Domácí úkoly --> L4

Céčko:
Domácí úkoly
Zdrojové texty z výuky

Řešení domácího úkolů -- L4

Obsluha směnárny

Navrhněte a vytvořte aplikaci pro obsluhu směnárny. Aktuální kurzovní lístek čtěte ze souboru. V případě nákupu zadává směnárna měnu a částku, kterou od zákazníka nakupuje, a výstupem je částka v Kč, kterou zaplatí zákazníkovi. V případě prodeje zadává směnárna měnu a částku, kterou chce zákazník nakoupit a výstupem je částka v Kč, kterou má zákazník zaplatit.

Ovládání volte tak, aby bylo pro uživatele co možná nejpohodlnější a nejrychlejší. Uživatel jako výstup uvidí směněnou částku zaokrouhlenou na celé koruny. Dále aplikaci navrhněte tak, aby nerozlišovala desetinou tečku a čárku (to jak v kurzovním lístku, tak v uživatelském vstupu).

Obsluha směnárny -- příklad řešení


Komplexní kalkulátor

Vytvořte kalkulátor s reverzní polskou notací, který podporuje komplexní čísla a umí pracovat jak s algebraickým, tak exponenciálním tvarem. Kalkulátor bude podporovat následující matematické operace:

Dále bude možné se přepínat mezi stupni a radiány.

Vstup 3,4 odpovídá číslu 3+4j. Vstup 3 odpovídá čistě reálnému číslu 3. Vstup ,4 odpovídá čistě imaginárnímu číslu 4j. Pokud je přepnuto na stupně vstup 5L36 odpovídá číslu 5 ej36°. Pokud je přepnuto na radiány 5L1.6 odpovídá číslu 5 ej1.6.

Příklad práce programu

  >>> [ ]
 > help
 > Kalkulátor s polskou reverzní notací. Pořadí matematických
operací je dáno přímo zápisem. Například: 

(5 * (4 + 3) ) / (10-3) odpovídá 5 4 3 + * 10 3 - /

Kalkulátor počítá v komplexních číslech. Podporované matematické operace:
+ - * /

deg|d    přepne pro počítání ve stupních
rad|r    přepne pro počítání v radiánech
rem|m    vymaže poslední číslo ze zásobníku
alg|a    print vypisuje v algebraickém tvaru
exp|e    print vypisuje v exponenciálním tvaru
clr|c    vymaže celý zásobník
quit|q   ukončí program

>>> [ ]
 > 3,4 print
 > >>> [ (5L53.13°) ]
 > 5L53.13
 > alg
 > print
 > >>> [ (3+j4) (3+j4) ]
 > e p
 > >>> [ (5L53.13°) (5L53.13°) ]
 > /
 > >>> [ (1L0.0001024°) ]
 > a p
 > >>> [ (1+j1.786e-06) ]
 > 3,4
 > p
 > >>> [ (1+j1.786e-06) (3+j4) ]
 > rad
 > exp print
 > >>> [ (1L1.786e-06) (5L0.9273) ]
 > alg print
 > >>> [ (1+j1.786e-06) (3+j4) ]
 > q
 

Komplexní kalkulátor příklad řešní

Příklad řešení

Projekt ke stažení

crcal.tar.gz

 $ make && ./crcal 

Kalkulátor s postfixovou notací

Vytvořte kalkulátor s reverzní polskou notací. Kalkulátor bude podporovat následující matematické operace.

Příklad práce programu

 
5 4 3 + * 10 3 - /
>>> [ 5 7 ]
>>> [ 35 ]
>>> [ 35 7 ]
>>> [ 5 ]
2 **
>>> [ 25 ]
23 /
>>> [ 1.08696 ]
exp
>>> [ 2.96524 ]
2 sqrt
>>> [ 2.96524 1.41421 ]
+
>>> [ 4.37945 ]
 

Kalkulátor s postfixovou notací -- příklad řešení

Při řešení je použit zásobník. Protože zásobník je problém sám o sobě a nesouvisí s kalkulátorem jako takovým je zásobník implementován do samostatného modulu, se kterým je hlavní zdrojový soubor spojen pomocí hlavičkového souboru. Překlad je možné provádět i odděleně.

Zásobník

Zásobník je implementován velice jednoduše pomocí pole.

Rozdělení projektu do více souborů má několik výhod. Stejný modul lze díky tomuto použít ve více projektech a jednou napsaný kód tak můžete lépe zužitkovat. Hlavně nám to ale umožňuje spolupráci více programátorů na jednom projektu. V hlavním modulu/programu se nemusíme vůbec starat o to, jak konkrétně zásobník pracuje. Důležité je, že máme přesně definováno rozhraní -- tj. hlavičky funkcí.

Abych toto demonstroval vytvořil jsem ještě jednu implementaci zásobníku, tentokrát pomocí dynamického jednosměrného seznamu. Protože hlavičky funkcí jsou stejné programátor funkce main může kdykoliv přejít od jedné implementace zásobníku k druhé a v jeho kódu se vůbec nic nezmění.

Kalkulátor

Všimněte si prosím, že zdrojový kód je rozdělen do mnoha malých funkcí. Tyto funkce má smyl psát i přesto, že jsou tak malé. Umožnilo mi to totiž pracovat s odkazy na funkce: Díky tomu je kód funkce main přehledný a velice pružný, takže přidání podpory pro další matematické operace je velice jednoduché. Při rozdělování kódu do funkcí jsem se soustředil na to, aby se mi neopakoval stejný kód. Potřebný kód jsem napsal pouze jednou a odkazuji se na něj pomocí odkazů na funkce.

Vše v jednom

posfix-kalkul.tar.gz

 $ make && ./posfix-kalkul 

Výukový program matematiky, pro základní školy

Vytvořte výukový program pro první stupeň základní školy, který zkouší sčítání a odčítání do 100 a malou násobilku. Program bude generovat náhodné příklady pro zvolené matematické operace a na závěr vyhodnotí statistiku úspěšnosti.

Operace +, -, *, / je generována náhodně, ale při spuštění programu lze na příkazovém řádku zadat, které operace jsou povolené. Dále lze pomocí přepínače -n zadat počet příkladů.

Například matematika -n 20 + - generuje 20 příkladů na sčítání a odčítání.

Malá rada

Pokud při řešení použijete odkaz na funkci bude váš kód jistě přehlednější a pružnější.

Příklad

$ ./task-gen -h 
task-gen [-n number] [+-(*|.)(/|:)]

 -n number  number of tasks

 + Addition
 - Subtraction
 * Multiplication
 . Multiplication
 / Division
 : Division

./task-gen -n 6 + .: 
16 /  8 = 2
28 + 12 = 40
 7 *  5 = 12
51 + 39 = a
requires a number
51 + 39 = 90
30 /  6 = 5
48 /  6 = 8
---------------------
5 :-)    1 :-{    83%

Je také možné ovlivnit pravděpodobnost volby jednotlivých matematických operací. V tomto příkladu bude nejvíce úloh na násobení.

$ ./task-gen +.....:
 6 *  1 = 6
10 *  9 = 90
48 + 19 = 67
 5 *  2 = 10
 1 *  1 = 1
13 + 72 = 85
 6 *  8 = 48
42 /  6 = 7
10 *  5 = 20
 1 * 10 = 10
16 + 35 = 51
 3 *  5 = 15
---------------------
11 :-)    1 :-{    91%

Výukový program matematiky, pro základní školy -- ukázky řešní

Bláznivé řešení

Teto řešení je trochu bláznivé, ale skrývá v sobě jisté kouzlo a pokud ho pochopíte, může vás hodně posunout. Je zde použito odkazů na funkce, které se řadí do lineárního jednosměrného kruhového seznamu. Do seznamu řadím pouze ty funkce, které uživatel zadá a jednu funkci, tam můžu zařadit i víckrát. (Tím je zvýšena pravděpodobnost jejího výběru.) Náhodný výběr funkce se potom děje podobně jako u rozpočítávadla tj. v kruhovém seznam se stále dokola posunuje o, náhodný počet míst.

Čisté řešení

Zde jsou také použity odkazy na funkce ale skládají se jednoduše do pole.


Logik

Vytvořte jednoduchou hru, která se vzdáleně může podobat (dnes možná již zapomenuté) deskové hře Logik. Program náhodně vygeneruje 5 čísel (0-9) -- čísla nemusí být nutně různá. Hráč v každém kroku hádá číslo a jeho pozici. Hráč má celkem 10 pokusů.

Při každém pokusu je hráči vhodným způsobem podávána informace o tom, zda číslo uhodl nebo nikoli a to ve třech úrovních:

Příklad

 
Hádej 5 čísel od 0 do 9.
Správné místo ↑
Chybné místo ↔
Nesprávné číslo ✗
 > 1 2 3 4 5 
-> ↔ ✗ ✗ ↔ ↑ 
 > 6 7 4 1 5
-> ✗ ↔ ↑ ↔ ↑ 
 > 7 1 4 8 5
-> ↑ ↑ ↑ ✗ ↑ 
 > 7 1 4 9 5
-> ↑ ↑ ↑ ✗ ↑ 
 > 7 1 4 0 5
-> ↑ ↑ ↑ ✗ ↑ 
 > 7 1 4 4 5
-> ↑ ↑ ↑ ↔ ↑ 
 > 7 1 7 1 5
-> ↑ ↑ ↔ ↔ ↑ 
 > 7 1 4 7 5
-> ↑ ↑ ↑ ↔ ↑ 
 > 7 1 4 5 5
-> ↑ ↑ ↑ ↑ ↑ 
Gratuluji!!!  Uhodnuto v 9 pokusech

 

Logik -- řešení


Výpočty a tabulky goniometrických funkcí

Navrhněte aplikaci pro výpočet a generování tabulky funkcí sin, cos, tan, cotg. Výstup zobrazte s přesností na 3 desetinná místa.

Aplikace se bude ovládat interaktivně pomocí textových příkazů:

Při zadání jedné hodnoty úhlu se vypíše pouze jedna hodnota funkce. Při zadání tří hodnot od do krok se vypíše tabulka s hodnotami.

Příklad:


 > s 30
     x [°]     sin(x)
    30.000      0.500
 > c 60
     x [°]     cos(x)
    60.000      0.500
 > r
 > s 1
    x [rad]     sin(x)
     1.000      0.841
 > d
 > s 1
     x [°]     sin(x)
     1.000      0.017
 > o 0 30 2
     x [°]    cotg(x)
     0.000        INF
     2.000     28.636
     4.000     14.301
     6.000      9.514
     8.000      7.115
    10.000      5.671
    12.000      4.705
    14.000      4.011
    16.000      3.487
    18.000      3.078
    20.000      2.747
    22.000      2.475
    24.000      2.246
    26.000      2.050
    28.000      1.881
    30.000      1.732
 > ^D
 
Malá pomůcka:
odkaz na funkci

Výpočty a tabulky goniometrických funkcí -- řešení

Při řešní je využoto odkazů na funkce, které se předávají jako parametry funkcím. Tímto způsobem je možné zapsat jednotný kód pro všechny goniometrické funkce a jednoduše přepínat mezi vstupem v radiánech a stupních.


Práce se soubory

Vytvořte aplikaci, která čte uživatelem zadaný soubor, zapisuje do dalšího uživatelem zadaného souboru a provádí následující akce:

Aplikace se bude ovládat interaktivně pomocí jednoduchého menu.

 
$ ./filemishmash 

Vyber akci:
  1) Převod na malá písmena
  2) Nahrazení znaků
  3) Statistika souboru
  4) Náhodný text
  5) Konec
2
zadej vstupní znak > a
zadej výstupní znak > @

Vyber akci:
  1) Převod na malá písmena
  2) Nahrazení znaku
  3) Generování náhodného textu
  4) Statistika souboru
  5) Konec
3
Zadej výstupní soubor > /dev/stdout
Zadej počet generovaných slov > 20
ytutoqyc nef aqopikydide madamyro yryziwig ujebirinocyh vujyrugyd ysifikavil
p qav q azynixucudy i ic gubypewucu kowyjujuzi qufun u vuxej tuli

Vyber akci:
  1) Převod na malá písmena
  2) Nahrazení znaků
  3) Statistika souboru
  4) Náhodný text
  5) Konec
5
$
 

Práce se soubory -- řešení


Ukazatelová aritmetika

Stáhněte si následující zdrojový kód, program zkompilujte, upravte, experimentujte s ním a na základě vašeho experimentování, případně hledání odhalte funkci jednotlivých konstrukcí, které jsou v programu použity.


Časovač AS51

Toto zadání jste si navrhli sami, takže si ho prosím dotvořte na Wiki.


X PixMap

Vytvořte dvojrozměrné pole a následně je uložte do formátu X PixMap. Takto vytvořte následující obrázek.


Lineární seznam

Do následujícího předpřipraveného programu dopište funkce pro přáci s lineárním jednosměrným seznamem.

lin-jednosm-sezn-kostra.c
   1 /*
   2  * Soubor:  lin-jednosm-sezn.c
   3  * Datum:   09.12.2011 17:03
   4  * Autor:   Marek Nožka, nozka <@t> spseol <d.t> cz
   5  * Licence: GNU/GPL 
   6  * Úloha: 
   7  * Popis:   
   8  ****************************************************/
   9 #define _ISOC99_SOURCE
  10 #define _GNU_SOURCE
  11 #include <stdio.h>
  12 #include <stdlib.h>
  13 
  14 
  15 typedef struct point {
  16     int data;
  17     struct point *next;
  18 } POINT;
  19 
  20 /* ***************   Funkce    ******************** */
  21 
  22 /** Přidá položku na začátek seznamu.
  23  *
  24  * @param data Data uložená v seznamu.
  25  * @param list Ukazatel na ukazatal na seznam;
  26  *        musí být deklarován jako ukazatel na ukazatel, protože
  27  *        se uvnitř funkce musí přepsat.
  28  */
  29 void addBegin(int data, POINT ** list)
  30 {
  31     POINT *working = NULL;
  32 
  33 }
  34 
  35 /** Přidá položku na konec seznamu.
  36  *
  37  * @param data Data uložená v seznamu.
  38  * @param list Ukazatel na ukazatal na seznam;
  39  *        musí být deklarován jako ukazatel na ukazatel, protože
  40  *        se uvnitř funkce musí přepsat.
  41  */
  42 void addEnd(int data, POINT ** list)
  43 {
  44     POINT *working;
  45     POINT *end;
  46 
  47 }
  48 
  49 /** Tiskne celý seznam.
  50  *
  51  * @param list Ukazatel na seznam.
  52  */
  53 void printList(POINT * list)
  54 {
  55 }
  56 
  57 /** Uvolní seznam z paměti.
  58  *
  59  * @param list Ukazatel na ukazatal na seznam;
  60  *        musí být deklarován jako ukazatel na ukazatel, protože
  61  *        se uvnitř funkce musí přepsat.
  62  */
  63 void freeList(POINT ** list)
  64 {
  65     POINT *begin = *list;
  66     POINT *working;
  67     while (begin != NULL) {
  68         working = begin;
  69         begin = working->next;
  70         free(working);
  71     }
  72     *list = NULL;
  73 }
  74 
  75 /** Funkce vrátí ukazatel na položku seznamu 
  76  * danou pořadovým číslem předaným v parametru.
  77  *
  78  * @param list Ukazatel na seznam.
  79  * @param order Pořadové číslo prvku seznamu. První 
  80  *        prvek má číslo 0.
  81  * @return odkaz na požadovaný prvek seznamu
  82  */
  83 POINT *getItem(POINT * list, unsigned int order)
  84 {
  85 
  86 }
  87 
  88 
  89 
  90 /****************************************************
  91  *               Hlavní program.
  92  ****************************************************/
  93 int main(void)
  94 {
  95     POINT *list = NULL;
  96     POINT *item = NULL;
  97 
  98     addEnd(440, &list);
  99     addBegin(20, &list);
 100     addBegin(11, &list);
 101     addEnd(38, &list);
 102     addBegin(13, &list);
 103     addEnd(9, &list);
 104 
 105     printList(list);
 106     puts("-----------------------------");
 107     if ((item = getItem(list, 3)) != NULL) {
 108         printf("%d\n", item->data);
 109     } else {
 110         puts("Tato položka v seznamu není");
 111     }
 112     if ((item = getItem(list, 9)) != NULL) {
 113         printf("%d\n", item->data);
 114     } else {
 115         puts("Tato položka v seznamu není");
 116     }
 117     puts("-----------------------------");
 118     freeList(&list);
 119     printList(list);
 120     return 0;
 121 }
`--> stáhnout

program by měl dát následující výsledek:

13
11
20
440
38
9
-----------------------------
440
Tato položka v seznamu není 
-----------------------------

Lineární seznam -- řešení

lin-jednosm-sezn-lyUQgP9zbA.c
   1 /*
   2  * Soubor:  lin-jednosm-sezn.c
   3  * Datum:   09.12.2011 17:03
   4  * Autor:   Marek Nožka, nozka <@t> spseol <d.t> cz
   5  * Licence: GNU/GPL 
   6  * Úloha: 
   7  * Popis:   
   8  ****************************************************/
   9 #define _ISOC99_SOURCE
  10 #define _GNU_SOURCE
  11 #include <stdio.h>
  12 #include <stdlib.h>
  13 
  14 
  15 typedef struct point {
  16     int data;
  17     struct point *next;
  18 } POINT;
  19 
  20 /* ***************   Funkce    ******************** */
  21 
  22 /** Přidá položku na začátek seznamu.
  23  *
  24  * @param data Data uložená v seznamu.
  25  * @param list Ukazatel na ukazatal na seznam;
  26  *        musí být deklarován jako ukazatel na ukazatel, protože
  27  *        se uvnitř funkce musí přepsat.
  28  */
  29 void addBegin(int data, POINT ** list)
  30 {
  31     POINT *working = NULL;
  32 
  33     working = malloc(sizeof(POINT));
  34     working->data = data;
  35     working->next = (*list);
  36     (*list) = working;
  37 }
  38 
  39 /** Přidá položku na konec seznamu.
  40  *
  41  * @param data Data uložená v seznamu.
  42  * @param list Ukazatel na ukazatal na seznam;
  43  *        musí být deklarován jako ukazatel na ukazatel, protože
  44  *        se uvnitř funkce musí přepsat.
  45  */
  46 void addEnd(int data, POINT ** list)
  47 {
  48     POINT *working;
  49     POINT *end;
  50 
  51     working = malloc(sizeof(POINT));
  52     working->data = data;
  53     if (*list == NULL) {
  54         working->next = (*list);
  55         (*list) = working;
  56     } else {
  57         end = *list;
  58         while (end->next != NULL) {
  59             end = end->next;
  60         }
  61         end->next = working;
  62     }
  63 
  64 }
  65 
  66 /** Tiskne celý seznam.
  67  *
  68  * @param list Ukazatel na seznam.
  69  */
  70 void printList(POINT * list)
  71 {
  72     POINT *working = list;
  73     while (working != NULL) {
  74         printf("%d\n", working->data);
  75         working = working->next;
  76     }
  77 }
  78 
  79 /** Uvolní seznam z paměti.
  80  *
  81  * @param list Ukazatel na ukazatal na seznam;
  82  *        musí být deklarován jako ukazatel na ukazatel, protože
  83  *        se uvnitř funkce musí přepsat.
  84  */
  85 void freeList(POINT ** list)
  86 {
  87     POINT *begin = *list;
  88     POINT *working;
  89     while (begin != NULL) {
  90         working = begin;
  91         begin = working->next;
  92         free(working);
  93     }
  94     *list = NULL;
  95 }
  96 
  97 /** Funkce vrátí ukazatel na položku seznamu 
  98  * danou pořadovým číslem předaným v parametru.
  99  *
 100  * @param list Ukazatel na seznam.
 101  * @param order Pořadové číslo prvku seznamu. První 
 102  *        prvek má číslo 0.
 103  * @return odkaz na požadovaný prvek seznamu
 104  */
 105 POINT *getItem(POINT * list, unsigned int order)
 106 {
 107     unsigned int i = 0;
 108     POINT *working = list;
 109 
 110     // pokud je seznam prázdný
 111     if (working == NULL) {
 112         return NULL;
 113     }
 114     while (i < order) {
 115         if ((working = working->next) == NULL) {
 116             return NULL;
 117         }
 118         i++;
 119     }
 120     return working;
 121 }
 122 
 123 
 124 
 125 /****************************************************
 126  *               Hlavní program.
 127  ****************************************************/
 128 int main(void)
 129 {
 130     POINT *list = NULL;
 131     POINT *item = NULL;
 132 
 133     addEnd(440, &list);
 134     addBegin(20, &list);
 135     addBegin(11, &list);
 136     addEnd(38, &list);
 137     addBegin(13, &list);
 138     addEnd(9, &list);
 139 
 140     printList(list);
 141     puts("-----------------------------");
 142     if ((item = getItem(list, 3)) != NULL) {
 143         printf("%d\n", item->data);
 144     } else {
 145         puts("Tato položka v seznamu není");
 146     }
 147     if ((item = getItem(list, 9)) != NULL) {
 148         printf("%d\n", item->data);
 149     } else {
 150         puts("Tato položka v seznamu není");
 151     }
 152     puts("-----------------------------");
 153     freeList(&list);
 154     printList(list);
 155     return 0;
 156 }
`--> stáhnout

Kořeny polynomu

Vytvořte program, který ze souboru koreny.txt načte kořeny kvadratického polynomu a do souboru polynomy.txt uloží kvadratické polynomy příslušející těmto kořenům. Pro jednoduchost uvažujte pouze celá čísla.

Příklad vsupního souboru

0 2 
1 2
-3 4
8 5
   -1    1
 2  -5
-2 -7
-1 3

`--> stáhnout

Příklad výstupního souboru

xx-2x
xx-3x+2 
xx-1x-12 
xx-13x+40 
xx-1 
xx+3x-10 
xx+9x+14 
xx-2x-3

`--> stáhnout

nebo

x²-2x
x²-3x+2 
x²-1x-12 
x²-13x+40 
x²-1 
x²+3x-10 
x²+9x+14 
x²-2x-3

`--> stáhnout

Kořeny polynomu -- řešení

polynomy.c
   1 /*
   2  * Soubor:  polynomy.c
   3  * Datum:   09.12.2011 10:09
   4  * Autor:   Marek Nožka, nozka <@t> spseol <d.t> cz
   5  * Licence: GNU/GPL 
   6  * Popis:   Program ze souboru `koreny.txt` načte kořeny 
   7  *          kvadratického polynomu a do souboru `polynomy.txt`
   8  *          uloží kvadratické polynomy příslušející 
   9  *          těmto kořenům.
  10  ****************************************************/
  11 #define _ISOC99_SOURCE
  12 #define _GNU_SOURCE
  13 #include <stdio.h>
  14 
  15 int main(void)
  16 {
  17     FILE *inFile;
  18     FILE *outFile;
  19     int x1, x2;                 // kořeny
  20     int b, c;                   // koeficienty
  21 
  22     if ((inFile = fopen("koreny.txt", "r")) == NULL) {
  23         fprintf(stderr, "koreny.txt\n");
  24         perror("ERROR");
  25         return 1;
  26     }
  27 
  28     if ((outFile = fopen("polynomy.txt", "w")) == NULL) {
  29         fprintf(stderr, "koreny.txt\n");
  30         perror("ERROR");
  31         return 1;
  32     }
  33 
  34     while (fscanf(inFile, "%d%d", &x1, &x2) != EOF) {
  35         b = -(x1 + x2);
  36         c = x1 * x2;
  37         printf("(x%+d)*(x%+d) = xx", -x1, -x2);
  38         fprintf(outFile, "xx");
  39         if (b != 0) {
  40             printf("%+dx", b);
  41             fprintf(outFile, "%+dx", b);
  42         }
  43         if (c != 0) {
  44             printf("%+d", c);
  45             fprintf(outFile, "%+d", c);
  46         }
  47         printf("\n");
  48         fprintf(outFile, "\n");
  49     }
  50     fclose(inFile);
  51     fclose(outFile);
  52 
  53     return 0;
  54 }
`--> stáhnout

Velká a malá

Vytvořte program, který čte stdin a zapisuje na stdout všechna malá písmena jako velká a všechna velká písmena jako malá. Všechny nepísmenné znaky samozřejmě zůstanou tak jak jsou.

ctype.h


Prvočísla

Prvních N

Vytvořte program, který na standardní výstup vypíše prvních N prvočísel.

Menší než N

Vytvořte program, který na standardní výstup vypíše všechna prvočísla ≤ N .

Prvních N nebo menší než N

Vytvořte program, který obě předchozí úlohy kombinuje tak, že uživatel si parametrem na příkazové řádce zvolí, zda chce prvních N nebo menší než N. (Přebírání_parametrů_z_příkazového_řádku_v_jazyce_C)

Příklad

 $ ./prvocislaN -h
Program vypisuje na stdout prvočísla
-f N    tiskne prvních N prvočísel
-l N    tiskne prvočísla ≤ N

$ ./prvocislaN -f 10
2 3 5 7 11 13 17 19 23 29 

$ ./prvocislaN -l 10
2 3 5 7 
 

Prvočísla -- řešení


Trojúhelník z hvězdiček

Z hvězdiček (nebo jiného znaku, který zadá uživatel) vytvořte na zadaný počet řádků různé trojúhelníky.

Příklad

 $ ./trojuhelnik 5 *

*
**
***
**
*

    *
   ***
  ***** 
 *******
*********

*********
 *******
  ***** 
   ***
    *

  *
 **
***
 **
  *


 

Variace

Program nemusí pracovat jen interaktivně ale i dávkově. To znamená, že potřebné údaje mu předáme jako parametry nebo přepínače přímo na příkazové řádce.

Trojúhelník z hvězdiček -- řešení


Číslo právě dvakrát

Vygenerujte pole 20-ti náhodných čísel v intervalu <0,10>. Vypište čísla, která se v poli vyskytují právě dvakrát.

Číslo právě dvakrát -- řešení

Tento příklad má ukázat, jak lze pomocí funkcí poměrně složitou úlohu rozdělit na menší -- mnohem lépe zvládnutelné úlohy.

Algoritmus je zhruba následující: Procházíme pole a pro každý prvek spočítáme výskyty stejných prvků. Prvek uložíme do pole hotovo, aby se už znovu nepočítal, až v poli narazíme na další stejný prvek.

Funkce komunikují pomocí globálních proměnných

Funkce komunikují pomocí svých parametrů


Platidla

Je dáno přirozené číslo N. Jakým nejmenším počtem platidel je možné zaplatit částku N korun, máte-li k dispozici neomezené množství českých mincí a bankovek všech druhů? Na standardní výstup vypište nejen celkový počet platidel, ale také rozpis počtů jednotlivých použitých platidel.

Příklad rozhraní programu

> 987
>>> 1 x 500
>>> 2 x 200
>>> 1 x 50
>>> 1 x 20
>>> 1 x 10
>>> 1 x 5
>>> 1 x 2
>>> Celkem 9 platidel.

Platidla -- řešení


Lomená čára

c2=a2+b2Načítejte ze vstupu dvojice čísel, které určují souřadnice bodu v rovině. Vypočítejte celkovou délku lomené čáry, která všechny načtené body spojuje. Čtěte až do konce souboru.

Příklad rozhraní programu

 [x,y]> 0 0
 [x,y]> 3 4 
 >>>>>>>>> 5
 [x,y]> 4 3
 >>>>>>>>> 6.41
 [x,y]> 8 2
 >>>>>>>>> 10.54
 [x,y]> ^D

Lomená čára -- řešení


Wikibook

Editujte stánku Ukazatele v C a připište do stránky podstatné informace.


Dolní propust RC

Vytvořte program pro výpočet přenosu (modulu a fáze) dolní propusti RC na zadané frekvenci. Samotný výpočet bude realizován funkcí s následující hlavičkou:

int dprc(double r, double c, double f, double *modul, double *faze);

Funkce vrátí 1, pokud je vše v pořádku a výpočet proběhne správně. Funkce vrátí 0, pokud zadané vstupní hodnoty jsou nereálné a výpočet není možné provést.

Dolní propust -- řešení

Jen jednou

Jednoduché řešení -- jeden vstup, jeden výpočet.

Až do konce souboru

Trošku jiné řešení, kdy program čte vstup po řádcích a až do konce souboru.


Největší společný násobek, nejmenší společný dělitel

Vytvořte program, který načte ze vstupu dvě celá kladná čísla a vypočítá jejich největšího společného dělitele a nejmenší společný násobek

Příklad

Rozhraní programu může vypadat například takto:

 > 12 18
 nsd=6 nsn=36

 > -12 18.7
 Err: Očekávám jen celá kladná čísla

Největší společný násobek, nejmenší společný dělitel -- řešení


Kvadratická rovnice

Vytvořte program pro výpočet kořenů kvadratické rovnice a*x^2+b*x+c=0. Program načte ze vstupu koeficienty a, b, c a na výstup vypíše kořeny. Pokud je a=0, je rovnice lineární a bude vypsán jen jeden kořen. Uvažujte i záporný diskriminant a řešení v komplexních číslech. Přesvědčte se o tom, že program si dobře poradí také s ostatními chybovými stavy.

Příklad

$ ./kvadrr 
(a)xx+(b)x+(c)=0 > 1 -6 8

  ( 4 )  ( 2 )
$ ./kvadrr
(a)xx+(b)x+(c)=0 > 1 -6 10

  ( 3 + 1*j )  ( 3 - 1*j )

Testování

Pro testování vašeho programu můžete využít následující skript. S jeho pomocí budu testovat i programy, které mi odevzdáte.

Kvadratická rovnice -- řešení

Program


π

Vytvořte funkci, která realizuje výpočet čísla ¶ pomocí vzorce pi.

Úplný funkční prototyp bude vypadat takto:
double mypi(double count);
count je zde počet členů, které budou do výpočtu zahrnuty.

π -- řešení

Program


Exponenciální funkce

Vytvořte funkci, která realizuje výpočet exponenciální funkce ex pomocí součtu nekonečné konvergentní řady
e^x=1+x/1!+x^2/2!+...+x^n/n!.
Do výpočtu nezahrnujte členy posloupnosti menší než 10-8 (<1E-8).

Úplný funkční prototyp bude vypadat takto:
double myexp(double x);

Exponenciální funkce -- řešení

Program


Porovnání rychlostí řadících algoritmů

Implementujte základní řadící algoritmy (Select sort, Insert sort, Bubble sort a Quick sort) a porovnejte jejich rychlosti.

Porovnání rychlostí řadících algoritmů -- řešení

Tento příklad je dobrou ukázkou, jak lze spravovat projekt pomocí programu make. Řadící algoritmy jsou implementovány v souboru libsort.c. Ty jsou potom volány z msort.c. Pro kompilaci kódu stačí zavolat program make. test.sh je skript, který spustí vytvořené binární soubory a seřadí je podle rychlosti.


Řazení

Pomocí algoritmu Přímého vkládání (Insert sort) nebo přímého výběru (Selection sort) seřaďte pole náhodných čísel.


Bargraf počtu znaků

Vytvořte program, který vypíše počty výskytů jednotlivý písmen anglické abecedy a znázorní je v normovaném bargrafu.

Příklad

Jako test můžeme stáhnou anglickou html stránku, zbavit ji html značek a poslat ji na vstup vašeho programu. Mělo by být vidět, proč má E v Morseově abecedě nejkratší symbol.
$ curl 'http://en.wikipedia.org/wiki/C_(programming_language)' | sed 's/<[^>]\+>//g' | ./pocty-znaku

Variace (dobrovolná)

Mnohem větší výzvou pro vás může být tvorba vertikálního bargrafu.

Bargraf počtu znaků -- řešení

Program


Vždy jen jeden bílý znak

Vytvořte program, který nahradí výskyt několika mezer vždy jen jednou mezerou a výskyt několika prázdných řádků vždy jen jedním prázdným řádkem.

Příklad vstupu

abcd    kocka    prede


bez klobouku
bez klobouku
bez klobouku


bos

narazil    si 



nos

Příklad výstupu

abcd kocka prede

bez klobouku
bez klobouku
bez klobouku

bos

narazil si 

nos

Variace (dobrovolná)

Program upravte, tak aby počítal i s tabulátory a posloupnost libovolného počtu tabulátorů a mezer nahradil jedním znakem. Řádek, na kterém se nachází jen mezery a tabulátory považujte za prázdný.

Příklad vstupu

Příklad výstupu

Vždy jen jeden bílý znak -- řešení

Program


Malá a velká písmena

Vytvořte program, který čte standardní vstup a na standardní výstup zapisuje místo malých písmen velká písmena a místo velkých písmen malá.

Malá a velká písmena -- řešení

První řešení je sice funkční, ale je určeno pouze pro systémy se znakovou sadou ASCII.

Zde už je vše jak má být. Je použita standardní knihovna a proto je kód nezávislí na použité znakové sadě.


Zvýraznění bílých znaků

Napište program pro zvýraznění mezer, tabulátorů a nových řádků. Mezery nahraďte podtržítkem, tabulátory značkou \t a před znak nového řádku přidejte značkou \n.

Příklad vstupu

Příklad výstupu

Zvýraznění bílých znaků -- řešení

Program


Věk

Vytvořte program, který načte rok narození a dle věku zařadí osobu do odpovídající kategorie. Předpokládejte, že vstup je zadán korektně. Aktuální rok v programu uveďte jako symbolickou konstantu.

Kategorie
dítě (0-14 let)
student (15-26 let)
pracující (27-64 let)
důchodce (65 a více let)

Příklad

rok> 2000 
  >> dite 

Věk -- řešení


Převodní tabulka Celsius, Fahrenheit

Vytvořte program, který na obrazovku vytiskne převodní tabulku ze stupňů Celsia (od 0 do 100) na stupně Fahrenheita. Tabulka bude obsahovat i hlavičku s nadpisem sloupců.

C=5*(F-32)/9 , F=(9*C/5)+32

Příklad výstupu

Převodní tabulka Celsius, Fahrenheit -- řešení

Program

Pro zajímavost nabízím ještě řešení s použitím barev.


--> aktuální zadání

Licence Creative Commons Valid XHTML 1.0 Strict Valid CSS! Antispam.er.cz Blog: Tlapicka.net