diff --git a/HomeWork3/Igor Vyhovanets Third Hometask 1.cpp b/HomeWork3/Igor Vyhovanets Third Hometask 1.cpp new file mode 100644 index 0000000..0fecc0a --- /dev/null +++ b/HomeWork3/Igor Vyhovanets Third Hometask 1.cpp @@ -0,0 +1,32 @@ +#include +#include + +int main(int argc, char* argv[]) { + std::cout << "This program reverses string that user inputs" << std::endl; + + if (argc != 2) { + std::cout << "Wrong number of parameters" << std::endl; + std::cout << "Usage: ./reverse " << std::endl; + return 0; + } + + const size_t kMaxLength = 100; + const size_t kLength = strlen(argv[1]); + + if (kLength > kMaxLength) { + std::cout << "Error! Input string should be less than " << kMaxLength << " characters" << std::endl; + return 0; + } + + char reversed[kMaxLength + 1]{}; // string should contain termination zero (+1 byte) + char *pReversed = reversed; + + // Reverse the string + for (auto *begin = argv[1], *end = begin + kLength, *limit = end; begin < limit; ++begin) { + *pReversed++ = *--end; + } + + std::cout << "Initial string: " << argv[1] << std::endl; + std::cout << "Reversed string: " << reversed << std::endl; + + return 0; \ No newline at end of file diff --git a/HomeWork3/Igor Vyhovanets Third Hometask 6.cpp b/HomeWork3/Igor Vyhovanets Third Hometask 6.cpp new file mode 100644 index 0000000..0deb538 --- /dev/null +++ b/HomeWork3/Igor Vyhovanets Third Hometask 6.cpp @@ -0,0 +1,35 @@ +#include +#include + +int main(int argc, char *argv[]) { + + std::cout << "This program transforms string to lower case" << std::endl; + + const size_t kMaxLength = 100; + char inputString[kMaxLength]{}, outputString[kMaxLength]{}; + + std::cout << "Enter a string (max " << kMaxLength << " symbols): "; + std::cin >> inputString; + + size_t length = strlen(inputString); + + if (length > kMaxLength) { + std::cout << "Error! Too long string. Exiting." << std::endl; + return 0; + } + + std::cout << "Input string: " << inputString << std::endl; + + const char kDiff = 'A'-'a'; + + for (size_t i = 0; i < length; i++) { + outputString[i] = inputString[i]; + if (inputString[i] >= 'A' && inputString[i] <= 'Z') { + outputString[i] -= kDiff; + } + } + + std::cout << "Output string: " << outputString << std::endl; + + return 0; +} \ No newline at end of file diff --git a/HomeWork3/Igor Vyhovanets Third Hometask2.cpp b/HomeWork3/Igor Vyhovanets Third Hometask2.cpp new file mode 100644 index 0000000..a7e56de --- /dev/null +++ b/HomeWork3/Igor Vyhovanets Third Hometask2.cpp @@ -0,0 +1,51 @@ +#include + +void print_array(const unsigned int array[], const size_t size) { + std::cout << '['; + for (size_t i=0; i> element; + } while (element == 0); + + insert_element(array, kArraySize, element); + + print_array(array, kArraySize); + } + + return 0; +} \ No newline at end of file diff --git a/HomeWork3/Igor Vyhovanets Third Hometask3.cpp b/HomeWork3/Igor Vyhovanets Third Hometask3.cpp new file mode 100644 index 0000000..1d3df41 --- /dev/null +++ b/HomeWork3/Igor Vyhovanets Third Hometask3.cpp @@ -0,0 +1,101 @@ +#include +#include +#include +#include + +void print_array(const int array[], const size_t size) { + std::cout << '['; + for (size_t i=0; i> method; + } while (method < METHOD_1_BY_HAND || method > METHOD_3_WITH_MT19937); + + // Start RNG + std::random_device device; + std::mt19937 generator(device()); + std::uniform_int_distribution distribution(0,kMaxRandomNumber); + srand(time(0)); + + switch (method) { + case METHOD_1_BY_HAND: + for (size_t i = 0; i < kArraySize; i++) { + std::cout << "array[" << i << "]: "; + std::cin >> array[i]; + } + break; + case METHOD_2_WITH_RAND: + for (size_t i = 0; i < kArraySize; i++) { + array[i] = rand() % kMaxRandomNumber; + } + break; + case METHOD_3_WITH_MT19937: + for (size_t i = 0; i < kArraySize; ++i) { + array[i] = distribution(generator); + } + break; + default: + std::cout << "Unknown error, exiting" << std::endl; + return 0; + } + + print_array(array, kArraySize); + + while ( !is_array_empty(array, kArraySize) ) { + int number; + std::cout << "Enter number to delete: "; + std::cin >> number; + remove_element(array, kArraySize, number); + print_array(array, kArraySize); + } + + return 0; +} \ No newline at end of file diff --git a/HomeWork3/Igor Vyhovanets Third Hometask4.cpp b/HomeWork3/Igor Vyhovanets Third Hometask4.cpp new file mode 100644 index 0000000..25929a0 --- /dev/null +++ b/HomeWork3/Igor Vyhovanets Third Hometask4.cpp @@ -0,0 +1,34 @@ +#include + #include + + int main(int argc, char* argv[]) { + std::cout << "This program reverses string that user inputs" << std::endl; + + if (argc != 2) { + std::cout << "Wrong number of parameters" << std::endl; + std::cout << "Usage: ./reverse " << std::endl; + return 0; + } + + const size_t kMaxLength = 100; + const size_t kLength = strlen(argv[1]); + + if (kLength > kMaxLength) { + std::cout << "Error! Input string should be less than " << kMaxLength << " characters" << std::endl; + return 0; + } + + char reversed[kMaxLength + 1]{}; // string should contain termination zero (+1 byte) + + // Reverse the string + // Reduce number of iterations by copying 2 chars at a time (from start and end) + for (size_t i = 0; i <= kLength / 2; i++) { + *(reversed + i) = *(argv[1] + kLength - i - 1); + *(reversed + kLength - i - 1) = *(argv[1] + i); + } + + std::cout << "Initial string: " << argv[1] << std::endl; + std::cout << "Reversed string: " << reversed << std::endl; + + return 0; + } diff --git a/HomeWork3/Igor Vyhovanets Third Hometask5.cpp b/HomeWork3/Igor Vyhovanets Third Hometask5.cpp new file mode 100644 index 0000000..4628eda --- /dev/null +++ b/HomeWork3/Igor Vyhovanets Third Hometask5.cpp @@ -0,0 +1,30 @@ +#include + +int main(int argc, char *argv[]) { + std::cout << "This progtam checks char array and outputs digit from it" << std::endl; + + const size_t kMaxArrayLen = 100; + char array[kMaxArrayLen]{}; + + std::cout << "Enter string (max " << kMaxArrayLen << " elements): "; + std::cin >> array; + + std::cout << "Digits in array: "; + bool isNumFound = false; + char *ptr = array; + + while (*ptr != '\0') { + if (*ptr >= '0' && *ptr <= '9') { + if (!isNumFound) { + isNumFound = true; + std::cout << '['; + } + std::cout << *ptr << ", "; + } + ++ptr; + } + + std::cout << ((isNumFound) ? "\b\b]" : "none") << std::endl; + + return 0; +} \ No newline at end of file diff --git a/HomeWork4/Igor_vyhovanets_Four_hometaskcpp.cpp b/HomeWork4/Igor_vyhovanets_Four_hometaskcpp.cpp new file mode 100644 index 0000000..cd0232a --- /dev/null +++ b/HomeWork4/Igor_vyhovanets_Four_hometaskcpp.cpp @@ -0,0 +1,547 @@ +#include +#include +#include +#include +#include + +using Comp = std::function; +using CompDouble = std::function; +using CharSettings = std::function; + +void clear_stream() { + std::cin.clear(); + std::cin.ignore(); +} + +void swap(int &a, int &b) { + int temp = b; + b = a; + a = temp; +} + +void swap(char &a, char &b) { + char temp = b; + b = a; + a = temp; +} + +/***************************** PRINT ARRAYS (, , , ) ******************************/ + +// prints sequence of integers +void print_sequence(const int *begin, const int *const end) { + if (begin == nullptr || end == nullptr) { + std::cout << "print_sequence() - Exception\n"; + return; + } + while (begin != end) { + std::cout << *begin++ << ' '; + } + std::cout << std::endl; +} + +// prints sequence of doubles +void print_sequence(const double *begin, const double *const end) { + if (begin == nullptr || end == nullptr) { + std::cout << "print_sequence() - Exception\n"; + return; + } + while (begin != end) { + std::cout << *begin++ << ' '; + } + std::cout << std::endl; +} + +// prints sequence of unsigned int +void print_sequence(const unsigned *begin, const unsigned *const end) { + if (begin == nullptr || end == nullptr) { + std::cout << "print_sequence() - Exception\n"; + return; + } + while (begin != end) { + std::cout << *begin++ << ' '; + } + std::cout << std::endl; +} + +// prints sequence of char +void print_sequence(const char *begin) { + if (begin == nullptr) { + std::cout << "print_sequence() - Exception\n"; + return; + } + while (*begin != '\0') { + std::cout << *begin++; + } + std::cout << std::endl; +} + +/******************** COPY ARRAY, USER-INPUT ARRAY, RANDOM GENERATED ARRAY, RANDOM NUMBER ************************/ + +// copies contents from a source integer sequence into the destination integer sequence +void copy_sequence(const int *src_begin, const int *const src_end, int *dst_begin) { + if (src_begin == nullptr || src_end == nullptr || dst_begin == nullptr) { + std::cout << "copy_sequence() - Exception\n"; + return; + } + while (src_begin != src_end) { + *dst_begin++ = *src_begin++; + } +} + +// changes the values of integer sequence to user provided numbers +void fill_sequence_with_user_input(int *begin, const int *const end) { + if (begin == nullptr || end == nullptr) { + std::cout << "fill_sequence_with_user_input() - Exception\n"; + return; + } + size_t index{}; + while (begin != end) { + std::cout << "Enter element #" << ++index << ": "; + std::cin >> *begin++; + clear_stream(); + } +} + +// changes the values of integer sequence to random numbers +void fill_sequence_with_random_numbers(int *begin, const int *const end, const int LOW_LIMIT, const int HIGH_LIMIT) { + if (begin == nullptr || end == nullptr) { + std::cout << "fill_sequence_with_random_numbers() - Exception\n"; + return; + } + std::random_device seed; + std::default_random_engine rng(seed()); + std::uniform_int_distribution distr(LOW_LIMIT, HIGH_LIMIT); + while (begin != end) { + *begin++ = distr(rng); + } +} + +// returns a random number between 0 and N-1 +int random_number(const size_t N) { + std::random_device seed; + std::default_random_engine rng(seed()); + std::uniform_int_distribution distr(0, N - 1); + return distr(rng); +} + +/********************************** BUBBLE SORT for , , *************************************/ + +// sorts an integer sequence according to the bubble sort algorithm +void bubble_sort(int *begin, int *const end, Comp predicate) { + if (begin == nullptr || end == nullptr) { + std::cout << "bubble_sort() - Exception\n"; + return; + } + while (true) { + int *it{begin}; + size_t swap_counter{0}; + while (it != end - 1) { + if (predicate(*it, *(it + 1))) { + swap(*it, *(it + 1)); + ++swap_counter; + } + ++it; + } + if (swap_counter == 0) { + break; + } + } +} + +// sorts a double sequence according to the bubble sort algorithm +void bubble_sort(double *begin, const double *const end, CompDouble predicate) { + if (begin == nullptr || end == nullptr) { + std::cout << "bubble_sort() - Exception\n"; + return; + } + while (true) { + double *it{begin}; + size_t swap_counter{0}; + while (it != end - 1) { + if (predicate(*it, *(it + 1))) { + double temp{*it}; + *it = *(it + 1); + *(it + 1) = temp; + ++swap_counter; + } + ++it; + } + if (swap_counter == 0) { + break; + } + } +} + +// sorts an unsigned sequence according to the bubble sort algorithm +void bubble_sort(unsigned *begin, const unsigned *const end, Comp predicate) { + if (begin == nullptr || end == nullptr) { + std::cout << "bubble_sort() - Exception\n"; + return; + } + while (true) { + unsigned *it{begin}; + size_t swap_counter{0}; + while (it != end - 1) { + if (predicate(*it, *(it + 1))) { + unsigned temp{*it}; + *it = *(it + 1); + *(it + 1) = temp; + ++swap_counter; + } + ++it; + } + if (swap_counter == 0) { + break; + } + } +} + +/****************************************** BUBBLE SORT for ********************************************/ + +// returns address of null terminator in char sequence +char *find_null_terminator(char *begin, char *end) { + if (begin == nullptr || end == nullptr) { + std::cout << "find_null_terminator() - Exception\n"; + return end; + } + while (begin != end) { + if (*begin == '\0') { + return begin; + } + ++begin; + } + return end; +} + +char *find_first_occurence(char * begin, char *end, CharSettings predicate) { + if (begin == nullptr || end == nullptr) { + std::cout << "find_first_occurence() - Exception\n"; + return end; + } + while (*begin != '\0') { + if (predicate(*begin)) { + return begin; + } + ++begin; + } + return end; +} + +// moves digits to the end of char sequence +void shift(char *begin, char *end) { + if (begin == nullptr || end == nullptr) { + std::cout << "shift() - Exception\n"; + return; + } + char *it = begin; + char *first_digit = find_first_occurence(it, end, [] (char c) { return c >= '0' && c <= '9'; }); + char *first_non_digit = find_first_occurence(it, end, [] (char c) { return c < '0' || c > '9'; }); + const ptrdiff_t SHIFT = first_non_digit - first_digit; + char *digits = new char[SHIFT]; + for(ptrdiff_t i{0}; i < SHIFT; ++i) { + *(digits + i) = *(first_digit + i); + } + it = begin; + while(it != end - SHIFT) { + *it = *(it + SHIFT); + ++it; + } + while(it != end) { + *it++ = *digits++; + } + delete [] digits; +} + +// reverse a char sequence +void reverse(char *begin, char *terminator) { + if (begin == nullptr || terminator == nullptr) { + std::cout << "reverse() - Exception\n"; + return; + } + if (begin > terminator) { + std::cout << "reverse() - Exception\n"; + return; + } + const size_t SEQUENCE_HALF = (terminator - begin) / 2; + for (size_t i{0}; i < SEQUENCE_HALF; ++i) { + swap(*(begin + i), *(terminator - 1 - i)); + } +} + +// sorts a char sequence according to the bubble sort algorithm +void bubble_sort(char *begin, char *end, Comp predicate) { + if (begin == nullptr || end == nullptr) { + std::cout << "bubble_sort() - Exception\n"; + return; + } + // find null terminator adress. stop sorting if sequence has just one element + char *terminator = find_null_terminator(begin, end); + if (terminator - begin < 2) { + return; + } + // Bubble sort + while (true) { + char *it = begin; + size_t swap_counter{0}; + while (*(it + 1) != '\0') { + if (predicate(*it, *(it + 1))) { + swap(*it, *(it + 1)); + ++swap_counter; + } + ++it; + } + if (swap_counter == 0) { + break; + } + } + // if all elements are same stop + if (*(terminator - 1) == *begin) { + return; + } + // increasing order implementation + if (*(terminator - 1) > *begin) { + shift(begin, terminator); + } + // decreasing order implementation + else { + reverse(begin, terminator); + shift(begin, terminator); + reverse(begin, terminator); + } +} + +/************************************* QUICKSORT ALGORITHM **********************************/ + +// methods to choose pivot number in quicksort algorithm +enum PIVOT_CHOISE { FIRST, MIDDLE, LAST, RANDOM, SIZE }; + +// returns first, middle, last, or random element from a sequence +std::function choose_pivot[SIZE]{ + [](int *begin, int *end) { return begin; }, + [](int *begin, int *end) { return begin + (end - begin) / 2; }, + [](int *begin, int *end) { return end - 1; }, + [](int *begin, int *end) { return begin + random_number(end - begin); }}; + +// sorts an integer sequence according to the quicksort algorithm +void quick_sort(int *begin, int *end, Comp predicate) { + if (begin == nullptr || end == nullptr) { + std::cout << "quick_sort() - Exception\n"; + return; + } + if (begin >= end - 1) { + return; + } + // Choose reference pivot, then move it to the end + int *pivot = choose_pivot[FIRST](begin, end); + swap(*pivot, *(end - 1)); + pivot = end - 1; + // it - general iterator, it2 - set to first number >= pivot. (<= for decreasing order) + int *it{begin}; + int *it2{nullptr}; + while (it != end) { + if (predicate(*it, *pivot)) { + it2 = it++; + break; + } + ++it; + } + // Swap it2 with any number < pivot, then incremenet it2. (> for decreasing order) + while (it != end) { + if (!predicate(*it, *pivot)) { + swap(*it, *it2); + ++it2; + } + ++it; + } + // Move pivot from end to proper location + swap(*pivot, *it2); + pivot = it2; + // Repeat process for parts before and after the pivot + quick_sort(begin, pivot, predicate); + quick_sort(pivot + 1, end, predicate); +} + +/********************************************** TASK 1 **************************************************/ + +// Sets "random/manual array", and "print/don't print array" flags, show general +// info about test +void task_1_user_IO(const size_t _ARRAY_SIZE, const size_t _NUMBER_OF_TESTS, bool &_ENABLE_PRINT, bool &_RANDOM_ARRAY) { + std::cout << "------------------------------------\n"; + std::cout << "\n\t\tBenchmark for Bubblesort and Quicksort Algorithms\n" << std::endl; + std::cout << "Array size: " << _ARRAY_SIZE << std::endl; + std::cout << "Number of tests: " << _NUMBER_OF_TESTS << std::endl; + std::cout << "------------------------------------\n"; + std::cout << "Do you want to show arrays or hide them?\n"; + std::cout << " - Type 0 to hide arrays\n"; + std::cout << " - Type 1 to print arrays \n"; + std::cout << "Enter your selection: "; + std::cin >> _ENABLE_PRINT; + clear_stream(); + std::cout << "You have selected to " << (_ENABLE_PRINT ? "print arrays\n" : "hide arrays\n"); + std::cout << "------------------------------------\n"; + std::cout << "Do you want to fill arrays manually or randomly?\n"; + std::cout << " - Type 0 to fill array manually\n"; + std::cout << " - Type 1 to fill array randomly\n"; + std::cout << "Enter your selection: "; + std::cin >> _RANDOM_ARRAY; + std::cout << "You have selected to " << (_RANDOM_ARRAY ? "fill array randomly\n" : "fill array manually\n"); + clear_stream(); + std::cout << "------------------------------------\n"; + std::cout << "Processing..." << std::endl; +} + +// Task 1 - Comparison of Bubble-Sort and Quick-Sort algorithms +void task_1() { + + // benchmark settings + bool ENABLE_PRINT{}, RANDOM_ARRAY{}; + const size_t ARRAY_SIZE{10}, NUMBER_OF_TESTS{1}; + const int LOW_LIMIT{-10}, HIGH_LIMIT{10}; + int array[ARRAY_SIZE]{}, array_copy[ARRAY_SIZE]{}; + int* const array_end = array + ARRAY_SIZE; + int* const array_copy_end = array_copy + ARRAY_SIZE; + std::chrono::duration bubble_sort_duration{}, quick_sort_duration{}; + + // arrange user settings and provide general info + task_1_user_IO(ARRAY_SIZE, NUMBER_OF_TESTS, ENABLE_PRINT, RANDOM_ARRAY); + // disable manual input for large arrays or many tests + if (RANDOM_ARRAY == false && (ARRAY_SIZE > 20 || NUMBER_OF_TESTS > 2)) { + std::cout << "task_1(): Exception - Can't allow manual input. Requires too much time. Exiting\n"; + return; + } + // benchmark loop + for (size_t i{0}; i < NUMBER_OF_TESTS; ++i) { + + // Fill array. Copy values to array_copy, so both algorithms process same data. + if (RANDOM_ARRAY) { + fill_sequence_with_random_numbers(array, array_end, LOW_LIMIT, HIGH_LIMIT); + } else { + fill_sequence_with_user_input(array, array_end); + } + copy_sequence(array, array_end, array_copy); + + // Show arrays before sorting + if (ENABLE_PRINT) { + std::cout << "------------------------------------\n"; + std::cout << "\t\t\tTEST " << i + 1 << std::endl; + std::cout << "ARRAY BEFORE BUBBLESORT: "; + print_sequence(array, array_end); + std::cout << "ARRAY BEFORE QUICKSORT : "; + print_sequence(array_copy, array_copy_end); + } + + // Bubble sort duration + auto bubble_start_time = std::chrono::system_clock::now(); + bubble_sort(array, array_end, [](int p1, int p2) { return p1 > p2; }); + auto bubble_end_time = std::chrono::system_clock::now(); + bubble_sort_duration += bubble_end_time - bubble_start_time; + + // Quick sort duration + auto quick_start_time = std::chrono::system_clock::now(); + quick_sort(array_copy, array_copy_end, [](int p1, int p2) { return p1 >= p2; }); + auto quick_end_time = std::chrono::system_clock::now(); + quick_sort_duration += quick_end_time - quick_start_time; + + // Show arrays after sorting + if (ENABLE_PRINT) { + std::cout << "ARRAY AFTER BUBBLESORT : "; + print_sequence(array, array_end); + std::cout << "ARRAY AFTER QUICKSORT : "; + print_sequence(array_copy, array_copy_end); + } + } + bubble_sort_duration /= NUMBER_OF_TESTS; + quick_sort_duration /= NUMBER_OF_TESTS; + + // Test results + std::cout << "------------------------------------\n"; + std::cout << "Bubble Sort: " << bubble_sort_duration.count() << " seconds" << std::endl; + std::cout << "Quick Sort: " << quick_sort_duration.count() << " seconds" << std::endl; + double ratio = bubble_sort_duration / quick_sort_duration; + if (ratio > 1) { + std::cout << "Quicksort is " << ratio << " times faster" << std::endl; + } else { + std::cout << "Bubble sort is " << 1 / ratio << "times faster" << std::endl; + } +} + +/************************************************* TASK 2 **********************************************************/ + +// generates an unsigned array. shows it before and after the sorting process +void print_and_sort_unsigned(Comp predicate) { + const size_t UNSIGNED_ARRAY_SIZE{10}; + unsigned unsigned_array[UNSIGNED_ARRAY_SIZE]{1, 0, 300, 522, 6, 41, 0, 10, 155, 2222}; + unsigned *begin = unsigned_array; + const unsigned *const end = unsigned_array + UNSIGNED_ARRAY_SIZE; + std::cout << "unsigned array before sort: "; + print_sequence(begin, end); + bubble_sort(begin, end, predicate); + std::cout << "unsigned array after sort : "; + print_sequence(begin, end); + std::cout << "------------------------------------\n"; +} + +// generates a double array. shows it before and after the sorting process +void print_and_sort_double(CompDouble predicate) { + const size_t DOUBLE_ARRAY_SIZE{5}; + double double_array[DOUBLE_ARRAY_SIZE]{-4.75, 5.11, 7.45, -4, 0}; + double *begin = double_array; + const double *const end = double_array + DOUBLE_ARRAY_SIZE; + std::cout << "double array before sort: "; + print_sequence(begin, end); + bubble_sort(begin, end, predicate); + std::cout << "double array after sort : "; + print_sequence(begin, end); + std::cout << "------------------------------------\n"; +} + +// generates a char array. shows it before and after the sorting process +void print_and_sort_char(Comp predicate) { + const size_t CHAR_ARRAY_SIZE{1000}; + char char_array[CHAR_ARRAY_SIZE] = "zA1xB2yC3"; + char *begin = char_array; + char *end = char_array + CHAR_ARRAY_SIZE; + std::cout << "char array before sort: "; + print_sequence(begin); + bubble_sort(begin, end, predicate); + std::cout << "char array after sort : "; + print_sequence(begin); +} + +// Task 2 - Sorting unsigned, double, and char arrays +void task_2() { + std::cout << "------------------------------------\n"; + std::cout << "\n\t\tSort unsigned, double, and char arrays\n" << std::endl; + std::cout << "------------------------------------\n"; + print_and_sort_unsigned([](unsigned p1, unsigned p2) { return p1 < p2; }); + print_and_sort_double([](double p1, double p2) { return p1 < p2; }); + print_and_sort_char([](char p1, char p2) { return p1 > p2; }); +} + +/*********************************************** MENU *************************************************/ + +enum MENU { QUIT, TASK_1, TASK_2}; + +int main() { + std::function menu[TASK_2]{task_1, task_2}; + while (true) { + std::cout << "------------------------------------\n"; + std::cout << " MENU \n"; + std::cout << TASK_1 << " - TASK 1\n"; + std::cout << TASK_2 << " - TASK 2\n"; + std::cout << QUIT << " - QUIT \n"; + std::cout << "Enter your selection: "; + size_t selection; + std::cin >> selection; + if (selection != QUIT && selection != TASK_1 && selection != TASK_2) { + std::cout << "Unknown command\n"; + continue; + } + if (selection == QUIT) { + std::cout << "Quitting...\n"; + return 0; + } + menu[selection - 1](); + } + return 1; +} \ No newline at end of file diff --git a/HomeWork5/Hometaskcpp.cpp b/HomeWork5/Hometaskcpp.cpp new file mode 100644 index 0000000..4cc3ac1 --- /dev/null +++ b/HomeWork5/Hometaskcpp.cpp @@ -0,0 +1,57 @@ +#include + + void print_array(unsigned int * const parray, const size_t size) { + std::cout << '['; + for (size_t i = 0; i < size; i++){ + std::cout << *(parray + i); + if (i != (size - 1)) { + std::cout << ", "; + } + } + std::cout << ']' << std::endl; + } + + void insert_element (unsigned int * const parray, const size_t size, const unsigned int element) { + size_t largerElementPos{}; + + // Iterate all array and find position where larger elements start + size_t i{}; + while ( (*(parray + i) < element) && + (*(parray + i) != 0) && + (i < size) ) { + ++i; + largerElementPos = i; + } + + // Move all larger elements to the right + for (size_t i = size-1; i > largerElementPos; i--) { + if (i > 0) { + *(parray + i) = *(parray + i - 1); + } + } + + *(parray + largerElementPos) = element; + } + + int main(int argc, char **argv) { + const size_t kArraySize = 20; + unsigned int array[kArraySize]{}; + + std::cout << "This program inserts elements in array" << std::endl; + + // print_array(); + + for (size_t i = 0; i < kArraySize; i++) { + unsigned int element; + do { + std::cout << "Insert element (" << i << "), greater than 0: "; + std::cin >> element; + } while (element == 0); + + insert_element(array, kArraySize, element); + + print_array(array, kArraySize); + } + + return 0; + } \ No newline at end of file diff --git "a/HomeWork5/Igor_Vyhovanets_Five_hometaskcpp 2 \320\272\320\276\320\277\321\226\321\217.cpp" "b/HomeWork5/Igor_Vyhovanets_Five_hometaskcpp 2 \320\272\320\276\320\277\321\226\321\217.cpp" new file mode 100644 index 0000000..9492ce8 --- /dev/null +++ "b/HomeWork5/Igor_Vyhovanets_Five_hometaskcpp 2 \320\272\320\276\320\277\321\226\321\217.cpp" @@ -0,0 +1,179 @@ +#include +#include +#include +#include + +// prototypes - for better code flow in the first part +std::string *generate_deck(); +void show_deck(); + +/*************************** Generate 52 Cards Deck - Not related to stack data structure **********************/ + +const size_t DECK_SIZE = 52; +const std::string *DECK = generate_deck(); + +// generate 52 cards deck on a heap +std::string *generate_deck() { + // Card values: 2 -> Ace + const size_t VALUE_COUNT{13}; + std::string values[VALUE_COUNT]{"2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"}; + // Card symbols: Spade, Heart, Diamond, Club + const size_t SYMBOL_COUNT{4}; + std::string symbols[SYMBOL_COUNT]{"\u2660", "\u2665", "\u2666", "\u2663"}; + // Allocate memory for 52 card deck + std::string *deck = new std::string[DECK_SIZE]; + // Fill deck + for (size_t i{0}; i < SYMBOL_COUNT; ++i) { + for (size_t j{0}; j < VALUE_COUNT; ++j) { + deck[i * VALUE_COUNT + j] = values[j] + symbols[i]; + } + } + return deck; +} + +// display the generated deck - for optional use / testing +void show_deck() { + std::cout << "----------------------------------------------------\n"; + std::cout << "\t\t\tDECK\n"; + for (size_t i{0}; i < DECK_SIZE; ++i) { + if (i % 13 == 0) { + std::cout << "\n"; + } + std::cout << DECK[i] << " "; + } + std::cout << std::endl; +} + +// returns a random card from deck +std::string get_random_card() { + std::random_device seed; + std::default_random_engine rng(seed()); + std::uniform_int_distribution distr(0, DECK_SIZE); + return DECK[distr(rng)]; // !!!BUG!!! causes BAD ALLOC sometimes. Couldn't find problem. +} + +/******************************************* CARD STACK DATA STRUCTURE *****************************************/ + +// INTERNAL DATA + +const size_t STACK_SIZE{10}; +size_t top_index{0}; +std::string Cards[STACK_SIZE]{}; + +// FUNCTIONS FOR EXTERNAL USE + +inline bool is_empty() { return (top_index == 0 && Cards[0] == "" ? true : false); } + +inline bool is_full() { return (top_index == STACK_SIZE ? true : false); } + +inline std::string &top() { return (top_index == 0 ? Cards[top_index] : Cards[top_index - 1]); } + +void push() { + if (is_full()) { + std::cout << "Can't push. Stack full\n"; + return; + } + Cards[top_index++] = get_random_card(); +} + +void pop() { + if (is_empty()) { + std::cout << "Can't pop. Bottom of stack\n"; + return; + } + if (top_index-- == 1) { + Cards[0] = ""; + return; + } +} + +void print_stack() { + if (is_empty()) { + std::cout << "No cards in the stack\n"; + return; + } + std::cout << "Cards:\n"; + for (size_t i{0}; i < top_index; ++i) { + std::cout << i + 1 << " : " << Cards[i] << std::endl; + } +} + +/***************************************************** MAIN ****************************************************/ + +void update_top() { + if (is_empty()) { + std::cout << "Nothing to update\n"; + return; + } + std::string ¤t_top = top(); + current_top = get_random_card(); +} + +void clear_stack() { + while (!is_empty()) { + pop(); + } + std::cout << "Stack has been flushed\n"; +} + +void fill_stack() { + if (is_full()) { + std::cout << "Stack already full\n"; + return; + } + while (!is_full()) { + push(); + } + std::cout << "Stack has been filled\n"; +} + +enum Options { + QUIT, + POP, + PUSH, + SHOW_TOP, + PRINT_STACK, + UPDATE_TOP, + CLEAR_STACK, + FILL_STACK, + END +}; + +std::function user_commands[END]{ + pop, + push, + []() { std::cout << top() << std::endl; }, + print_stack, + update_top, + clear_stack, + fill_stack, + []() { std::cout << "Unknown command. Try again\n"; }}; + +void menu_text() { + std::cout << "---------------------------------------------\n"; + std::cout << "\t\tCARD STACK\n"; + std::cout << POP << " - Pop\n"; + std::cout << PUSH << " - Push\n"; + std::cout << SHOW_TOP << " - Show top card\n"; + std::cout << PRINT_STACK << " - Print the stack\n"; + std::cout << UPDATE_TOP << " - Update top with new card\n"; + std::cout << CLEAR_STACK << " - Clear the stack\n"; + std::cout << FILL_STACK << " - Fill the stack (SOMETIMES ERROR. LINE:58)\n"; + std::cout << QUIT << " - Quit\n"; + std::cout << "Enter selection: "; +} + +int main() { + while (true) { + menu_text(); + int user_selection; + std::cin >> user_selection; + if (user_selection == QUIT) { + return 0; + } + if (user_selection > END) { + user_selection = END; + } + user_commands[user_selection - 1](); + } +} \ No newline at end of file diff --git a/HomeWork5/Igor_Vyhovanets_Five_hometaskcpp 2 .cpp b/HomeWork5/Igor_Vyhovanets_Five_hometaskcpp 2 .cpp new file mode 100644 index 0000000..dd8618c --- /dev/null +++ b/HomeWork5/Igor_Vyhovanets_Five_hometaskcpp 2 .cpp @@ -0,0 +1,164 @@ +#include +#include +#include +#include + +// prototypes - for better code flow in the first part +std::string *generate_deck(); + +/*************************** Generate 52 Cards Deck - Not related to stack data structure **********************/ + +const size_t DECK_SIZE = 52; +const std::string *DECK = generate_deck(); + +// generate 52 cards deck on a heap +std::string *generate_deck() { + // Card values: 2 -> Ace + const size_t VALUE_COUNT{13}; + std::string values[VALUE_COUNT]{"2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"}; + // Card symbols: Spade, Heart, Diamond, Club + const size_t SYMBOL_COUNT{4}; + std::string symbols[SYMBOL_COUNT]{"\u2660", "\u2665", "\u2666", "\u2663"}; + // Allocate memory for 52 card deck + std::string *deck = new std::string[DECK_SIZE]; + // Fill deck + for (size_t i{0}; i < SYMBOL_COUNT; ++i) { + for (size_t j{0}; j < VALUE_COUNT; ++j) { + deck[i * VALUE_COUNT + j] = values[j] + symbols[i]; + } + } + return deck; +} + +// returns a random card from deck +std::string get_random_card() { + std::random_device seed; + std::default_random_engine rng(seed()); + std::uniform_int_distribution distr(0, DECK_SIZE - 1); + return DECK[distr(rng)]; +} + +/******************************************* CARD STACK DATA STRUCTURE *****************************************/ + +// INTERNAL DATA + +const size_t STACK_SIZE{10}; +size_t top_index{0}; +std::string Cards[STACK_SIZE]{}; +bool empty(std::string s) { return s == ""; } + +// FUNCTIONS FOR EXTERNAL USE + +bool is_empty() { return top_index == 0 && empty(Cards[0]); } + +bool is_full() { return top_index == STACK_SIZE; } + +std::string &top() { return (top_index == 0 ? Cards[top_index] : Cards[top_index - 1]); } + +void push() { + if (is_full()) { + std::cout << "Can't push. Stack full\n"; + return; + } + Cards[top_index++] = get_random_card(); +} + +void pop() { + if (is_empty()) { + std::cout << "Can't pop. Bottom of stack\n"; + return; + } + if (top_index-- == 1) { + Cards[0] = ""; + } +} + +void print_stack() { + if (is_empty()) { + std::cout << "No cards in the stack\n"; + return; + } + std::cout << "Cards:\n"; + for (size_t i{0}; i < top_index; ++i) { + std::cout << i + 1 << " : " << Cards[i] << std::endl; + } +} + +/***************************************************** MAIN ****************************************************/ + +void update_top() { + if (is_empty()) { + std::cout << "Nothing to update\n"; + return; + } + top() = get_random_card(); +} + +void clear_stack() { + top_index = 0; + Cards[top_index] = ""; + std::cout << "Stack has been flushed\n"; +} + +void fill_stack() { + if (is_full()) { + std::cout << "Stack already full\n"; + return; + } + while (!is_full()) { + push(); + } + std::cout << "Stack has been filled\n"; +} + +enum Options { + QUIT, + POP, + PUSH, + SHOW_TOP, + PRINT_STACK, + UPDATE_TOP, + CLEAR_STACK, + FILL_STACK, + END +}; + +std::function user_commands[END]{ + pop, + push, + []() { std::cout << top() << std::endl; }, + print_stack, + update_top, + clear_stack, + fill_stack, + []() { std::cout << "Unknown command. Try again\n"; }}; + +void menu_text() { + std::cout << "---------------------------------------------\n"; + std::cout << "\t\tCARD STACK\n"; + std::cout << POP << " - Pop\n"; + std::cout << PUSH << " - Push\n"; + std::cout << SHOW_TOP << " - Show top card\n"; + std::cout << PRINT_STACK << " - Print the stack\n"; + std::cout << UPDATE_TOP << " - Update top with new card\n"; + std::cout << CLEAR_STACK << " - Clear the stack\n"; + std::cout << FILL_STACK << " - Fill the stack\n"; + std::cout << QUIT << " - Quit\n"; + std::cout << "Enter selection: "; +} + +int main() { + while (true) { + menu_text(); + int user_selection; + std::cin >> user_selection; + if (user_selection == QUIT) { + return 0; + } + if (user_selection > END) { + user_selection = END; + } + user_commands[user_selection - 1](); + } + delete [] DECK; +} \ No newline at end of file diff --git a/HomeWork6/Igor_vyhovanets_hometaskcpp.cpp b/HomeWork6/Igor_vyhovanets_hometaskcpp.cpp new file mode 100644 index 0000000..ca01c43 --- /dev/null +++ b/HomeWork6/Igor_vyhovanets_hometaskcpp.cpp @@ -0,0 +1,407 @@ + +#include + +// get length of a string literal +size_t get_length(const char *text) { + if (text == nullptr) { + std::cout << "Exception\n"; + return 0; + } + size_t text_length{0}; + while (*text != '\0') { + ++text_length; + ++text; + } + return text_length; +} + +// copy text +void copy_text(const char *src_text, char *dst_text) { + if (src_text == nullptr || dst_text == nullptr) { + std::cout << "Exception\n"; + return; + } + while (*src_text != '\0') { + *dst_text++ = *src_text++; + } + *dst_text = '\0'; +} + +/**************************************** NODE FOR RESTAURANT ORDER ********************************************/ + +// Node for restaurant order +class Order { +public: + // User-defined Constructor + Order(const char ORDERED_FOOD[]) : next{nullptr} { set_food(ORDERED_FOOD); } + // Destructor + ~Order() { delete[] food; } + // Get next order + Order *get_next() const { return next; } + // Get name of ordered food + char *get_food() const { return food; }; + // Set next order + void set_next(Order *NEXT_ORDER) { next = NEXT_ORDER; } + // Set name of ordered food + void set_food(const char[]); + // Print the name of ordered food + void print() const; + +private: + char *food = nullptr; + Order *next = nullptr; +}; + +// Set name of ordered food +void Order::set_food(const char FOOD_NAME[]) { + delete[] food; + food = new char[get_length(FOOD_NAME)]; + copy_text(FOOD_NAME, food); +} + +// Print the name of ordered food +void Order::print() const { + std::cout << get_food(); + if (get_next() != nullptr) { + std::cout << " -> "; + } +} + +/********************************* LINKED-LIST QUEUE FOR RESTAURANT ORDERS *************************************/ + +// Queue of restaurant orders +class Orders { +public: + // shows current food orders in the queue + void print_queue() const; + // adds food order into the queue + bool enqueue(); + // cook the order from the queue + bool dequeue(); + bool update_order_by_index(); + bool cancel_order_by_index(); + bool cancel_all_orders(); + +private: + size_t get_order_count() const; + Order *search_previous_order(const Order *) const; + Order *search_order_by_index(const size_t) const; + size_t ask_index_from_user(); + bool delete_order(Order *); + + const size_t MAX_ORDERS = 5; + Order *head = nullptr; +}; + +// Shows current food orders in the queue +void Orders::print_queue() const { + std::cout << "--------------------------\n"; + const size_t COUNT{get_order_count()}; + if (COUNT == 0) { + std::cout << "No orders pending\n"; + return; + } + std::cout << "Number of orders: " << COUNT << std::endl; + Order *it{head}; + while (it != nullptr) { + it->print(); + it = it->get_next(); + } + std::cout << std::endl; +} + +// Adds food order into the queue +bool Orders::enqueue() { + std::cout << "--------------------------\n"; + if (get_order_count() == MAX_ORDERS) { + std::cout << "Can't order. Queue is full\n"; + return false; + } + const size_t SIZE{100}; + char ordered_food[SIZE]; + std::cout << "Enter food name: "; + std::cin >> ordered_food; + std::cout << ordered_food << " order has been added to the queue\n"; + if (head == nullptr) { + head = new Order{ordered_food}; + return true; + } + Order *tail = search_order_by_index(get_order_count()); + Order *new_tail = new Order{ordered_food}; + tail->set_next(new_tail); + return true; +} + +// Cook the order from the queue +bool Orders::dequeue() { + std::cout << "--------------------------\n"; + if (delete_order(head)) { + std::cout << "Order has been prepared\n"; + return true; + } else { + std::cout << "Nothing to be cooked\n"; + return false; + } +} + +// Update an order at user provided index +bool Orders::update_order_by_index() { + const size_t INDEX = ask_index_from_user(); + if (INDEX == 0) { + return false; + } + Order *order_to_update = search_order_by_index(INDEX); + if (order_to_update == nullptr) { + return false; + } + const size_t SIZE{100}; + char updated_food[SIZE]; + std::cout << "Enter food name: "; + std::cin >> updated_food; + order_to_update->set_food(updated_food); + std::cout << "Order has been updated successfully\n"; + return true; +} + +// Cancel an order at user provided index +bool Orders::cancel_order_by_index() { + const size_t INDEX = ask_index_from_user(); + if (INDEX == 0) { + return false; + } + Order *order_to_delete = search_order_by_index(INDEX); + if (order_to_delete == nullptr) { + return false; + } + if (delete_order(order_to_delete)) { + std::cout << "Order has been cancelled successfully\n"; + return true; + } + return false; +} + +// Cancel all orders in the queue +bool Orders::cancel_all_orders() { + std::cout << "--------------------------\n"; + size_t count = get_order_count(); + if (count == 0) { + std::cout << "Queue is empty. Can't process\n"; + return false; + } + while (count != 0) { + delete_order(head); + --count; + } + std::cout << "All orders has been cancelled\n"; + return true; +} + +// Calculate current number of orders in the queue +size_t Orders::get_order_count() const { + Order *it = head; + if (it == nullptr) { + return 0; + } + size_t count{}; + while (it != nullptr) { + it = it->get_next(); + ++count; + } + return count; +} + +// Find a previous order +Order *Orders::search_previous_order(const Order *order) const { + if (order == head) { + return head; + } + Order *previous = head; + while (previous->get_next() != order) { + previous = previous->get_next(); + } + return previous; +} + +// Find an order by its index(count) +Order *Orders::search_order_by_index(const size_t INDEX) const { + if (INDEX == 0 || INDEX > get_order_count()) { + std::cout << "Invalid order number. Try again\n"; + return nullptr; + } + Order *it = head; + for (size_t i{INDEX}; i != 1; --i) { + it = it->get_next(); + } + return it; +} + +// Ask for user to enter an index in the queue. Return 0 on exceptions +size_t Orders::ask_index_from_user() { + std::cout << "--------------------------\n"; + const size_t COUNT = get_order_count(); + if (COUNT == 0) { + std::cout << "Queue is empty. Can't process\n"; + return 0; + } + std::cout << "Enter an index: "; + size_t index; + std::cin >> index; + if (index > COUNT || index == 0) { + std::cout << "Invalid order number. Try again\n"; + return 0; + } + return index; +} + +// Delete an order +bool Orders::delete_order(Order *order) { + if (get_order_count() == 0) { + std::cout << "Queue is empty\n"; + return false; + } + if (order == nullptr) { + std::cout << "Passed order is empty. Can't process\n"; + return false; + } + if (order != head) { + Order *previous = search_previous_order(order); + previous->set_next(order->get_next()); + } else { + head = order->get_next(); + } + delete order; + return true; +} + +/********************************************* SINGLETON LOGGER ************************************************/ + +const size_t LOG_SIZE = 10000; + +// Singleton simple logger to track restaurant activities +class Logger { +public: + void add_log(const char[]); + void read_log() const { std::cout << logs << std::endl; } + static Logger *get_instance() { + if (instance == nullptr) { + instance = new Logger; + } + return instance; + } +private: + static Logger *instance; + Logger() {}; + Logger(const Logger &) = delete; + Logger &operator=(const Logger &) = delete; + char logs[LOG_SIZE] = "\n\tACTIVITY LOGS"; +}; + +Logger *Logger::instance = nullptr; + +void Logger::add_log(const char TEXT[]) { + const size_t CURRENT_INDEX = get_length(logs); + size_t text_length = get_length(TEXT); + if (CURRENT_INDEX + text_length + 2 > LOG_SIZE) { + std::cout << "Unable to add log. Logbook is full\n"; + return; + } + // add newline before new message is entered into the logbook + logs[CURRENT_INDEX] = '\n'; + // add null-terminator to the end of logbook + logs[CURRENT_INDEX + text_length + 1] = '\0'; + // copy the text intto the log + for (size_t i{0}; text_length != 0; ++i) { + logs[CURRENT_INDEX + i + 1] = TEXT[i]; + --text_length; + } +} + +/************************************************** MAIN ******************************************************/ + +enum Menu { + QUIT, + ORDER, + COOK, + SHOW, + UPDATE, + CANCEL_BY_INDEX, + CANCEL_ALL, + READ_LOG +}; + +void show_menu() { + std::cout << "--------------------------\n"; + std::cout << "\tOPTIONS\n"; + std::cout << ORDER << " - ACCEPT A NEW FOOD ORDER\n"; + std::cout << COOK << " - COOK THE ORDERED FOOD\n"; + std::cout << SHOW << " - SHOW ALL ORDERS IN THE QUEUE\n"; + std::cout << UPDATE << " - UPDATE ORDER BY INDEX\n"; + std::cout << CANCEL_BY_INDEX << " - CANCEL ORDER BY INDEX\n"; + std::cout << CANCEL_ALL << " - CANCEL ALL ORDERS\n"; + std::cout << READ_LOG << " - CHECK ACTIVITY LOGS\n"; + std::cout << QUIT << " - QUIT\n"; + std::cout << "Enter selection: "; +} + +int main() { + Orders PizzaQueue; + while (true) { + show_menu(); + int user_selection{}; + std::cin >> user_selection; + std::cin.clear(); + std::cin.ignore(); + switch (user_selection) { + case QUIT: + std::cout << "--------------------------\n"; + std::cout << "Quitting\n"; + return 0; + case ORDER: + + if (PizzaQueue.enqueue()) { + Logger *Logger_of_Programmer_A = Logger::get_instance(); + Logger_of_Programmer_A->add_log("An order has been accepted"); + } + continue; + case COOK: + if (PizzaQueue.dequeue()) { + Logger *Logger_of_Programmer_B = Logger::get_instance(); + Logger_of_Programmer_B->add_log("An order was served to the customer"); + } + continue; + case SHOW: + PizzaQueue.print_queue(); + continue; + case UPDATE: + if (PizzaQueue.update_order_by_index()) { + Logger *Logger_of_Programmer_C = Logger::get_instance(); + Logger_of_Programmer_C->add_log("An order was updated succesffully"); + } + continue; + case CANCEL_BY_INDEX: + if (PizzaQueue.cancel_order_by_index()) { + Logger *Logger_of_Programmer_D = Logger::get_instance(); + Logger_of_Programmer_D->add_log("An order was cancelled"); + } + continue; + case CANCEL_ALL: + if (PizzaQueue.cancel_all_orders()) { + Logger *Logger_of_Programmer_E = Logger::get_instance(); + Logger_of_Programmer_E->add_log("All orders were cancelled"); + } + continue; + case READ_LOG: { + Logger *Logger_of_Programmer_B = Logger::get_instance(); + Logger_of_Programmer_B->read_log(); + continue; + } + + default: + std::cout << "--------------------------\n"; + std::cout << "Unknown command. Try again\n"; + continue; + } + } + return 1; + +