pridat zbytek

This commit is contained in:
Matyáš Caras 2024-11-21 17:14:54 +01:00
parent d4f77aed1b
commit 6ffbdfa881
Signed by: hernik
GPG key ID: 2A3175F98820C5C6
43 changed files with 2563 additions and 1 deletions

1
.gitignore vendored
View file

@ -1 +1,2 @@
main
vgcore.*

12
Cviko5_1/Makefile Normal file
View file

@ -0,0 +1,12 @@
all: main
CC = clang
override CFLAGS += -std=c11 -Wall -Wextra -Wno-unused-variable -Wno-unused-parameter -Wno-unused-result -Wno-unknown-pragmas -pedantic -lm
main: main.c
$(CC) $(CFLAGS) -O0 ./*.c -o "$@"
run: main
./main $(ARGS)
clean:
rm -f main main-*

86
Cviko5_1/main.c Normal file
View file

@ -0,0 +1,86 @@
#include "types.h"
#include <stdio.h>
bool is_leap_year(int year) {
return (year % 4 == 0 && year % 100 != 0) ||
(year % 4 == 0 && year % 400 == 0);
}
/**
* Determine whether the provided date is valid.
*
* @param date Datová struktura reprezentující datum
*
* @return `true` v případě validního data, `false` jinak
*/
bool is_valid_date(struct date_t date) {
return !(date.day > 31 || date.day < 1 || date.month > 12 || date.month < 1 ||
(date.month == 2 && date.day > 29 && is_leap_year(date.year)) ||
(date.month == 2 && date.day > 28 && !is_leap_year(date.year)) ||
date.year < 1582 || date.year > 2024 ||
((date.month == 4 || date.month == 6 || date.month == 9 ||
date.month == 11) &&
date.day > 30));
}
/**
* Find the earlier date by comparing years, months and days.
*
* @param date1 Datová struktura reprezentující první datum
* @param date2 Datová struktura reprezentující druhé datum
*
* @return `DATE1_IS_EARLIER` v případě date1 je dřívější,
* `DATE1_IS_LATER` když date2 je dřívější,
* `DATES_ARE_EQUAL` jinak (data jsou stejná)
*/
int earlier_date(struct date_t date1, struct date_t date2) {
// TODO: implementujte funkci dle zadání
if (date1.year == date2.year && date1.month == date2.month &&
date1.day == date2.day) {
return DATES_ARE_EQUAL;
}
if (date1.year < date2.year ||
(date1.year == date2.year && date1.month < date2.month) ||
(date1.year == date2.year && date1.month == date2.month &&
date1.day < date2.day)) {
return DATE1_IS_EARLIER;
}
return DATE1_IS_LATER;
}
#ifndef TEST_BUILD
int main(void) {
struct date_t date1, date2;
// Load two dates from the user
printf("Provide the first date (format yyyy-mm-dd): ");
scanf("%d-%d-%d", &date1.year, &date1.month, &date1.day);
printf("Provide the second date (format yyyy-mm-dd): ");
scanf("%d-%d-%d", &date2.year, &date2.month, &date2.day);
// Check that the dates are valid
if (!is_valid_date(date1) || !is_valid_date(date2)) {
printf("Invalid date!\n");
return 1;
}
// Compare the dates and find the earlier one
int earlier = earlier_date(date1, date2);
if (earlier == DATE1_IS_EARLIER) {
printf("The date %d-%d-%d is earlier.\n", date1.year, date1.month,
date1.day);
} else if (earlier == DATE1_IS_LATER) {
printf("The date %d-%d-%d is earlier.\n", date2.year, date2.month,
date2.day);
} else {
printf("The dates are the same.\n");
}
return 0;
}
#endif

42
Cviko5_1/types.h Normal file
View file

@ -0,0 +1,42 @@
/**
* Hlavičkový soubor types.h
*
* OBSAH V TOMTO SOUBROU NEUPRAVUJTE!
*/
#ifndef TYPES_H
#define TYPES_H
#include <stdbool.h>
// DEKLAROVANÉ HLAVIČKY FUNKCÍ A STRUKTUR NIJAK NEMĚŇTE
// Structures allow us to "bundle" number of variables that are related together
// e.g., date consists of year, month and day
//
// To access specific elements of our date structure, we use the "dot" notation:
// date.year, date.month, date.day, etc.
#define DATE1_IS_EARLIER -1
#define DATE1_IS_LATER 1
#define DATES_ARE_EQUAL 0
// Date structure
struct date_t {
int year;
int month;
int day;
};
// Time structure
struct time_t {
int hour;
int min;
int sec;
};
bool is_valid_date(struct date_t date);
int earlier_date(struct date_t date1, struct date_t date2);
#endif

12
Cviko5_2/Makefile Normal file
View file

@ -0,0 +1,12 @@
all: main
CC = clang
override CFLAGS += -std=c11 -Wall -Wextra -Wno-unused-variable -Wno-unused-parameter -Wno-unused-result -Wno-unknown-pragmas -pedantic -lm
main: main.c
$(CC) $(CFLAGS) -O0 ./*.c -o "$@"
run: main
./main $(ARGS)
clean:
rm -f main main-*

124
Cviko5_2/main.c Normal file
View file

@ -0,0 +1,124 @@
#include "types.h"
#include <stdio.h>
/**
* Print the contents of the provided 2D matrix.
*
* @param arr 2D matrix
*/
void print_2d(int arr[MAT_ROWS][MAT_COLUMNS]) {
// TODO: 1. print contents of the matrix:
// 1 2 3
// 4 5 6
// 7 8 9
for (int row = 0; row < MAT_ROWS; ++row) {
for (int col = 0; col < MAT_COLUMNS; ++col) {
printf("%d ", arr[row][col]);
}
printf("\n");
}
printf("\n");
}
/**
* Search for a value in the provided 2D matrix.
*
* @param arr 2D matrix
* @returns true when found, false otherwise
*/
bool contains_value(int arr[MAT_ROWS][MAT_COLUMNS], int value) {
// TODO: 2. try to locate the provided value in the provided array
for (int row = 0; row < MAT_ROWS; ++row) {
for (int col = 0; col < MAT_COLUMNS; ++col) {
if (arr[row][col] == value) {
return true;
}
}
}
return false;
}
/**
* Search for a value in the provided 2D matrix.
*
* @param arr 2D matrix
* @param value the value to find in the matrix
*
* @return coordinates of the value in the matrix when found;
* corrdinates {-1, -1} otherwise
*/
MatCoords find_value(int arr[MAT_ROWS][MAT_COLUMNS], int value) {
// TODO: 3. try to locate the provided value in the provided array
// and return its coordinates when found
for (int row = 0; row < MAT_ROWS; ++row) {
for (int col = 0; col < MAT_COLUMNS; ++col) {
if (arr[row][col] == value) {
return (MatCoords){row, col};
}
}
}
return (MatCoords){-1, -1};
}
#ifndef TEST_BUILD
int main(void) {
// Create 3x3 array (matrix, table, ...)
// The array has 3 rows and in each row, 3 columns
// MAT_ROWS and MAT_COLUMNS are defined in ./types.h
int matrix[MAT_ROWS][MAT_COLUMNS], value;
// TODO: Initialize the 2d array by setting each element to 0, i.e.:
// --- C_0 C_1 C_2
// R_0 0 0 0
// R_1 0 0 0
// R_2 0 0 0
for (int row = 0; row < MAT_ROWS; ++row) {
for (int col = 0; col < MAT_COLUMNS; ++col) {
matrix[row][col] = 0;
}
}
print_2d(matrix);
int identity_matrix[MAT_ROWS][MAT_COLUMNS];
// TODO: Create and initialize an identity matrix, i.e.:
// --- C_0 C_1 C_2
// R_0 1 0 0
// R_1 0 1 0
// R_2 0 0 1
for (int row = 0; row < MAT_ROWS; ++row) {
for (int col = 0; col < MAT_COLUMNS; ++col) {
if (row == col) {
identity_matrix[row][col] = 1;
} else {
identity_matrix[row][col] = 0;
}
}
}
print_2d(identity_matrix);
// Set new value to row = 1, col = 2
value = matrix[1][2] = 5;
// Try to find the value
bool contains_result = contains_value(matrix, value);
if (contains_result) {
printf("Value: %d found!\n", value);
} else {
printf("Value: %d not found!\n", value);
}
// Try to find the value and obtain its coordinates in the matrix
MatCoords coords = find_value(matrix, value);
if (coords.row == -1 || coords.column == -1) {
printf("Value: %d not found!\n", value);
} else {
printf("Value: %d found at [%d, %d].\n", value, coords.row, coords.column);
}
return 0;
}
#endif

55
Cviko5_2/types.h Normal file
View file

@ -0,0 +1,55 @@
/**
* Hlavičkový soubor types.h
*
* OBSAH V TOMTO SOUBROU NEUPRAVUJTE!
*/
#include <stdbool.h>
#ifndef TYPES_H
#define TYPES_H
// DEKLAROVANÉ HLAVIČKY FUNKCÍ A STRUKTUR NIJAK NEMĚŇTE
#define MAT_ROWS 3
#define MAT_COLUMNS 3
/**
* Structure representing coordinates in a generic 2D matrix;
*/
struct mat_coords_t {
/** Row index in the matrix */
int row;
/** Column index in the matrix row */
int column;
};
// create `MatCoords` type as an alias for `struct mat_coords_t`
typedef struct mat_coords_t MatCoords;
/**
* Print the contents of the provided 2D matrix.
*
* @param matrix 2D matrix
*/
void print_2d(int matrix[MAT_ROWS][MAT_COLUMNS]);
/**
* Search for a value in the provided 2D matrix.
*
* @param matrix 2D matrix
* @returns 1 when found, 0 otherwise
*/
bool contains_value(int matrix[MAT_ROWS][MAT_COLUMNS], int value);
/**
* Search for a value in the provided 2D matrix.
*
* @param matrix 2D matrix
* @param value the value to find in the matrix
*
* @return coordinates of the value in the matrix when found;
* corrdinates {-1, -1} otherwise
*/
MatCoords find_value(int matrix[MAT_ROWS][MAT_COLUMNS], int value);
#endif

12
Cviko5_3/Makefile Normal file
View file

@ -0,0 +1,12 @@
all: main
CC = clang
override CFLAGS += -std=c11 -Wall -Wextra -Wno-unused-variable -Wno-unused-parameter -Wno-unused-result -Wno-unknown-pragmas -pedantic -lm
main: main.c
$(CC) $(CFLAGS) -O0 ./*.c -o "$@"
run: main
./main $(ARGS)
clean:
rm -f main main-*

116
Cviko5_3/main.c Normal file
View file

@ -0,0 +1,116 @@
#include "types.h"
#include <stdio.h>
void print_2d(int matrix[MAT_ROWS][MAT_COLUMNS])
{
for (int row = 0; row < MAT_ROWS; row++) {
for (int column = 0; column < MAT_COLUMNS; column++) {
printf("%d ", matrix[row][column]);
}
printf("\n");
}
}
bool save_to(FILE *output, int matrix[MAT_ROWS][MAT_COLUMNS])
{
for (int row = 0; row < MAT_ROWS; row++) {
for (int column = 0; column < MAT_COLUMNS; column++) {
if (fprintf(output, "%d ", matrix[row][column]) < 0) {
return false;
}
}
if (fprintf(output, "\n") < 0) {
return false;
}
}
// TODO: return true when successful
return true;
}
bool save_to_file(const char *filename, int matrix[MAT_ROWS][MAT_COLUMNS])
{
// FILE * is the type used to represent files and data streams
FILE *output = fopen(filename, "w");
if (output == NULL) {
return false;
}
// TODO: 1. open the destination file
// TODO: 2. validate that the stream has opened correctly
bool result = save_to(output, matrix);
// TODO: 4. Don't forget to close the file!
fclose(output);
return result;
}
bool load_from(FILE *input, int matrix[MAT_ROWS][MAT_COLUMNS])
{
// TODO: Read the matrix items from the file into the matrix
int row = 0;
int column = 0;
int currNumber = 0;
while (fscanf(input, "%d", &currNumber)) {
matrix[row][column] = currNumber;
if (++column >= MAT_COLUMNS && row < MAT_ROWS) {
row++;
column = 0;
} else if (row >= MAT_ROWS) {
break;
}
}
// TODO: return true when successful
return true;
}
bool load_from_file(const char *filename, int matrix[MAT_ROWS][MAT_COLUMNS])
{
FILE *input = fopen(filename, "r");
if (input == NULL) {
return false;
}
// TODO: 1. open the source file
// TODO: 2. validate that the stream has opened correctly
bool result = load_from(input, matrix);
// TODO: 4. Don't forget to close the file!
fclose(input);
return result;
}
#ifndef TEST_BUILD
int main(int argc, char *argv[])
{
// Create and initialize a matrix
int matrix[MAT_ROWS][MAT_COLUMNS];
for (int row = 0; row < MAT_ROWS; row++) {
for (int column = 0; column < MAT_COLUMNS; column++) {
matrix[row][column] = (row + 1) * (column + 1);
}
}
// Save the matrix to a file
if (save_to_file(MAT_FILE_PATH, matrix) == false) {
printf("Error during saving matrix to file!\n");
return 1;
}
// Load matrix contents from a file
int matrix_loaded[MAT_ROWS][MAT_COLUMNS];
if (load_from_file(MAT_FILE_PATH, matrix_loaded) == false) {
printf("Error during loading matrix from file!\n");
return 1;
}
// Print the matrix contents
print_2d(matrix_loaded);
return 0;
}
#endif

3
Cviko5_3/matrix.txt Normal file
View file

@ -0,0 +1,3 @@
1 2 3
2 4 6
3 6 9

30
Cviko5_3/types.h Normal file
View file

@ -0,0 +1,30 @@
/**
* Hlavičkový soubor types.h
*
* OBSAH V TOMTO SOUBROU NEUPRAVUJTE!
*/
#include <stdbool.h>
#include <stdio.h>
#ifndef TYPES_H
#define TYPES_H
// DEKLAROVANÉ HLAVIČKY FUNKCÍ NIJAK NEMĚŇTE
#define MAT_ROWS 3
#define MAT_COLUMNS 3
#define MAT_FILE_PATH "matrix.txt"
void print_2d(int matrix[MAT_ROWS][MAT_COLUMNS]);
bool save_to_file(const char *filename, int matrix[MAT_ROWS][MAT_COLUMNS]);
bool save_to(FILE *output, int matrix[MAT_ROWS][MAT_COLUMNS]);
bool load_from_file(const char *filename, int matrix[MAT_ROWS][MAT_COLUMNS]);
bool load_from(FILE *input, int matrix[MAT_ROWS][MAT_COLUMNS]);
#endif

12
Cviko6_1/Makefile Normal file
View file

@ -0,0 +1,12 @@
all: main
CC = clang
override CFLAGS += -std=c11 -Wall -Wextra -Wno-unused-variable -Wno-unused-parameter -Wno-unused-result -Wno-unknown-pragmas -pedantic -lm
main: main.c
$(CC) $(CFLAGS) -O0 ./*.c -o "$@"
run: main
./main $(ARGS)
clean:
rm -f main main-*

28
Cviko6_1/main.c Normal file
View file

@ -0,0 +1,28 @@
#include "types.h"
#include <stdio.h>
/**
* Funkce vymění hodnoty dvou celočíselných proměnných.
*/
void swapInts(int *variableA, int *variableB) {
int interm = *variableA;
*variableA = *variableB;
*variableB = interm;
}
#ifndef TEST_BUILD
int main(int argc, char *argv[]) {
int number1, number2;
// načtení čísel ze stdin
scanf("%d", &number1);
scanf("%d", &number2);
swapInts(&number1, &number2);
printf("%d %d\n", number1, number2);
return 0;
}
#endif

14
Cviko6_1/types.h Normal file
View file

@ -0,0 +1,14 @@
/**
* Hlavičkový soubor types.h
*
* OBSAH V TOMTO SOUBROU NEUPRAVUJTE!
*/
#ifndef TYPES_H
#define TYPES_H
// DEKLAROVANÉ HLAVIČKY FUNKCÍ A STRUKTUR NIJAK NEMĚŇTE
void swapInts(int *variableA, int *variableB);
#endif

12
Cviko6_2/Makefile Normal file
View file

@ -0,0 +1,12 @@
all: main
CC = clang
override CFLAGS += -std=c11 -Wall -Wextra -Wno-unused-variable -Wno-unused-parameter -Wno-unused-result -Wno-unknown-pragmas -pedantic -lm
main: main.c
$(CC) $(CFLAGS) -O0 ./*.c -o "$@"
run: main
./main $(ARGS)
clean:
rm -f main main-*

47
Cviko6_2/main.c Normal file
View file

@ -0,0 +1,47 @@
#include "types.h"
#include <stdio.h>
/**
* Funkce provede výpočet `dividend / divisor`.
* Výsledek vrací prostřednictvím ukazatele `quotient`.
*
* Funkce nic netiskne!
*
* @param dividend Dělenec
* @param divisor Dělitel
* @param quotient Ukazatel na podíl/kvocient (výsledek)
*
* @returns hodnotu true při úspěšném dělení, false jinak
*/
bool divide(int dividend, int divisor, double *quotient) {
if(divisor == 0) return false;
*quotient = dividend/(double)divisor;
return true;
}
#ifndef TEST_BUILD
int main(int argc, char *argv[]) {
int dividend, divisor;
double quotient;
// načtení dělence a dělitele ze stdin
scanf("%d", &dividend);
scanf("%d", &divisor);
// TODO: Zavolejte funkci divide s odpovídajícími parametry
bool divOk = divide(dividend, divisor, &quotient);
// TODO: Ošetřete případné chybné zpracování,
// v případě chyby, vypiště "divide: error" na stdout
if(!divOk){
printf("divide: error");
return 1;
}
// výpis výsledku dělení
printf("%.3f\n", quotient);
return 0;
}
#endif

16
Cviko6_2/types.h Normal file
View file

@ -0,0 +1,16 @@
/**
* Hlavičkový soubor types.h
*
* OBSAH V TOMTO SOUBROU NEUPRAVUJTE!
*/
#ifndef TYPES_H
#define TYPES_H
#include <stdbool.h>
// DEKLAROVANÉ HLAVIČKY FUNKCÍ NIJAK NEMĚŇTE
bool divide(int dividend, int divisor, double *quotient);
#endif

12
Cviko6_3/Makefile Normal file
View file

@ -0,0 +1,12 @@
all: main
CC = clang
override CFLAGS += -std=c11 -Wall -Wextra -Wno-unused-variable -Wno-unused-parameter -Wno-unused-result -Wno-unknown-pragmas -pedantic -lm
main: main.c
$(CC) $(CFLAGS) -O0 ./*.c -o "$@"
run: main
./main $(ARGS)
clean:
rm -f main main-*

180
Cviko6_3/main.c Normal file
View file

@ -0,0 +1,180 @@
#include "types.h"
#include <stdio.h>
const int UNIVERSUM[MAXITEMS] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
#ifndef TEST_BUILD
int main(void) {
Set set = {.items = {1, 3, 5}, .cardinality = 3};
const int pairCount = 7;
// TODO: 2. staticky inicializujte pole struktur Pair
Pair pairs[pairCount] = {
{1, 1}, {1, 3}, {3, 1}, {3, 3}, {3, 5}, {5, 3}, {5, 5},
};
// TODO: 3., 4., 5. zavolejte implementované funkce a vypište své výsledky
if (rel_isFunction(pairs, pairCount, &set)) {
printf("Relation is a function\n");
} else {
printf("Relation is NOT a function\n");
}
int min, max;
rel_minMax(pairs, pairCount, &min, &max);
printf("Minimum and maximum values are %d and %d respectively.\n", min, max);
if (rel_isEquivalence(pairs, pairCount, &set)) {
printf("Relation is equivalent\n");
} else {
printf("Relation is NOT equivalent\n");
}
return 0;
}
#endif
bool exists_on_set(Pair pairs[], int pairCount, Set *set) {
for (int setIndex = 0; setIndex < set->cardinality; setIndex++) {
bool exists = false;
for (int pairIndex = 0; pairIndex < pairCount; pairIndex++) {
if (set->items[setIndex] == pairs[pairIndex].first ||
set->items[setIndex] == pairs[pairIndex].second) {
exists = true;
break;
}
}
if (!exists) {
return false;
}
}
return true;
}
/**
* @param pairs Prvky nějaké binární relace (pole dvojic)
* @param pairCount Počet položek (dvojic) v relaci
* @param set Množina nad kterou je relace definována
*
* @returns hodnotu true pokud relace je funkcí, false jinak
*/
bool rel_isFunction(Pair pairs[], int pairCount, Set *set) {
if (pairCount == 0 || !exists_on_set(pairs, pairCount, set)) {
return false;
}
int existing[pairCount];
bool ok = true;
for (int pairIndex = 0; pairIndex < pairCount; pairIndex++) {
for (int existingIndex = 0; existingIndex < pairCount; existingIndex++) {
if (existing[existingIndex] == pairs[pairIndex].first) {
ok = false;
break;
}
existing[existingIndex] = pairs[pairIndex].first;
}
}
return ok;
}
/**
* @param pairs Prvky nějaké binární relace (pole dvojic)
* @param pairCount Počet položek (dvojic) v relaci
* @param relMin Ukazatel na proměnnou minimální hodnoty relace
* @param relMax Ukazatel na proměnnou maximální hodnoty relace
*
* @returns hodnotu true pokud bylo hledání úspěšné, false jinak
*/
bool rel_minMax(Pair pairs[], int pairCount, int *relMin, int *relMax) {
if (pairCount == 0)
return false;
*relMin = pairs[0].second;
*relMax = pairs[0].second;
for (int i = 1; i < pairCount; i++) {
if (pairs[i].second < *relMin) {
*relMin = pairs[i].second;
}
if (pairs[i].second > *relMax) {
*relMax = pairs[i].second;
}
}
return true;
}
/**
* @param pairs Prvky nějaké binární relace (pole dvojic)
* @param pairCount Počet položek (dvojic) v relaci
* @param set Množina nad kterou je relace definována
*
* @returns hodnotu true pokud relace je relací ekvivalence, false jinak
*/
bool rel_isEquivalence(Pair pairs[], int pairCount, Set *set) {
if (pairCount == 0 || !exists_on_set(pairs, pairCount, set)) {
return false;
}
// Relace je ekvivalence, pokud je reflexivní, symetrická a tranzitivní.
// Reflexivní = pro každý prvek 'a' z množiny A platí aRa
for (int setIndex = 0; setIndex < set->cardinality; setIndex++) {
bool reflexive = false;
for (int pairIndex = 0; pairIndex < pairCount; pairIndex++) {
if (pairs[pairIndex].first == set->items[setIndex] ||
pairs[pairIndex].second == set->items[setIndex]) {
reflexive = true;
break;
}
}
if (!reflexive) {
return false;
}
}
// Symetrická = Pro každé aRb platí i bRa
for (int pairIndex = 0; pairIndex < pairCount; pairIndex++) {
bool symmetrical = false;
for (int secondRoundIndex = 0; secondRoundIndex < pairCount;
secondRoundIndex++) {
if (pairs[pairIndex].first == pairs[secondRoundIndex].second &&
pairs[pairIndex].second == pairs[secondRoundIndex].first) {
symmetrical = true;
break;
}
}
if (!symmetrical) {
return false;
}
}
// Tranzitivní = platí: (aRb ^ bRc) => aRc
for (int pairIndex = 0; pairIndex < pairCount; pairIndex++) {
bool transitive = false;
for (int secondRoundIndex = 0; secondRoundIndex < pairCount;
secondRoundIndex++) {
if (pairs[pairIndex].second == pairs[secondRoundIndex].first) {
// máme aRb ^ bRc
for (int thirdRoundIndex = 0; thirdRoundIndex < pairCount;
thirdRoundIndex++) {
if (pairs[pairIndex].first == pairs[thirdRoundIndex].first &&
pairs[secondRoundIndex].second == pairs[thirdRoundIndex].second) {
// printf("%dR%d ^ %dR%d => %dR%d\n\n", pairs[pairIndex].first,
// pairs[pairIndex].second, pairs[secondRoundIndex].first,
// pairs[secondRoundIndex].second, pairs[thirdRoundIndex].first,
// pairs[thirdRoundIndex].second);
transitive = true;
break;
}
}
if (!transitive) {
return false;
}
}
}
}
return true;
}

44
Cviko6_3/types.h Normal file
View file

@ -0,0 +1,44 @@
/**
* Hlavičkový soubor types.h
*
* OBSAH V TOMTO SOUBROU NEUPRAVUJTE!
*/
#ifndef TYPES_H
#define TYPES_H
#include <stdio.h>
#include <stdbool.h>
// maximální počet prvků v množině
// (za použití všech dostupných prvků)
#define MAXITEMS 10
// zcela všechny prvky, které nám jsou ve všech množinách k dispozici
extern const int UNIVERSUM[MAXITEMS];
// TODO: 1. seznamte se s definovanými datovými typy
typedef struct {
// prvky množiny, MAXITEMS určuje maximální počet,
// ne ovšem ten skutečný
int items[MAXITEMS];
// skutečný počet prvků v množině, vždy platí:
// 0 <= cardinality <= MAXITEMS
int cardinality;
} Set;
typedef struct {
int first; // první prvek dvojice
int second; // druhý prvek dvojice
} Pair;
// DEKLAROVANÉ HLAVIČKY FUNKCÍ NIJAK NEMĚŇTE
bool rel_isFunction(Pair pairs[], int pairCount, Set *set);
bool rel_minMax(Pair pairs[], int pairCount, int *relMin, int *relMax);
bool rel_isEquivalence(Pair pairs[], int pairCount, Set *set);
#endif

12
Cviko7_1/Makefile Normal file
View file

@ -0,0 +1,12 @@
all: main
CC = clang
override CFLAGS += -std=c11 -Wall -Wextra -Wno-unused-variable -Wno-unused-parameter -Wno-unused-result -Wno-unknown-pragmas -pedantic -lm
main: main.c
$(CC) $(CFLAGS) -O0 ./*.c -o "$@"
run: main
./main $(ARGS)
clean:
rm -f main main-*

98
Cviko7_1/main.c Normal file
View file

@ -0,0 +1,98 @@
#include "types.h"
#include <stdio.h>
// fixed array size
#define ARR_SIZE 10
#ifndef TEST_BUILD
int main(int argc, char *argv[]) {
// TODO: 0. Staticky inicializujte alokované pole
int array[ARR_SIZE] = {1,2,3,4,5,6,7,8,9,10};
array_print(array, ARR_SIZE);
// TODO: 2b. Pronásobte hodnoty pole libovolným číslem
array_multiply(array, ARR_SIZE,2);
// TODO: 2c. Vytiskněte aktualizované pole
array_print(array, ARR_SIZE);
// TODO: 3b. Vložte libovolnou hodnotu na indexy 3 a 7
int a = array_insert(array,ARR_SIZE, 69, 3);
int b = array_insert(array,ARR_SIZE, 420, 7);
// TODO: 3c. V případě chyby informujte uživatele
if(!a || !b){
printf("Upsík dupsík, nastala chyba");
return 1;
}
// TODO: 3d. Vytiskněte aktualizované pole
array_print(array, ARR_SIZE);
return 0;
}
#endif
/**
* Vytiskne obsah pole na standardní výstup programu.
* Tisk musí proběhnout na jeden řádek, konkrétní
* oddělovač jednotlivých prvků není vynucován.
*
* Hlavičky žádných funkcí NEMĚŇTE!
*
* @param array pole, které bude zobrazeno
* @param size velikost pole
*/
void array_print(int array[], int size) {
// TODO: 1a. implementujte funkci dle zadání
for (int i = 0; i < size; i++) {
printf("%d ", array[i]);
}
printf("\n");
}
/**
* Vynásobí všechny prvky zadaného pole zvolenou hodnotou.
*
* Hlavičky žádných funkcí NEMĚŇTE!
*
* @param array pole, jehož hodnoty budou násobeny
* @param size velikost pole
* @param multiplier násobitel
*/
void array_multiply(int *array, int size, int multiplier) {
for (int i = 0; i < size; i++) {
array[i] *= multiplier;
}
}
/**
* Vloží prvek do zadaného pole na zvolený index.
* Ostatní prvky přesune směrem doprava, ke konci pole.
* Přebývající prvek je smazán.
*
* Hodnoty relevantních vstupních parametrů odpovídajícím
* způsobem ošetřete.
*
* Hlavičky žádných funkcí NEMĚŇTE!
*
* @param array pole, do kterého bude nový prvek vložen
* @param size velikost pole
* @param value hodnota k vložení
* @param position index na který bude hodnota vložena
*
* @returns hodnotu 1 pokud vložení proběhlo úspšně, 0 jinak
*/
int array_insert(int array[], int size, int value, int position) {
if(position > size-1 || position < 0) return 0;
for (int i = 0; i < size; i++) {
if(position == i){
for (int afterInsertIndex = size-1; afterInsertIndex>position; afterInsertIndex--) {
array[afterInsertIndex] = array[afterInsertIndex-1];
}
array[position] = value;
break;
}
}
return 1;
}

18
Cviko7_1/types.h Normal file
View file

@ -0,0 +1,18 @@
/**
* Hlavičkový soubor types.h
*
* OBSAH V TOMTO SOUBROU NEUPRAVUJTE!
*/
#ifndef TYPES_H
#define TYPES_H
// DEKLAROVANÉ HLAVIČKY FUNKCÍ NIJAK NEMĚŇTE
void array_print(int array[], int size);
void array_multiply(int *array, int size, int multiplier);
int array_insert(int array[], int size, int value, int position);
#endif

12
Cviko7_2/Makefile Normal file
View file

@ -0,0 +1,12 @@
all: main
CC = clang
override CFLAGS += -std=c11 -Wall -Wextra -Wno-unused-variable -Wno-unused-parameter -Wno-unused-result -Wno-unknown-pragmas -pedantic -lm
main: main.c
$(CC) $(CFLAGS) -O0 ./*.c -o "$@"
run: main
./main $(ARGS)
clean:
rm -f main main-*

93
Cviko7_2/main.c Normal file
View file

@ -0,0 +1,93 @@
#include "types.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef TEST_BUILD
int main(int argc, char *argv[]) {
// konfigurace programu
Config config = {
.xFlag = false, .yFlag = false, .sValue = NULL, .nValue = 10};
// TODO: 2. odpovídajícím způsobem zavolejte funkci parse_args
bool parse = parse_args(argv, argc, &config);
// TODO: 3. v případě chyby zpracování vypište obsah
// globální proměnné usage na chybový výstup
// a ukončente program s chybovým kódem 1
if (!parse) {
printf("%s", usage);
return 1;
}
return 0;
}
#endif
/**
* Zpracuje argumenty příkazové řádky programu.
* Výsledky ukládá do struktury Config z parametrů metody.
*
* Duplicity žádných přepínačů nejsou dovoleny.
*
* Hlavičky žádných funkcí NEMĚŇTE!
*
* @param arguments pole argumentů z CLI
* @param argumentCount velikost pole argumentů
* @param config ukazatel na výstupní konfiguraci
*
* @returns hodnotu true při úspěšném zpracování, false jinak
*/
bool parse_args(char **arguments, int argumentCount, Config *config) {
// TODO: 1. implementujte funkci dle specifikace zadání
// a chování jednotlivých přepínačů
config->nValue = 10;
config->sValue = NULL;
bool valid = true;
bool hasN = false;
for (int i = 0; i < argumentCount; i++) {
if (strcmp(arguments[i], "-x") == 0) {
if (config->yFlag || config->xFlag) {
valid = false;
break;
}
config->xFlag = true;
} else if (strcmp(arguments[i], "-y") == 0) {
if (config->yFlag || config->xFlag) {
valid = false;
break;
}
config->yFlag = true;
} else if (strcmp(arguments[i], "-n") == 0) {
if (i + 1 >= argumentCount || hasN) {
valid = false;
break;
}
for (unsigned int argIndex = 0; argIndex < strlen(arguments[i + 1]);
argIndex++) {
if (!(arguments[i + 1][argIndex] >= '0' &&
arguments[i + 1][argIndex] <= '9')) {
valid = false;
break;
}
}
if (!valid) {
break;
}
config->nValue = atoi(arguments[i + 1]);
hasN = true;
} else if (strcmp(arguments[i], "-s") == 0) {
if (config->sValue != NULL) {
valid = false;
break;
}
config->sValue = arguments[i + 1];
}
}
if (config->sValue == NULL || !valid) {
return false;
}
return true;
}

32
Cviko7_2/types.h Normal file
View file

@ -0,0 +1,32 @@
/**
* Hlavičkový soubor types.h
*
* OBSAH V TOMTO SOUBROU NEUPRAVUJTE!
*/
#include <stdbool.h>
#ifndef TYPES_H
#define TYPES_H
static const char *usage = "syntax: program [-x|-y] [-n COUNT] -s STR\n"
" -x and -y are optional and mutually exclusive\n"
" -s STR - mandatory, STR is a string\n"
" -n COUNT - optional, COUNT is non-negative integer (default: 10)\n";
typedef struct {
// indikuje, že přepínač -x byl/nebyl použit
bool xFlag;
// indikuje, že přepínač -y byl/nebyl použit
bool yFlag;
// uchovává znakový řetězec specifikovaný parametrem -s
char *sValue;
// uchovává kladnou celočíselnou hodnotu specifikovanou parametrem -n
unsigned nValue;
} Config;
// DEKLAROVANÉ HLAVIČKY FUNKCÍ NIJAK NEMĚŇTE
bool parse_args(char **arguments, int argumentCount, Config *config);
#endif

12
Cviko7_3/Makefile Normal file
View file

@ -0,0 +1,12 @@
all: main
CC = clang
override CFLAGS += -std=c11 -g -Wall -Wextra -Wno-unused-variable -Wno-unused-parameter -Wno-unused-result -Wno-unknown-pragmas -pedantic -lm
main: main.c
$(CC) $(CFLAGS) -O0 ./*.c -o "$@"
run: main
./main $(ARGS)
clean:
rm -f main main-*

209
Cviko7_3/main.c Normal file
View file

@ -0,0 +1,209 @@
#include "types.h"
#include <stdio.h>
#ifndef TEST_BUILD
int main(int argc, char *argv[]) {
// TODO: volejte vámi implementované funkce
// Vector *v = malloc(sizeof(Vector));
// Vector *ouJe = malloc(sizeof(Vector));
// Vector *spatny = malloc(sizeof(Vector));
Vector v = {NULL,2};
Vector ouJe = {NULL,2};
Vector spatny = {NULL,3};
if (!vector_ctor(&v, 3) || !vector_ctor(&ouJe, 3) || !vector_ctor(&v, 2)) {
fprintf(stderr, "Upsík dupsík, nepodařilo se dynamicky vytvořit vektor");
return 1;
}
vector_init(&v);
vector_print(&v);
vector_scalar_multiply(&v, 3);
vector_print(&v);
printf("---\n");
if (!vector_add(&v, &ouJe)) {
fprintf(stderr, "Nepodařilo se sečíst vektory");
}
vector_print(&v);
if (!vector_add(&v, &spatny)) {
fprintf(stderr, "Nepodařilo se sečíst vektory");
}
vector_print(&v);
printf("---\n");
if (!vector_sub(&v, &ouJe)) {
fprintf(stderr, "Nepodařilo se odečíst vektory\n");
}
vector_print(&v);
if (!vector_sub(&v, &spatny)) {
fprintf(stderr, "Nepodařilo se odečíst vektory\n");
}
vector_print(&v);
printf("---\n");
vector_dtor(&v);
vector_dtor(&ouJe);
vector_dtor(&spatny);
// if (v != NULL || ouJe != NULL || spatny != NULL) {
// fprintf(stderr, "Špatné promazání paměti!");
// return 1;
// }
return 0;
}
#endif
/**
* Vytiskne vektor (velikost a jeho prvky) na standardní výstup.
*
* @param v ukazatel na vektor
*/
void vector_print(Vector *v) {
if (v == NULL)
return;
// TODO: implementujte funkci dle zadání
if (v->size == 0) {
printf("Vector(0) = (null)\n");
return;
}
printf("Vector(%d) = [", v->size);
for (int i = 0; i < v->size; i++) {
printf((i == v->size - 1) ? "%d]" : "%d, ", v->items[i]);
}
printf("\n");
}
/**
* Vytvoří (dynamicky alokuje) vektor o specifikovaném rozměru.
* Nově alokovaná paměť a korespondující počet prvků
* je do struktury uložen prostřednictvím ukazatele v.
*
* @param v ukazatel na strukturu vektoru
* @param size počet prvků vektoru (rozměr)
*
* @returns hodnotu true v případě úspěšné alokace, false jinak
*/
bool vector_ctor(Vector *v, unsigned int size) {
if (v == NULL)
return false;
// TODO: implementujte funkci dle zadání
// v = malloc(sizeof(Vector));
v->items = (size == 0) ? NULL : malloc(size * sizeof(int));
if(v->items == NULL) return false;
v->size = size;
return true;
}
/**
* Inicializuje prvky vektoru na číselnou posloupnost
* od 0 do velikosti vektoru - 1.
*
* Příklad:
* Vector3 [0, 1, 2]
* Vector5 [0, 1, 2, 3, 4]
*
* @param v ukazatel na existující vektor
*/
void vector_init(Vector *v) {
if (v == NULL || v->items == NULL)
return;
// TODO: implementujte funkci dle zadání
for (int i = 0; i < v->size; i++) {
v->items[i] = i;
}
}
/**
* Provede zrušení (uvolnění alokované paměti) daného vektoru.
* Ukazatel na prvky zrušeného vektoru je NULL.
* Rozměr zrušeného vektoru je 0.
*
* @param v ukazatel na existující vektor
*/
void vector_dtor(Vector *v) {
// TODO: implementujte funkci dle zadání
if (v == NULL || v->items == NULL)
return;
v->size = 0;
free(v->items);
v->items = NULL;
}
/**
* Provede výpočet skalárního součinu vektoru s daným číslem.
* Výpočet se provádí nad hodnotami poskytnutého vektoru v,
* změny probíhají tzv. in-place, bez alokace nového vektoru.
*
* @param v ukazatel na existující vektor
* @param scalar skalární hodnota
*/
void vector_scalar_multiply(Vector *v, int scalar) {
if (v == NULL || v->items == NULL)
return;
// TODO: implementujte funkci dle zadání
for (int i = 0; i < v->size; i++) {
v->items[i] *= scalar;
}
}
/**
* Provede součet dvou vektorů v1 + v2.
* Výpočet se provádí nad hodnotami poskytnutého vektoru v1,
* změny probíhají tzv. in-place, bez alokace nového vektoru.
*
* Vzájemně kontrolujte rozměry obou vektorů!
* Operaci nelze provádět nad vektory různých rozměrů.
*
* @param v1 ukazatel na první vektor
* @param v2 ukazatel na druhý vektor
*
* @returns hodnotu true při úspěšném sečtení, false jinak
*/
bool vector_add(Vector *v1, Vector *v2) {
if (v1 == NULL || v2 == NULL || v1->items == NULL || v2->items == NULL ||
v1->size != v2->size)
return false;
// TODO: implementujte funkci dle zadání
for (int i = 0; i < v1->size; i++) {
v1->items[i] += v2->items[i];
}
return true;
}
/**
* Provede odečtení dvou vektorů v1 + v2.
* Výpočet se provádí nad hodnotami poskytnutého vektoru v1,
* změny probíhají tzv. in-place, bez alokace nového vektoru.
*
* Vzájemně kontrolujte rozměry obou vektorů!
* Operaci nelze provádět nad vektory různých rozměrů.
*
* @param v1 ukazatel na první vektor
* @param v2 ukazatel na druhý vektor
*
* @returns hodnotu true při úspěšném odečtení, false jinak
*/
bool vector_sub(Vector *v1, Vector *v2) {
if (v1 == NULL || v2 == NULL || v1->items == NULL || v2->items == NULL)
return false;
// TODO: implementujte funkci dle zadání
if (v1->size != v2->size) {
return false;
}
for (int i = 0; i < v1->size; i++) {
v1->items[i] -= v2->items[i];
}
return -1;
}

36
Cviko7_3/types.h Normal file
View file

@ -0,0 +1,36 @@
/**
* Hlavičkový soubor types.h
*
* OBSAH V TOMTO SOUBROU NEUPRAVUJTE!
*/
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#ifndef TYPES_H
#define TYPES_H
typedef struct {
int *items;
int size;
} Vector;
// DEKLAROVANÉ HLAVIČKY FUNKCÍ NIJAK NEMĚŇTE
void vector_print(Vector *v);
bool vector_ctor(Vector *v, unsigned int size);
void vector_init(Vector *v);
void vector_dtor(Vector *v);
void vector_scalar_multiply(Vector *v, int scalar);
bool vector_add(Vector *v1, Vector *v2);
bool vector_sub(Vector *v1, Vector *v2);
#endif

16
Cviko8_1/.vscode/launch.json vendored Normal file
View file

@ -0,0 +1,16 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "lldb",
"request": "launch",
"name": "Debug",
"program": "${workspaceFolder}/main",
"args": [],
"cwd": "${workspaceFolder}"
}
]
}

12
Cviko8_1/Makefile Normal file
View file

@ -0,0 +1,12 @@
all: main
CC = clang
override CFLAGS += -std=c11 -Wall -Wextra -Wno-unused-variable -Wno-unused-parameter -Wno-unused-result -Wno-unknown-pragmas -pedantic -lm
main: main.c
$(CC) $(CFLAGS) -O0 ./*.c -o "$@"
run: main
./main $(ARGS)
clean:
rm -f main main-*

141
Cviko8_1/main.c Normal file
View file

@ -0,0 +1,141 @@
#include "types.h"
#include <stdio.h>
#include <stdlib.h>
#ifndef TEST_BUILD
int main(int argc, char *argv[])
{
Vector *v = vector_ctor();
// TODO: 1. V nekonečném cyklu čtete nenulové celočíselné hodnoty a jednotlivě
// je přidávejte do vektoru.
// Nulová hodnota ukončuje čtecí cyklus.
while (true) {
printf("Zadejte číslo, které se přidá do vektoru: ");
int cislo = 0;
scanf("%d", &cislo);
if (cislo == 0) {
break;
}
vector_expand(v, cislo);
}
// TODO: 2. Vypište uživateli obsah vektoru a jeho celkovou velikost voláním
// `vector_print`.
vector_print(v);
// TODO: 3. Uvolněte alokovanou paměť.
vector_dtor(&v);
return 0;
}
#endif
/**
* Na haldě dynamicky alokuje a inicializuje nový vektor o nulovém rozměru.
*
* hint: malloc, sizeof
*
* @returns ukazatel na alokovanou paměť v případě úspěšné alokace, NULL jinak
*/
Vector *vector_ctor(void)
{
Vector *newVec = malloc(sizeof(Vector));
if (newVec == NULL) {
return NULL;
}
newVec->size = 0;
newVec->items = NULL;
return newVec;
// return NULL;
}
/**
* Provede zrušení (uvolnění alokované paměti) daného vektoru.
* A to včetně pole jeho komponent.
* Po uvolnění ukazatel na původní vektor vynulujte.
*
* hint: free
*
* @param v ukazatel na ukazatel na existující vektor
*/
void vector_dtor(Vector **v)
{
free((*v)->items);
free(*v);
*v = NULL;
}
/**
* Vytiskne vektor (rozměr a všechny jeho prvky) na standardní výstup.
*
* @param v ukazatel na vektor
*/
void vector_print(Vector *v)
{
if (v == NULL) {
return;
}
if (v->size == 0) {
printf("Vector(0) = (null)\n");
return;
}
printf("Vector(%d) = [", v->size);
for (int i = 0; i < v->size; i++) {
printf((i == v->size - 1) ? "%d]" : "%d, ", v->items[i]);
}
printf("\n");
}
/**
* Změní rozměr vektoru na nove definovaný rozměr.
* Odpovídajícím způsobem aktualizuje pole komponent a rozměr vektoru.
*
* hint: realloc, sizeof
*
* @param v ukazatel na existující vektor
* @param new_size nový rozměr vektoru (počet složek/komponent)
*
* @returns hodnotu true v případě úspěšné změny, false jinak
*/
bool vector_resize(Vector *v, int new_size)
{
// Reallocate to a helper var, so we can verify success
int *resizedItems = realloc(v->items, sizeof(int) * new_size);
if (resizedItems == NULL) {
// in case of failure, free old memory and return false
free(v->items);
return false;
}
// otherwise set new address and return true
v->size = new_size;
v->items = resizedItems;
return true;
}
/**
* Rozšíří rozměr vektoru o jedna a přidá do něj jednu novou složku
* (komponenetu). Odpovídajícím způsobem aktualizuje pole komponent a rozměr
* vektoru.
*
* hint: vector_resize
*
* @param v ukazatel na existující vektor
* @param value složka, která být přidána do vektoru
*
* @returns hodnotu true v případě úspěšného přidání složky do vektoru, false
* jinak
*/
bool vector_expand(Vector *v, int value)
{
bool resize = vector_resize(v, v->size + 1);
if (!resize) {
return false;
}
v->items[v->size - 1] = value;
return true;
}

30
Cviko8_1/types.h Normal file
View file

@ -0,0 +1,30 @@
/**
* Hlavičkový soubor types.h
*
* OBSAH V TOMTO SOUBROU NEUPRAVUJTE!
*/
#include <stdbool.h>
#ifndef TYPES_H
#define TYPES_H
typedef struct {
int *items;
int size;
} Vector;
// DEKLAROVANÉ HLAVIČKY FUNKCÍ NIJAK NEMĚŇTE
Vector *vector_ctor(void);
void vector_dtor(Vector **vector);
bool vector_resize(Vector *v, int new_size);
bool vector_expand(Vector *vec, int value);
void vector_print(Vector *v);
#endif

12
Cviko8_2/Makefile Normal file
View file

@ -0,0 +1,12 @@
all: main
CC = clang
override CFLAGS += -std=c11 -Wall -Wextra -Wno-unused-variable -Wno-unused-parameter -Wno-unused-result -Wno-unknown-pragmas -pedantic -lm
main: main.c
$(CC) $(CFLAGS) -O0 ./*.c -o "$@"
run: main
./main $(ARGS)
clean:
rm -f main main-*

185
Cviko8_2/main.c Normal file
View file

@ -0,0 +1,185 @@
#include "types.h"
#include <stdio.h>
#include <stdlib.h>
#ifndef TEST_BUILD
#define SIZE 15
int main(int argc, char *argv[]) { return 0; }
#endif
/**
* Zjistí délku řetězce.
* Všechny řetězce v C jsou ukončeny nulovým bytem.
*
* @param str vstupní řetězec
*
* @returns délku řetězce (počet znaků řetězce)
*/
size_t str_len(char *str) {
if (str == NULL) {
return 0;
}
int length = 0;
while (true) {
if (str[length] == '\0') {
break;
}
length++;
}
return length;
}
/**
* Kopíruje data po bytech v paměti o dane velikosti.
*
* Zdroj dat ke kopírování není změněn.
* Předpokládejte, že v cíli je k dispozici dostatek volné paměti.
*
* hint: (char *) k pretypovani z void*
*
* @param dest ukazatel na paměť do které se kopíruje
* @param src ukazatel na paměť ze které se kopíruje
* @param n velikost kopírované paměti v bytech
*/
void mem_cpy(void *dest, void *src, size_t n) {
if (dest == NULL || src == NULL) {
return;
}
char *d = (char *)dest;
char *s = (char *)src;
// Procházíme paměť a kopírujeme byte po bytu
for (size_t i = 0; i < n; i++) {
d[i] = s[i];
}
}
/**
* Najde první výskyt podřetězce v řetězci.
*
* Ani jeden z řetězců není změněn.
*
* hint: str_len
*
* @param str řetězec ve kterém se vyhledává
* @param substr vyhledávaný podřetězec
*
* @returns index na kterém v řetězci začíná podřetězec,
* nebo -1 pokud se podřetězec v řetězci nenachází.
*/
int find_substr(char *str, char *substr) {
if (str == NULL || substr == NULL || str_len(substr) > str_len(str)) {
return -1;
}
// Projdeme celý řetězec (zkrácený o délku podřetězce, protože tam už nikdy
// nepůjde najít)
for (size_t i = 0; i <= str_len(str) - str_len(substr); i++) {
size_t j;
// V druhé smyčce zkoušíme, jestli od `i` po `str_len(substr)` dojdeme bez
// přerušení
for (j = 0; j < str_len(substr); j++) {
if (str[i + j] != substr[j]) {
break;
}
}
// Pokud jsme prošli bez přerušení, našli jsme shodu
if (j == str_len(substr)) {
return i;
}
}
// Podřetězec nenalezen
return -1;
}
/**
* Nahradí podřetězec substr za nahrazující podřetězec v řetězci,
* kde oba podřetězce jsou o stejné délce.
*
* Podřetězce nejsou změněny.
* Pokud nejsou podřetězce stejně dlouhé, funkce substituci neprovede,
* stejně tak pokud podřetězec není v řetězci nalezen.
*
* hint: mem_cpy, find_substr, str_len
*
* @param str řetězec ve kterém se vyhledává
* @param substr vyhledávaný nahrazovaný podřetězec
* @param new_substr nahrazující podřetězec
*/
void replace_same_length(char *str, char *substr, char *new_substr) {
if (str == NULL || substr == NULL || new_substr == NULL ||
str_len(substr) != str_len(new_substr)) {
return;
}
int replaceIndex = find_substr(str, substr);
if (replaceIndex == -1) {
return;
}
// Přepíšeme v paměti na nový podřetězec
mem_cpy(str + replaceIndex, new_substr, str_len(new_substr));
}
/**
* Nahradí nahrazovaný podřetězec za nahrazující podřetězec v řetězci,
* kde každý podřetězec může mít jinou velikost.
* Původní řetězec je uvolněn.
*
* Podřetězce nejsou změněny.
* V případě chyby není původní řetězec uvolněn a zůstává nezměněn.
*
* hint: mem_cpy, find_substr, str_len, malloc, free
*
* @param str dynamicky řetězec ve kterém se vyhledává
* @param substr vyhledávaný nahrazovaný podřetězec
* @param new_substr nahrazující podřetězec
*
* @returns nový řetězec vytvořený v nově alokované paměti v případě úspěchu,
* pointer na původní řetězec v případě že podřetězec se v řetězci nenachází,
* NULL jinak.
*/
char *replace(char *str, char *substr, char *new_substr) {
if (str == NULL || substr == NULL || new_substr == NULL) {
return NULL;
}
int replaceIndex = find_substr(str, substr);
if (replaceIndex == -1) {
return str;
}
size_t newSize = str_len(str) - str_len(substr) + str_len(new_substr);
char *newStr = malloc(sizeof(char) * (newSize + 1));
if (newStr == NULL) {
// Chyba alokace
return NULL;
}
// Zkopírujeme část před nálezem
mem_cpy(newStr, str, replaceIndex);
// Zkopírujeme nový podřetězec
// Musíme se posunout na místo v paměti, kde je první znak nálezu
mem_cpy(newStr + replaceIndex, new_substr, str_len(new_substr));
// Zkopírujeme část za nálezem
// Posuneme se na místo za první znak nálezu + délka nového podřetězce
// Překopírujeme vše, co je v paměti na místě paměti původního řetězce + index
// prvního nálezu + délka hledaného podřetězce
mem_cpy(newStr + replaceIndex + str_len(new_substr),
str + replaceIndex + str_len(substr),
str_len(str) - replaceIndex - str_len(substr));
// Na konec dáme ukončovací znak
newStr[newSize] = '\0';
// Uvolníme původní řetězec a vrátíme novou adresu
free(str);
return newStr;
}

24
Cviko8_2/types.h Normal file
View file

@ -0,0 +1,24 @@
/**
* Hlavičkový soubor types.h
*
* OBSAH V TOMTO SOUBROU NEUPRAVUJTE!
*/
#include <stdbool.h>
#include <stddef.h>
#ifndef TYPES_H
#define TYPES_H
// DEKLAROVANÉ HLAVIČKY FUNKCÍ NIJAK NEMĚŇTE
void mem_cpy(void *dest, void *src, size_t n);
size_t str_len(char *str);
int find_substr(char *str, char *substr);
void replace_same_length(char *str, char *substr, char *new_substr);
char *replace(char *str, char *substr, char *new_substr);
#endif

12
Cviko9_1/Makefile Normal file
View file

@ -0,0 +1,12 @@
all: main
CC = clang
override CFLAGS += -std=c11 -Wall -Wextra -Wno-unused-variable -Wno-unused-parameter -Wno-unused-result -Wno-unknown-pragmas -pedantic -lm --debug
main: main.c
$(CC) $(CFLAGS) -O0 ./*.c -o "$@"
run: main
./main $(ARGS)
clean:
rm -f main main-*

303
Cviko9_1/main.c Normal file
View file

@ -0,0 +1,303 @@
#include "types.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/**
* Konstruktor.
* Nastaví data o osobě z parametrů do odkazovaného místa p.
*
* @param p Ukazatel na existující instanci osoby
* @param birthYear Rok narození osoby
* @param name Jméno osoby
*/
void person_ctor(Person *p, unsigned birthYear, const char *name)
{
p->birthYear = birthYear;
p->name = malloc(strlen(name) + 1);
strcpy(p->name, name);
}
/**
* Destruktor.
* Zruší záznam o osobě.
*
* @param p Ukazatel na existující instanci osoby
*/
void person_dtor(Person *p)
{
p->birthYear = 0;
free(p->name);
p->name = NULL;
}
/**
* Přesune data osoby ze src do dst.
*
* @param src Ukazatel na existující zdrojovou instanci
* @param dst Ukazatel na existující cílovou instanci
*/
void person_move(Person *src, Person *dst) { *dst = *src; }
/**
* Zkopíruje data osoby ze src do dst.
*
* @param src Ukazatel na existující zdrojovou instanci
* @param dst Ukazatel na existující cílovou instanci
*
* @returns Ukazatel na alokovanou paměť, NULL při neúspěšné alokaci
*
* použijte: person_ctor
*/
void *person_copy(Person *src, Person *dst)
{
if(src == NULL || dst == NULL) return NULL;
person_ctor(dst, src->birthYear, src->name);
return dst;
}
/**
* Zamění dvě existující instance osob.
*
* @param a Ukazatel na existující instanci osoby
* @param b Ukazatel na existující instanci osoby
*/
void person_swap(Person *a, Person *b)
{
Person tmp = *a;
*a = *b;
*b = tmp;
}
/**
* Porovná dvě instance osoby.
*
* @param a Ukazatel na existující instanci osoby
* @param b Ukazatel na existující instanci osoby
*
* @returns
* <0 pokud a < b,
* >0 pokud b < a,
* 0 jinak (tedy a == b).
*/
int person_cmp(Person *a, Person *b)
{
if (a->birthYear < b->birthYear) {
return -1;
}
if (a->birthYear > b->birthYear) {
return +1;
}
return strcmp(a->name, b->name);
}
/**
* Vytiskne obsah instance osoby na standardní výstup.
*
* @param p Ukazatel na existující instanci osoby
*/
void person_print(Person *p)
{
if (p == NULL) {
printf("(null)");
return;
}
printf("Person { .birthYear=%d, .name=%s }", p->birthYear, p->name);
}
/**
* Konstruktor.
* Inicializuje pole osob o nulové velikosti v již alokované paměti.
*
* @param array Ukazatel na existující instanci pole osob
*/
void array_ctor(PersonArray *array)
{
array->length = 0;
array->items = NULL;
}
/**
* Destruktor.
* Zruší a uvolní alokované pole a všechny v něm existující položky.
*
* @param array Ukazatel na existující instanci pole osob
*/
void array_dtor(PersonArray *array)
{
for (unsigned int i = 0; i < array->length; i++) {
person_dtor(&array->items[i]);
}
free(array->items);
array->items = NULL;
array->length = 0;
}
/**
* Zvětší velikost pole o 1.
* S nově alokovanou položkou neprovádí žádné změny.
*
* @param array Ukazatel na existující instanci pole osob
*
* @returns Ukazatel na alokovanou paměť, NULL při neúspěšné alokaci
*/
void *array_expand(PersonArray *array)
{
void *p = realloc(array->items, (array->length + 1) * sizeof(Person));
if (p == NULL) {
return NULL;
}
array->length++;
return array->items = p;
}
/**
* Rozšíří existující pole a na jeho konec vloží nový prvek;
*
* @param array Ukazatel na existující instanci pole osob
* @param p Ukazatel na existující instanci osoby
*
* @returns Ukazatel na alokovanou paměť, NULL při neúspěšné alokaci
*/
void *array_append(PersonArray *array, Person *p)
{
if (array_expand(array)) {
return person_copy(p, &array->items[array->length - 1]);
}
return NULL;
}
/**
* Odstraní z pole existující prvek na zadaném indexu.
* Po odstranění zmenší alokovanou velikost pole.
*
* @param array Ukazatel na existující instanci pole osob
* @param index Pozice ze které bude prvek odstraněn
*/
void array_remove(PersonArray *array, unsigned int index)
{
for (unsigned i = index + 1; i < array->length; i++) {
person_move(&array->items[i - 1], &array->items[i]);
}
if (array->length) {
array->items = realloc(array->items, (array->length - 1) * sizeof(Person));
if (array->items) {
array->length--;
}
}
}
/**
* Najde v poli osobu, která nejmenší rok narození (případně jejíž jméno je dříve v abecedě).
* Minimum hledá pouze od zvoleného indexu (pro hledání v celém poli startIndex=0).
*
* @param array Ukazatel na existující instanci pole osob
* @param startIndex Počáteční index prohledávání
*
* @returns Index nejmenšího prvku v poli v případě nalezení, -1 jinak
*
* použijte: person_cmp
*/
int array_find_min(PersonArray *array, unsigned int startIndex)
{
if (array == NULL || startIndex >= array->length) {
return -1;
}
unsigned int smallestIndex = startIndex;
for (unsigned int i = startIndex + 1; i < array->length; i++) {
int op = person_cmp(&array->items[smallestIndex], &array->items[i]);
if (op > 0) {
// a > b
smallestIndex = i;
}
}
return smallestIndex;
}
/**
* Seřadí prvky v poli podle rok narození (případně podle jména).
* Implementujte algoritmem selection-sort.
*
* @param array Ukazatel na existující instanci pole osob
*
* použijte: array_find_min, person_swap
*/
void array_sort(PersonArray *array)
{
for (unsigned int i = 0; i < array->length; i++) {
int smallestElementIndex = array_find_min(array, i);
if (smallestElementIndex < 0) {
continue;
}
person_swap(&array->items[smallestElementIndex], &array->items[i]);
}
}
/**
* Vytiskne prvky pole osob.
*
* @param array Ukazatel na existující pole
*/
void array_print(PersonArray *array)
{
for (unsigned i = 0; i < array->length; i++) {
if (i) {
putchar('\n');
}
printf("- ");
person_print(&array->items[i]);
}
putchar('\n');
}
#ifndef TEST_BUILD
int main(int argc, char *argv[])
{
PersonArray a;
array_ctor(&a);
// Vytvorime nekolik osob
Person p1;
person_ctor(&p1, 2000, "Bill");
Person p2;
person_ctor(&p2, 2010, "Amanda");
Person p3;
person_ctor(&p3, 1990, "Joe");
// Osoby postupne NAKOPIRUJEME do pole (na konec, append)
array_append(&a, &p1);
array_append(&a, &p2);
array_append(&a, &p3);
// jeste vytvorime ctvrtou osobu, oproti 1. se bude lisit rokem.
p1.birthYear = 1990;
array_append(&a, &p1);
// Odstranime docasne vytvorene zaznamy o osobach
// Vsechny osoby by mely mit zaznam v poli
person_dtor(&p1);
person_dtor(&p2);
person_dtor(&p3);
array_print(&a);
// Najdeme první prvek
unsigned int idx = array_find_min(&a, 0);
printf("Minimalni prvek v poli je na indexu: %u\n", idx);
// Pole seřadíme
array_sort(&a);
array_print(&a);
array_dtor(&a);
return 0;
}
#endif

283
Cviko9_1/origo.c Normal file
View file

@ -0,0 +1,283 @@
#include "types.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/**
* Konstruktor.
* Nastaví data o osobě z parametrů do odkazovaného místa p.
*
* @param p Ukazatel na existující instanci osoby
* @param birthYear Rok narození osoby
* @param name Jméno osoby
*/
void person_ctor(Person *p, unsigned birthYear, const char *name)
{
p->birthYear = birthYear;
p->name = malloc(strlen(name) + 1);
strcpy(p->name, name);
}
/**
* Destruktor.
* Zruší záznam o osobě.
*
* @param p Ukazatel na existující instanci osoby
*/
void person_dtor(Person *p)
{
p->birthYear = 0;
p->name = NULL;
}
/**
* Přesune data osoby ze src do dst.
*
* @param src Ukazatel na existující zdrojovou instanci
* @param dst Ukazatel na existující cílovou instanci
*/
void person_move(Person *src, Person *dst)
{
*dst = *src;
}
/**
* Zkopíruje data osoby ze src do dst.
*
* @param src Ukazatel na existující zdrojovou instanci
* @param dst Ukazatel na existující cílovou instanci
*
* @returns Ukazatel na alokovanou paměť, NULL při neúspěšné alokaci
*
* použijte: person_ctor
*/
void *person_copy(Person *src, Person *dst)
{
*dst = *src;
return dst;
}
/**
* Zamění dvě existující instance osob.
*
* @param a Ukazatel na existující instanci osoby
* @param b Ukazatel na existující instanci osoby
*/
void person_swap(Person *a, Person *b)
{
Person tmp = *a;
*a = *b;
*b = tmp;
}
/**
* Porovná dvě instance osoby.
*
* @param a Ukazatel na existující instanci osoby
* @param b Ukazatel na existující instanci osoby
*
* @returns
* <0 pokud a < b,
* >0 pokud b < a,
* 0 jinak (tedy a == b).
*/
int person_cmp(Person *a, Person *b)
{
if (a->birthYear < b->birthYear){
return -1;
}
if (a->birthYear > b->birthYear) {
return +1;
}
return strcmp(a->name, b->name);
}
/**
* Vytiskne obsah instance osoby na standardní výstup.
*
* @param p Ukazatel na existující instanci osoby
*/
void person_print(Person *p) {
if (p == NULL) {
printf("(null)");
return;
}
printf("Person { .birthYear=%d, .name=%s }", p->birthYear, p->name);
}
/**
* Konstruktor.
* Inicializuje pole osob o nulové velikosti v již alokované paměti.
*
* @param array Ukazatel na existující instanci pole osob
*/
void array_ctor(PersonArray *array)
{
array->length = 0;
array->items = NULL;
}
/**
* Destruktor.
* Zruší a uvolní alokované pole a všechny v něm existující položky.
*
* @param array Ukazatel na existující instanci pole osob
*/
void array_dtor(PersonArray *array)
{
// TODO: implementujte funkci dle zadání
}
/**
* Zvětší velikost pole o 1.
* S nově alokovanou položkou neprovádí žádné změny.
*
* @param array Ukazatel na existující instanci pole osob
*
* @returns Ukazatel na alokovanou paměť, NULL při neúspěšné alokaci
*/
void *array_expand(PersonArray *array)
{
void *p = realloc(array->items, (array->length + 1) * sizeof(Person));
if (p == NULL) {
return NULL;
}
array->length++;
return array->items = p;
}
/**
* Rozšíří existující pole a na jeho konec vloží nový prvek;
*
* @param array Ukazatel na existující instanci pole osob
* @param p Ukazatel na existující instanci osoby
*
* @returns Ukazatel na alokovanou paměť, NULL při neúspěšné alokaci
*/
void *array_append(PersonArray *array, Person *p)
{
if (array_expand(array)) {
return person_copy(p, &array->items[array->length - 1]);
}
return NULL;
}
/**
* Odstraní z pole existující prvek na zadaném indexu.
* Po odstranění zmenší alokovanou velikost pole.
*
* @param array Ukazatel na existující instanci pole osob
* @param index Pozice ze které bude prvek odstraněn
*/
void array_remove(PersonArray *array, unsigned int index)
{
for (unsigned i = index + 1; i < array->length; i++) {
person_move(&array->items[i - 1], &array->items[i]);
}
if (array->length) {
array->items = realloc(array->items, (array->length - 1) * sizeof(Person));
if (array->items) {
array->length--;
}
}
}
/**
* Najde v poli osobu, která nejmenší rok narození (případně jejíž jméno je dříve v abecedě).
* Minimum hledá pouze od zvoleného indexu (pro hledání v celém poli startIndex=0).
*
* @param array Ukazatel na existující instanci pole osob
* @param startIndex Počáteční index prohledávání
*
* @returns Index nejmenšího prvku v poli v případě nalezení, -1 jinak
*
* použijte: person_cmp
*/
int array_find_min(PersonArray *array, unsigned int startIndex)
{
// TODO: implementujte funkci dle popisu
return -2;
}
/**
* Seřadí prvky v poli podle rok narození (případně podle jména).
* Implementujte algoritmem selection-sort.
*
* @param array Ukazatel na existující instanci pole osob
*
* použijte: array_find_min, person_swap
*/
void array_sort(PersonArray *array)
{
// TODO: implementujte funkci dle popisu
}
/**
* Vytiskne prvky pole osob.
*
* @param array Ukazatel na existující pole
*/
void array_print(PersonArray *array)
{
for (unsigned i = 0; i < array->length; i++)
{
if (i) {
putchar('\n');
}
printf("- ");
person_print(&array->items[i]);
}
putchar('\n');
}
#ifndef TEST_BUILD
int main(int argc, char *argv[])
{
PersonArray a;
array_ctor(&a);
// Vytvorime nekolik osob
Person p1;
person_ctor(&p1, 2000, "Bill");
Person p2;
person_ctor(&p2, 2010, "Amanda");
Person p3;
person_ctor(&p3, 1990, "Joe");
// Osoby postupne NAKOPIRUJEME do pole (na konec, append)
array_append(&a, &p1);
array_append(&a, &p2);
array_append(&a, &p3);
// jeste vytvorime ctvrtou osobu, oproti 1. se bude lisit rokem.
p1.birthYear = 1990;
array_append(&a, &p1);
// Odstranime docasne vytvorene zaznamy o osobach
// Vsechny osoby by mely mit zaznam v poli
person_dtor(&p1);
person_dtor(&p2);
person_dtor(&p3);
array_print(&a);
// Najdeme první prvek
unsigned int idx = array_find_min(&a, 0);
printf("Minimalni prvek v poli je na indexu: %u\n", idx);
// Pole seřadíme
array_sort(&a);
array_print(&a);
array_dtor(&a);
return 0;
}
#endif

54
Cviko9_1/types.h Normal file
View file

@ -0,0 +1,54 @@
/**
* Hlavičkový soubor types.h
*
* OBSAH V TOMTO SOUBROU NEUPRAVUJTE!
*/
#ifndef TYPES_H
#define TYPES_H
// DEKLAROVANÉ HLAVIČKY FUNKCÍ A STRUKTUR NIJAK NEMĚŇTE
typedef struct {
unsigned birthYear;
char *name;
} Person;
typedef struct {
unsigned length;
Person *items;
} PersonArray;
// Person Methods
void person_ctor(Person *p, unsigned birthYear, const char *name);
void person_dtor(Person *p);
void person_move(Person *src, Person *dst);
void *person_copy(Person *src, Person *dst);
void person_swap(Person *a, Person *b);
int person_cmp(Person *a, Person *b);
void person_print(Person *p);
// PersonArray Methods
void array_ctor(PersonArray *array);
void array_dtor(PersonArray *array);
void *array_expand(PersonArray *array);
void *array_append(PersonArray *array, Person *p);
void array_remove(PersonArray *array, unsigned int index);
int array_find_min(PersonArray *array, unsigned int startIndex);
void array_sort(PersonArray *array);
void array_print(PersonArray *array);
#endif

12
Cviko9_2/Makefile Normal file
View file

@ -0,0 +1,12 @@
all: main
CC = clang
override CFLAGS += -std=c11 -Wall -Wextra -Wno-unused-variable -Wno-unused-parameter -Wno-unused-result -Wno-unknown-pragmas -pedantic -lm --debug
main: main.c
$(CC) $(CFLAGS) -O0 ./*.c -o "$@"
run: main
./main $(ARGS)
clean:
rm -f main main-*

77
Cviko9_2/main.c Normal file
View file

@ -0,0 +1,77 @@
#include "types.h"
#include <stdio.h>
#include <stdlib.h>
ull fib_calls = 0;
ull fib_fast_calls = 0;
/**
* Vypočítá n- číslo Fibonnacciho posloupnosti.
*
* Fib(n) =
* 0 n = 0
* 1 n = 1
* fib(n-1) + fib(n-2) n > 1
*
* @param n Index čísla Fibonacciho posloupnosti
*
* @returns n- číslo Fibonacciho posloupnosti
*/
ull fib(ull n) {
fib_calls++; // TENTO ŘÁDEK NECHTE NA PRVNÍM MÍSTĚ TÉTO FUNKCE
if (n == 0) {
return 0;
}
if (n == 1) {
return 1;
}
return fib(n - 1) + fib(n - 2);
}
ull memo[1000] = {0};
/**
* Vypočítá n- číslo Fibonnacciho posloupnosti.
* Využijte statického/globálního pole s mezivýsledky k urychlení výpočtů.
*
* @param n Index čísla Fibonacciho posloupnosti
*
* @returns n- číslo Fibonacciho posloupnosti
*/
ull fib_fast(ull n) {
fib_fast_calls++; // TENTO ŘÁDEK NECHTE NA PRVNÍM MÍSTĚ TÉTO FUNKCE
if (n == 0) {
return 0;
}
if (n == 1) {
memo[1] = 1;
return 1;
}
if (memo[n] == 0) {
memo[n] = fib_fast(n - 1) + memo[n - 2];
}
return memo[n];
}
#ifndef TEST_BUILD
int main(int argc, char **argv) {
ull n;
printf("fibonacci number index: ");
scanf("%llu", &n);
putchar('\n');
printf("fib_fast(%llu) = %llu\n", n, fib_fast(n));
printf("number of calls = %llu\n", fib_fast_calls);
putchar('\n');
printf("fib(%llu) = %llu\n", n, fib(n));
printf("number of calls = %llu\n", fib_calls);
return 0;
}
#endif

21
Cviko9_2/types.h Normal file
View file

@ -0,0 +1,21 @@
/**
* Hlavičkový soubor types.h
*
* OBSAH V TOMTO SOUBROU NEUPRAVUJTE!
*/
#ifndef TYPES_H
#define TYPES_H
// DEKLAROVANÉ HLAVIČKY FUNKCÍ NIJAK NEMĚŇTE
typedef unsigned long long int ull;
extern ull fib_calls;
extern ull fib_fast_calls;
ull fib(ull n);
ull fib_fast(ull n);
#endif