Website Summary Files Commits Branches @commit @diff @stats
path: root / Week01
diff options
context:
space:
mode:
Commitfcf38e62e8160f2c9901bdfd33760afed28beb8d (patch)
Author
 Syndamia <kamen@syndamia.com>
2026-02-22 19:18:46 +0200
Committer
 Syndamia <kamen@syndamia.com>
2026-02-22 19:18:46 +0200
Files838fd5897d88700491a389cdf6837e35da3347ae /Week01
oop-2025-solutions-fcf38e62e8160f2c9901bdfd33760afed28beb8d.tar
oop-2025-solutions-fcf38e62e8160f2c9901bdfd33760afed28beb8d.tar.gz
oop-2025-solutions-fcf38e62e8160f2c9901bdfd33760afed28beb8d.zip
Parentc365ede952f852c6e8feb92fc3a0766186f989f1 (diff)
feat(Week01): Add solutions
diff --git a/Week01/Exercise01/main.cpp b/Week01/Exercise01/main.cpp
new file mode 100644
index 0000000..7958615
--- /dev/null
+++ b/Week01/Exercise01/main.cpp
@@ -0,0 +1,29 @@
+#include <iostream>
+#include "matrix.h"
+
+int main() {
+ unsigned rowsA, colsA;
+ std::cin >> rowsA >> colsA;
+
+ int** matA = newMatrix(rowsA, colsA);
+
+ for (unsigned row = 0; row < rowsA; ++row)
+ for (unsigned col = 0; col < colsA; ++col)
+ std::cin >> matA[row][col];
+
+ unsigned rowsB, colsB;
+ std::cin >> rowsB >> colsB;
+
+ int** matB = newMatrix(rowsB, colsB);
+
+ for (unsigned row = 0; row < rowsB; ++row)
+ for (unsigned col = 0; col < colsB; ++col)
+ std::cin >> matB[row][col];
+
+ std::cout << (sumMatrix((const int**)matA, rowsA, colsA) - sumMatrix((const int**)matB, rowsB, colsB)) << std::endl;
+
+ deleteMatrix(matA, rowsA);
+ deleteMatrix(matB, rowsB);
+
+ return 0;
+}
diff --git a/Week01/Exercise01/matrix.cpp b/Week01/Exercise01/matrix.cpp
new file mode 100644
index 0000000..c8bdff2
--- /dev/null
+++ b/Week01/Exercise01/matrix.cpp
@@ -0,0 +1,28 @@
+#include "matrix.h"
+
+int** newMatrix(unsigned rows, unsigned cols) {
+ int** mat = new int*[rows];
+
+ for (unsigned i = 0; i < rows; ++i)
+ mat[i] = new int[cols];
+
+ return mat;
+}
+
+void deleteMatrix(int**& matrix, unsigned rows) {
+ for (unsigned i = 0; i < rows; ++i)
+ delete[] matrix[i];
+ delete[] matrix;
+
+ matrix = nullptr;
+}
+
+int sumMatrix(const int** matrix, unsigned rows, unsigned cols) {
+ int sum = 0;
+
+ for (unsigned row = 0; row < rows; ++row)
+ for (unsigned col = 0; col < cols; ++col)
+ sum += matrix[row][col];
+
+ return sum;
+}
diff --git a/Week01/Exercise01/matrix.h b/Week01/Exercise01/matrix.h
new file mode 100644
index 0000000..334fab0
--- /dev/null
+++ b/Week01/Exercise01/matrix.h
@@ -0,0 +1,11 @@
+#ifndef _MATRIX
+#define _MATRIX
+
+// Създава нова динамично-заделена матрица
+int** newMatrix(unsigned rows, unsigned cols);
+// Изтрива динамично-заделена матрица
+void deleteMatrix(int**& matrix, unsigned rows); // Запишете nullptr в matrix!
+// Връща сумата на всички елементи в матрицата
+int sumMatrix(const int** matrix, unsigned rows, unsigned cols);
+
+#endif
diff --git a/Week01/Exercise02/arrmath.cpp b/Week01/Exercise02/arrmath.cpp
new file mode 100644
index 0000000..d518134
--- /dev/null
+++ b/Week01/Exercise02/arrmath.cpp
@@ -0,0 +1,57 @@
+#include "arrmath.h"
+
+int sum(const int* elements, unsigned length) {
+ if (elements == nullptr || length == 0)
+ return 0;
+
+ int sum = 0;
+
+ for (unsigned i = 0; i < length; ++i)
+ sum += elements[i];
+
+ return sum;
+}
+
+double average(const int* elements, unsigned length) {
+ if (elements == nullptr || length == 0)
+ return 0.0;
+
+ return (double)sum(elements, length) / length;
+}
+
+int largest(const int* elements, unsigned length) {
+ if (elements == nullptr || length == 0)
+ return 0;
+
+ int largest = elements[0];
+ for (unsigned i = 1; i < length; ++i)
+ if (elements[i] > largest)
+ largest = elements[i];
+
+ return largest;
+}
+
+int smallest(const int* elements, unsigned length) {
+ if (elements == nullptr || length == 0)
+ return 0;
+
+ int smallest = elements[0];
+ for (unsigned i = 1; i < length; ++i)
+ if (elements[i] < smallest)
+ smallest = elements[i];
+
+ return smallest;
+}
+
+unsigned findIndex(const int* elements, unsigned length, int elementToSearch) {
+ if (elements == nullptr || length == 0)
+ return length;
+
+ for (unsigned i = 0; i < length; ++i)
+ if (elements[i] == elementToSearch)
+ return i;
+
+ // Коректно е да връщаме length вместо 0, защото
+ // 0 може да е валиден индекс в масива с елементи
+ return length;
+}
diff --git a/Week01/Exercise02/arrmath.h b/Week01/Exercise02/arrmath.h
new file mode 100644
index 0000000..4f1a550
--- /dev/null
+++ b/Week01/Exercise02/arrmath.h
@@ -0,0 +1,15 @@
+#ifndef ARRMATH
+#define ARRMATH
+
+// Сума на стойностите в elements
+int sum(const int* elements, unsigned length);
+// Средно аритметично на стойностите в elements
+double average(const int* elements, unsigned length);
+// Най-голямата стойност в elements
+int largest(const int* elements, unsigned length);
+// Най-малката стойност в elements
+int smallest(const int* elements, unsigned length);
+// Връща индекса на първото срещане на elementToSearch
+unsigned findIndex(const int* elements, unsigned length, int elementToSearch);
+
+#endif
diff --git a/Week01/Exercise02/main.cpp b/Week01/Exercise02/main.cpp
new file mode 100644
index 0000000..9e3c593
--- /dev/null
+++ b/Week01/Exercise02/main.cpp
@@ -0,0 +1,26 @@
+#include <iostream>
+#include "arrmath.h"
+
+int main() {
+ unsigned N;
+ std::cin >> N;
+
+ int* arr = new int[N];
+ for (unsigned i = 0; i < N; ++i)
+ std::cin >> arr[i];
+
+ int startIndex = findIndex(arr, N, smallest(arr, N));
+ int endIndex = findIndex(arr, N, largest(arr, N));
+
+ if (startIndex > endIndex) {
+ int temp = startIndex;
+ startIndex = endIndex;
+ endIndex = temp;
+ }
+
+ std::cout << average(arr + startIndex, endIndex - startIndex + 1) << std::endl;
+
+ delete[] arr;
+
+ return 0;
+}
diff --git a/Week01/Exercise03/ioHelpers.cpp b/Week01/Exercise03/ioHelpers.cpp
new file mode 100644
index 0000000..caf63fe
--- /dev/null
+++ b/Week01/Exercise03/ioHelpers.cpp
@@ -0,0 +1,57 @@
+#include <iostream>
+#include "ioHelpers.h"
+#include "stringHelpers.h"
+
+int readInteger(const char* prompt, int min, int max) {
+ std::cout << prompt;
+
+ int value;
+ std::cin >> value;
+
+ while (value < min || max < value) {
+ std::cout << "Value must in range [" << min << ", " << max << "]! Try again... " << std::endl;
+ std::cin >> value;
+ }
+
+ return value;
+}
+
+double readDouble(const char* prompt, double min, double max) {
+ std::cout << prompt;
+
+ double value;
+ std::cin >> value;
+
+ while (value < min || max < value) {
+ std::cout << "Value must in range [" << min << ", " << max << "]! Try again... " << std::endl;
+ std::cin >> value;
+ }
+
+ return value;
+}
+
+char* readString(const char* prompt) {
+ std::cout << prompt;
+
+ const unsigned BUFFER_SIZE = 1024;
+ char buffer[BUFFER_SIZE];
+
+ // Когато правим "std::cin >> x", std::cin чете само нужния брой знаци за x,
+ // докато std::cin.getline чете от последната позиция нататък.
+ // Тоест, ако направим например "std::cin >> integerValue" и след това
+ // "std::cin.getline(...)" и входа ни е "5 ABC", тогава първото std::cin
+ // ще прочете само 5-цата и getline ще запише " ABC".
+ // Когато обаче имаме нов ред, тоест еквивалентно на "5\nABC", тогава
+ // getline ще почне да чете от "\nABC", ще види това "\n" и ще запише
+ // празния низ "".
+ // std::cin.peek() връща текущата буква, без да премества напред четенето,
+ // std::cin.ignore() игнорира една буква (т.е. четенето продължава след нея).
+ // Общо взето, това долу игнорира знак за нов ред, ако сме срещнали такъв.
+ // Това оправя ситуацията, когато получаваме "First name: Last name: ".
+ if (std::cin.peek() == '\n')
+ std::cin.ignore();
+
+ std::cin.getline(buffer, BUFFER_SIZE);
+
+ return newString(buffer);
+}
diff --git a/Week01/Exercise03/ioHelpers.h b/Week01/Exercise03/ioHelpers.h
new file mode 100644
index 0000000..bf365dd
--- /dev/null
+++ b/Week01/Exercise03/ioHelpers.h
@@ -0,0 +1,17 @@
+#ifndef IOHELPERS
+#define IOHELPERS
+
+// Прочита от потребителския вход цяло число между min и max включително,
+// като предоставя prompt преди въведената стойност
+// При невалидна стойност, пита пак за вход
+int readInteger(const char* prompt, int min, int max);
+// Прочита от потребителския вход число с плаваща запетая между min и max включително,
+// като предоставя prompt преди въведената стойност
+// При невалидна стойност, пита пак за вход
+double readDouble(const char* prompt, double min, double max);
+// Прочита от потребителския вход един ред текст,
+// като предоставя prompt преди въведената стойност
+// При невалидна стойност, пита пак за вход
+char* readString(const char* prompt);
+
+#endif
diff --git a/Week01/Exercise03/main.cpp b/Week01/Exercise03/main.cpp
new file mode 100644
index 0000000..beea1f5
--- /dev/null
+++ b/Week01/Exercise03/main.cpp
@@ -0,0 +1,40 @@
+#include <iostream>
+#include "ioHelpers.h"
+#include "stringHelpers.h"
+
+int main() {
+ // Нямаме ограничение на броя студенти, затова просто ще сложим максимума
+ // да е най-голямата стойност за 32-битов signed integer: 2^31 - 1
+ // По-коректно е да се ползват специални константи, които пазят максималната
+ // стойност на отделните типове данни, защото на стар компютър, int може да
+ // не е 32 бита.
+ unsigned numStudents = readInteger("Number of students: ", 0, 2147483647);
+
+ double* grades = new double[numStudents];
+ char** names = new char*[numStudents];
+
+ for (unsigned i = 0; i < numStudents; ++i) {
+ char* firstName = readString("First name: ");
+ char* lastName = readString("Last name: ");
+
+ names[i] = concatStrings(firstName, lastName, " ");
+
+ deleteString(firstName);
+ deleteString(lastName);
+
+ double grade = readDouble("Grade: ", 2.0, 6.0);
+
+ grades[i] = grade;
+ }
+
+ for (unsigned i = 0; i < numStudents; ++i) {
+ std::cout << names[i] << " has grade " << grades[i] << std::endl;
+ }
+
+ delete[] grades;
+ for (unsigned i = 0; i < numStudents; ++i)
+ deleteString(names[i]);
+ delete[] names;
+
+ return 0;
+}
diff --git a/Week01/Exercise03/stringHelpers.cpp b/Week01/Exercise03/stringHelpers.cpp
new file mode 100644
index 0000000..ee9e691
--- /dev/null
+++ b/Week01/Exercise03/stringHelpers.cpp
@@ -0,0 +1,74 @@
+#include "stringHelpers.h"
+
+char* newString(unsigned length) {
+ return new char[length + 1];
+}
+
+// Тази функция е локална: не можем да я използваме в друг файл!
+unsigned stringLength(const char* string) {
+ if (string == nullptr)
+ return 0;
+
+ unsigned length = 0;
+
+ while (*string != '\0') {
+ ++length;
+ ++string;
+ }
+
+ return length;
+}
+
+char* newString(const char* string) {
+ if (string == nullptr)
+ return nullptr;
+
+ unsigned length = stringLength(string);
+
+ char* str = newString(length);
+
+ // Правим <= length, за да пренесем и терминиращата нула
+ for (unsigned i = 0; i <= length; ++i) {
+ str[i] = string[i];
+ }
+
+ return str;
+}
+
+char* concatStrings(const char* first, const char* second, const char* separator) {
+ unsigned length = stringLength(first) + stringLength(separator) + stringLength(second);
+
+ char* str = newString(length);
+ unsigned i = 0;
+
+ if (first != nullptr) {
+ while (*first != '\0' && i < length) {
+ str[i] = *first;
+ ++first;
+ ++i;
+ }
+ }
+
+ if (separator != nullptr) {
+ while (*separator != '\0' && i < length) {
+ str[i] = *separator;
+ ++separator;
+ ++i;
+ }
+ }
+
+ if (second != nullptr) {
+ while (*second != '\0' && i < length) {
+ str[i] = *second;
+ ++second;
+ ++i;
+ }
+ }
+
+ return str;
+}
+
+void deleteString(char*& string) {
+ delete[] string;
+ string = nullptr;
+}
diff --git a/Week01/Exercise03/stringHelpers.h b/Week01/Exercise03/stringHelpers.h
new file mode 100644
index 0000000..7f86130
--- /dev/null
+++ b/Week01/Exercise03/stringHelpers.h
@@ -0,0 +1,14 @@
+#ifndef STRINGHELPERS
+#define STRINGHELPERS
+
+// Създава динамично-заделен низ по подадената дължина
+char* newString(unsigned length);
+// Създава динамично-заделен низ, копие на подадения низ
+char* newString(const char* string);
+// Слепява first и second, като поставя separator между тях (ако е валиден) и
+// връща резултатния (динамичо-заделен) низ
+char* concatStrings(const char* first, const char* second, const char* separator);
+// Освобождава паметта на динамичо-заделен низ
+void deleteString(char*& string); // Запишете nullptr в string!
+
+#endif
diff --git a/Week01/README.md b/Week01/README.md
new file mode 100644
index 0000000..69458d7
--- /dev/null
+++ b/Week01/README.md
@@ -0,0 +1,3 @@
+# Задачи
+
+<https://syndamia.com/teaching/oop-2025/week01/>