Website Summary Files Commits Branches @commit @diff @stats
path: root / Week08
diff options
context:
space:
mode:
Commit5294e73a21f3402e14fcf3379c721275e2dd19c2 (patch)
Author
 Syndamia <kamen@syndamia.com>
2025-11-23 15:25:29 +0200
Committer
 Syndamia <kamen@syndamia.com>
2025-11-23 16:05:21 +0200
Files3f02cc12e0868ac043d7f937fec380b29f54c71a /Week08
upp-2025-solutions-5294e73a21f3402e14fcf3379c721275e2dd19c2.tar
upp-2025-solutions-5294e73a21f3402e14fcf3379c721275e2dd19c2.tar.gz
upp-2025-solutions-5294e73a21f3402e14fcf3379c721275e2dd19c2.zip
Parent3e8ac7ba4a8f410703aa5a8426f542217adcbf2f (diff)
feat(Week08): Add solutions
16 files changed, 622 insertions, 0 deletions
-rw-r--r--Week08/Exercise01.cpp29
-rw-r--r--Week08/Exercise02.cpp28
-rw-r--r--Week08/Exercise03.cpp48
-rw-r--r--Week08/Exercise04.cpp56
-rw-r--r--Week08/Exercise05.cpp53
-rw-r--r--Week08/Exercise06.cpp40
-rw-r--r--Week08/Exercise07.cpp45
-rw-r--r--Week08/Exercise08.cpp39
-rw-r--r--Week08/Exercise09.cpp36
-rw-r--r--Week08/Exercise10.cpp23
-rw-r--r--Week08/Exercise11.cpp65
-rw-r--r--Week08/Exercise12.cpp53
-rw-r--r--Week08/Exercise13.cpp31
-rw-r--r--Week08/Exercise14.cpp25
-rw-r--r--Week08/Exercise15.cpp48
-rw-r--r--Week08/README.md3
diff --git a/Week08/Exercise01.cpp b/Week08/Exercise01.cpp
new file mode 100644
index 0000000..3052799
--- /dev/null
+++ b/Week08/Exercise01.cpp
@@ -0,0 +1,29 @@
+#include <iostream>
+
+/* Тази задача може да се реши без матрици.
+ * Все пак идеята е да упражним точно тях.
+ */
+
+int main() {
+ const unsigned int SIZE = 5;
+ int mat[SIZE][SIZE];
+
+ for (unsigned int i = 0; i < SIZE; i++)
+ for (unsigned int j = 0; j < SIZE; j++)
+ std::cin >> mat[i][j];
+
+ unsigned int countZeroes = 0;
+ for (unsigned int i = 0; i < SIZE; i++)
+ for (unsigned int j = 0; j < SIZE; j++)
+ countZeroes += mat[i][j] == 0;
+
+ /* Бройката нули е повече от бройката на всички елементи които не са нули.
+ * Алтернативно, може и да се пази втори брояч за ненулеви елементи.
+ */
+ if (countZeroes > SIZE * SIZE - countZeroes)
+ std::cout << "Sparse" << std::endl;
+ else
+ std::cout << "Not sparse" << std::endl;
+
+ return 0;
+}
diff --git a/Week08/Exercise02.cpp b/Week08/Exercise02.cpp
new file mode 100644
index 0000000..34752c5
--- /dev/null
+++ b/Week08/Exercise02.cpp
@@ -0,0 +1,28 @@
+#include <iostream>
+
+void rowSum(const unsigned int* matrix, unsigned int rows, unsigned int cols, unsigned int* sum) {
+ for (unsigned int row = 0; row < rows; row++)
+ for (unsigned int col = 0; col < cols; col++)
+ /* За повече информация защо така индексираме в matrix, вижте
+ * https://syndamia.com/teaching/upp-2025/cpp-pitfalls/#-int73-vs-int3-vs-int
+ */
+ sum[col] += matrix[row * cols + col];
+}
+
+int main() {
+ const unsigned int ROWS = 7, COLS = 3;
+ unsigned int mat[ROWS][COLS];
+
+ for (unsigned int i = 0; i < ROWS; i++)
+ for (unsigned int j = 0; j < COLS; j++)
+ std::cin >> mat[i][j];
+
+ unsigned int sum[COLS] = { 0 };
+ rowSum((const unsigned int*)mat, ROWS, COLS, sum);
+
+ for (unsigned int col = 0; col < COLS; col++)
+ std::cout << sum[col] << ' ';
+ std::cout << std::endl;
+
+ return 0;
+}
diff --git a/Week08/Exercise03.cpp b/Week08/Exercise03.cpp
new file mode 100644
index 0000000..7badee5
--- /dev/null
+++ b/Week08/Exercise03.cpp
@@ -0,0 +1,48 @@
+#include <iostream>
+
+void subMatrix(const double* inmat, unsigned int inRows, unsigned int inCols,
+ double* outmat, unsigned int outRows, unsigned int outCols)
+{
+ for (unsigned int row = 0; row < outRows; row++)
+ for (unsigned int col = 0; col < outCols; col++)
+ /* За повече информация защо така индексираме в матриците, вижте
+ * https://syndamia.com/teaching/upp-2025/cpp-pitfalls/#-int73-vs-int3-vs-int
+ */
+ outmat[row * inCols + col] = inmat[row * inCols + col];
+}
+
+int main() {
+ const unsigned int ROWS = 6, COLS = 6;
+ double mat[ROWS][COLS];
+
+ for (unsigned int i = 0; i < ROWS; i++)
+ for (unsigned int j = 0; j < COLS; j++)
+ std::cin >> mat[i][j];
+
+ unsigned int startRow, startCol, rows, cols;
+ std::cin >> startCol >> startRow >> cols >> rows;
+
+ double submat[ROWS][COLS] = { 0 };
+ /* По условие се иска функцията да попълва елементите от горния ляв ъгъл на матрицата.
+ * Това означава, че трябва да променим горния ляв ъгъл къде е (т.е. да съответства
+ * на елемента на началните позиции).
+ *
+ * Един лош ефект от това е, че подадените размери (особено броя колони) на входната
+ * матрица са спрямо цялата матрица, не подматрицата която искаме.
+ * Тоест, на теория, функцията може да излезе извън паметта на матрицата, заради
+ * начина по който индексираме.
+ *
+ * Интересното е, че ако матрицата беше динамично заделена, това нямаше да е проблем.
+ * По тази тема ще говорим в бъдеще.
+ */
+ subMatrix((const double*)mat + startRow * COLS + startCol, ROWS, COLS,
+ (double*)submat, rows, cols);
+
+ for (unsigned int row = 0; row < rows; row++) {
+ for (unsigned int col = 0; col < cols; col++)
+ std::cout << submat[row][col] << ' ';
+ std::cout << std::endl;
+ }
+
+ return 0;
+}
diff --git a/Week08/Exercise04.cpp b/Week08/Exercise04.cpp
new file mode 100644
index 0000000..d779cd4
--- /dev/null
+++ b/Week08/Exercise04.cpp
@@ -0,0 +1,56 @@
+#include <iostream>
+
+const unsigned int SIZE = 5;
+
+/* counts масива съдържа бройката на всеки тип сграда в околност/съседство на тази на подадените индекси.
+ * counts[0] - бройка жилищни
+ * counts[1] - бройка търговски
+ * counts[2] - бройка офисни
+ * counts[3] - бройка луксозни
+ */
+void surroundingBuildings(const unsigned short mat[SIZE][SIZE], unsigned int row, unsigned int col, unsigned short counts[4]) {
+ for (unsigned int type = 0; type < 4; type++)
+ counts[type] = 0;
+
+ /* Възползваме се от факта, че сградите ни се представят като числата от 1 до 4 вкл.
+ * Намаляйки с единица, те се превръщат в 0 до 3 вкл. и стават валидни индекси в counts.
+ */
+ if (0 < row) counts[mat[row - 1][col] - 1]++;
+ if (row < SIZE - 1) counts[mat[row + 1][col] - 1]++;
+ if (0 < col) counts[mat[row][col - 1] - 1]++;
+ if (col < SIZE - 1) counts[mat[row][col + 1] - 1]++;
+}
+
+int main() {
+ /* Изкушаващо е да спестим малко памет и да използваме unsigned char, обаче
+ * тогава std::cin ще вкарва стойностите като букви, не като числа.
+ * Реално, винаги можем да ги превърнем обратно в числовите им стойности, но
+ * така е по-лесно.
+ */
+ unsigned short city[SIZE][SIZE];
+
+ for (unsigned int i = 0; i < SIZE; i++)
+ for (unsigned int j = 0; j < SIZE; j++)
+ std::cin >> city[i][j];
+
+ unsigned short surroundings[4] = { 0 };
+
+ bool valid = true;
+ for (unsigned int i = 0; i < SIZE && valid; i++) {
+ for (unsigned int j = 0; j < SIZE && valid; j++) {
+ surroundingBuildings(city, i, j, surroundings);
+
+ valid = (city[i][j] == 1) ||
+ (city[i][j] == 2 && surroundings[0] >= 1) ||
+ (city[i][j] == 3 && surroundings[0] >= 1 && surroundings[1] >= 1) ||
+ (city[i][j] == 4 && surroundings[0] >= 1 && surroundings[1] >= 1 && surroundings[2] >= 1);
+ }
+ }
+
+ if (valid)
+ std::cout << "Valid" << std::endl;
+ else
+ std::cout << "Invalid" << std::endl;
+
+ return 0;
+}
diff --git a/Week08/Exercise05.cpp b/Week08/Exercise05.cpp
new file mode 100644
index 0000000..d046ee8
--- /dev/null
+++ b/Week08/Exercise05.cpp
@@ -0,0 +1,53 @@
+#include <iostream>
+
+const unsigned int SIZE = 3;
+
+void swap(int &a, int &b) {
+ int temp = a;
+ a = b;
+ b = temp;
+}
+
+void transpose(int mat[SIZE][SIZE]) {
+ /* Има по-проста имплементация за матрица 3x3, но тази работи за всякакъв размер матрица.
+ * Каква е идеята: движим се по диагоналите над главния и разменяме елементите със съответния
+ * диагонал под главния.
+ *
+ * Ето така обикаляме, като числото показва използваната diagDist и плюсовете маркират главния диагонал:
+ * +1234
+ * 1+123
+ * 21+12
+ * 321+1
+ * 4321+
+ *
+ * Би трябвало да е очевидно, че първия ред ще участва във всеки диагонал.
+ * Затова, почваме от елемента на първия ред, който участва в текущия диагонал, и от там
+ * увеличаваме реда и колоната на всяка итерация.
+ *
+ * Когато имаме позиция над главния диагонал, стигаме до тази под главния като просто
+ * разменим реда и колоната.
+ *
+ * Ако не разбирате някои от тези сметки/индексирания, просто си разпишете някой по-голям пример.
+ */
+ for (unsigned int diagDist = 1; diagDist < SIZE; diagDist++)
+ for (unsigned int diagElem = 0; diagElem + diagDist < SIZE; diagElem++)
+ swap(mat[diagElem][diagElem + diagDist], mat[diagElem + diagDist][diagElem]);
+}
+
+int main() {
+ int mat[SIZE][SIZE];
+
+ for (unsigned int i = 0; i < SIZE; i++)
+ for (unsigned int j = 0; j < SIZE; j++)
+ std::cin >> mat[i][j];
+
+ transpose(mat);
+
+ for (unsigned int i = 0; i < SIZE; i++) {
+ for (unsigned int j = 0; j < SIZE; j++)
+ std::cout << mat[i][j] << ' ';
+ std::cout << std::endl;
+ }
+
+ return 0;
+}
diff --git a/Week08/Exercise06.cpp b/Week08/Exercise06.cpp
new file mode 100644
index 0000000..30ef172
--- /dev/null
+++ b/Week08/Exercise06.cpp
@@ -0,0 +1,40 @@
+#include <iostream>
+
+void swap(double &a, double &b) {
+ double temp = a;
+ a = b;
+ b = temp;
+}
+
+void swapColumns(double* mat, unsigned int rows, unsigned int cols, unsigned int column1, unsigned int column2) {
+ if (column1 >= cols || column2 >= cols)
+ return;
+
+ for (unsigned int row = 0; row < rows; row++)
+ /* За повече информация защо така индексираме в матриците, вижте
+ * https://syndamia.com/teaching/upp-2025/cpp-pitfalls/#-int73-vs-int3-vs-int
+ */
+ swap(mat[row * cols + column1], mat[row * cols + column2]);
+}
+
+int main() {
+ const unsigned int ROWS = 3, COLS = 5;
+ double mat[ROWS][COLS];
+
+ for (unsigned int i = 0; i < ROWS; i++)
+ for (unsigned int j = 0; j < COLS; j++)
+ std::cin >> mat[i][j];
+
+ unsigned int col1, col2;
+ std::cin >> col1 >> col2;
+
+ swapColumns((double*)mat, ROWS, COLS, col1, col2);
+
+ for (unsigned int row = 0; row < ROWS; row++) {
+ for (unsigned int col = 0; col < COLS; col++)
+ std::cout << mat[row][col] << ' ';
+ std::cout << std::endl;
+ }
+
+ return 0;
+}
diff --git a/Week08/Exercise07.cpp b/Week08/Exercise07.cpp
new file mode 100644
index 0000000..470b53e
--- /dev/null
+++ b/Week08/Exercise07.cpp
@@ -0,0 +1,45 @@
+#include <iostream>
+
+const unsigned int SIZE_PAT = 3;
+
+bool matchesPattern(const char pattern[SIZE_PAT][SIZE_PAT], const char* input, unsigned int inputRows, unsigned int inputCols) {
+ for (unsigned int i = 0; i < SIZE_PAT; i++) {
+ for (unsigned int j = 0; j < SIZE_PAT; j++) {
+ /* За повече информация защо така индексираме в input, вижте
+ * https://syndamia.com/teaching/upp-2025/cpp-pitfalls/#-int73-vs-int3-vs-int
+ */
+ if (pattern[i][j] != '*' && pattern[i][j] != input[i * inputRows + j])
+ return false;
+ }
+ }
+ return true;
+}
+
+int main() {
+ char pattern[SIZE_PAT][SIZE_PAT];
+
+ for (unsigned int i = 0; i < SIZE_PAT; i++)
+ for (unsigned int j = 0; j < SIZE_PAT; j++)
+ std::cin >> pattern[i][j];
+
+ const unsigned int SIZE = 6;
+ char inp[SIZE][SIZE];
+
+ for (unsigned int i = 0; i < SIZE; i++)
+ for (unsigned int j = 0; j < SIZE; j++)
+ std::cin >> inp[i][j];
+
+ unsigned int matches = 0;
+ for (unsigned int i = 0; i <= SIZE - SIZE_PAT; i++) {
+ for (unsigned int j = 0; j <= SIZE - SIZE_PAT; j++) {
+ /* За повече информация защо подаваме такива стойности на функцията,
+ * вижте решението на 3та задача.
+ */
+ matches += matchesPattern(pattern, (const char*)inp + i * SIZE + j, SIZE, SIZE);
+ }
+ }
+
+ std::cout << matches << std::endl;
+
+ return 0;
+}
diff --git a/Week08/Exercise08.cpp b/Week08/Exercise08.cpp
new file mode 100644
index 0000000..1baef7c
--- /dev/null
+++ b/Week08/Exercise08.cpp
@@ -0,0 +1,39 @@
+#include <iostream>
+
+const unsigned int SIZE = 3;
+
+void inputMatrix(unsigned int mat[SIZE][SIZE]) {
+ for (unsigned int i = 0; i < SIZE; i++)
+ for (unsigned int j = 0; j < SIZE; j++)
+ std::cin >> mat[i][j];
+}
+
+unsigned int multiplyRowCol(const unsigned int matA[SIZE][SIZE], const unsigned int matB[SIZE][SIZE], unsigned int rowA, unsigned int colB) {
+ unsigned int result = 0;
+ for (unsigned int i = 0; i < SIZE; i++)
+ result += matA[rowA][i] * matB[i][colB];
+ return result;
+}
+
+void multiplyMatrices(const unsigned int matA[SIZE][SIZE], const unsigned int matB[SIZE][SIZE], unsigned int out[SIZE][SIZE]) {
+ for (unsigned int row = 0; row < SIZE; row++)
+ for (unsigned int col = 0; col < SIZE; col++)
+ out[row][col] = multiplyRowCol(matA, matB, row, col);
+}
+
+int main() {
+ unsigned int matA[SIZE][SIZE], matB[SIZE][SIZE];
+ inputMatrix(matA);
+ inputMatrix(matB);
+
+ unsigned int mult[SIZE][SIZE];
+ multiplyMatrices(matA, matB, mult);
+
+ for (unsigned int row = 0; row < SIZE; row++) {
+ for (unsigned int col = 0; col < SIZE; col++)
+ std::cout << mult[row][col] << ' ';
+ std::cout << std::endl;
+ }
+
+ return 0;
+}
diff --git a/Week08/Exercise09.cpp b/Week08/Exercise09.cpp
new file mode 100644
index 0000000..4753903
--- /dev/null
+++ b/Week08/Exercise09.cpp
@@ -0,0 +1,36 @@
+#include <iostream>
+
+int main() {
+ const unsigned int ROWS = 4, COLS = 3;
+ char keypad[ROWS][COLS] = {
+ '1', '2', '3',
+ '4', '5', '6',
+ '7', '8', '9',
+ '*', '0', '#',
+ };
+
+ bool rowOn[ROWS];
+ for (unsigned int i = 0; i < ROWS; i++)
+ std::cin >> rowOn[i];
+
+ bool colOn[COLS];
+ for (unsigned int i = 0; i < COLS; i++)
+ std::cin >> colOn[i];
+
+ bool somethingPressed = false;
+ for (unsigned int row = 0; row < ROWS; row++) {
+ for (unsigned int col = 0; col < COLS; col++) {
+ if (rowOn[row] && colOn[col]) {
+ std::cout << keypad[row][col] << ' ';
+ somethingPressed = true;
+ }
+ }
+ }
+
+ if (!somethingPressed)
+ std::cout << "Nothing pressed";
+
+ std::cout << std::endl;
+
+ return 0;
+}
diff --git a/Week08/Exercise10.cpp b/Week08/Exercise10.cpp
new file mode 100644
index 0000000..024d4c8
--- /dev/null
+++ b/Week08/Exercise10.cpp
@@ -0,0 +1,23 @@
+#include <iostream>
+
+int main() {
+ const unsigned int SIZE = 11;
+ unsigned int pascal[SIZE][SIZE] = { 0 };
+
+ for (unsigned int i = 0; i < SIZE; i++)
+ pascal[i][0] = pascal[i][i] = 1;
+
+ for (unsigned int row = 2; row < SIZE; row++)
+ for (unsigned int col = 1; col < row; col++)
+ /* Елемента над и в ляво на текущия, сумирано с елемента над текущия.
+ */
+ pascal[row][col] = pascal[row - 1][col - 1] + pascal[row - 1][col];
+
+ for (unsigned int row = 0; row < SIZE; row++) {
+ for (unsigned int col = 0; col < SIZE; col++)
+ std::cout << pascal[row][col] << ' ';
+ std::cout << std::endl;
+ }
+
+ return 0;
+}
diff --git a/Week08/Exercise11.cpp b/Week08/Exercise11.cpp
new file mode 100644
index 0000000..a2922bb
--- /dev/null
+++ b/Week08/Exercise11.cpp
@@ -0,0 +1,65 @@
+#include <iostream>
+
+/* В това решение използваме int за размери, вместо unsigned int, защото
+ * правим изваждания, които се обработват по-лесно като можеш да имаш отрицателни числа.
+ * Може да се преработи с unsigned int (и окуражавам да го направите), но кода става
+ * по-досаден и грозен.
+ */
+const int SIZE = 10;
+
+int clamp(int value, int min, int max) {
+ if (value < min) return min;
+ if (value > max) return max;
+ return value;
+}
+
+void sumCells(const unsigned int mat[SIZE][SIZE],
+ int startRow, int endRow,
+ int startCol, int endCol,
+ unsigned int &sum, unsigned int &count)
+{
+ startRow = clamp(startRow, 0, SIZE - 1);
+ endRow = clamp(endRow, 0, SIZE - 1);
+ startCol = clamp(startCol, 0, SIZE - 1);
+ endCol = clamp(endCol, 0, SIZE - 1);
+
+ for (int row = startRow; row <= endRow; row++) {
+ for (int col = startCol; col <= endCol; col++) {
+ sum += mat[row][col];
+ count++;
+ }
+ }
+}
+
+double averageCells(const unsigned int mat[SIZE][SIZE], int row, int col, unsigned int radius) {
+ unsigned int sum = 0, sumCount = 0;
+
+ sumCells(mat, row - radius, row + radius, col - radius, col + radius, sum, sumCount);
+
+ return (double)sum / sumCount;
+}
+
+int main() {
+ unsigned int mat[SIZE][SIZE];
+
+ for (int i = 0; i < SIZE; i++)
+ for (int j = 0; j < SIZE; j++)
+ std::cin >> mat[i][j];
+
+ unsigned int radius;
+ std::cin >> radius;
+
+ double blurred[SIZE][SIZE] = { 0 };
+
+ for (int i = 0; i < SIZE; i++)
+ for (int j = 0; j < SIZE; j++)
+ blurred[i][j] = averageCells(mat, i, j, radius);
+
+ for (int i = 0; i < SIZE; i++) {
+ for (int j = 0; j < SIZE; j++)
+ std::cout << blurred[i][j] << ' ';
+ std::cout << std::endl;
+ }
+
+ return 0;
+}
diff --git a/Week08/Exercise12.cpp b/Week08/Exercise12.cpp
new file mode 100644
index 0000000..acdc848
--- /dev/null
+++ b/Week08/Exercise12.cpp
@@ -0,0 +1,53 @@
+#include <iostream>
+
+const unsigned int SIZE = 10;
+const double STEP = 0.001;
+
+void swap(double& a, double& b) {
+ double temp = a;
+ a = b;
+ b = temp;
+}
+
+void fill(char mat[SIZE][SIZE], char filler) {
+ for (unsigned int i = 0; i < SIZE; i++)
+ for (unsigned int j = 0; j < SIZE; j++)
+ mat[i][j] = filler;
+}
+
+int main() {
+ double startX, startY, endX, endY;
+ std::cin >> startX >> startY >> endX >> endY;
+
+ char mat[SIZE][SIZE];
+ fill(mat, ' ');
+
+ /* Преместваме началната точка към крайната точка, следвайки отсечката.
+ * Все едно една мравка е започнала в началната точка и се движи върху правата,
+ * докато стигне крайната точка.
+ *
+ * Разменяме двете точки, защото правим изчислението все едно началната точка е
+ * в ляво от крайната.
+ */
+
+ if (startX > endX) {
+ swap(startX, endX);
+ swap(startY, endY);
+ }
+
+ double dx = (endX - startX) * STEP, dy = (endY - startY) * STEP;
+
+ while (startX < endX) {
+ mat[(int)startY][(int)startX] = 'x';
+ startX += dx;
+ startY += dy;
+ }
+
+ for (int i = 0; i < SIZE; i++) {
+ for (int j = 0; j < SIZE; j++)
+ std::cout << mat[i][j];
+ std::cout << std::endl;
+ }
+
+ return 0;
+}
diff --git a/Week08/Exercise13.cpp b/Week08/Exercise13.cpp
new file mode 100644
index 0000000..71b530c
--- /dev/null
+++ b/Week08/Exercise13.cpp
@@ -0,0 +1,31 @@
+#include <iostream>
+
+int main() {
+ const unsigned int SIZE = 8;
+ char mat[SIZE][SIZE];
+
+ for (unsigned int i = 0; i < SIZE; i++)
+ for (unsigned int j = 0; j < SIZE; j++)
+ std::cin >> mat[i][j];
+
+ int minRow = SIZE, maxRow = 0, minCol = SIZE, maxCol = 0;
+ for (unsigned int i = 0; i < SIZE; i++) {
+ for (unsigned int j = 0; j < SIZE; j++) {
+ if (mat[i][j] == '+') {
+ if (i < minCol) minCol = i;
+ if (i > maxCol) maxCol = i;
+ if (j < minRow) minRow = j;
+ if (j > maxRow) maxRow = j;
+ }
+ }
+ }
+
+ if (minRow == SIZE) {
+ minRow = 1;
+ minCol = 1;
+ }
+
+ std::cout << (maxCol - minCol + 1) << ' ' << (maxRow - minRow + 1) << std::endl;
+
+ return 0;
+}
diff --git a/Week08/Exercise14.cpp b/Week08/Exercise14.cpp
new file mode 100644
index 0000000..c224948
--- /dev/null
+++ b/Week08/Exercise14.cpp
@@ -0,0 +1,25 @@
+#include <iostream>
+
+int main() {
+ const unsigned int ROWS = 6, COLS = 3;
+
+ double vec[ROWS];
+ for (unsigned int i = 0; i < ROWS; i++)
+ std::cin >> vec[i];
+
+ double mat[ROWS][COLS];
+ for (unsigned int i = 0; i < ROWS; i++)
+ for (unsigned int j = 0; j < COLS; j++)
+ std::cin >> mat[i][j];
+
+ double mult[COLS] = { 0.0 };
+ for (unsigned int col = 0; col < COLS; col++)
+ for (unsigned int row = 0; row < ROWS; row++)
+ mult[col] += vec[row] * mat[row][col];
+
+ for (unsigned int i = 0; i < COLS; i++)
+ std::cout << mult[i] << ' ';
+ std::cout << std::endl;
+
+ return 0;
+}
diff --git a/Week08/Exercise15.cpp b/Week08/Exercise15.cpp
new file mode 100644
index 0000000..fba54ff
--- /dev/null
+++ b/Week08/Exercise15.cpp
@@ -0,0 +1,48 @@
+#include <iostream>
+
+const int ROWS = 9, COLS = 7;
+
+int max(int a, int b) {
+ return a > b ? a : b;
+}
+
+int min(int a, int b) {
+ return a < b ? a : b;
+}
+
+double abs(double x) {
+ return x < 0 ? -x : x;
+}
+
+bool checkSurroundingCells(const double mat[ROWS][COLS], int row, int col, double maxDiff)
+{
+ for (int r = max(0, row - 1); r <= min(ROWS - 1, row + 1); r++) {
+ for (int c = max(0, col - 1); c <= min(COLS - 1, col + 1); c++) {
+ if (abs(mat[r][c] - mat[row][col]) >= maxDiff)
+ return false;
+ }
+ }
+ return true;
+}
+
+int main() {
+ double mat[ROWS][COLS];
+ for (int i = 0; i < ROWS; i++)
+ for (int j = 0; j < COLS; j++)
+ std::cin >> mat[i][j];
+
+ double maxDiff;
+ std::cin >> maxDiff;
+
+ bool smooth = true;
+ for (int i = 0; i < ROWS && smooth; i++)
+ for (int j = 0; j < COLS && smooth; j++)
+ smooth = checkSurroundingCells(mat, i, j, maxDiff);
+
+ if (smooth)
+ std::cout << "Smooth" << std::endl;
+ else
+ std::cout << "Not smooth" << std::endl;
+
+ return 0;
+}
diff --git a/Week08/README.md b/Week08/README.md
new file mode 100644
index 0000000..c3816ec
--- /dev/null
+++ b/Week08/README.md
@@ -0,0 +1,3 @@
+# Задачи
+
+<https://syndamia.com/teaching/upp-2025/week08/>