diff --git a/.gitignore b/.gitignore index 88d050b..a7d29b3 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -main \ No newline at end of file +main +vgcore.* \ No newline at end of file diff --git a/Cviko5_1/Makefile b/Cviko5_1/Makefile new file mode 100644 index 0000000..2d8af15 --- /dev/null +++ b/Cviko5_1/Makefile @@ -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-* diff --git a/Cviko5_1/main.c b/Cviko5_1/main.c new file mode 100644 index 0000000..d0a0c8e --- /dev/null +++ b/Cviko5_1/main.c @@ -0,0 +1,86 @@ +#include "types.h" +#include + +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 diff --git a/Cviko5_1/types.h b/Cviko5_1/types.h new file mode 100644 index 0000000..c98354c --- /dev/null +++ b/Cviko5_1/types.h @@ -0,0 +1,42 @@ +/** + * Hlavičkový soubor types.h + * + * OBSAH V TOMTO SOUBROU NEUPRAVUJTE! + */ + +#ifndef TYPES_H +#define TYPES_H + +#include + +// 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 diff --git a/Cviko5_2/Makefile b/Cviko5_2/Makefile new file mode 100644 index 0000000..2d8af15 --- /dev/null +++ b/Cviko5_2/Makefile @@ -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-* diff --git a/Cviko5_2/main.c b/Cviko5_2/main.c new file mode 100644 index 0000000..4138db9 --- /dev/null +++ b/Cviko5_2/main.c @@ -0,0 +1,124 @@ +#include "types.h" +#include + +/** + * 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 diff --git a/Cviko5_2/types.h b/Cviko5_2/types.h new file mode 100644 index 0000000..ddb90e5 --- /dev/null +++ b/Cviko5_2/types.h @@ -0,0 +1,55 @@ +/** + * Hlavičkový soubor types.h + * + * OBSAH V TOMTO SOUBROU NEUPRAVUJTE! + */ +#include + +#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 diff --git a/Cviko5_3/Makefile b/Cviko5_3/Makefile new file mode 100644 index 0000000..2d8af15 --- /dev/null +++ b/Cviko5_3/Makefile @@ -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-* diff --git a/Cviko5_3/main.c b/Cviko5_3/main.c new file mode 100644 index 0000000..a3046ea --- /dev/null +++ b/Cviko5_3/main.c @@ -0,0 +1,116 @@ +#include "types.h" +#include + +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 diff --git a/Cviko5_3/matrix.txt b/Cviko5_3/matrix.txt new file mode 100644 index 0000000..860863c --- /dev/null +++ b/Cviko5_3/matrix.txt @@ -0,0 +1,3 @@ +1 2 3 +2 4 6 +3 6 9 diff --git a/Cviko5_3/types.h b/Cviko5_3/types.h new file mode 100644 index 0000000..c451c83 --- /dev/null +++ b/Cviko5_3/types.h @@ -0,0 +1,30 @@ +/** + * Hlavičkový soubor types.h + * + * OBSAH V TOMTO SOUBROU NEUPRAVUJTE! + */ + +#include +#include + +#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 diff --git a/Cviko6_1/Makefile b/Cviko6_1/Makefile new file mode 100644 index 0000000..2d8af15 --- /dev/null +++ b/Cviko6_1/Makefile @@ -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-* diff --git a/Cviko6_1/main.c b/Cviko6_1/main.c new file mode 100644 index 0000000..f0068f5 --- /dev/null +++ b/Cviko6_1/main.c @@ -0,0 +1,28 @@ +#include "types.h" +#include + +/** + * 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 diff --git a/Cviko6_1/types.h b/Cviko6_1/types.h new file mode 100644 index 0000000..275b9af --- /dev/null +++ b/Cviko6_1/types.h @@ -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 diff --git a/Cviko6_2/Makefile b/Cviko6_2/Makefile new file mode 100644 index 0000000..2d8af15 --- /dev/null +++ b/Cviko6_2/Makefile @@ -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-* diff --git a/Cviko6_2/main.c b/Cviko6_2/main.c new file mode 100644 index 0000000..266d3de --- /dev/null +++ b/Cviko6_2/main.c @@ -0,0 +1,47 @@ +#include "types.h" +#include + +/** + * 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", ÷nd); + scanf("%d", &divisor); + + // TODO: Zavolejte funkci divide s odpovídajícími parametry + bool divOk = divide(dividend, divisor, "ient); + + // 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 diff --git a/Cviko6_2/types.h b/Cviko6_2/types.h new file mode 100644 index 0000000..c980fc2 --- /dev/null +++ b/Cviko6_2/types.h @@ -0,0 +1,16 @@ +/** + * Hlavičkový soubor types.h + * + * OBSAH V TOMTO SOUBROU NEUPRAVUJTE! + */ + +#ifndef TYPES_H +#define TYPES_H + +#include + +// DEKLAROVANÉ HLAVIČKY FUNKCÍ NIJAK NEMĚŇTE + +bool divide(int dividend, int divisor, double *quotient); + +#endif diff --git a/Cviko6_3/Makefile b/Cviko6_3/Makefile new file mode 100644 index 0000000..2d8af15 --- /dev/null +++ b/Cviko6_3/Makefile @@ -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-* diff --git a/Cviko6_3/main.c b/Cviko6_3/main.c new file mode 100644 index 0000000..e671aad --- /dev/null +++ b/Cviko6_3/main.c @@ -0,0 +1,180 @@ +#include "types.h" +#include + +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; +} diff --git a/Cviko6_3/types.h b/Cviko6_3/types.h new file mode 100644 index 0000000..f2ffe5e --- /dev/null +++ b/Cviko6_3/types.h @@ -0,0 +1,44 @@ +/** + * Hlavičkový soubor types.h + * + * OBSAH V TOMTO SOUBROU NEUPRAVUJTE! + */ + +#ifndef TYPES_H +#define TYPES_H + +#include +#include + +// 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 diff --git a/Cviko7_1/Makefile b/Cviko7_1/Makefile new file mode 100644 index 0000000..2d8af15 --- /dev/null +++ b/Cviko7_1/Makefile @@ -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-* diff --git a/Cviko7_1/main.c b/Cviko7_1/main.c new file mode 100644 index 0000000..d68f581 --- /dev/null +++ b/Cviko7_1/main.c @@ -0,0 +1,98 @@ +#include "types.h" +#include + +// 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; +} diff --git a/Cviko7_1/types.h b/Cviko7_1/types.h new file mode 100644 index 0000000..6c8416c --- /dev/null +++ b/Cviko7_1/types.h @@ -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 diff --git a/Cviko7_2/Makefile b/Cviko7_2/Makefile new file mode 100644 index 0000000..2d8af15 --- /dev/null +++ b/Cviko7_2/Makefile @@ -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-* diff --git a/Cviko7_2/main.c b/Cviko7_2/main.c new file mode 100644 index 0000000..f248948 --- /dev/null +++ b/Cviko7_2/main.c @@ -0,0 +1,93 @@ +#include "types.h" +#include +#include +#include + +#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; +} diff --git a/Cviko7_2/types.h b/Cviko7_2/types.h new file mode 100644 index 0000000..901c687 --- /dev/null +++ b/Cviko7_2/types.h @@ -0,0 +1,32 @@ +/** + * Hlavičkový soubor types.h + * + * OBSAH V TOMTO SOUBROU NEUPRAVUJTE! + */ +#include + +#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 diff --git a/Cviko7_3/Makefile b/Cviko7_3/Makefile new file mode 100644 index 0000000..fe8ca02 --- /dev/null +++ b/Cviko7_3/Makefile @@ -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-* diff --git a/Cviko7_3/main.c b/Cviko7_3/main.c new file mode 100644 index 0000000..53c2558 --- /dev/null +++ b/Cviko7_3/main.c @@ -0,0 +1,209 @@ +#include "types.h" +#include + +#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; +} diff --git a/Cviko7_3/types.h b/Cviko7_3/types.h new file mode 100644 index 0000000..5edb1ee --- /dev/null +++ b/Cviko7_3/types.h @@ -0,0 +1,36 @@ +/** + * Hlavičkový soubor types.h + * + * OBSAH V TOMTO SOUBROU NEUPRAVUJTE! + */ +#include +#include +#include + +#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 diff --git a/Cviko8_1/.vscode/launch.json b/Cviko8_1/.vscode/launch.json new file mode 100644 index 0000000..aea25a9 --- /dev/null +++ b/Cviko8_1/.vscode/launch.json @@ -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}" + } + ] +} \ No newline at end of file diff --git a/Cviko8_1/Makefile b/Cviko8_1/Makefile new file mode 100644 index 0000000..2d8af15 --- /dev/null +++ b/Cviko8_1/Makefile @@ -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-* diff --git a/Cviko8_1/main.c b/Cviko8_1/main.c new file mode 100644 index 0000000..18e6d64 --- /dev/null +++ b/Cviko8_1/main.c @@ -0,0 +1,141 @@ +#include "types.h" +#include +#include + +#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á má 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; +} diff --git a/Cviko8_1/types.h b/Cviko8_1/types.h new file mode 100644 index 0000000..e544b25 --- /dev/null +++ b/Cviko8_1/types.h @@ -0,0 +1,30 @@ +/** + * Hlavičkový soubor types.h + * + * OBSAH V TOMTO SOUBROU NEUPRAVUJTE! + */ +#include + +#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 diff --git a/Cviko8_2/Makefile b/Cviko8_2/Makefile new file mode 100644 index 0000000..2d8af15 --- /dev/null +++ b/Cviko8_2/Makefile @@ -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-* diff --git a/Cviko8_2/main.c b/Cviko8_2/main.c new file mode 100644 index 0000000..d57774d --- /dev/null +++ b/Cviko8_2/main.c @@ -0,0 +1,185 @@ +#include "types.h" +#include +#include + +#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; +} diff --git a/Cviko8_2/types.h b/Cviko8_2/types.h new file mode 100644 index 0000000..1375e17 --- /dev/null +++ b/Cviko8_2/types.h @@ -0,0 +1,24 @@ +/** + * Hlavičkový soubor types.h + * + * OBSAH V TOMTO SOUBROU NEUPRAVUJTE! + */ +#include +#include + +#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 diff --git a/Cviko9_1/Makefile b/Cviko9_1/Makefile new file mode 100644 index 0000000..dc20300 --- /dev/null +++ b/Cviko9_1/Makefile @@ -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-* diff --git a/Cviko9_1/main.c b/Cviko9_1/main.c new file mode 100644 index 0000000..18d836d --- /dev/null +++ b/Cviko9_1/main.c @@ -0,0 +1,303 @@ +#include "types.h" +#include +#include +#include + +/** + * 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á má 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 diff --git a/Cviko9_1/origo.c b/Cviko9_1/origo.c new file mode 100644 index 0000000..e36a953 --- /dev/null +++ b/Cviko9_1/origo.c @@ -0,0 +1,283 @@ +#include "types.h" +#include +#include +#include + + +/** + * 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á má 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 diff --git a/Cviko9_1/types.h b/Cviko9_1/types.h new file mode 100644 index 0000000..284969e --- /dev/null +++ b/Cviko9_1/types.h @@ -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 diff --git a/Cviko9_2/Makefile b/Cviko9_2/Makefile new file mode 100644 index 0000000..dc20300 --- /dev/null +++ b/Cviko9_2/Makefile @@ -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-* diff --git a/Cviko9_2/main.c b/Cviko9_2/main.c new file mode 100644 index 0000000..d1130cc --- /dev/null +++ b/Cviko9_2/main.c @@ -0,0 +1,77 @@ +#include "types.h" +#include +#include + +ull fib_calls = 0; +ull fib_fast_calls = 0; + +/** + * Vypočítá n-té čí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-té čí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-té čí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-té čí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 diff --git a/Cviko9_2/types.h b/Cviko9_2/types.h new file mode 100644 index 0000000..11d83fa --- /dev/null +++ b/Cviko9_2/types.h @@ -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