Summary Files Commits Branches @commit @diff @stats
path: root / src / teaching
diff options
context:
space:
mode:
Commit010597ad71b3bc48784cb9a13b3e0fc8dccc69cd (patch)
Author
 Kamen Mladenov <kamen@syndamia.com>
2024-10-06 07:59:36 +0000
Committer
 Kamen Mladenov <kamen@syndamia.com>
2024-10-06 07:59:36 +0000
Files784604f5818679987f940285077cd8e0460a6488 /src/teaching
syndamia.com-010597ad71b3bc48784cb9a13b3e0fc8dccc69cd.tar
syndamia.com-010597ad71b3bc48784cb9a13b3e0fc8dccc69cd.tar.gz
syndamia.com-010597ad71b3bc48784cb9a13b3e0fc8dccc69cd.zip
Parent6fe00c6ec76028fc055084a3398004fbbefac0be (diff)
Parentc027ddea2e1d6ed69a012edf47d3b39e25b6c9d5 (diff)
Merge branch 'master' into 'blog/black-hole-shader'
# Conflicts: # src/blog/index.md
39 files changed, 3521 insertions, 305 deletions
-rw-r--r--src/teaching/index.md5
-rw-r--r--src/teaching/oop-2023/index.md32
-rw-r--r--src/teaching/oop-2023/week1/good-software.md519
-rw-r--r--src/teaching/oop-2023/week1/index.md111
-rw-r--r--src/teaching/oop-2023/week1/organization.md61
-rw-r--r--src/teaching/oop-2023/week10/index.md146
-rw-r--r--src/teaching/oop-2023/week11/index.md201
-rw-r--r--src/teaching/oop-2023/week12/index.md94
-rw-r--r--src/teaching/oop-2023/week13/index.md138
-rw-r--r--src/teaching/oop-2023/week14/index.md73
-rw-r--r--src/teaching/oop-2023/week15/index.md37
-rw-r--r--src/teaching/oop-2023/week16/index.md30
-rw-r--r--src/teaching/oop-2023/week2/index.md194
-rw-r--r--src/teaching/oop-2023/week3/index.md175
-rw-r--r--src/teaching/oop-2023/week4/img/Rotation_matrix.pngbin0 -> 12305 bytes
-rw-r--r--src/teaching/oop-2023/week4/index.md110
-rw-r--r--src/teaching/oop-2023/week5/index.md116
-rw-r--r--src/teaching/oop-2023/week6/index.md102
-rw-r--r--src/teaching/oop-2023/week7/index.md83
-rw-r--r--src/teaching/oop-2023/week8/index.md167
-rw-r--r--src/teaching/oop-2023/week9/index.md112
-rw-r--r--src/teaching/upp-2023/additional1/index.md28
-rw-r--r--src/teaching/upp-2023/additional2/index.md16
-rw-r--r--src/teaching/upp-2023/index.md11
-rw-r--r--src/teaching/upp-2023/week1/setup.md175
-rw-r--r--src/teaching/upp-2023/week1/welcome.md180
-rw-r--r--src/teaching/upp-2023/week10/img/fib.pngbin0 -> 6292 bytes
-rw-r--r--src/teaching/upp-2023/week10/index.md90
-rw-r--r--src/teaching/upp-2023/week11/index.md127
-rw-r--r--src/teaching/upp-2023/week12/index.md109
-rw-r--r--src/teaching/upp-2023/week13/index.md145
-rw-r--r--src/teaching/upp-2023/week14/index.md239
-rw-r--r--src/teaching/upp-2023/week2/revision.md74
-rw-r--r--src/teaching/upp-2023/week3/revision.md80
-rw-r--r--src/teaching/upp-2023/week4/revision.md30
-rw-r--r--src/teaching/upp-2023/week6/index.md2
-rw-r--r--src/teaching/upp-2023/week7/index.md6
-rw-r--r--src/teaching/upp-2023/week8/index.md4
-rw-r--r--src/teaching/upp-2023/week9/index.md4
diff --git a/src/teaching/index.md b/src/teaching/index.md
index 29bad9b..c36de4d 100644
--- a/src/teaching/index.md
+++ b/src/teaching/index.md
@@ -4,5 +4,8 @@ This is a list of all the subjects I've taught professionally.
<br>
-&&bg 2023-2024 &emsp; [3107 Увод в програмирането - практикум, КН, 8 група](/teaching/upp-2023)
+&.bg 2023-2024 &emsp; [З520 Обектно-ориентрано програмиране - практикум, КН, 8 група](/teaching/oop-2023)
+: Хоноруван преподавател във [ФМИ](https://www.fmi.uni-sofia.bg/) на специалност [Компютърни науки](https://www.fmi.uni-sofia.bg/bg/kompyutrni-nauki)
+
+&.bg 2023-2024 &emsp; [3107 Увод в програмирането - практикум, КН, 8 група](/teaching/upp-2023)
: Хоноруван преподавател във [ФМИ](https://www.fmi.uni-sofia.bg/) на специалност [Компютърни науки](https://www.fmi.uni-sofia.bg/bg/kompyutrni-nauki)
diff --git a/src/teaching/oop-2023/index.md b/src/teaching/oop-2023/index.md
new file mode 100644
index 0000000..63acb0f
--- /dev/null
+++ b/src/teaching/oop-2023/index.md
@@ -0,0 +1,32 @@
+# Обектно-ориентирано програмиране - практикум, Компютърни науки, 8 група
+
+Материали на проведените през 2023/2024 практикуми по Обектно-ориентирано програмиране на Компютърни науки (2 поток), 8 група.
+
+**Зала:** ФМИ 120 ||
+**Време:** 13:15 - 15:00 ||
+**Ден:** Четвъртък
+<br>
+**Директни връзки:**
+[Контакт с мен](../upp-2023/week1/welcome.html?a#section-4) |
+[Решения на задачи](https://github.com/Syndamia/oop-2023-solutions) |
+[Материали от семинари](https://github.com/Aleksis99/Object-Oriented-Programming_FMI_2023-2024) |
+[Курс в мудъл](https://learn.fmi.uni-sofia.bg/course/view.php?id=10041)
+
+|&#8470;|Дата|Материали|
+|-------|----|---------|
+|1 |22.02.2024|[Организационно](./week1/organization.html?a) \|\| [Основни добри софтуерни практики](./week1/good-software.html?a) \|\| [Задачи](./week1/) \|\| [Решения](https://github.com/Syndamia/oop-2023-solutions/tree/main/week01) \|\| [GitHub classroom](https://classroom.github.com/a/UPJOzHty)|
+|2 |29.02.2024|[Задачи](./week2/) \|\| [Решения](https://github.com/Syndamia/oop-2023-solutions/tree/main/week02) \|\| [GitHub classroom](https://classroom.github.com/a/3qPsfyyI)|
+|3 |07.03.2024|[Задачи](./week3/) \|\| [Решения](https://github.com/Syndamia/oop-2023-solutions/tree/main/week03) \|\| [GitHub classroom](https://classroom.github.com/a/KPMqXsFp)|
+|4 |14.03.2024|[Задачи](./week4/) \|\| [Решения](https://github.com/Syndamia/oop-2023-solutions/tree/main/week04) \|\| [GitHub classroom](https://classroom.github.com/a/qa_FfWeG)|
+|5 |21.03.2024|[Задачи](./week5/) \|\| [Решения](https://github.com/Syndamia/oop-2023-solutions/tree/main/week05) \|\| [GitHub classroom](https://classroom.github.com/a/42ZZ56Mg)|
+|6 |28.03.2024|[Задачи](./week6/) \|\| [Решения](https://github.com/Syndamia/oop-2023-solutions/tree/main/week06) \|\| [GitHub classroom](https://classroom.github.com/a/rzSTn5pu)|
+|7 |04.04.2024|[Задачи](./week7/) \|\| [Решения](https://github.com/Syndamia/oop-2023-solutions/tree/main/week07) \|\| [GitHub classroom](https://classroom.github.com/a/vvZENbkX)|
+|8 |11.04.2024|[Задачи](./week8/) \|\| [Решения](https://github.com/Syndamia/oop-2023-solutions/tree/main/week08) \|\| [GitHub classroom](https://classroom.github.com/a/7d0MBjcK)|
+|9 |18.04.2024|[Задачи](./week9/) \|\| [Решения](https://github.com/Syndamia/oop-2023-solutions/tree/main/week09) \|\| [GitHub classroom](https://classroom.github.com/a/wlL1oUg2)|
+|10|25.04.2024|[Задачи](./week10/) \|\| [Решения](https://github.com/Syndamia/oop-2023-solutions/tree/main/week10) \|\| [GitHub classroom](https://classroom.github.com/a/PbkITWhF)|
+|11|09.05.2024|[Задачи](./week11/) \|\| [Решения](https://github.com/Syndamia/oop-2023-solutions/tree/main/week11) \|\| [GitHub classroom](https://classroom.github.com/a/oYQehcnN) **Това упражнение е от 11:15 до 13:15**|
+|12|09.05.2024|[Задачи](./week12/) \|\| [Решения](https://github.com/Syndamia/oop-2023-solutions/tree/main/week12) \|\| [GitHub classroom](https://classroom.github.com/a/o7hNz1pr)|
+|13|16.05.2024|[Задачи](./week13/) \|\| [Решения](https://github.com/Syndamia/oop-2023-solutions/tree/main/week13) \|\| [GitHub classroom](https://classroom.github.com/a/GvV1wrC1)|
+|14|23.05.2024|[Задачи](./week14/) <!-- \|\| [Решения](https://github.com/Syndamia/oop-2023-solutions/tree/main/week12) --> \|\| [GitHub classroom](https://classroom.github.com/a/K0XomKEP)|
+|15|30.05.2024|[Задачи](./week15/) <!-- \|\| [Решения](https://github.com/Syndamia/oop-2023-solutions/tree/main/week12) --> \|\| [GitHub classroom](https://classroom.github.com/a/z2QadyEE) **Това упражнение е от 11:15 до 13:15**|
+|16|06.06.2024|[Задачи](./week16/) <!-- \|\| [Решения](https://github.com/Syndamia/oop-2023-solutions/tree/main/week12) --> \|\| [GitHub classroom](https://classroom.github.com/a/BWjw2dUC)|
diff --git a/src/teaching/oop-2023/week1/good-software.md b/src/teaching/oop-2023/week1/good-software.md
new file mode 100644
index 0000000..79a51b0
--- /dev/null
+++ b/src/teaching/oop-2023/week1/good-software.md
@@ -0,0 +1,519 @@
+# Основни добри софтуерни практики - ООП, Седмица 1, 22.02.2024
+
+Миналия семестър не ни стигна времето да обсъдим домашното по-сериозно.
+Главния проблем, който забелязах, беше колко грозно и нагласено бяха написани решенията.
+Като въведение в ООП, ще поговорим по тази тема.
+
+&.presentation
+
+&[title
+
+# Основни идеи<br>при добро писане на код
+
+&]
+
+
+
+&[slide35
+
+## Какво прави програмиста с чужд код?
+
+&.br4
+
+1. Чете
+2. Разучава как се ползва/какво прави
+3. Използва го/Модифицира го
+
+Добър код прави тези задачи лесни!
+
+&]
+
+
+
+&[slide35
+
+## Подобряване на четене
+
+&.br4
+
+- Лично вярвам, че четимост е по-важна от конвенции
+- Човек вижда най-лесно "контрастни" шаблони
+
+
+```
+ . . 0.00.0 010010 815213
+ 000000 000000 738438
+. . .0000. 100001 122481
+ .... 0....0 011110 511119
+```
+
+&]
+
+
+
+Както виждате, в примера има усмихнато личице, "закодирано" по различни начини.
+С точка и шпации е най-ясно, като заменим шпациите с нули става по-неясно, като заменим точките с единици става още повече и като заменим нулите със случайни не-единични цифри, става пък съвсем невидимо.
+Важното е шаблона да се намира в среда на други шаблони, иначе трудно се забелязва.
+
+При код, ще илюстрирам идеята си с един пример, но няма да задълбавам, следващата секция е много по-важна.
+Пък и тази тема е малко религиозна и ще чувате различни мнения според човека който питате.
+
+
+
+&[middle
+
+Труден за четене код *(забелязвате ли грешките?)*:
+
+&(font22
+
+```
+int a, b;
+std::cout << "Enter coordinates" << std::endl;
+std::cin >> a;
+if (a == -1) return layerNavigation(board, rows, cols, layers);
+if (a < 0 || a >= rows || b < 0 || a >= cols) return false;
+for (int i = 0; i < layers; i++) {
+if (board[a][b][i] == ' ') {
+ for (int j = 0; j < 8; j++){
+ if (enptyRow[j] != ' ') {
+ emptyRow[j] = board[a][b][i];
+ board[a][b][i] = ' ';
+ return true;
+ }
+ }
+ return false;
+}
+}
+```
+
+&) &]
+
+
+
+Нарочно съм премахнал оцветяването, то драстично помага, но тук повече се интересуваме от "формата" на код.
+
+Вмъкнал съм три грешки: едно нещо липсва, има една печатна и една логическа грешка.
+Разбира се, ако се зачетете дума по дума сигурно ще ги откриете, но сега да сравним.
+
+
+
+&[middle
+
+По-лесен за четене код *(а сега виждат ли се по-лесно?)*:
+
+&(font18
+
+```
+std::cout << "Enter coordinates" << std::endl;
+int a, b;
+
+std::cin >> a;
+if (a == -1) {
+ return layerNavigation(board, rows, cols, layers);
+}
+
+if (a < 0 || a >= rows || b < 0 || a >= cols) {
+ return false;
+}
+
+for (int i = 0; i < layers; i++)
+{
+ if (board[a][b][i] == ' ')
+ {
+ for (int j = 0; j < 8; j++)
+ {
+ if (enptyRow[j] != ' ') {
+ emptyRow[j] = board[a][b][i];
+ board[a][b][i] = ' ';
+
+ return true;
+ }
+ }
+ return false;
+ }
+}
+```
+
+&) &]
+
+
+
+Би трябвало да е малко по-лесно, в последния `if` имаме "e**n**ptyRow", което е печатната грешка, `!=` което трябва да бъде `==` и липсва въвеждането на `b` след първия `if`.
+
+Примерът не е перфектен, но илюстрира какво се опитвам да кажа: формата на код е от огромно значение, обръщайте ѝ внимание.
+
+
+
+&[slide
+
+## Абстракцията - улеснява изучаване И употреба/модификация
+
+&.br1
+
+- Разделяме обработване на стойностите от директната имплементацията
+- Създаваме нови "машинни инструкции"
+
+&.br1
+
+- `doX()` е по-лошо от `do(X)`
+ - можем да преизползваме `do()` за неща, различни от `X`
+ - един път разбрано, всяка употреба на `do()` също е разбрана; този стил кара `do()` да бъде по-обща функция, което я прави по-лесна за разбиране
+ - модификация на `do(X)` се свежда до заменяне на `do()` с `doOther()` или до заменяне на `X` с `Y`; променяме "инструкцията" или променяме данната
+
+&]
+
+
+
+Нека сега разгледаме няколко примера, първият е много груб и елементарен, но служи за добро начало:
+
+
+
+&[middle
+
+
+```cpp
+Лошо - doX() │ Добро - do(X)
+ │
+int fib5() │ int fib(int n)
+{ │ {
+ int prev = 0, curr = 1; │ int prev = 0, curr = 1;
+ for (int i = 1; i < 5; i++) │ for (int i = 1; i < n; i++)
+ { │ {
+ int tempPrev = prev; │ int tempPrev = prev;
+ prev = curr; │ prev = curr;
+ curr = curr + prev; │ curr = curr + prev;
+ } │ }
+ return curr; │ return curr;
+} │ }
+```
+
+&]
+
+
+
+Би трябвало да е супер очевидно, никой няма да пише отделна функция на Фибоначи за всяко число.
+
+Нека сега да разгледаме няколко "реални" примера, свързани с домашното (за припомняне, условието се намира [тук](https://learn.fmi.uni-sofia.bg/mod/assign/view.php?id=296069)).
+Самите решения няма винаги да са добре форматирани, това е направено с цел да се поберат добре в слайда.
+
+Първия е върху функция, която приема координатите на плочка, премахва я от дъската (ако съществува) и я слага в края на празния ред.
+
+
+
+&[slide
+
+Лошо - `doX()` в тялото на функцията
+
+```cpp
+void tryTakeTile(char** board, int rows, int cols,
+ char emptyRow[8]) {
+ int x, y;
+ std::cin >> x >> y;
+ if (x<0 || x>=rows || y<0 || y>=cols || board[x][y] == ' ') {
+ std::cout << "Invalid coordinates!" << std::endl;
+ }
+ else {
+ int emptyRowIndex = -1;
+ for (int i = 0; i < 8; i++) {
+ if (emptyRow[i] == ' ') {
+ emptyRowIndex = i;
+ break;
+ }
+ }
+ emptyRow[emptyRowIndex] = board[x][y];
+ board[x][y] = ' ';
+ }
+}
+```
+
+&]
+
+
+
+Повечето предадени работи са имплементирали функционалността по точно този начин.
+Замислете се обаче, какво става ако сменим типа данна, тоест ако дъската е триизмерна?
+Тогава трябва да добавим още една `int` променлива, още едно условие в `if`, трябва да я добавим при трите индексирания на `board`.
+
+Какво става ако променим самата структура от данни за `emptyRow` (за сега сте учили само масиви, но скоро ще видите, че има и други начини да съхраняваш редица информация), тогава ще трябва да пренапишем целия цикъл.
+
+Тоест, ако променим нещо, трябва да пренапишем значителни части от самия код, и като разширим това върху 10-20 функции, изведнъж малка промяна става голяма.
+Нека сега да пренапишем функцията, използвайки колкото се може повече абстракция.
+
+
+&[middle
+
+Добро - `do(X)`
+
+```cpp
+bool tryReadCoordinates(int& x, int& y) {
+ std::cin >> x >> y;
+ if (!availablePosition(board, rows, cols, x, y)) {
+ std::cout << "Invalid coordinates!" << std::endl;
+ return false;
+ }
+ return true;
+}
+
+void tryTakeTile(char** board, int rows, int cols,
+ char emptyRow[8]) {
+ int x, y;
+ if (tryReadCoordinates(x, y)) {
+ appendToArray(emptyRow, 8, board[x][y]);
+ board[x][y] = ' ';
+ }
+}
+```
+
+&]
+
+
+
+Искаме трето измерение на `board`?
+Няма проблем, написали сме нова `tryReadCoordinates`, която приема три променливи, и в `tryTakeTile` добавяме една декларация и обновяваме двете индексирания на `board`.
+Ако `emptyRow` стане друг тип данна, просто променяме функцията да бъде `appendToOtherDataType` и сме готови.
+
+И ако тази промяна трябва да се направи в много функции, даже бихме могли да употребяваме функционалност на самия текстов редактор да търси и заменя срещания на един низ с друг.
+
+Нека сега да увеличим сложността още малко, да разгледаме функция за генерирането на дъската.
+Отново, повечето предадени решения изглеждаха подобни на примера.
+
+
+
+&[slide
+
+Лошо - всички цикли са `doX()`
+
+```cpp
+void generateLayer(char** layer, int rows, int cols,
+ char* tiles, int* tileCounts, int tilesSize) {
+ for (int i = 0; i < rows; i++) {
+ for (int j = 0; j < cols; j++) {
+ layer[i][j] = ' ';
+ }
+ }
+ for (int i = 0; i < tilesSize; i++) {
+ for (int j = 0; j < tileCounts[i]; j++) {
+ int x, y;
+ do { // randNum(x,y) връща случайно число∈[x,y]
+ x = randNum(0, rows - 1);
+ y = randNum(0, cols - 1);
+ } while(layer[x][y] != ' ');
+ layer[x][y] = tileCounts[i];
+ }
+ }
+}
+```
+
+&]
+
+
+
+Стария проблем, някакви цикли, ако искаме да променям някоя данна или как нещо работи, трябва да пренапишем половината функция.
+
+Този сегмент е по-интересен за променяне от преди, понеже за да го направим хубаво трябва да променим самата ни логика.
+Запълването със шпации е ясно, обаче случайното поставяне на плочки не е.
+
+Ако имаме функция `placeRandomЕлемент` която само поставя една плочка в слоя, пак ще имаме вложени цикли, трябва да има начин да останем с един цикъл.
+Ако направим `placeRandomElementNTimes`, тогава пък абстрахираната функция става твърде специфична и вече имаме `doX()` при самата нея.
+
+Чрез функционално програмиране този проблем може да се разреши лесно, обаче вие ще го учите следващия семестър.
+С достатъчно размишления, може да стигнем до следния вариант: вместо всяка плочка да я поставяме на случайна позиция, защо не поставим всички плочки една след друга и не разбъркаме слоя?
+
+
+
+&[middle
+
+Добро - `do(X)`
+
+```cpp
+void generateLayer(char** layer, int rows, int cols,
+ char* tiles, int* tileCounts, int tilesSize) {
+ fillMatrix(layer, rows, cols, '\0');
+ for (int i = 0; i < tilesSize; i++) {
+ // appendToMatrix(mat,rows,cols,fill,max):
+ // замества първите (най-много) max празни клетки с fill
+ // връща колко клетки наистина е заместило
+ appendToMatrix(layer, rows, cols,
+ tiles[i], tileCounts[i]);
+ }
+ shuffleMatrix(layer, rows, cols);
+}
+```
+
+**Бонус:** работи по-коректно от преди
+
+&]
+
+
+
+В предходния вариант, ако примерно цялата е пълна освен една клетка, и трябва да поставим една финална плочка, тогава трябва да чакаме докато случайните стойности се напаснат точно с координатите на тази една клетка.
+Това може да се случи след половин секунда, но може да отнеме и един час докато се случи.
+Даже, този проблем става все по-тегав с времето: с всяка запълнена клетка, шанса случайните стойности да ударят на заети координати се увеличава.
+
+Докато тук, нямаме този проблем, отнема някакво консистентно предопределено време да разбъркаме матрицата.
+Как имплементираме `shuffleMatrix` си има и своите тънкости, но най-елементарния начин е просто да направим сортираш алгоритъм, при който вместо да сравним две стойности, използваме случайна стойност, която определя дали ще разменим плочките.
+
+Друго хубаво нещо на решения с абстракция, е един лек лавинен ефект, където веднъж като почнем да мислим за абстракции, намираме къде да ги ползваме навсякъде.
+Да разгледаме същата функция, обаче при D подточка.
+
+
+
+&[middle
+
+Решения със слоеве правят същото. Лошо - `doX()` при циклите:
+
+```cpp
+void generate(char*** board, int rows, int cols, int layers,
+ char* tiles, int* tileCounts, int tilesSize) {
+ ...
+ do {
+ x = randNum(0, rows - 1); y = randNum(0, cols - 1);
+ layer = randNum(0, layers - 1);
+ } while(layer[x][y][layer] != ' ');
+ ...
+}
+```
+
+&]
+
+
+
+Без абстракция отново ще пренапишем голяма част от `generate` функцията, за да се побере на слайда съм оставил само "най-сложната" промяна - случайните стойности.
+Пак, имаше решения на подточката, без преизползване на `generate` за един слой.
+Айде да разгледаме решението, заедно с абстрахираната `generate`.
+
+
+
+&[slide
+
+Добро - `do(X)`
+
+```cpp
+void generateLayer(char** layer, int rows, int cols,
+ char* tiles, int* tileCounts, int tilesSize) {
+ fillMatrix(layer, rows, cols, '\0');
+ for (int i = 0; i < tilesSize; i++) {
+ int actuallyAppended =
+ appendToMatrix(layer, rows, cols,
+ tiles[i], tileCounts[i]);
+ tileCounts[i] -= actuallyAppended;
+ }
+ shuffleMatrix(layer, rows, cols);
+}
+void generate(char*** board, int rows, int cols, int layers,
+ char* tiles, int* tileCounts, int tilesSize) {
+ for (int i = 0; i < layers; i++) {
+ generateLayer(board[i], rows, cols,
+ tiles, tileCounts, tilesSize);
+ }
+}
+```
+
+&]
+
+
+
+Супер елементарно, има-няма 5-6 реда код промяна, при генериране за всеки слой, просто извикваме функцията за генериране върху един слой, за всеки слой.
+А в самата функция само премахваме броя вмъкнати плочки от сумата на даден тип.
+
+Наблюдателните са забелязали, че в "ръчното" решение слоевете са третия индекс, тоест имаме `board[x][y][layer]`, докато в това решение е първия, тоест `board[layer][x][y]`.
+Разликата е значителна, но от гледна точка на код, особено когато използваме абстракция, промяната е лесна.
+
+Иначе, в момента се намираме в много добра позиция, без абстракция как правим рестартирането на играта?
+По условие броя и типовете плочки трябва да се запазят, но позиции не.
+Истината е, че става малко тромаво: цикълът за намираме на позиции се преизползва, и броя плочки трябва да се запази.
+
+Обаче, сега това става с едно `shuffleMatrix`, не е нужно нищо специално да правим!
+
+
+
+&[middle35
+
+### Абстракцията - подобрява и коментари
+
+- Целта на коментарите е да направи разбиране и модификация на код по-лесни.
+- В повечето случаи, коментарът трябва да ни дава *нова* информация или да *свърже* парчета информация
+
+&]
+
+
+
+Да разгледаме следния пример.
+
+
+
+&[middle
+
+Лошо:
+
+```cpp
+// Fill matrix with '\0'
+for (int i = 0; i < rows; i++) {
+ for (int j = 0; j < cols; j++) {
+ matrix[i][j] = '\0';
+ }
+}
+```
+
+Добро:
+
+```cpp
+// Prepare matrix for functionX
+// (for which empty cells are '\0')
+for (int i = 0; i < rows; i++) {
+ for (int j = 0; j < cols; j++) {
+ matrix[i][j] = '\0';
+ }
+}
+```
+
+
+&]
+
+
+
+При добрия вариант, получаваме нова информация, че това запълване се случва понеже ще подаваме към някаква си `functionX`, и че евентуално може да има други функции, при които празни клетки може да не се обозначават с `'\0'`.
+В лошия можем да стигнем до същото заключение като погледнем самия код.
+
+<!--
+<br>
+
+Всичко това е много хубаво, обаче цитирайки Дийкстра, малки изолирани примери не са достатъчни:
+
+
+
+&[middle
+
+> For practical reasons, the demonstration programs must be small, many times smaller than the "life-size programs" I have in mind. My basic problem is that precisely this difference in scale is one of the major sources of our difficulties in programming!
+
+&mdash; Edsger W. Dijkstra, [Notes on Structured Programming, On our inability to do much](https://www.cs.utexas.edu/users/EWD/ewd02xx/EWD249.PDF)
+
+&.br1
+
+Решение на цялото домашно, с описаните методи TODO
+
+&]
+
+
+
+Окуражавам ви да разгледате решенията, да ги сравните с вашите и поне да придобиете някаква интуиция за нещата.
+Така да мислиш не е лесно, отнема време и усилия.
+-->
+
+Умението да разрешиш един проблем *не те* прави добър програмист, да го разрешиш по четим, разширяем, лесен, ефикасен, ... начин *те* прави добър програмист.
+
+
+
+&[slide35
+
+## Изводи
+
+&.br4
+
+- Форматирайте/подравнявайте си кода, искате лесно четене
+- Вдигайте абстракция
+ - Обширни функции > код за конкретни стойности
+ - Преизползване на възможно най-много код
+ - Коментари които дават или разширяват знание
+
+&]
diff --git a/src/teaching/oop-2023/week1/index.md b/src/teaching/oop-2023/week1/index.md
new file mode 100644
index 0000000..df05b2e
--- /dev/null
+++ b/src/teaching/oop-2023/week1/index.md
@@ -0,0 +1,111 @@
+# Задачи - ООП, Седмица 1, 22.02.2024
+
+GitHub classroom: [classroom.github.com/a/UPJOzHty](https://classroom.github.com/a/UPJOzHty)
+
+## Задача 1
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week01/Exercise1.cpp)
+
+Имплементирайте низ чрез структура.
+В структурата трябва да запазвате указател към низа и неговата дължина.
+
+Имплементирайте функция `concatString`, която приема две структури от този тип и връща низ, пак в същата структура, който е конкатенация (слепване) на първите два низа.
+
+&:question Има ли значение дали типовете на аргументите, или на върнатата стойност, са референции или указатели (или нито едното)?
+
+В самия код тествайте функциите (не е нужен потребителски вход).
+
+## Задача 2
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week01/Exercise2.cpp)
+
+Имплементирайте структура за динамично-заделен масив от целочислени числа.
+Тя трябва да запазва указател към масива, размера на масива и бройката на елементи в масива.
+
+Заделянето на динамична памет е бавна операция, затова винаги ще заделяме повече клетки, отколкото са ни нужни.
+
+Имплементирайте функция `resize`, която удвоява размера на масива (нека първоначалния размер на масива е 2), на подадена стойност от тип вашата структура.
+
+Имплементирайте функция `addToEnd`, която приема (инстанция на) структурата ви и вмъква елемент в първата незаета позиция.
+
+В самия код тествайте функциите (не е нужен потребителски вход).
+
+## Задача 3
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week01/Exercise3.cpp)
+
+Разглеждате "пакети" (логове) информация от редица датчици.
+Един пакет запазва времето, когато информацията е била отчетена от датчиците, и стойностите на всички датчици: температура, атмосферно налягане, влажност и надморска височина.
+Всички типове данни са целочислени.
+
+От входа получавате N, броя пакети, които трябва да запазите, и след това 5N на брой целочислени стойности.
+Накрая получавате буква: `t`, `p`, `h`, `e`, всяка съответства на някоя отделна стойност от датчиците.
+
+Трябва да изкарате на екрана всичките стойности от пакетите, подредени в нарастващ ред на времето, като всички след първата са разликите им спрямо първата.
+
+**Пример:**
+
+|Вход|Изход|
+|----|-----|
+|6<br>56 45 64 -8 98<br>14 40 -15 -18 -1<br>22 89 72 62 4<br>85 44 60 17 13<br>75 18 -12 48 21<br>27 10 94 -5 16<br>p|-15 87 109 79 3 75|
+
+## Задача 4
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week01/Exercise4.cpp)
+
+Направете структура за съхранение на полети[^sabre].
+Трябва да запазите имената на началния и крайния град като низове (допускаме, че няма шпации в имената на градовете), часът на излитане и на кацане в целочислен формат (като на циферблат на дигитален часовник, без разделителното двоеточие) и цената на полета в тип с плаваща запетая (в долари).
+
+### а) въвеждане
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week01/Exercise4.cpp#L15-L36)
+
+От входа получавате N, това определя броя полети, които трябва да се добавят в системата.
+Всеки полет е редица от 5 стойности, в реда в който са дефинирани.
+
+*Напомням, че това е нагласено да ползвате `std::cin` вместо ръчно да обработвате целия ред.*
+
+Изкарайте началните и крайните градове, както и цената на полетите, подредени в нарастващ ред на час на излитане.
+
+**Пример:**
+
+|Вход|Изход|
+|----|-----|
+|5<br>Berlin Paris 1105 1255 140<br>Sofia Paris 0915 1115 140<br>Paris NewYork 1225 1610 500<br>Sofia NewYork 0610 1345 800<br>Sofia Berlin 1020 1130 200|Sofia NewYork 800<br>Sofia Paris 140<br>Sofia Berlin 200<br>Berlin Paris 140<br>Paris NewYork 500|
+
+### б) търсене
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week01/Exercise4.cpp#L38-L247)
+
+След като се въведат всички полети, получавате от входа два низа - имена на градове.
+Трябва да изкарате най-евтиния, и след него най-бързия, вариант за пътуване от първия град към втория.
+
+Прикачване между полети е позволено, така че под "вариант" трябва да изкарате всичките полети, които са решение.
+За един полет е нужно да изкарате само началния град, крайния град, час на излитане и цена, като градовете трябва да са подредени в нарастващ ред на часа на излитане.
+
+**Пример:**
+
+|Вход|Изход|
+|----|-----|
+|5<br>Berlin Paris 1105 1255 140<br>Sofia Paris 0915 1115 140<br>Paris NewYork 1225 1610 500<br>Sofia NewYork 0610 1245 800<br>Sofia Berlin 1020 1130 200<br>Sofia NewYork|Cheapest:<br>Sofia Paris 0915 140<br>Paris NewYork 1225 500<br>Quickest:<br>Sofia NewYork 0610 800|
+
+
+## Задача 5
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week01/Exercise5.cpp)
+
+Имате система за потребители, всеки потребител си има име и приятели (един приятел е **указател към потребител**).
+
+В началото се въвежда N, това е броят потребители в системата.
+За един потребител, първо се въвежда на нов ред името му, след това броя на неговите приятели и накрая, на отделни редове, имената на всички тези приятели.
+
+Накрая получавате едно име, това е началния потребител.
+Трябва да намерите, започвайки от него, с колко други потребителя има някаква приятелска връзка (директна, приятел на приятел, приятел на приятел на приятел, ...).
+
+**Пример:**
+
+|Вход|Изход|
+|----|-----|
+|5<br>Георги<br>2<br>Асен Гьонов<br>Майстора<br>Асен Гьонов<br>2<br>Георги<br>др. Божидаров<br>Майстора<br>1<br>Георги<br>др. Божидаров<br>1<br>Асен Гьонов<br>Павел<br>0<br>Майстора|3|
+
+[^sabre]: Защото една от първите индустрии, които са се нуждаели от компютърни системи, била [авиационната индустрия](https://en.wikipedia.org/wiki/Sabre_%28travel_reservation_system%29#History).
diff --git a/src/teaching/oop-2023/week1/organization.md b/src/teaching/oop-2023/week1/organization.md
new file mode 100644
index 0000000..92fdcc8
--- /dev/null
+++ b/src/teaching/oop-2023/week1/organization.md
@@ -0,0 +1,61 @@
+# Организация - ООП, Седмица 1, 22.02.2024
+
+&.presentation
+
+&[title35
+
+# Добре дошли в ООП
+
+&]
+
+
+
+За разлика от Увод в програмиране, по ООП практикума е малко по-специален.
+
+
+
+&[middle35
+
+- ООП практикум е избираема, която няма смисъл да не запишете
+ - Само плюсове за вас
+- Оценката е според контролни/изпити по ООП
+
+&]
+
+
+
+Така ви помагаме с избираемите: по учебен план трябва да имате поне 2 практикума, сравнително безплатно получавате единия.
+Относно оценяване:
+
+
+
+&[middle35
+
+- Освобождаване от изпит според работата ви по време на практикум
+- Няма намаляване на оценка
+- Оценявам общите ви умения<br>
+ Важното е да умеете да сте програмисти: коректност, брой и трудност на решени задачи се зачитат по-малко отколкото успех да напишете прилично-изглеждаща програма (дори с малко мой тласък)
+
+&]
+
+
+
+Все пак не може да ви даваме безплатни оценки, затова:
+
+
+
+&[middle35
+
+- Зачитат се **единствено нещата, качени в GitHub classroom, качени в срок**
+ - До **15** минути след края на часа
+- Както преди, не е нужно да присъствате, за да качвате решения
+- Ако случайно някой не знае как се ползва:
+
+&(centered [syndamia.com/upp-2023/week1/setup.html?a](../upp-2023/week1/setup.html?a) &)
+
+&]
+
+
+
+Който по време на УП е използвал GitHub classroom не би трябвало да прави нещо, продължавате си по старо му, със същите акаунти.
+Разбира се, за всякакви проблеми се [свържете с мен](../upp-2023/week1/welcome.html?a#section-4).
diff --git a/src/teaching/oop-2023/week10/index.md b/src/teaching/oop-2023/week10/index.md
new file mode 100644
index 0000000..06d9a7b
--- /dev/null
+++ b/src/teaching/oop-2023/week10/index.md
@@ -0,0 +1,146 @@
+# Задачи - ООП, Седмица 10, 25.04.2024
+
+GitHub classroom: [classroom.github.com/a/PbkITWhF](https://classroom.github.com/a/PbkITWhF)
+
+## Преговорни
+
+&:warn Моля, не отделяйте на преговорните задачи повече от 30мин
+
+### Задача 1 - Шаблони
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week10/Exercise01)
+
+Реализирайте шаблонен клас `Array`, който запазва динамично-заделен и оразмеряем масив от елементи с подаден тип.
+Имплементирайте голяма четворка.
+
+### Задача 2 - Оператори
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week10/Exercise02)
+
+За предходния шаблонен клас имплементирайте оператори:
+
+- [], който връща референция към елемента на подадения индекс
+- == и !=, които сравняват поелементно
+- +, += които конкатенират (слепват) два масива
+
+### Задача 3 - Грешки
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week10/Exercise03)
+
+Имплементирайте функция, която приема име на текстов файл и изкарва на екрана първия ред от него.
+Ако файлът не може да бъде отворен, хвърлете грешка - низ.
+Ако във файлът няма други редове (няма знакът `'\n'`), тогава хвърлете грешка число - размерът на файла.
+
+В главната функция, приемете името на файла от потребителския вход и извикайте функцията.
+Ако файлът не може да бъде отворен, тогава изкарайте хвърлената грешка на терминала и приключете програмата (успешно).
+Ако няма други редове в него, тогава изкарайте съобщението "In X characters, there is no newline!", където X е хвърленото число, и пробвайте да приемете пак име на файла от потребителския вход.
+
+## Лесни
+
+### Задача 4
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week10/Exercise04)
+
+Реализирайте клас `Time24`, който запазва час и минути (в 24-часов формат) в две отделни целичислени член-данни.
+Имплементирайте член-функция `Print24`, която изкарва часа на екрана в 24-часов формат.
+Нека конструкторът му приема две целочислени променливи, една за часа и втора за минутите.
+
+Реализирайте негов наследник `Time12`, който имплементира метод `Print12`, принтиращ часа в 12-часов формат.
+Имплементирайте и негов конструктор, който приема две целочислени променливи (една за часа и една за минутите), заедно с булева променлива описваща дали часа е следобеден или не.
+
+### Задача 5
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week10/Exercise05)
+
+Реализирайте клас `FN`, който запазва факултетен номер като неотрицателно цяло число от 5 цифри.
+Реализирайте негов наследник `ModernFN`, който запазва и начален (префиксен) низ, състоящ се от цифра, две букви и още две цифри.
+
+Имплементирайте конструктори, като този на `FN` приема число, докато този на `ModernFN` приема низ, състоящ се от целия факултетен номер (и трябва да конвертирате последните 5 цифри към число).
+Имплементирайте метод `PrintOldFN` на класа `FN` и метод `PrintNewFN` на класа `ModernFN`, които изкарват целия факултетен номер на съответния клас.
+
+### Задача 6
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week10/Exercise06)
+
+Реализирайте клас `Grade`, който запазва оценка (от 2 до 6) като неотрицателна целочислена член-данна.
+Реализирайте и негов наследник `GradeWithName`, който запазва и името на оценката като низ с произволна дължина.
+
+Конструктора на `Grade` приема само числовата стойност, докато този на наследника приема и името на оценката.
+Имплементирайте голяма петица на `GradeWithName`.
+
+### Задача 7
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week10/Exercise07)
+
+Реализирайте клас `String`, който запазва низ с произволна дължина.
+Имплементирайте голяма петица и член-функция `At`, която приема индекс и връща референция към буквата на този индекс (при невалиден индекс хвърляте грешка).
+
+Реализирайте негов наследник `FileString`, който запазва и името на текстов файл като низ с произволна дължина.
+Ако е нужно, имплементирайте голяма петица.
+
+Самия низ в `FileString` е първия низ (начало първата буква и край `'\n'`) от файла с подадено име.
+
+Имплементирайте метод `ChangeAt`, който приема индекс и нова буква, променя буквата на дадения индекс с подадената и обновява файла със запазеното име.
+
+### Задача 8
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week10/Exercise08)
+
+Реализирайте клас `User`, който запава име и парола като два низа с произволна дължина.
+Реализирайте негов наследник `Moderator`, който запазва и подпис, който също е низ с произволна дължина.
+Реализирайте наследник `Administrator` на `Moderator`, който запазва и оразмеряващ се масив от цели числа.
+
+Идеята е, че всяко действие от модератор или администратор се "подписва" публично (за да се знае, че той го е направил, дори да си смени името), а за администратор допълнително пазим масив от идентификатори на форуми, които администрира.
+
+За всеки клас имплементирайте голяма петица и гетъри и сетъри за името и паролата, когато е нужно.
+За `Moderator` имплементирайте гетър за подписа, но без сетър.
+За `Administrator` имплементирайте методи за добавяне и премахване на идентификатор на форум.
+
+### Задача 9
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week10/Exercise09)
+
+Реализирайте клас `CommunicationPacket`, който запазва начален и краен адрес като две неотрицателни цели числа, заедно с трето число за размера на данните.
+В този клас никога няма данни, затова размера винаги е нула.
+
+Реализирайте негови наследници `StringPacket` и `IntPacket`, където първия запазва и низ с произволна дължина (и дължината му е размера на данните) докато втория запазва и едно цяло число (и размера на `int` е размера на данните).
+
+Размерът не се подава на конструктори, а се изчислява в конструктори.
+Имплементирайте голяма петица и конструктори с нужните параметри.
+
+### Задача 10
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week10/Exercise10)
+
+Реализирайте клас `String`, който запазва низ с произволна дължина, и имплементира оператори ==, !=, + (който връща нов низ с конкатенацията на двата низа).
+
+Реализирайте негов наследник `ModifiableString`, който имплементира оператор[] &#20;(връщащ референция към буквата на дадения индекс) и оператор+=.
+
+Реализирайте наследник на `ModifiableString`, `ShowableString`, който имплементира оператори << и >>.
+Реализирайте наследник на `ModifiableString`, `SaveableString`, който имплементира методи write и read, приемащи име на двоичен файл и записващи или четещи низа от този файл.
+
+За всички класове имплементирайте голяма петица, когато е нужно.
+
+## Трудни
+
+### Задача 11
+
+Реализирайте шаблонен клас `Array`, който запазва оразмеряем масив с елементи от подаден тип.
+Имплементирайте оператор== и оператор!=, заедно с метод `isEmpty`.
+Концептуално идеята е, че този масив не може да се променя след като му се въведат стойностите от конструктора.
+
+Реализирайте негов наследник `PrintableArray`, който имплементира оператори << и >>.
+Реализирайте наследник `SaveableArray` на `Array`, който имплементира методи write и read, приемащи име на файл и булева стойност дали е двоичен или не, и съответно прочитат или запазват елементите от този масив във файла.
+
+Реализирайте трети наследник, `ModifiableArray`, на `Array`, в който са имплементирани член-функции:
+
+- `push`, която приема елемент и го вмъква в (десния) края на масива
+- `pop`, който премахва елемент от (десния) края на масива
+- `last`, който връща последния елемент от масива
+
+Може да се налага масива да се оразмерява.
+Като подсказка, имплементирайте си метод, наличен за класа и наследници, който вмъква елемент на произволен индекс.
+
+Реализирайте наследник `IndexableArray` на `ModifiableArray`, който имплементира оператор[].
+Ако индекса е след края, тогава "вмъквате" елементи по подразбиране между края и подадения индекс, и връщате елемента от сега новия край.
+Реализирайте наследник `FrontableArray` на `ModifiableArray`, който имплементира методи `pushf` и `popf`, които работят като `push` и `pop`, но с елемента в началото на масива (първия елемент).
diff --git a/src/teaching/oop-2023/week11/index.md b/src/teaching/oop-2023/week11/index.md
new file mode 100644
index 0000000..8ac676b
--- /dev/null
+++ b/src/teaching/oop-2023/week11/index.md
@@ -0,0 +1,201 @@
+# Задачи - ООП, Седмица 11, 09.05.2024
+
+GitHub classroom: [classroom.github.com/a/oYQehcnN](https://classroom.github.com/a/oYQehcnN)
+
+## Преговорни
+
+&:warn Моля, не отделяйте на преговорните задачи повече от 30мин
+
+&:important Всеки бащин клас, във всички случаи, трябва да има виртуален деструктор (`virtual ~ClassName();`).
+
+### Задача 1 - Шаблони и оператори
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week11/Exercise01)
+
+Реализирайте шаблонен клас множество, който запазва фиксиран брой елементи от подаден тип.
+Реализирайте голяма петица и оператори:
+
+- `+`, `+=` които действат като обединение
+- `*`, `*=` които действат като сечение
+- `-`, `-=` които действат като допълнение
+
+### Задача 2 - Наследяване
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week11/Exercise02)
+
+Реализирайте клас `Employee`, съхраняващ име на човек, позиция и департамент като низове със съответно дължина 512, 128 и 64, заедно със заплата като число с плаваща запетая.
+
+Реализирайте негов наследник `Manager`, който допълнително пази масив с фиксиран размер от Employee.
+
+Реализирайте наследника на `Employee`, `Developer`, който допълнително пази брой проекти върху който работи.
+
+Наследниците не могат да достъпят заплатата, но трябва да могат да достъпят другите данни на `Employee`.
+
+## Лесни
+
+### Задача 3
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week11/Exercise03)
+
+<!-- Динамично свързване, Inherit 3 -->
+
+Реализирайте клас `Electronics`, който съдържа модел (низ с максимална дължина от 255 знака), `needsVolts` и `needsAmps` (стойности с плаваща запетая).
+
+Имплементирайте негови наследници:
+
+- `Laptop`, който допълнително съхранява размер на екрана като число с плаваща запетая
+- `WashingMachine`, който допълнително запазва максимално тегло на прането, като цяло неотрицателно число
+- `Camera`, която допълнително запазва резолюция като число с плаваща запетая (в мегапиксели)
+
+За всеки клас реализирайте член-функция `Print`, която изкарва всички данни на екрана.
+
+&:question Чрез статично или динамично свързване сте имплементирали `Print`? Каква е разликата?
+
+### Задача 4
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week11/Exercise04)
+
+<!-- Dynamic linking, Inherit 2 -->
+
+Реализирайте клас `String`, който запазва динамично-заделен масив.
+
+Имплементирайте негов наследник `Name`, който допълнително запазва число: номер на името (първо име, бащино име (второ име), фамилия (трето име)).
+
+Имплементирайте втори наследник на `String`, `Street`, който запазва и число: номер на улицата.
+
+Във всеки клас имплементирайте голяма петица, член-функция `Length`, като:
+
+- в `String` връща дължината на низа,
+- в `Name` връща дължината на името умножена по номера си и
+- в `Street` връща дължината на името на улицата плюс броя цифри в номера на улицата.
+
+Самият низ в `String` **не** може да се достъпва от наследниците.
+
+### Задача 5
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week11/Exercise05)
+
+<!-- Templates 1 type -->
+
+Реализирайте шаблонен клас `Counted`, който запазва елемент от подаден тип и неговата бройка (цяло неотрицателно число).
+Имплементирайте оператори `++`, `--`, `+=`, `-=`, които променят бройката, както и гетъри за елемента и бройката.
+
+### Задача 6
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week11/Exercise06)
+
+<!-- Templates 2 types -->
+
+Реализирайте шаблонен клас `TwoArray`, който запазва два динамично-заделени масива с подадени типове.
+Масивите не могат да се оразмеряват и имат еднаква дължина.
+
+Имплементирайте:
+
+- голяма петица,
+- оператор `[]`, който по подаден индекс връща елемент от първия масив, и
+- оператор `()`, който по подаден индекс връща елемент от втория масив.
+
+### Задача 7
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week11/Exercise07)
+
+<!-- Abstract class -->
+
+Реализирайте абстрактен клас `DynamicArray`, който задължава наследниците да имплементират оператор `[]` и оператор `+=`.
+
+Реализирайте негови наследници:
+
+- `Numbers`, който "имплементира" динамично-заделен масив от цели числа, като
+ + оператор `[]` връща първия елемент, по-малък от подадения индекс. Ако няма такъв, връщате първия елемент.
+ + оператор `+=` вмъква елементите в началото на масива
+- `String`, който "имплементира" динамично-заделен масив от букви, като
+ + оператор `[]` връща индекс на брой (първата, втората, ...) главна буква в низа. Ако няма такава, тогава връща последната буква.
+ + оператор `+=` вмъква елементите в края на масива
+
+Имплементирайте голяма петица.
+
+&:question Къде ще имплементирате динамичния масив и голямата петица?
+
+&:question Можем ли да използваме оператор `+=` в полиморфна йерархия?
+
+### Задача 8
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week11/Exercise08)
+
+<!-- Abstract class -->
+
+Имплементирайте абстрактен клас `Message`, който съдържа динамично-заделен низ (текстово съобщение, което се показва на екрана) и задължава наследниците да имплементират:
+
+- метод `size`, който връща общия размер на всички данни в байтове.
+
+Реализирайте негов наследник `Link` (хипервръзка), който запазва и втори динамично-заделен низ, запазващ адресът към който линкът сочи.
+
+Реализирайте втори негов наследник `Location`, чието текстово съдържание е адрес, и който допълнително запазва две стойности с плаваща запетая: една за географска ширина и втора за географска дължина.
+
+За всички класове реализирайте член-функция `Length`, която връща размера на **текстовото съобщение** и оператор `<<`.
+
+&:question Има ли разлика между оператор `<<` на трите класа?
+
+### Задача 9
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week11/Exercise09)
+
+Реализирайте абстрактен шаблонен клас `MixedArray`, който съхранява алтерниращи елементи от два типа.
+Тоест, на индекс 0 имаме елемент от първия тип, на индекс 1 от втория, на индекс 2 от първи и так. нат.
+
+Елементите не е нужно да могат да се конвертират помежду си (тоест не може да използвате полиморфен контейнер), затова се достъпват с член функция `At`, приемаща индекс и референции към указатели към всеки тип.
+При подаден индекс, на единия указател се записва адресът на съответната стойност, а на другия `nullptr`.
+
+Също имплементира голяма петица и задължава наследниците да имплементират оператори `+=`, върщащи указател.
+
+Реализирайте негов наследник `DirectConcat`, който реализира `+=` като директно слепване (конкатениране).
+
+Реализирайте втори негов наследник, `MixedConcat`, който реализир `+=` като алтернира елемент от първия масив с елемент от втория.
+
+## Трудни
+
+### Задача 10
+
+Реализирайте система за документ с форматиран текст.
+В нея всеки елемент от документа е от тип Node, като за един Node трябва да имате:
+
+- id, автоматично-избрано число, с което отличава Node
+- operator<<
+- operator[]
+
+Реализирайте следните типове Node:
+
+- paragraph, това е най-обикновен низ
+- anchor, това е хипервръзка (линк), която съхранява видимо съдържание и уеб адрес
+- emplaced link, това е хипервръзка при която видимото съдържание съвпада с уеб адреса
+- заглавие, което е като хипервръзка, но уеб адресът започва с '#' и останалото съвпада със текстовото съдържание, като всяка буква е малка и вместо шпации има тирета
+- bulletpoint list, който съхранява редица Node-ове и ги изкарва на екрана, всяко на нов ред, започващи с '-'
+- table, която съхранява таблица с Node-ове
+
+Имплементирайте клас Document, който запазва масив от Node-ове и за който са имплементирани:
+
+- методи save и load, които запазват и четат цялото съдържание на документа в **текстов** файл с произволен формат.
+
+### Задача 11
+
+Ще реализирате система за изпълнение на крайни автомати (от Теоретични Компютърни науки, ЕАИ).
+
+За тази цел е нужен абстрактен шаблонен клас State, чиито тип определя азбуката, който съхранява динамично-заделен масив от преходи (Transition) и задължава protected имплементация на член-функцията equal, която приема два елемента от азбуката и връща дали са равни.
+Имплементирайте голяма петица и оператор +=, който вмъква нов преход в състоянието.
+
+Реализирайте абстрактен шаблонен клас Transition, чиито тип определя азбуката, и който съхранява елемент от този тип (стойността, която ако е равна на подадената ще изпълним прехода) и указател към следващо състояние.
+Класът задължава имплементацията на оператор [], който по подаден елемент от азбуката или връща указателя към следващото състояние, или връща nullptr.
+
+Реализирайте наследник на State, ArrayState, който (допускате че) приема указател на динамичо-заделен масив.
+
+Реализирайте наследник на Transition, PrintedTransition, който при всяко извикване на оператор [] също изкарва съобщение на екрана.
+
+Реализирайте клас FiniteStateMachine, който съхранява динамичен масив от състояния.
+За него имплементирайте голяма петица и конструктор, приемащ име на текстов файл в CSV формат, в който са запазени:
+
+- на първия ред обща информация във формата "Transitions,StartStateName", след това
+- състояния и преходи във формата "StateName,OnValue,TransitionTo", после
+- финални състояния във формата "FinalStateName1,FinalStateName2,...", и накрая
+- входни букви от азбуката "Letter1,Letter2,...".
+
+Имплементирайте метод Run, който изпълнява автомата и връща булева стойност: дали приема входните букви или не.
diff --git a/src/teaching/oop-2023/week12/index.md b/src/teaching/oop-2023/week12/index.md
new file mode 100644
index 0000000..b492678
--- /dev/null
+++ b/src/teaching/oop-2023/week12/index.md
@@ -0,0 +1,94 @@
+# Задачи - ООП, Седмица 12, 09.05.2024
+
+GitHub classroom: [classroom.github.com/a/o7hNz1pr](https://classroom.github.com/a/o7hNz1pr)
+
+### Задача 1
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week12/Exercise1)
+
+<!-- Multiple inheritance -->
+
+Реализирайте клас `Publication`, който пази:
+
+- низ от максимална дължина 1023, съхраняващ автори и
+- втори низ с максимална дължина от 255, съхраняващ име на (научно) списание.
+
+Реализирайте клас `TextDocument`, който пази неоразмеряем низ с текстово съдържание и неговия размер.
+
+Реализирайте наследник на двата класа `ScientificPaper`, който допълнително пази и низ от максимално 511 знака, съдържащ име на научна дисциплина.
+За всички класове реазлизирайте оператор <<.
+
+### Задача 2
+
+*Не говорим за нея, условието беше толкова сбъркано, че се наложи да я сваля*
+
+### Задача 3
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week12/Exercise3)
+
+Реализирайте абстрактен клас `MobileDevice`, който запазва:
+
+- телефонен номер като цяло неотрицателно число и
+- масив с максимална дължина от 511 знака за текстово съобщение.
+
+Допълнително нека:
+
+- класът да задължава имплементацията на метод `Show`,
+- да има член-функция `CanAccept`, която по подадено "хиперсъобщение" връща дали неговия номер съвпада с този на класа.
+ Под "хиперсъобщение" имаме предвид низ, който започва с телефонния номер, след това има шпация и след това е самото съобщение.
+- да има член-функция `Accept`, която по подадено "хиперсъобщение" запазва текстовото съобщение.
+ Ако номерът не съответства тогава хвърля грешка.
+
+Реализирайте негов наследник `Telephone`, за който `Show` изкарва съобщението на екрана.
+
+Реализирайте втори негов наследник `Pager`[^pager], който съхранява име на файл (като динамично-заделен низ) и `Show` изкарва съобщението в съответния файл.
+Разбира се, имплементирайте голяма петица.
+
+Реализирайте клас `TelecommunicationCompany`, който съхранява динамично-заделен и оразмеряем масив от (указатели към) `MobileDevice`.
+Имплементирайте всичко от голяма петица.
+
+### Задача 4
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week12/Exercise4)
+
+<!-- Multiple inheritance with mixed class types, polymorphic container, and copying -->
+
+Реализирайте клас `Employee`, който запазва:
+
+- заплата като число с плаваща запетая и
+- производителост също като число с плаваща запетая.
+
+Производителността е множител на заплатата, тоест ако има производителност 0.5 значи работи като човек на който му плащат с половината заплата.
+
+Реализирайте абстрактен клас `Person`, който запазва:
+
+- име като низ с произволна дължина и
+- възраст като цяло неотрицателно число
+
+Допълнително задължава реализацията на член-функция `Workload`, връщаща стойност с плаваща запетая.
+Разбира се имплементирайте голяма петица.
+
+Реализирайте наследник на двата класа на име `Developer`, който допълнително запазва:
+
+- цяло неотрицателно число - брой проекти в които участва, и
+- второ което е брой проекти на които ще се пуска нова версия.
+
+Реализирайте оператори `++` и `--`, като префиксните променят броя проекти на които ще се пуска нова версия, докато постфиксните променя броя проекти в които участва.
+За него `Workload` се определя като 1.1 по всеки проект и допълнително по 2.3 за всеки проект на който ще се пуска нова версия.
+
+Реализирайте наследник на двата класа на име `Manager`, който допълнително запазва динамично-заделен и оразмеряем масив от `Person`, които менижира.
+
+Имплементирайте голяма петица и:
+
+- оператори `==` и `!=`, сравняващи хора по име
+- член-функция `StartManaging`, която приема `Person` и го запазва, и
+- член-функция `StopManaging`, която приема `Person` и го премахва от масива ако съществува в него.
+
+`Workload` се определя като 0.6 на човек който менижира.
+
+Финално реализирайте клас `Company`, който запазва масив от 128 указателя `Person` в компанията.
+Имплементирайте негова член-функция:
+
+- `PaymentDifference`, която връща с колко платената заплата на всички служители се отличава с тази според тяхната производителност
+
+[^pager]: От времето без мобилни телефони, хората са си купували пейджъри, които ти пращат нотификация ако някой ти звънне и не вдигнеш. Пейджърите са "заключени" за определени региони, тоест някой ти се обажда, не вдигаш, и всички телекомуникционни кули в региона изпращат съобщение "на теб ти звънна този", и пейджъра като засече сигнала ти писука. Мисля че също можеш да пращаш кратки съобщения. Не е било хич сигурна система, все още се ползва от болници в някои държави.
diff --git a/src/teaching/oop-2023/week13/index.md b/src/teaching/oop-2023/week13/index.md
new file mode 100644
index 0000000..5d2ad35
--- /dev/null
+++ b/src/teaching/oop-2023/week13/index.md
@@ -0,0 +1,138 @@
+# Задачи - ООП, Седмица 13, 16.05.2024
+
+GitHub classroom: [classroom.github.com/a/GvV1wrC1](https://classroom.github.com/a/GvV1wrC1)
+
+&:warn Навсякъде, където е нужно, реализирайте голяма петица.
+
+## Преговорни
+
+### Задача 1 - Множествено наследяване
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week13/Exercise1)
+
+Реализирайте клас `String`, който запазва динамичен низ с фиксиран размер.
+
+Реализирайте клас `IndexArray`, който запазва динамичен масив с фиксиран размер от цели числа - индекси.
+
+&:warn **Не** правете общ родител, който имплементира динамичен масив!
+
+Реализирайте наследник на двата класа, `WordsString`, при който индексите определят началото на всяка дума от запазения низ.
+Индексите се дефинират при конструктора.
+
+## Лесни
+
+### Задача 2
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week13/Exercise2)
+
+<!-- Диамант -->
+
+Реализирайте шаблонен клас `Container`, който съхранява масив с фиксиран размер от елементи с подаден тип.
+**Не** трябва да реализирате нищо повече от задължителните компоненти (голяма петица).
+
+Реализирайте негов наследник `Indexable`, който реализира оператор[].
+
+Реализирайте втори негов наследник `Resizeable`, който реализира член-функция `InsertAt`, приемаща елемент и индекс, и която вмъква елемента на даден индекс.
+Разбира се, може да се наложи оразмеряване на масива.
+
+Реализирайте наследник `Vector` на `Indexable` и `Resizeable`, който реализира оператор[] и член-функции:
+
+- `pop_back`, премахваща последния елемент
+- `pop_front`, премахваща първия елемент
+- `push_back`, приемаща елемент който се вкарва в края на масив
+- `push_front`, приемаща елемент който се вкарва в началото на масив
+
+&:important Не забравяйте за диамантния проблем!
+
+### Задача 3
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week13/Exercise3)
+
+<!-- Диамант -->
+
+Реализирайте клас `User`, който запазва потребителско име и парола като низове с произволна дължина, заедно с булев флаг `banned`, определящ дали акаунтът може да прави действия.
+Потребителско име не може да съдържа шпации.
+
+Реализирайте клас `Thread`, който запазва масив с произволна дължина, от низове с произволна дължина.
+Имплементирайте член-функция:
+
+- `PostMessage`, която приема потребител и негово съобщение и добавя съобщението с потребителското име като един низ.
+ Ако потребителя е `banned`, тогава хвърлете грешка.
+
+Реализирайте наследник `ThreadModerator` на `User`, който може да променя `Thread` обекти, без да се нуждае от публични член-функции в `Thread`.
+Имплементирайте методи:
+
+- `RemoveMessage`, който приема `Thread` и индекс на съобщение и премахва съответното съобщение
+- `RemoveByUser`, който приема `Thread` и потребител, и премахва всички съобщения, направени от дадения потребител
+
+Реализирайте наследник `UserModerator` на `User`, който може да променя `User` обекти, без да се нуждае от публични член-функции в `User`.
+Имплементирайте методите:
+
+- `BanUser`, който приема потребител и вдига `banned` флага
+- `UnbanUser`, който приема потребител и сваля `banned` флага
+
+Реализирайте наследник `Administrator` на `ThreadModerator` и `UserModerator`, който може да прави всичко, което и родителите могат.
+
+&:important Не забравяйте за диамантния проблем!
+
+## Трудни
+
+### Задача 4
+
+Реализирайте абстрактен клас `ShopLocation`, който съхранява член-данни:
+
+- адрес като низ с максимална дължина от 511 знака.
+ Всеки адрес съдържа произволни символи и задължително завършва на число, определящо неговия район.
+- време на отваряне и време на затваряне
+
+Имплементирате методи:
+
+- `IsOpen`, който връща по подаден час дали локацията е отворена
+- `InCenter`, който връща дали локацията се намира в центъра на града.
+ Всички адреси с регион, по-малък от 11, се намират в центъра.
+
+Реализирайте шаблонен клас `Inventory`, който съхранява **фиксиран** брой елементи и техните неотрицателни бройки (количества).
+Имплементирайте член-функции:
+
+- оператор[], който връща елемент на дадения индекс
+- оператор(), който връща бройка на елемент на дадения индекс
+- `Stock`, приемащ индекс на елемент и бройка (положителна/отрицателна) с която бройката на дадения елемент се променя.
+ Бройката може да бъде най-малко 0.
+- `List`, който връща всички елементи и техните индекси
+
+Реализирайте абстрактен шаблонен наследник `DeliverableInventory` на `Inventory`, който е инвентар с максимум 2048 елемента и допълнително задължава имплементацията на:
+
+- `ShippingDelay`, който приема адрес и връща времето в което ще може да се достави обекта
+
+Реализирайте наследник на `DeliverableInventory`, склад `Warehouse`, който допълнително запазва разстояние от града в километри и имплементира `ShippingDelay` по следната логика:
+
+- доставки в центъра отнемат един ден + регионът в който се доставя
+- доставки извън центъра отнемат толкова време, колкото е нужно да се стигне до града ако пътува с 80 километра в час + времето което ще отнеме да се измине номер на региона на брой километри при скорост от 20 километра в час
+
+Доставка не може да се случи преди 9 сутринта и след 18 вечерта.
+Ако попадне в този диапазон, тогава се отлага за най-скорошния следващ възможен час.
+
+Реализирайте шаблонен наследник магазин `Shop` на `ShopLocation` и `Inventory`, който е инвентар с максимум 256 елемента, запазващ:
+
+- **оразмеряем** масив от низове с произволен размер, всеки низ който е "отчет на продажба"
+- общо бройка продажби
+
+и който имплементира методи:
+
+- `SellItems`, който приема масив от идентификатори на обекти, намалява бройката на всеки от тях и създава нов отчет.
+ Отчета е в произволен формат, но трябва да съдържа идентификаторите и бройките на всеки обект.
+ Ако за някой обект няма достатъчно бройки или изобщо не се пази, хвърлете грешка.
+
+Реализирайте шаблонен клас `WebStore`, който запазва оразмеряеми масиви от `Shop` и `Warehouse`.
+Имплементирайте:
+
+- оператор<<, който изкарва всички уникални (unique) обекти от всички магазини и складове, с индекс до тях
+- `GetEstimate`, който приема индекс на уникален обект от всички магазини и складове, сегашно време и адрес, и изкарва на екрана всички магазини които са отворени в дадения час и кое е най-скорошното време в което може обектът да се достави от склад.
+ Ако няма отворени магазини, ако няма магазин с наличност и так. нат. изкарайте съответно съобщение.
+
+Последно реализирайте клас `Book`, който запазва заглавие на книга и име на автор като низове с максимална дължина от 127 знака.
+Имплементирайте оператор<<, който изкарва съответната книга в произволен формат.
+
+В главната функция реализирайте `WebStore` от книги, заедно с набор от книги, магазини и складове по ваш избор.
+Нека в началото на програмата да приемате от потребителя сегашното време и адрес, след това изкарайте на екрана всички ункални книги с индекси.
+Накрая потребителя може да въведе индекс на книга и да получи информация кои отворени сега магазини имат съответната книга и кога най-скоро може да бъде доставена от склад.
diff --git a/src/teaching/oop-2023/week14/index.md b/src/teaching/oop-2023/week14/index.md
new file mode 100644
index 0000000..917c11b
--- /dev/null
+++ b/src/teaching/oop-2023/week14/index.md
@@ -0,0 +1,73 @@
+# Задачи - ООП, Седмица 14, 23.05.2024
+
+GitHub classroom: [classroom.github.com/a/K0XomKEP](https://classroom.github.com/a/K0XomKEP)
+
+## Задача
+
+В тази задача се оставя голямо количество свобода на имплементация, за всяко нещо сами преценете типове, помощни класове/член функции, оператори и так. нат.
+Както винаги, реализирайте голяма петица където е нужно.
+
+Препоръчително е първо да изчетете цялото условие и след това да пишете код.
+
+Реализирайте система като СУСИ.
+Преди да стигнем до потребителите, ще се нуждаем от някои други компоненти.
+
+Реализирайте предмет, като в един предмет се пазят:
+
+- име
+- тип (задължителен/избираем)
+- брой ECTS кредити, които носи
+- код, комбинация от главна буква и 3-цифрено число
+
+Реализирайте семестър, като в един семестър се пазят:
+
+- учебната година
+- тип (зимен/летен)
+- учебния план (низ във формата "СПЕЦИАЛННОСТ(УЧЕБЕН КУРС)")
+- предмети; разбира се един предмет може да се споделя от няколко семестъра
+
+Реализирайте специалност, която пази:
+
+- свое име
+- катедра към която е свързана
+- всички семестри, в които е (била) активна
+- предмети, съответстващи на всеки тип семестър
+
+и имплементира метод:
+
+- `NewSemester`, който приема учебна година и тип, и връща нов обект от семестър с попълнени данни
+
+Имаме потребители, като всеки си има роля, определяща неговите способности в системата.
+Ролята може да бъде студент, преподавател или администратор, като при конкретизиране в условието на някои от тях трябва да се извършат съответните проверки.
+Ваш избор е какво да бъде ролята.
+
+За един потребител със сигурност се пазят:
+
+- име
+- факултетен номер (от модерния стил)
+- потребителско име, което се определя като първата буква от първото име, конкатенирана с фамилията.
+ Ако съществува потребител с такова потребителско име, тогава добавяте букви от бащиното име, и накрая в краен случай, от първото име.
+- парола
+- година на учебния план
+- име на сегашна специалност
+
+<br>
+
+- данни за контакт, като една данна съдържа тип и описание (произволни низове)
+
+<br>
+
+- семестри, в които е (бил) включен
+- изпити, които са комбинация от предмети, преподаватели и оценки (която е възможно да не е въведена)
+
+Реализирайте мениджър на факултета, който съхранява, създава, обновява и премахва всички потребители и специалности.
+Имплементирайте съответни член-функции, които да правят тези действия.
+
+Имплементирйате и методи, приемащи потребителско име, които:
+
+- за един потребител изкарва всички негови лични данни, заедно с кратко описание на семестрите в които е включен
+- за един студент изкарва всички изпити, заедно със семестрите към които са свързани и сума на всички успешно получени кредити за дадения семестър (кредитите се броят само когато има оценка, която не е двойка)
+- един преподавател може да създаде нов предмет
+- един администратор може да създаде нов потребител, специалност, семестър, както и да свързва предмети със семестри и специалности
+
+Реализирайте конзолен интерфейс.
diff --git a/src/teaching/oop-2023/week15/index.md b/src/teaching/oop-2023/week15/index.md
new file mode 100644
index 0000000..6719bf0
--- /dev/null
+++ b/src/teaching/oop-2023/week15/index.md
@@ -0,0 +1,37 @@
+# Задачи - ООП, Седмица 15, 30.05.2024
+
+GitHub classroom: [classroom.github.com/a/z2QadyEE](https://classroom.github.com/a/z2QadyEE)
+
+## Задача
+
+В тази задача се оставя голямо количество свобода на имплементация, за всяко нещо сами преценете типове, помощни класове/член функции, оператори и так. нат.
+Както винаги, реализирайте голяма петица където е нужно.
+
+Препоръчително е първо да изчетете цялото условие и след това да пишете код.
+
+Реализирайте система за чат.
+В нея имаме съобщения, като едно съобщение може да бъде:
+
+- текст, като низ
+- локация, като съвкупност от държава, град, област (число), улица и номер на улица
+- линк (хипервръзка) като текст и (уеб) адрес
+- време: дата и час
+
+Всеки тип трябва да имплементира `Print` член-функция, която изкарва текстово съдържание на съобщението.
+За текстово съобщение това е самия текст, за локация това е низ във формата "[ДЪРЖАВА] ГРАД(ОБЛАСТ) УЛИЦА NoНОМЕР НА УЛИЦА", за линк е самия текст и за време е "ЧАС:МИНУТИ ДЕН.МЕСЕЦ.ГОДИНА".
+
+Реализирайте потребители, като за всеки потребител имаме потребителско име и парола.
+
+Реализирайте чатруум, който съхранява записани потребители в групата, съобщения и съответните потребителски имена на авторите.
+Един потребител може да се добави в чатруум, да създава нови съобщения и може да излезе, като един излязъл потребител може да вижда историята на чата до момента в който е излязъл.
+Ако обратно бъде вкаран, тогава пак може да вижда всички съобщения от историята и да създава нови.
+
+Всеки потребител може да създаде чатруум и да запише хора в него (по потребителски имена), и може да излезе.
+Допълнително собственика на чатруум може да изтрие самия чатруум и да премахва хора.
+Ако собственикът се отпише тогава новият собственик е следващия по ред записан потребител.
+
+Реализирайте "платформа" в която се съхраняват всички чатове и потребители, от която също се създават потребители.
+
+Имплементирайте конзолен интерфейс, от който може да създадете потребител, да влезете в акаунта на потребител, след като сте влезли да разглеждате всички налични чатове.
+Ако сте член на даден чат да създавате ново съобщение и да излезете.
+Ако сте собственик да изтриете чат и да премахвате потребители от чата.
diff --git a/src/teaching/oop-2023/week16/index.md b/src/teaching/oop-2023/week16/index.md
new file mode 100644
index 0000000..f95271d
--- /dev/null
+++ b/src/teaching/oop-2023/week16/index.md
@@ -0,0 +1,30 @@
+# Задачи - ООП, Седмица 16, 06.06.2024
+
+GitHub classroom: [classroom.github.com/a/BWjw2dUC](https://classroom.github.com/a/BWjw2dUC)
+
+## Задача
+
+Първо си разпишете структурата, след това пишете код.
+НЕ е нужно да реализирайте пълно решение, това е по-блико до архитектурното контролно, не е нужно да конкретизирате всички член-функции.
+
+В добре реализираните операционни системи, комуникация със свързани устройства се свежда до работа с файлове: ако искаш да кажеш устройството да прави нещо, ти пишеш във файла, ако устройството иска да ти каже на тебе нещо, четеш от файла.
+Разбира се, отдолу няма истински файлове които се запазват в харддиск (примерно), просто ОС превежда всички тези операции върху файлове със съответни действия към устройството.
+
+Реализирайте подобна система.
+Първо трябва ни обща схема за файлове, за всеки файл имаме `Read` и `Write` методи, и пазим името на файла.
+
+За всяко устройство само по себе си знаем, че трябва да използваме определен драйвър (по име) и че то има малко информация за себе си: марка като низ и модел като цяло число.
+По-конкретно разглежаме два основни типа устройства: индексируемо и поточно (streamable).
+
+Първия тип са устройства като харддиск, където можем да си изберем индекс в който да запазваме или четем данни.
+Втория тип са устройства като клавиатура или тонколони, можем или да прочетем или пишем по един байт, и този байт "изчезва" (клавиатурата изпраща байт като е натиснат бутон, тонколоните изкарват звук според байт, но никъде тази информация не се запазва дълготрайно).
+Имплементирйате съответните оператори.
+
+Допълнително имаме поточно-индексируеми устройства, това са примерно фенси дигитални камери, които позволяват да се свържат като нормални уеб камери (тоест серийни устройства, изпращат данни за сегашния кадър) и могат да пазят снимки (тоест индексируеми устройства).
+
+Последно, с популярността на интернетът е добавен мрежов интерфейс, за който трябва да реализираме член-функции за изпращане и приемане на пакет с данни.
+Един пакет съдържа начален и краен адрес като цели неотрицателни числа, име на протокола (низ с 4 знака) и данни (масив от байтове).
+
+Имаме и конкретен тип поточно устройство: мрежов адаптер.
+Разбира се, той е и мрежов интерфейс, като идеята е, че по файловия интерфейс се предават статистични и информативни данни, но не и пакети.
+
diff --git a/src/teaching/oop-2023/week2/index.md b/src/teaching/oop-2023/week2/index.md
new file mode 100644
index 0000000..f8f27d9
--- /dev/null
+++ b/src/teaching/oop-2023/week2/index.md
@@ -0,0 +1,194 @@
+# Задачи - ООП, Седмица 2, 29.02.2024
+
+GitHub classroom: [classroom.github.com/a/3qPsfyyI](https://classroom.github.com/a/3qPsfyyI)
+
+## Задача 0 - Преговорна
+
+&::solution-link [Решения](https://github.com/Syndamia/oop-2023-solutions/blob/main/week02/Exercise0.cpp)
+
+Ще работим върху N-мерен [морски шах](https://en.wikipedia.org/wiki/Tic-tac-toe), тоест ще имаме дъска за морски шах, която може да е по-голяма от 3 на 3 (примерно 5 на 5, 7 на 7 и т.н.).
+Няма да се занимаваме с проверки дали (и кой) е спечелил след даден ход, интересуваме се само от запазването на данни.
+
+Основната логика е следната, като във всяка подточка правила по имплементацията са зададени.
+
+&:warn Не почвайте веднага да имплементирайте, погледнете подточките!
+
+В началото от входа се въвеждат два реда, всеки съответстващ на имената на даден играч (в тези имена може да има шпации).
+Първият играч винаги играе като X, вторият винаги като O.
+
+След това се въвежда цяло число N, това е размерът на дъската.
+Накрая се въвеждат NxN на брой X-ове и O-та.
+
+За всеки играч трябва съответно да изкарате общия брой X-ове или броя O-та в цялата дъска, както и дължината на най-дългата последователност от Х-ове или О-та в един реда на дъската (примерно за първия играч, търсим реда с най-много последователни X-ове, и изкарваме тяхната бройка).
+
+**Пример:**
+
+|Вход|Изход|
+|----|-----|
+|Emil Petkov<br>BoburaBG<br>5<br>X X O O O<br>O X O X X<br>O X X X O<br>O X X X X<br>O X O O O<br>|Emil Petkov: Total - 13, Longest - 4<br>BoburaBG: Total - 12, Longest - 3|
+
+### а) без структури
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week02/Exercise0.cpp#L3-L83)
+
+&:important Решете подточката **без** структури, тоест без знания по ООП
+
+Имплементирайте **функция** `boardCounts`, която приема дъската и връща по някакъв начин нужните бройки: общ брой X-ове, общ брой O-та, брой X-ове в най-дългата последователност от X-ове в ред, брой O-та в най-дългата последователност от O-та в ред.
+
+След това имплементирайте фукция `printResult`, която приема имената на двата играча, както и бройките, върнати от `boardCounts`, и изкарва на екрана съобщенията във формата от примера.
+
+### б) структура за board
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week02/Exercise0.cpp#L85-L166)
+
+"Слепете" в една съвкупност (структура) указателя към самата дъска за морски шах, както и нейния размер N.
+Нека името на структурата да бъде `GameBoard`.
+
+Обновете `boardCounts`, така че вместо да приема дъската и размера ѝ чрез две променливи, да ги приема чрез една променлива от тип `GameBoard`.
+
+### в) структура за числата
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week02/Exercise0.cpp#L168-L255)
+
+"Слепете" в една съвкупност (структура) на име `BoardCounts` четирите променливи, които `boardCounts` връща.
+
+Обновете `boardCounts` да връща една стойност от тип `BoardCounts`, вместо да връща четирите бройки като отделни числа.
+Обновете `printResult` да приема стойност от тип `BoardCounts`, вместо да приема четирите бройки като отделни числа.
+
+### г) структура за цялата игра
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week02/Exercise0.cpp#L257-L300)
+
+Сега "слепете" предходните две структури, заедно с имената на нашите играчи, в една голяма обща структура за цялата игра на име `Game`.
+Тоест, всичките ни данни: дъската, бройките и имената на играчите, да се намират в `Game`.
+
+&:important Искам да *композирате*, тоест искам да използвате `GameBoard` и `BoardCounts` структурите в `Game` структурата.
+
+Обновете `boardCounts` и `printResult`, така че да използват тази структура.
+
+## Задача 1 - Основи от материала
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week02/Exercise1.cpp)
+
+Работите върху система за инвентар на книжарница.
+
+&:warn Не е задължително, но е препоръчително да си направите и една структура `String` с конструктор и деструктор
+
+Създайте структура `Book` със скрити (private) данни за:
+
+- заглавие, като един низ
+- автори, като масив от низове
+- година на публикация, като целочислено число
+- цена, като число с плаваща запетая
+
+За всяка от тях създайте съответните публични селектор (get-ър) и мутатор (set-ър) член-функции (методи).
+Set-ърите трябва да записват стойности в данните, само когато съответните проверки са изпълнени:
+
+- заглавието не може да бъде празния низ
+- трябва да има поне един автор, името на даден автор не може да бъде празния низ
+- годината на публикация не може да надвишава 2024, не може да е по-малка от -2100 (2100 п.н.е.) и не може да бъде нула
+- цената не може да е отрицателна
+
+Всеки от мутаторите трябва да връща булева стойност, `true` ако проверките са изпълнени (и запазването на данни е извършено) и `false` ако съответната проверка не е изпълнена (и няма промяна в данните).
+Създайте съответните конструктори и деструктори.
+
+След това направете структура `Library`, която държи масив от книги и бройката за всяка книга (отново като скрити данни).
+Най-лесния вариант е да имате втори масив, като за всеки индекс в масива с книги, на същия индекс в масива за бройки се намира съответната бройка.
+Можете и да го направите чрез структура `Pair` и да имате един масив.
+
+Като публични методи на `Library` имплементирайте `AddBook`, която вмъква нова книга в масива, и `RemoveBook` която съответно "премахва" книга по заглавие и година.
+Допълнително направете член-функция `StockBook`, която приема заглавие на книга, годината ѝ, и цяло число с което наличната бройка се увеличава.
+Аналогично направете и `SellBook`.
+За всики тези методи трябва да имате съответните проверки:
+
+- ако напълно идентична книга вече съществува, `AddBook` не трябва да я добавя на ново
+- `RemoveBook` не трябва да "гърми" ако книгата не съществува
+- бройката на добавени/продадени книги, подадени на `SellBook` и `StockBook`, трябва да бъдат положителни, както и книгите да съществуват
+
+Аналогично като при `Book`, тези функции трябва да връщат булева стойност, дали проверките са изпълнени.
+Не забравяйте за конструктор и деструктор!
+
+&:question Можете ли да си улесните работата, ако използвате скрити член-функции?
+
+Не е нужно да правите потребителски вход/изход, но тествайте ръчно кода си в `main`.
+
+## Задача 2
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week02/Exercise2.cpp)
+
+Работите върху система за Excel-ски таблици.
+Една клетка може да съдържа някаква числена стойност, или проста формула която определя тази стойност.
+
+Създайте структура `Cell`, която запазва (скрито) целочислена стойност, знак, който определя опреацията във формулата, и два указателя на `Cell` към двете страни на оператора.
+Оператора (знака) може да бъде `+`, `-`, `*` или `/`.
+
+Идеята е, че ако клетката само запазва стойност, тогава оператора ще бъде нещо празно (терминираща нула например).
+Обаче ако се определя от формула, тогава оператора и указателите също ще са попълнени, а запазената стойност ще действа като кеш, тоест вместо всеки път да преизчисляваме стойността когато я искаме, преизчислили сме я веднъж и я запазваме.
+
+За тази цел имплементирайте публична член-функция `evaluate`, ако не е запазена формула, тя не прави нищо, ако е, прави съответното изчисление и запазва резултата.
+Разбира се, направете и мутатори `setValue` и `setFormula`, със съответните проверки.
+Не забравяйте за конструктор и деструктор.
+
+Сега направете структура `Table`, която пази (скрито) двумерен масив от клетки.
+Имплементирайте селектор `getCell`, който връща указател на клетка по координати и мутатор `setCell`, който приема клетка и координати в масива.
+
+&:question Какъв ще е типа на подадената клетка и стойностите в масива?
+
+Направете метод `updateCell`, чрез която стойностите на клетка по координати могат да бъдат променени, и след това всички клетки в таблицата се преизчисляват.
+
+Последно, имплементирайте и член-функция `printTable`, която изкарва на екрана цялата таблица, като клетката на индекси 0,0 се намира в горния ляв ъгъл, всички клетки са разделени с `|`.
+
+Не е нужно да правите потребителски вход/изход, но тествайте ръчно кода си в `main`.
+
+## Задача 3
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week02/Exercise3.cpp)
+
+Изграждате "симулация" за трафик върху секция от магистрала.
+
+Самата магистрала се характеризира от брой платна (ширина) и дължина.
+
+Върху магистралата се слагат произволен брой коли.
+Всяка кола се определя с координатите си върху магистралата и своета скорост.
+Всички коли се движат от "ляво" на "дясно" по магистралата, винаги в едно и също платно, без да могат да се надминават или заобикалят.
+Една кола има скорост: число между 0 и 8 включително.
+
+В началото на симулацията, всяка кола се разпределя по случаен начин върху магистралата, и всяка кола има случайна скорост между 4 и 6 включително.
+Разглеждайки от най-десните към най-левите, всяка кола се опитва да се придвижи, като нейната скорост определя с колко клетки надясно ще се мръдне.
+
+Ако по пътя ѝ няма други коли, тя се премества спокойно.
+Ако има, тогава нейната скорост се намалява на половина, и пробва да се придвижи пак.
+Ако и с намалената скорост има кола на пътя ѝ, двете коли се удрят, "предната" кола застава на място, "задната" застава директно зад нея и двете получават скорост 0.
+
+След като една кола успешно се е придвижила напред, тя увеличва своета скорост със случайно количество между 0 и 3.
+Ако една кола се е блъснала или просто е спряла (има скорост 0), тогава увеличава своета скорост на единица, и след това продължава както нормално.
+
+Ако една кола успешно "излиза" от участака на магистралата, тоест тя се опитва да се придвижи някъде след края ѝ, зачитаме че успешно е минала пътя и спираме да я разглеждаме.
+
+Сами определете как ще изглеждат структурите за колата и магистралата, както и нужните методи.
+Имайте предвид, че трябва цялата логика да присъства в тези структури, тоест в `main` трябва да присъства само някакъв инициализиращ код.
+
+&:important Не е позволено магистралата да бъде двумерна матрица, координатите на всяка кола се пазят в самата кола.
+
+Накрая пуснете симулацията няколко пъти, на всяко извикване трябва да изкарате на екрана брой получили се сблъсаци, както и броя нужни итерации с които сте обходили всички коли на пътя, докато всички те излязат от магистралата.
+Симулации се различават с позиции и началните скорости на колите, бройката коли и размерите на магистралата си стоят.
+
+## Задача 4
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week02/Exercise4.cpp)
+
+Имате фабрика, цялата ѝ структура се разглежда като един конвейер, тоест като една редица машини, всяка от които приема някакъв материал и връща този материал преобразуван.
+
+Един материал се определя с три целочислени стойности: идентификационен номер, начален тип (тоест като какво се подава) и краен тип (тоест в какво се очаква да се преобразува).
+
+Една машина се характеризира с ефикасност спрямо материали: представете си една таблица, от едната колона има идентификационни номера на материали, от друга има числа с плаваща запетая, определящи процент ефикасност.
+Допълнително за нея знаем колко материал може да преобразува, преди да се нуждае от ремонт.
+
+Когато даден материал е подаден на машината, тя го преобразува в материал от дадения краен тип.
+Типовете на материалите са отделни стойности от идентификационните номера, тоест като е подаден материал, той се превръща в крайния тип, и трябва да намерите на кой материал точва число е началния тип.
+
+Всички тези данни трябва да са скрити, трябва за съответните структури да присъстват конструктори и деструктори.
+Допълнително при машините трябва да има член-функция `convertMaterial`, която получава идентификационен номер на материал и бройка, и връща колко от резултатния материал е успяла да създаде (спрямо ефикасността, закръглена надолу, и дали се нуждае от ремонт по средата на работата).
+
+Ще получите данни за всички материали и машини, както и задачи, тоест идентификационни номера на начален и краен материал, както и бройката на началния материал.
+Трябва да намерите редицата от машини, които ще създадат възможно най-много краен материал.
diff --git a/src/teaching/oop-2023/week3/index.md b/src/teaching/oop-2023/week3/index.md
new file mode 100644
index 0000000..c9b4963
--- /dev/null
+++ b/src/teaching/oop-2023/week3/index.md
@@ -0,0 +1,175 @@
+# Задачи - ООП, Седмица 3, 07.03.2024
+
+GitHub classroom: [classroom.github.com/a/KPMqXsFp](https://classroom.github.com/a/KPMqXsFp)
+
+## Преговорни
+
+### Задача 1 - Структури
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week03/Exercise1.cpp)
+
+Имплементирайте структура `Lightbulb`, която запазва идентифициращите данни за една крушка:
+
+- диаметър и дължина: и двете са целочислени стойности
+- тип: низ с максимална дължина от 100 знака
+- серия: буква на латиница
+
+### Задача 2 - Капсулация
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week03/Exercise2.cpp)
+
+Имплементирайте структура `Alarm`, която съдържа следните **скрити** данни:
+
+- име на модел: низ с максимална дължина от 1024 знака
+- пин код: целочислено число
+- ревизия на модела: число с плаваща запетая
+
+За всяка данна трябва да създадете съответните get-ъри и set-ъри: публични член-функции, които съответно връщат и записват всяка от изброените скрити стойности.
+
+При set-ърите имплементирайте следните проверки:
+
+- името на модела може да има само главни букви
+- пин кода трябва да бъде 4 цифри (нули са позволени)
+- ревизията трябва да бъде положително число
+
+Ако дадена проверка не е изпълнена, не записвате новата стойност (и оставяте старата).
+
+### Задача 3 - Капсулация с динамична памет
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week03/Exercise3.cpp)
+
+Имплементирайте структура `Person`, която запазва двете имена на човек, възраст като целочислено число и неговия имейл.
+Имената и имейла са низвое с произволна дължина.
+
+Направете конструктор, който приема възрастта и тези три низа, и **копира** стойностите им в динамичната памет.
+Също напишете и деструктор, който коректно трие нужните данни.
+
+### Задача 4 - Динамично-заделени структури в други структури
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week03/Exercise4.cpp)
+
+Имплементирайте структура `Bus`, която публично запазва капацитета хора и километража на един автобус.
+
+Имплементирайте структура `BusWarehouse`, която запазва динамично-заделен масив от автобуси.
+В конструктора се въвежда максималния брой автобуси, който може един `BusWarehouse` да съдържа.
+
+Имплементирайте конструктор, който само инициализира нужните данни, и деструктор който трие каквото трябва.
+Имплементирайте член-функция `AddBus`, която добавя автобус в инстанция на `BusWarehouse`, ако има място за него.
+
+## Лесни задачи
+
+### Задача 5
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week03/Exercise5.cpp)
+
+Имплементирайте структура `Car`, всяка кола пази скрито своя модел като низ с произволна дължина, брой врати и брой седалки като целочислени числа.
+Направете съответните get-ъри, set-ъри, конструктор и деструктор.
+
+Имплементирайте структура `TrafficJam`, която пази произволно дълга редица коли в задръстване.
+Направете и член-функция `AddCar`, която вмъква кола в края на редицата.
+Тази функция може да се извиква произволен брой пъти, затова имплементирайте и оразмеряване на вътрешната редица.
+
+`TrafficJam` трябва да има конструктор, деструктор и тази член-функция.
+
+### Задача 6
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week03/Exercise6.cpp)
+
+Ще работите с N-мерна шахматна дъска.
+
+Направете структура `ChessPiece`, която запазва цвета и типа на фигурата от шах, като първото е целочислена стойност, второто е буква.
+
+Направете структура `ChessBoard`, която по подадено N в конструктора създава шахматна дъска с размер NxN с **указатели** към съответните фигури на дъската.
+Разбира се, някои от тези указатели трябва да сочат към някакви създадени шахматни фигури.
+
+При създаване на дъската, трябва да подредите фигурите.
+На най-долните два реда присъстват белите фигури, на най-горните два - черните.
+За дъска 8х8, фигурите са подредени както нормално:
+
+![](https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/The_chess_board_from_Chess.jpg/1024px-The_chess_board_from_Chess.jpg?20210610045654)
+
+При по-големи дъски започвате да повтаряте редиците, докато при по-малките ги режете, от дясната страна.
+Тоест в дъска 10x10 първите 8 колони изглеждат като на картинката, на 9та колона (отгоре-надолу) имате черен топ, черна пешка, 6 празни места, бяла пешка, бял топ и на последната колона са черен кон, черна пешка, 6 празни места, бяла пешка, бял кон.
+
+Ако N не е поне 5, програмата ви трябва да хвърли грешка.
+Не забравяйте да напишете и деструктор.
+
+### Задача 7
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week03/Exercise7.cpp)
+
+Имате затворени интервали от целочислени числа.
+Разглеждаме смесване на интервали:
+
+- смеската на допиращи се интервали е тяхното слепване, тоест смеската на `[0, 3]` и `[3, 5]` е `[0, 5]`
+- смеската на препокриващи се интервали е тяхното обединение, тоест смеската на `[0, 5]` и `[3, 8]` е `[0, 8]`
+
+В противен случай не можем да смесим интервалите (примерно не можем да смесим `[0, 3]` и `[4, 8]`).
+
+Започвайки от някакво множество с интервали, смесете колкото се може повече от тях и изкарайте всичките резултатни интервали, които не могат повече да се смесят.
+Използвайте структури и член-функции.
+
+### Задача 8
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week03/Exercise8.cpp)
+
+"Моделирайте" (тоест сами се сетете за типовете данни и нужните структури) един град със следните харакетристики.
+
+В града имате два типа сгради: жилищни и търговски.
+
+- Жилищните се харакетиризират с цена на апратамент, бройката етажи, количеството хора, които се побират на един етаж (една стойност за всички етажи) и дали имат мазе, паркомясто и/или таван.
+- Търговските се характеризират с цена на магазин, бройка етажи с паркинг, бройка етажи с магазини и максимално количество магазини, които се побират на един етаж (една стойност за всички етажи).
+
+Градът трябва да пази всички отделни сгради, като допълнително за всяка жилищна трябва да съхранява общата бройка жители, a за всяка търговска - общата бройка отворени магазини.
+Освен това трябва да се съхрани и нещо като карта на всичките сгради: допускаме Старозагоско/Манхатънско подреждане на сградите, тоест всички сгради се намират върху някаква "решетка".
+
+&:question Познавате ли структурата `Pair`?
+
+Имплементирайте възможност за построяване и събаряне на сгради.
+Направете нужните проверки на всички данни: цената да не е отрицателна, бройката жители да не надвишава капацитета на сградата и так. нат.
+
+## Трудни задачи
+
+### Задача 9
+
+Ще разглеждаме нещо като UNIX-базирана файлова система.
+
+Един файл във файловата система се характеризира с идентификационен номер (цяло неотрицателно число), брой твърди връзки (пак цяло неотрицателно число), тип (определен от цяло число) и данни (масив от цели числа).
+Ще разглеждаме два типа файлове: нормални и директории.
+
+В нормалните файлове, данните се интерпретират като една редица от числа.
+
+Директориите запазват имена на файлове (кодирани в числа, по начин който вие решите) и съответните им идентификационни номера.
+Нека имената да са закодирани на четните индекси в данните, докато идентификационните номера: нечетните.
+Когато една директория е запазила име към някакъв файл, броят твърди връзки на съответния файл се увеличава.
+
+Имплементирайте файловата система, чрез нея трябва да можем да създадем или изтрием файлове.
+При изтриване на файл, броят твърди връзки към него се намалява.
+Ако той стане нула, паметта за файла се освобождава.
+
+Във файловата система, всички файлове са подредени на случаен принцип (затова използваме идентификационен номер, вместо индекс в масив).
+Винаги започваме с една празна начална директория.
+
+Двете функции, за създаване и изтриване, трябва да приемат масив от низове, който определя път от директории към желания файл, започвайки от началния файл.
+Тоест, ако бяха подадени низовете `Documents`, `Personal`, `Health`, `receipt.txt`, тогава от началния файл намираме името `Documents` и "влизаме" в директорията със съответния идентификационен номер, в нея намираме името `Personal` и так. нат.
+
+### Задача 10
+
+Намираме се в равнината, при която всички (двуизмерни) координати са **целочислени**.
+
+В нея имаме стъклени панели (прави отсечки), дефинирани с координатите на двете им крайни точки.
+Допълнително всеки панел си има свой цвят (като проценти, между 0 и 1, от цветовете червено, зелено и синьо) и прозрачност (като процент, между 0 и 1).
+
+Също имаме и един лъч, той се характеризира с началния си координат и единичен двуизмерен вектор, определящ неговата посока на движение.
+Този лъч не се пречупва и винаги се движи напред (преместването на лъча се извършва чрез `позиция = позиция + посока`).
+
+Чрез този лъч трябва да изкарате композитния цвят, след като лъча е минал през всички стъклени панели пред него.
+Нека също композитния цвят винаги да има 100% прозрачност.
+
+Примерно, ако лъча премине през един панел с цветови проценти `0,1,0` и прозрачност `0.5` и още един панел с цветови проценти `0,1,1` и прозрачност `0.5`, тогава композитния цвят е `0,1,0.5`.
+
+&:question Колко структури ще ви трябват?
+
+## Признания
+
+Изображението на шахматната дъска от chess.com, направено от Hfjhjoiijklij4 за [Уикипедия](https://commons.wikimedia.org/w/index.php?curid=106440749) под лиценз CC BY-SA 4.0
diff --git a/src/teaching/oop-2023/week4/img/Rotation_matrix.png b/src/teaching/oop-2023/week4/img/Rotation_matrix.png
new file mode 100644
index 0000000..76faa6f
--- /dev/null
+++ b/src/teaching/oop-2023/week4/img/Rotation_matrix.png
Binary files differ
diff --git a/src/teaching/oop-2023/week4/index.md b/src/teaching/oop-2023/week4/index.md
new file mode 100644
index 0000000..b89a7a6
--- /dev/null
+++ b/src/teaching/oop-2023/week4/index.md
@@ -0,0 +1,110 @@
+# Задачи - ООП, Седмица 4, 14.03.2024
+
+GitHub classroom: [classroom.github.com/a/qa_FfWeG](https://classroom.github.com/a/qa_FfWeG)
+
+## Преговорни
+
+### Задача 1 - Капсулация
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week04/Exercise1.cpp)
+
+Имплементирайте структура `Smartphone`, която запазва **скрито**:
+
+- марка, низ с максимална дължина от 128 знака
+- модел, низ с максимална дължина от 512 знака
+- година на произвеждане, неотрицателно целочислено число
+- резолюция на камера, число с плаваща запетая (обозначаващо мегапиксели)
+
+За всяка стойност напревете съответните get-ъри и set-ъри, правейки следните проверки при set-ърите:
+
+- марката и моделът не могат да бъдат празни низове, или пък да надвишават максималната дължина
+- годината трябва да бъде между 2000 и 2024
+- резолюцията не може да бъде отрицателна (може да бъде нула, което показва, че смартфонът няма камера)
+
+При неизпълнено условие, хвърляте грешка.
+
+### Задача 2 - Капсулация с динамична памет
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week04/Exercise2.cpp)
+
+Имплементирайте структура `Bee`, която запазва възрастта на пчела чрез число с плаваща запетая и типа пчела с буква.
+
+Имплементирайте структура `BeeHive`, която запазва динамично-заделен масив с всички реещи се пчели и друг динамично-заделен масив с всички яйца в кошера.
+Размерите на двата масива се подават на конструктора.
+Имплементирайте нужните конструктор и деструктор.
+
+## Лесни задачи
+
+### Задача 3
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week04/Exercise3.cpp)
+
+Имплементирайте структура `Paper`, която запазва своето текстово съдържание като низ от максимум 1024 знака и положително цяло число, определящо номера на страницата.
+
+От входа получавате на един ред цялото текстото съдържание за един обект от тип `Paper` и на следващия ред - бройките копия `N` на дадения обект.
+
+Създайте `Paper` обект със съответното съдържание и номер на страницата `1`.
+Създайте динамично-заделен масив от `Paper` с размер `N`, като първия му елемент е новосъздадения обект, докато останалите са **копия** на първия обект.
+
+При всяко копие, трябва да увеличите номера на страницата.
+Имплементирейте логиката чрез копиращ конструктор.
+
+### Задача 4
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week04/Exercise4.cpp)
+
+Създайте структура `DynamicString`, чиито конструктор приема низ с терминираща нула, заделя точно толкова динамична памет, колкото е нужно да се запази целия низ и копира буквите на низа в тази памет.
+Имплементирайте оператор равно.
+
+&:question Какви данни трябва `DynamicString` да запазва скрито?
+
+&:question Какво трябва оператор равно да направи, ако записваме в `DynamicString` с вече заделена памет?
+ Тоест ако имахме:
+ `DynamicString s1("Hello"); DynamicString s2("World"); s2 = s1;`
+
+### Задача 5
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week04/Exercise5.cpp)
+
+Имплементирайте структура `TVProgram`, която запазва името на предаването като низ от максимум 1024 знака, начало на излъчване и край на излъчване като неотрицателни целочислени числа (като примерно 1347 е един часа и 47 минути следобед).
+Имплементирайте конструктор, деструктор, оператор равно и копиращ конструктор.
+
+Имплементирайте структура `TVChannel`, която запазва динамично заделен масив от `TVProgram`, размера на динамично заделената памет и броя "ненулеви" елементи (програми, добавени с `AddProgram`).
+
+Имплементирайте нейн метод `AddProgram`, който приема `TVProgram` **по копие** и го вмъква на последната свободна позиция в масива.
+Ако масива е пълен, трябва да го "оразмерите" (да направите нов, по-голям масив, да копирате данните от стария в новия, да изтриете стария и да обновите указателя да сочи към новия).
+
+&:question Кога използвате копиращия конструктор на `TVProgram` и кога използвате оператор равно?
+
+## Трудни задачи
+
+### Задача 6
+
+Ще разработим (изключително груба) симулация на вселената.
+За нас, гравитацията няма да бъде сила, която просто привлича тела към себе си, а сила която кара телата около нея да се въртят ("орбитират") в перфектен кръг.
+Имаме много звезди и една планета, като звездите са винаги неподвижни, а планетата се влияе от тях.
+
+Гравитационното привличане на звезда в своя център се определя от ъгъла &theta;<sub>max</sub> (в градуси).
+Планетата се върти около една звезда, използвайки стандартната матрица за ротация:
+
+![](./img/Rotation_matrix.png)
+
+Ъгълът на въртене &theta;, спрямо разстоянието до една звезда, се определя чрез [закона на обратните квадрати](https://en.wikipedia.org/wiki/Inverse-square_law), тоест в зависимост от разстоянието `d` между центъра на звездата и центъра на планетата, то истинският ъгъл на завъртане е &theta; = &theta;<sub>max</sub> * 1 / d^2.
+
+Допълнително, ако имаме повече от една звезда, тогава ще използваме &theta;' = max(&theta;<sub>i</sub> - average(&theta;<sub>1</sub>, ..., &theta;<sub>n</sub>)), където &theta;<sub>i</sub> е намереният ъгъл &theta; за i-тата звезда и имаме n на брой звезди.
+
+Ефектът на това е, че ако имаме две звезди на еднакво разстояние с еднакъв ъгъл, тогава планетата е неподвижна, а ако някоя планета е с малко по-близка, тогава се върти около нея и то съвсем бавно.
+
+Приемаме, че отнема единица време планетата да се завърти с ъгъл &theta;', без значение размера на ъгъла.
+Целта на задачата е да върнете при коя звезда и за колко единици време планетата е успяла да извърши пълна ротация (разбира се, &theta;' и планетата може да се измени след всяка ротация).
+
+Имплементирайте структури:
+
+- `Matrix2x2` и `Matrix2x1`, чиито стойности са числа с плаваща запетая, и с член функции за събиране и умножение (не оператор+, оператор\*)
+- `Coordinate`, която запазва (**не наследява**) точките в пространството като `Matrix2x1` и имплементира събиране, умножение и разстояние между координати и матрици
+- `Star`, запазваща координатата на своя център (`Matrix2x1`) и ъгълът &theta;<sub>max</sub> като число с плаваща запетая.
+ Имплементирайте и метод, който приема планета и връща ъгълът &theta;.
+- `Planet`, запазваща своите координати (`Matrix2x1`) и изминалото време (тоест колко пъти се е движела от началото на симулацията).
+ Имплементирайте метод `OrbitPlanet`, която приема планета и ъгъл &theta;', и се завърта около нея.
+- `Universe`, запазваща всички звездите и планетата.
+ Имплементирайте метод `FullOrbit`, която връща звездата около която планетата е успяла да извърши пълна ротация и времето за което това се е случило.
diff --git a/src/teaching/oop-2023/week5/index.md b/src/teaching/oop-2023/week5/index.md
new file mode 100644
index 0000000..be66316
--- /dev/null
+++ b/src/teaching/oop-2023/week5/index.md
@@ -0,0 +1,116 @@
+# Задачи - ООП, Седмица 5, 21.03.2024
+
+GitHub classroom: [classroom.github.com/a/42ZZ56Mg](https://classroom.github.com/a/42ZZ56Mg)
+
+## Преговорни
+
+### 1 задача - Капсулация с динамична памет
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week05/Exercise1.cpp)
+
+Пациент в болница се характеризира с идентификационен номер (неотрицателно целочислено число) и име (низ от максимум 1024 знака).
+Една болница има максимален капацититет на болни, които може да държи (максимален брой легла за тях).
+
+Конструктора за болницата приема максималния капацитет, като структурата за болницата пази всичките си пациенти.
+Имплементирайте методи `AddPatient`, който добавя нов пациент и `RemovePatient`, който го премахва от болницата.
+
+Не е нужно данните за пациентите да са скрити, но данните в болницата трябва да са.
+
+### 2 задача - Копиращ конструктор и оператор=
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week05/Exercise2.cpp)
+
+Имплементирайте структура `FloatArray`, която запазва динамично-заделен масив от `float` стойности.
+Размерът на масива се подава в конструктора.
+
+Имплементирайте копиращ конструктор, оператор= и get-ър/set-ър за елемент на индекс `i`.
+
+## Лесни задачи
+
+### 3 задача
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week05/Exercise3.cpp)
+
+Имейл се характеризира с две стойности: адресът от който е изпратен (низ с максимална дължина от 128 знака) и съдържание (низ с неограничен размер).
+Съобщението се подава като указател към знак, и трябва да заделите точно толкова динамична памет, колкото ви трябва за целия текст.
+
+Имплементирайте голяма четворка за имейла.
+
+### 4 задача
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week05/Exercise4.cpp)
+
+Имплементирайте структура за касов бон, която запазва скрит динамично-заделен масив от цени (числа с плаваща запетая).
+Можете да добавяте неограничен брой цени в края на касовия бон (ако масива е пълен, създавате по-голям и пренасяте стойностите).
+Можете да премахвате цени според индекс (и всички следващи се преместват с една позиция назад).
+
+Имплементирайте тези функционалности в методи.
+Имплементирайте голяма четворка.
+
+### 5 задача
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week05/Exercise5.cpp)
+
+Един контролен списък (checklist) пази няколко неща: булева стойност, дали е избран или не, текстово съдържание (низ с "произволна" дължина) и масив от контролни списъци (всеки списък от този масив ще наричам "подсписък" за удобство).
+Нека текстовото съдържание да не може да се редактира (задава се в конструктора и няма set-ър).
+
+Имплементирайте добавяне и премахване на подсписък, както и придвижване на подсписък с една позиция наляво или надясно.
+Имплементирайте голяма четворка.
+
+### 6 задача
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week05/Exercise6.cpp)
+
+Имате телефонен указател, който запазва масив от имена (низове).
+В началото винаги започва празен.
+Имплементирайте голяма четворка.
+
+Имплементирайте метод `InsertPerson`, който вмъква ново име в указателя, като вмъкването запазва сортировка по азбучен ред.
+Тоест ако указателя беше `{ "Atanas", "Yavor" }`, тогава след вмъкване на `Boris` ще имаме `{ "Atanas", "Boris", "Yavor" }`.
+
+&:important Имплементирайте вмъкване, запазващо "сортираност" без функция за сортиране!
+
+### 7 задача
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week05/Exercise7.cpp)
+
+Имплементирайте структура водомер, която скрито запазва отчетеното количество вода (double).
+Има **единствено** конструктор по подразбиране, при който отчетеното количество е нула, метод `AddWater`, който увеличава брояча с подаденото количество вода и метод `Print`, който изкарва стойността на брояча на екрана.
+Имплементирайте голяма четворка (когато е нужно).
+
+Имплементирайте структура сграда, която има инсталирани подаден брой водомери.
+
+Имплементирайте метод `SimulateDay`, който "симулира" ден в сградата - към всички датчици се добавят между 0 и 0.42 вода (разглеждаме само числа с максимум 3 цифри след запетаята).
+Количеството е случайно за всеки ден.
+
+Имплементирайте метод `SimulateMonth`, който "симулира" 30 дена в сградата, като на всеки 5 дена се прави "отчет" - всичките водомери се **копират** и запазват във вътрешен масив.
+На края на месеца изкарайте на екрана, на един ред, всичките водомери от първите дни (първи ден на първи отчет, първи ден на втори отчет, ...), вторите дни, ...
+
+### 8 задача
+
+Една интернет заявка се характеризира с тип (низ от максимум 4 знака), версия на протокола (положително число с плаваща запетая) и идентификатор (буква).
+Нека тези данни да са скрити, като единствено могат да се set-нат от конструктора (тоест няма set-ъри, но има get-ъри) и е имлементирана голяма четворка (когато е нужно).
+
+Интернет сървър обработва интернет заявки, като всяка получена заявка я запазва в нормалните логове (динамично-заделен масив със заявки) **и** в логовете за грешки (друг динамично-заделен масив със заявки).
+
+Разглеждаме четири типа заявки: `GET`, `HEAD`, `POST` и `PUT`.
+За всяка сървърът съдържа динамично-заделен масив от низове.
+Имплементирайте методи за добавяне на низ към всеки тип.
+Ако съответния масив от низове е пълен, тогава трябва да го уголемите.
+
+Имплементирайте метод `HandleRequest`, който приема интернет заявка **по копие**, запазва я в нормалните логове и връща първия низ от масива на съответния тип, който започва с идентификатор-буквата.
+Ако такъв низ не съществува, тогава връща низа "Bad request" и добавя заявката **и** в логовете за грешки.
+
+Размерите на логовете се подават на конструктора.
+По принцип добавяте нови заявки в края на лога.
+Логовете са циклични, тоест ако един лог е запълен, тогава трябва да почнете да презаписвате от началото.
+Имплементирайте голяма четворка.
+
+## Трудни задачи
+
+### 9 задача
+
+Имате точки в равнината.
+Намерете най-малкия полукръг, който съдържа половината точки в себе си.
+Точки върху ръбовете на полукръга се броят като част от кръга.
+Центърът на полукръгът трябва да съвпада с някоя от точките.
diff --git a/src/teaching/oop-2023/week6/index.md b/src/teaching/oop-2023/week6/index.md
new file mode 100644
index 0000000..c5bd777
--- /dev/null
+++ b/src/teaching/oop-2023/week6/index.md
@@ -0,0 +1,102 @@
+# Задачи - ООП, Седмица 6, 28.03.2024
+
+GitHub classroom: [classroom.github.com/a/rzSTn5pu](https://classroom.github.com/a/rzSTn5pu)
+
+&:warn В задачите за файлове имплементирайте всички нужни проверки и затваряния
+
+## Преговорни
+
+### 1 задача - Копиращ конструктор и оператор=
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week06/Exercise01.cpp)
+
+Имплементирайте структура `WoodenPlank`, която скрито запазва ширина, дължина и височина на дъската (целочислено), цената ѝ (число с плаваща запетая) и типа дърво (низ с максимум 1024 знака).
+
+Имплементирайте get-ъри, set-ъри, копиращ конструктор, оператор=
+
+### 2 задача - Голяма четворка
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week06/Exercise02.cpp)
+
+Имплементирайте структура `DynamicString`, която скрито запазва указател към низ (в динамичната памет) и неговия размер.
+
+Имплементирайте голяма четворка.
+
+## Лесни задачи
+
+### 3 задача
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week06/Exercise03.cpp)
+
+Имплементирайте програма, която отваря файл (създава го, ако вече не е създаден) и вкарва текста "Hello World!" във файла.
+Името на файла се подава от стандартния вход на един ред.
+
+### 4 задача
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week06/Exercise04.cpp)
+
+Имплементирайте програма, която приема име на файл от стандартния вход.
+Изкарайте последния ред от файла.
+
+Редовете са разделени със знака `\n`.
+
+### 5 задача
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week06/Exercise05.cpp)
+
+Имплементирайте програма, която приема име на файл от стандартния вход.
+Изкарайте броя редове и броя думи във файла.
+
+### 6 задача
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week06/Exercise06.cpp)
+
+От стандартния вход получавате, на два отделни реда, две имена на файлове.
+Вмъкнете съдържанието на втория файл по средата на първия файл.
+
+### 7 задача
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week06/Exercise07.cpp)
+
+От стандартния вход получавате числата m и n, както и името на файл (на свой си ред).
+Изкарайте на екрана от m-тата до n-тата буква (включително) от всеки ред във файла.
+Първата буква на един ред е на индекс 1.
+
+### 8 задача
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week06/Exercise08.cpp)
+
+Имплементирайте структура `FileBuffer`, която в конструктора си приема име на файл, отваря го и запазва (копира) цялото му съдържание в динамичната памет (с указател член-данна).
+
+&:question Кога трябва да затворим файла?
+
+Имплементирайте голяма четворка.
+
+### 9 задача
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week06/Exercise09.cpp)
+
+Имплементирайте структура `Person`, която приема име на човек (низ с максимална дължина от 1024 знака) и неговата възраст (целочислена стойност).
+Имплементирайте методи `Save` и `Load`, които съответно запазват/прочитат данните в (двоичен) файл с подадено име.
+
+## Трудни задачи
+
+### 10 задача
+
+Имплементирайте структура `Table`, която запазва произволен брой колони и редове с низови стойности.
+Броя редове/колони може да се уразмерява по време на изпълнение.
+Имплементирайте голяма четворка.
+
+Имплементирайте методи `AddRow` и `AddColumn`, които вмъкват подадените стойности като нов ред/колона на дадения индекс.
+Аналогично имплементирайте методи `RemoveRow` и `RemoveColumn`.
+**Чрез всички тези** имплементирайте метода `ModifyValue`, който променя стойността на клетката на дадените индекси.
+
+Имплементирайте методи `Save` и `Load`, които запазват/зреждат таблицата в/от файл с подадено име, в текстовия CSV формат (всеки ред в таблицата е ред във файла, всички стойности в реда от таблицата са разделени със запетая в реда във файла).
+
+### 11 задача
+
+Имплементирайте структура `City`, която запазва името на даден град (низ с максимална дължина от 1024 знака) и масив от указатели към други градове, които са негови съседи.
+Имплементирайте методи `AddNeighbour` и `RemoveNeighbour` (броя съседи може да се променя), както и голяма четворка.
+
+Имплементирайте методи `Save` и `Load`, които запазват/зреждат всичките достижими градове от сегашния в/от (бинарен) файл с подадено име.
+Подсказвам, че не можете да запазите указателите ей-така.
diff --git a/src/teaching/oop-2023/week7/index.md b/src/teaching/oop-2023/week7/index.md
new file mode 100644
index 0000000..0eb3899
--- /dev/null
+++ b/src/teaching/oop-2023/week7/index.md
@@ -0,0 +1,83 @@
+# Задачи - ООП, Седмица 7, 04.04.2024
+
+GitHub classroom: [classroom.github.com/a/vvZENbkX](https://classroom.github.com/a/vvZENbkX)
+
+## Преговорни
+
+### Задача 1 - Голяма петица
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week07/Exercise1.cpp)
+
+Една съставка е композирана от низ (с максимална дължина от 511 знака) определящ името ѝ и грамаж (число с плаваща запетая).
+
+Създайте клас `Recipe`, към който могат да се прибавят и премахват произволен брой съставки.
+Имплементирайте голяма петица (голяма четворка плюс move семантики) за него.
+
+### Задача 2 - Работа с файлове
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week07/Exercise2.cpp)
+
+От един ред на входа получавате името на текстови файл.
+Изкарайте на екрана средната една трета от файла, като буквите са в обратен ред.
+
+## Лесни задачи
+
+### Задача 3
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week07/Exercise3.cpp)
+
+Имплементирайте клас `Thermometer`, който запазва максималната и минималната възможна температура за измерване, както и сегашната температура, всичките които са цели неотрицателни числа.
+
+Имплементирайте методи `SaveText` и `LoadText`, които съответно записват и четат (тоест член-данните стават равни на тези от файла) данните си в/от **текстови** файл с подадено име.
+Аналогично имплементирайте `SaveBinary` и `LoadBinary`, които работят с **двоични** файлове.
+
+### Задача 4
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week07/Exercise4.cpp)
+
+Имплементирайте клас `Street`, който запазва скрито името на улицата като низ с произволна дължина и номер като цяло число.
+Имплементирайте голяма петица.
+
+Имплементирайте методите `SaveText`, `LoadText`, `SaveBinary`, `LoadBinary`.
+
+### Задача 5
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week07/Exercise5.cpp)
+
+За един транспортен билет е нужно скрито да пазим началната и крайната дестинация като динамично-заделени низове с произволна дължина, неговата цена като число с плаваща запетая и идентификационен номер като цяло неотрицателно число.
+
+Имплементирайте голяма петица и четирите функции за запазване и четене от файлове на съответния клас.
+
+### Задача 6
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week07/Exercise6.cpp)
+
+Имплементирайте клас `Matrix`, който запазва стойностите на матрица 2 на 2.
+Предефинирайте операторите за инкрементиране, декрементиране, събиране, изваждане, умножение и вход/изход от/към поток.
+
+Имплементирайте четирите функции за записване и четене от файлове.
+
+### Задача 7
+
+Имплементирайте клас `Paragraph`, който съдържа текст с много редове в него.
+Текстът се запазва като низ с произволна дължина, а редовете се разделят със знака `'\n'`.
+
+Имплементирайте голяма петица.
+Имплементирайте четирите функции за записване и четене от файлове.
+
+Имплементирайте операторите за събиране, които копират текстът от подадения параграф и го вмъкват в края на сегашния; оператор[] който връща начален указател на i-тия ред; операторите за (лексикографско) сравнение; вход/изход от/към поток.
+
+## Трудни задачи
+
+### Задача 8
+
+Имплементирайте клас `MatrixNМ`, който запазва стойностите на матрица с N реда и M колони (подадени на конструктор).
+
+Имплементирайте голяма петица.
+Имплементирайте четирите функции за записване и четене от файлове.
+
+Имплементирайте операторите за събиране, изваждане, умножение и деление (нека да дефинираме деление на две матрици като умножението на първата матрица по транспонираната втората матрица върху детерминантата ѝ).
+Ако някоя операция не е възможна, върнете съответна стойност по подразбиране.
+
+Имплементирайте оператор[], като индекса i е числена конкатенация на двете координати, разделени с нула (тоест ако искаме стойността на ред 27 и колона 9, тогава ще въведем индекса 2709).
+Имплементирайте оператори за равенство, инкрементиране, декрементиране, побитово отместване (прилага се върху всяка стойност в матрицата), логически (&& връща true само ако двете матрици са равни, || връща true ако имат еднакви размерности и съществува поне един равен елемент на еднакви индекси).
diff --git a/src/teaching/oop-2023/week8/index.md b/src/teaching/oop-2023/week8/index.md
new file mode 100644
index 0000000..be78f9f
--- /dev/null
+++ b/src/teaching/oop-2023/week8/index.md
@@ -0,0 +1,167 @@
+# Задачи - ООП, Седмица 8, 11.04.2024
+
+GitHub classroom: [classroom.github.com/a/7d0MBjcK](https://classroom.github.com/a/7d0MBjcK)
+
+## Преговорни
+
+### Задача 1 - Голяма петица
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week08/Exercise1.cpp)
+
+Имплементирайте клас `StreetList`, който запазва имената на улици (низове с произволна дължина) в динамичен масив.
+Може да се добавят нови имена в края на списъка, като съответния (вътрешен) масив трябва да се уголеми.
+
+Имплементирайте голяма петица за класа.
+
+### Задача 2 - Файлове и класове
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week08/Exercise2.cpp)
+
+Имплементирайте клас `Person`, който запазва трите имена (низове с произволна дължина) и идентификационния номер (цяло неотрицателно число) на човек.
+Имплементирайте голяма петица.
+
+Имплементирайте методи `SaveText` и `LoadText`, които съответно записват и четат (тоест член-данните стават равни на тези от файла) данните си в/от **текстови** файл с подадено име.
+Аналогично имплементирайте `SaveBinary` и `LoadBinary`, които работят с **двоични** файлове.
+
+## Лесни
+
+### Задача 3
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week08/Exercise3.hpp)
+
+Имплементирайте шаблонната структура `Pair`, която приема два типа и запазва по една стойност от всеки тип.
+
+### Задача 4
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week08/Exercise4.cpp)
+
+Имплементирайте клас `FloatArray`, който съдържа списък с числа с плаваща запетая.
+Може да добавяте нови числа в края на този списък.
+Имплементирйате голяма петица.
+
+Имплементирайте оператори:
+
+- += и +, които конкатенират два FloatArray-я. += вмъква елементите от десния масив в края на левия, + връща нов масив в който първо са елементите от левия масив и след тях са тези от десния.
+- += и +, които приемат FloatArray и число (с плаваща запетая) и го прибавят към всеки елемент на FloatArray-я
+- [], които връщат референция към елементът на подадения индекс. При невалиден хвърлят грешка.
+- == и !=, които сравняват два FloatArray-я покомпонентно.
+ Ако се различават по брой елементи или ако имат две различни стойности на еднакъв индекс, тогава не са равни.
+- <<, който вмъква всички стойности в подадения поток, разделени с шпация
+- >>, който презаписва всички стойности, разделени с шпация, четейки от подадени поток
+
+### Задача 5
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week08/Exercise5.hpp)
+
+Имплементирайте класът и неговите оператори от предходната задача като темплейтен (шаблонен) клас с име `DynamicArray`.
+Очевидно шаблонния тип определя типа на списъка с елементи.
+
+### Задача 6
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week08/Exercise6.cpp)
+
+Имплементирайте клас `NumberInput`, който запазва целочислена стойност.
+В конструктора се подава минимална и максимална възможна стойност, след това (все още в конструктора) се изкарва на екрана съответно съобщение и се приема потребителски вход.
+Ако той не е валиден или е извън подадения обхват, трябва да хвърлите грешка.
+
+В main създайте обект от този клас.
+Ако се хвърли грешка, прихванете я, изкарайте на екрана съответното съобщение и пробвайте пак.
+Това се повтаря докато обекта не е успешно създаден, след което изкарвате въведената стойност по две.
+
+### Задача 7
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week08/Exercise7.cpp)
+
+Имплементирайте клас `UserError`, чиято употреба е да се хвърля като грешка.
+За тази цел нека да запазва два низа, които се приемат в конструктора: името на клас и името на член-данната.
+
+Имплементирайте голяма петица и оператор<<, който изкарва съобщение с информация за класа и член-данната в подадения поток.
+Следете бройката на създадени `UserError` инстанции в самия клас (статична променлива) и имплементирате нужната (статична) член-функция, която връща този брой.
+
+Преобразувайте последната задача, така че да хвърля грешка от този клас.
+В края на програмата изкарайте колко грешки са се хвърлили **използвайки статичните членове на UserError**.
+
+## Трудни задачи
+
+### Задача 8
+
+Имплементирайте шаблонен клас `UserInput`, който запазва стойност от подадения тип.
+Ако типа е указател, тогава заделяте динамична памет за един такъв елемент.
+За проверка на типа използвайте [partial template specialization](https://en.cppreference.com/w/cpp/language/partial_specialization).
+
+В шаблона (`template <...>`) се приема указател към валидираща функция, която приема стойността от съответния тип и връща булева стойност.
+В конструктора се приема от входа нужната стойност и ако стойността е неуспешно приета или валидиращата функция върне false, тогава хвърляте грешка.
+Ако типа е указател, не забравяйте да освободите паметта.
+
+В класа следете статично за броя пъти когато е хвърлена грешка.
+
+### Задача 9
+
+&:important В тази задача се изикват помощни класове, прочетете цялото условие преди имплементиране!
+
+Имплементирайте шаблонен клас `Dictionary`, който запазва два динамично-заделени масива: първия е със стойност от подадения тип, втория е с низове.
+Низовете ще се използват за индексиране, вместо числа.
+Разбира се, очаквайте да може да се уразмерява.
+Имплементирайте голяма петица.
+
+Имплементирайте оператор:
+
+- <<=, който вмъква всички стойности от десния `Dictionary` в левия
+- [], който приема низ и връща референция "към" стойността.
+ Ако няма записана стойност на съответния индекс, тогава връщате референция в която може да се запише стойност.
+- [], който приема число, което се конвертира до низ и работи както предходния оператор
+- [], който приема низове (или числа), разделени със запетая и връща "масив" само с тези стойности
+- delete, който приема стойност, върната от оператор[] и "премахва" съответната стойност от `Dictionary`
+- префиксен++, префиксен+ и префиксен-, които ще се използват за итериране.
+ - ++ връща инкрементира индекса на сегашната стойност.
+ Ако индекса е равен на броя запазени стойности, тогава става нула.
+ По подразбиране индекса е броя.
+ Връща true ако след инкрементиране индекса не е броя.
+ - + връща референция към стойността на сегашния индекс
+ - - връща сегашния (низов) индекс
+- ->, такъв че можем да правим `a->(&func1)->(&func2)` и `a->[&func3]->[&func4]`.
+ Върху всяка двойка индекс-стойност се прилагат &func1 и &func2 (приемат индекс и стойност като параметри), които връщат нова стойност, заместваща сегашната.
+ &func3, &func4 аналогично приемат индекс и стойност, но връщат нов индекс.
+
+В края на задачата трябва да можете да правите:
+
+```cpp
+int doubleUp(const char* index, int value) {
+ return value * 2;
+}
+int sumIndexValue(const char* index, int value) {
+ return atoi(index) + value;
+}
+const char* indToName(const char* index, int value) {
+ if (strcmp(index, "2")) {
+ return "two";
+ }
+ return index;
+}
+
+int main() {
+ Dictionary<int> a;
+ a["first"] = 8;
+ a[2] = 13;
+ a[89] = -68;
+
+ Dictionary<int> b;
+ b["wow"] = 99;
+ b["nth"] = 773;
+
+ a <<= b;
+
+ /* някакъв тип */ two = a["first", 2];
+
+ delete a["wow"];
+
+ a->(&doubleUp)->(&sumIndexValue)->[&indToName];
+
+ while (++a) {
+ std::cout << +a << " at " << -a << ",";
+ /* Ще изкара на конзолата:
+ * 16 at first,52 at two,-12104 at 89,1546 at nth,
+ */
+ }
+}
+```
diff --git a/src/teaching/oop-2023/week9/index.md b/src/teaching/oop-2023/week9/index.md
new file mode 100644
index 0000000..50cea93
--- /dev/null
+++ b/src/teaching/oop-2023/week9/index.md
@@ -0,0 +1,112 @@
+# Задачи - ООП, Седмица 9, 18.04.2024
+
+На днешното упражнение ще решаваме [задачата от Контролно 1](https://learn.fmi.uni-sofia.bg/mod/resource/view.php?id=311448), затова задачите ще са в същия дух (макар и да не включват най-новия материал).
+
+Решението, което писахме по време на практикума, с някои разширения и коментари, може да намерите [тук](https://github.com/Syndamia/oop-2023-solutions/tree/main/week09/Exam1).
+
+GitHub classroom: [classroom.github.com/a/wlL1oUg2](https://classroom.github.com/a/wlL1oUg2)
+
+## Преговорни
+
+### Задача 1 - Голяма петица
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week09/Exercise1)
+
+Реализирайте клас Printer, който съдържа модел като низ с произволна дължина и брой принтирани страници като неотрицателно цяло число.
+Имплементирайте голяма петица.
+
+### Задача 2 - Файлове и класове
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week09/Exercise2)
+
+Реализирайте клас Date, който съдържа номера на деня, месеца и годината в три отделни целочислени член-данни.
+Имплементирайте член-методи `storeText`, `storeBinary`, които съответно запазват данните в текстов файл (във формата "YEAR MONTH DAY") и в двоичен файл с подадени имена.
+Аналогично имплементирайте `loadText` и `loadBinary`, които презаписват член-данните с тези от подадените (имена на) файлове.
+
+В главната функция създайте 5 дати, запазете всяка в **един и същ текстов файл**, след това прочетете датите в **нови** 5 променливи и изкарайте датите в обратен ред.
+
+## Лесни
+
+### Задача 3
+
+&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week09/Exercise3)
+
+Реализирайте клас Train, който съдържа:
+
+- модел като низ с максимална дължина от 127 знака
+- идентификационен номер на релсовата линия върху която се намира, като целочислена неотрицателна стойност
+- име на текстов файл, съдържащ всички райони от сегашната релсова линия, всеки на нов ред.
+ Самото име представяйте като низ с произволна дължина.
+- сегашна локация (район) от релсовата линия като низ с произволна дължина.
+ Тази локация не се подава, и при създаване на обекта винаги е първата във файла.
+
+Имплементирайте методите:
+
+- от голямата петица
+- `TransferNextRegion`, който променя сегашната локация на следващата по ред в текстовия файл (чието име е подадено в конструктор).
+ Ако няма следващо по ред, тогава локацията да си остане същата и да се хвърли грешка.
+ Ако се срещнат проблеми с файла, хвърлете грешка.
+- `SwitchRailLine`, който приема идентификационен номер на релсовата линия и име на текстов файл, и променя вътрешните стойности.
+ Съответно локацията трябва да бъде първата в подадения файл.
+ Ако се срещнат проблеми с файла, хвърлете грешка.
+
+Реализирайте клас TrainNetwork, който съдържа:
+
+- идентификационен код, като низ с максимална дължина от 7 знака
+- масив, запазващ максимум 511 влака (типа се оставя по ваша преценка)
+
+За този клас имплементирайте методите:
+
+- `HaveCollided`, който приема индекс на два влака и връща дали са се блъснали.
+ Това се случва ако в една и съща релсова линия и един и същи регион, когато регионът не е последния възможен.
+- `RunTrains`, който придвижва напред всички влакове, докато не стигнат финалната си възможна дестинация.
+ Влакове които са се ударили не се придвижват напред.
+ Връщате броя ударили се влакове.
+
+Да се имплементира главна функция, в която приемате име на двоичен файл от потребителя.
+В този файл имате някакъв брой редици с идентификационен номер на релсова линия, брой локации върху съответната линия и всички локации като нормални низове, разделени с нови редове.
+
+Допълнително в главната функция приемайте от потребителя влаковете, като имената на текстовите файлове се избират от програмата (**НЕ** от потребителя) според идентификационния номер на релсовата линия и информацията във файла с редиците.
+**Не може да променяте Train класа!**
+
+Последно в главната функция създайте обект от тип TrainNetwork и изкарайте резултата от `RunTrains` на екрана.
+
+## Трудни
+
+### Задача 4
+
+Реализирайте клас Car, в който се запазват:
+
+- марка като низ с максимум 31 знака
+- модел като низ с произволна дължина
+- брой седалки като положително цяло число
+- гладност на човека на всяка седлка като целочислен масив с размер броя седалки
+
+Имплементирайте методи:
+
+- от голямата петица
+- `AddPassenger`, който добавя нов човек на дадения индекс на седалка
+- `RemovePassenger`, който премахва човека от дадения индекс
+- `TotalHunger`, който връща общото количество гладност в колата
+- `StoreData`, който запазва всички данни от колата в **двоичен** файл с подадено име
+- `LoadData`, който презаписва всички данни с тези от подадения по име **двоичен** файл
+
+Реализирайте клас DriveThrough, в който се запазват:
+
+- име на ресторант, към който е свързано съответния проход, като низ с произволна дължина
+- коли на опашка, като масив с коли с произволна дължина
+
+Имплементирайте методи:
+
+- от голяма петица
+- `QueueUp`, който приема кола и я вкарва в края на опашката.
+ Разбира се, масивът се уголемява ако е нужно.
+- `Serve`, който изпълнява поръчката на най-предната кола в опашката.
+ За единица глад, ресторанта може да сготви достатъчно храна (за да нахрани клиента с "единица" храна) за единици време между половината от дължината на името на ресторанта и три пъти дължината на името на ресторанта време.
+ Максималното възможно количество време за изпълнение на поръчката варира и според броя коли в опашка: ако са под 6 на брой, тогава тогава се увеличава с 10%, а ако са над 10 тогава се намалява с по 5% за всяка кола след десетата.
+- `EfficiencyService`, който изпълнява поръчките на всички коли в опашката и връща средно колко време е отнело на поръчка.
+- `StoreData`, който запазва всички данни в **текстов** файл с подадено име
+- `LoadData`, който презаписва всички данни с тези от подадения по име **текстов** файл
+
+Имплементирайте главна функция, в която от потребителския вход приемате име на текстов файл.
+Създайте обект от тип DriveThrough, който да запълни своите стойности с тези от подадения файл и изкарайте на екрана стойността от `EfficiencyService`.
diff --git a/src/teaching/upp-2023/additional1/index.md b/src/teaching/upp-2023/additional1/index.md
index cf1dfce..f366858 100644
--- a/src/teaching/upp-2023/additional1/index.md
+++ b/src/teaching/upp-2023/additional1/index.md
@@ -2,13 +2,13 @@
GitHub classroom: [classroom.github.com/a/nlFuKALw](https://classroom.github.com/a/nlFuKALw)
-При изображението &&question трябва да спрете, да помислите и да си отговорите на дадения въпрос.
+При изображението ![](/img/dialog-question.png) трябва да спрете, да помислите и да си отговорите на дадения въпрос.
Почти винаги ако не може да отговорите, ще имате проблеми в бъдеще с решаването.
Понякога ще ви спираме и ще ви питаме за тези въпроси.
## Задача - База гаднни
-&&warn **Нямате** право да използвате каквито и да е функции, които вие не сте написали, както и неизучаван материал като двуизмерни масиви или динамична памет.
+&:warn **Нямате** право да използвате каквито и да е функции, които вие не сте написали, както и неизучаван материал като двуизмерни масиви или динамична памет.
**Не** употребявайте търсачки, ако ви трябва информация за нещо, ще може да си я изкарате с една проста тестова програма или калкулатор.
<br>
@@ -18,7 +18,7 @@ GitHub classroom: [classroom.github.com/a/nlFuKALw](https://classroom.github.com
Таблица А има максимум 8 реда, като всеки ред е едно цяло число с 9 цифри.
Таблица Б има максимум 8 реда, като всеки ред е число между 1 и 4294967295.
-&&question В какъв тип ще запазим всяка таблица?
+&:question В какъв тип ще запазим всяка таблица?
В задачата винаги номерираме редовете (числата) на всяка таблица, започвайки от индекс 1.
Чрез различни комбинации на ред в таблица А и ред в таблица Б получаваме различни стойности.
@@ -39,11 +39,11 @@ GitHub classroom: [classroom.github.com/a/nlFuKALw](https://classroom.github.com
Стойностите от таблица А са винаги ограничени отгоре с най-големия брой битове, които комфортно може да поберем в 7 цифри.
Тоест 9999999 не е валидна стойност от таблица А, докато 8388608 e.
-&&question Колко най-много *битове* можем със сигурност да поберем в 7 цифри?
+&:question Колко най-много *битове* можем със сигурност да поберем в 7 цифри?
Понеже редовете са от 1 до 9, ако в таблица А имаме ред 0 правим нещо специално, но това ще видите в бъдеще.
-&&question Разбрахте ли как таблиците "изглеждат"?
+&:question Разбрахте ли как таблиците "изглеждат"?
### a) разделяне на реда от таблица А
@@ -52,7 +52,7 @@ GitHub classroom: [classroom.github.com/a/nlFuKALw](https://classroom.github.com
`getRow` - приема ред от таблица А и указатели към променливи за ред, тип и стойност; не връща нищо
В подадените указатели пази съответните стойности от реда
-&&question Защо приемаме указатели към променливи? Каква е "сигнатурата" на функцията?
+&:question Защо приемаме указатели към променливи? Каква е "сигнатурата" на функцията?
<br>
**Примери:**
@@ -68,7 +68,7 @@ GitHub classroom: [classroom.github.com/a/nlFuKALw](https://classroom.github.com
Ако типа е цифрата "0", тогава стойността в базата данни е някакво число с плаваща запетая.
Самото число е разделено на две части: цифрите преди запетаята се намират в стойността от таблица А, докато цифрите след запетаята са в реда от таблица Б.
-&&question В какъв тип данни трябва да запазим числото? Как ще "слепим" двете му части.
+&:question В какъв тип данни трябва да запазим числото? Как ще "слепим" двете му части.
Имплементирайте функция:
@@ -107,14 +107,14 @@ GitHub classroom: [classroom.github.com/a/nlFuKALw](https://classroom.github.com
Тоест ако в нашия тип данни запазваме само 10 бита, тогава числото "2" ще бъде `0000000010` и имаме низа "AC".
Игнорирайте старшите битове, които остават като "остатък" (по-малко от 5 бита ширина).
-&&question Колко бита наистина запазваме в нашия тип данни? Колко бита ще трябва да игнорираме? Колко най-много букви може да поберем?
+&:question Колко бита наистина запазваме в нашия тип данни? Колко бита ще трябва да игнорираме? Колко най-много букви може да поберем?
Имплементирайте функция:
`decodeNumberText` - приема ред от таблица Б и указател към "низ"; не връща нищо
Записва декодиран текстът от реда в указателя
-&&question Нарочно има кавички около думата "низ", какъв трябва наистина да е типа на указателя?
+&:question Нарочно има кавички около думата "низ", какъв трябва наистина да е типа на указателя?
<br>
**Примери:**
@@ -135,7 +135,7 @@ GitHub classroom: [classroom.github.com/a/nlFuKALw](https://classroom.github.com
Как декодираме?
Отместваме буквите назад, тоест ако имаме текста "KHOOR" и ви кажа, че съм го кодирал като съм отместил всяка буква напред с 3 позиции, тогава при декодиране от K става на H, от H става на E, от О става на L и от R става на O.
-&&question Какво става със знака "!"? Има ли лесен (математически) начин да дешифрираме всяка буква?
+&:question Какво става със знака "!"? Има ли лесен (математически) начин да дешифрираме всяка буква?
Текстът, преди да е въведен в нашата база данни, ще бъде кодиран с шифъра на Цезар, като броя позиции с които сме отместили буквите се намира в стойността в таблица А.
@@ -162,7 +162,7 @@ GitHub classroom: [classroom.github.com/a/nlFuKALw](https://classroom.github.com
Ако типа е "2", тогава в реда от Б сме вложили масив от стойности (числа).
Всеки 4 бита определят една стойност, като първия елемент е старшите (най-левите) битове, докато последния е младшите (най-десните) битове.
-&&question Коколо на брой елемента пазим в реда от Б?
+&:question Коколо на брой елемента пазим в реда от Б?
Имплементирайте функцията:
@@ -207,7 +207,7 @@ GitHub classroom: [classroom.github.com/a/nlFuKALw](https://classroom.github.com
Ако редът в таблица А е 0, тогава цялата стойност в базата данни е побрана в стойността на таблица А.
Очевидно само в стойност на таблица А имаме по-малко битове, отколкото в стойност на таблица А плюс ред в таблица Б, затова се налага по някакъв начин да "компресираме" информацията, така че да се побере.
-&&question Колко бита побираме в стойност на таблица А? Колко бита ни трябват общо, за да обработим една стойност в базата данни?
+&:question Колко бита побираме в стойност на таблица А? Колко бита ни трябват общо, за да обработим една стойност в базата данни?
Ще го направим така: в стойността от таблица А ще пазим индекси, и всеки индекс ще съответства на някакво по-голямо число, което се съдържа в друг масив, който ще наричаме криптографски ред.
@@ -225,7 +225,7 @@ GitHub classroom: [classroom.github.com/a/nlFuKALw](https://classroom.github.com
Първите (най-левите) три бита от стойността в таблица А не са индекси, а трябва да се копират дословно.
След тях има 4 индекса, всеки с по 5 бита.
-&&question Как е разделена побитово една стойност от таблица А? Кои индекси за кои стойности ще се ползват? Достатъчно ли е всеки индекс към криптографския ред да бъде само 5 бита (тоест може ли да има повече от 2&#8309; числа в реда)? Защо имаме само 4 индекса?
+&:question Как е разделена побитово една стойност от таблица А? Кои индекси за кои стойности ще се ползват? Достатъчно ли е всеки индекс към криптографския ред да бъде само 5 бита (тоест може ли да има повече от 2&#8309; числа в реда)? Защо имаме само 4 индекса?
Напишете функция:
@@ -266,4 +266,4 @@ GitHub classroom: [classroom.github.com/a/nlFuKALw](https://classroom.github.com
Пробвате се да я запазите, използвайки и двете таблици, но ако Б вече е запълнена, добавяте я като компресирана стойност в таблица А.
Ако и А е запълнена, изкарвате съобщение за запълнена база данни и не запазвате стойността.
-&&question Какво трябва да направите, ако получите компресирана стойност за таблица А?
+&:question Какво трябва да направите, ако получите компресирана стойност за таблица А?
diff --git a/src/teaching/upp-2023/additional2/index.md b/src/teaching/upp-2023/additional2/index.md
index 75530f8..d4e07b4 100644
--- a/src/teaching/upp-2023/additional2/index.md
+++ b/src/teaching/upp-2023/additional2/index.md
@@ -2,7 +2,7 @@
GitHub classroom: [classroom.github.com/a/CrerXpf6](https://classroom.github.com/a/CrerXpf6)
-&&important Следете внимателно дали триете всичката си динамична памет коректно на всяка подточка!
+&:important Следете внимателно дали триете всичката си динамична памет коректно на всяка подточка!
Случвало се е на контролни да се пишат двойки ако всичко друго е коректно, но има неизтрита памет!
## Задача - текстов редактор
@@ -18,7 +18,7 @@ GitHub classroom: [classroom.github.com/a/CrerXpf6](https://classroom.github.com
Като за начало, нека да имплементираме запазването на текст.
От конзолата ще получавате редове текст, всеки ред ще е с максимална дължина от 1024 знака, след това трябва да го запазите.
-&&important Може да използвате масив със статична дължина за буфер, обаче трябва да използвате възможно най-малко памет за "перманентното" запазване на реда текст във вашата програма.
+&:important Може да използвате масив със статична дължина за буфер, обаче трябва да използвате възможно най-малко памет за "перманентното" запазване на реда текст във вашата програма.
Използвайте многомерен масив за запазване на редовете, вместо всичко да се запазва в един голям низ.
Това е нужно за бъдещи подточки.
@@ -58,10 +58,10 @@ est. It was a high bank, and he paused to breathe at the top.
Ако низът е команда, тогава връща масив от низове, първия от които съдържа буквата, определяща командата, докато останалите низове са параметрите.
Ако низът не е команда, тогава връща празен масив.
-&&warn Какво означава празен масив зависи от имплементацията ви.
+&:warn Какво означава празен масив зависи от имплементацията ви.
За предпочитане е да не заделяте памет, когато не е нужно.
-&&question Как ще върнем масив? Нужно ли е да връщаме бройката елементи?
+&:question Как ще върнем масив? Нужно ли е да връщаме бройката елементи?
*Само за тестване*, след всеки въведен ред, ако е команда, изкарайте извлечените стойности от `extractCommand`, със запетайки след всяка.
Като при [подточка a)](#section), ако редът започва с `Q`, спирате приемане на вход и изкарвате запазения текст.
@@ -195,9 +195,9 @@ the man turned aside from the main Yukon trail. He climbed the high
Имплементирайте функцията `deleteRow`, която получава целия текст, въведен до сега, и номер на реда (редовете се индексират от 1 до N).
Тя променя текста, като премахва реда на дадения номер.
-&&important Не забравяйте да промените размера на масива с низове! Не е решение просто да промените указателя към дадения ред на `nullptr`, не искаме да използваме излишна памет.
+&:important Не забравяйте да промените размера на масива с низове! Не е решение просто да промените указателя към дадения ред на `nullptr`, не искаме да използваме излишна памет.
-&&question Какъв ще бъде типа на аргумента, който приема целия текст?
+&:question Какъв ще бъде типа на аргумента, който приема целия текст?
Добавете командата `D`, която приема един параметър - цяло положително число, и го прилага върху функцията `deleteRow`.
Ако номера на реда е невалиден, трябва да изкарате съобщение "; Invalid row number".
@@ -297,7 +297,7 @@ He excused
Ред N+1 се изтрива.
Ако N е 0 или номера на последния ред, не прави нищо.
-&&important Не забравяйте да промените размера на масива с низове! Не е решение просто да промените указателя към дадения ред на `nullptr`, не искаме да използваме излишна памет.
+&:important Не забравяйте да промените размера на масива с низове! Не е решение просто да промените указателя към дадения ред на `nullptr`, не искаме да използваме излишна памет.
Добавете команда `J`, която приема номер на ред - положително число.
Следващия ред ще се вмъкне в края на сегашния, с една шпация между тях, използвайки функцията `joinRows`.
@@ -372,7 +372,7 @@ est. It was a high bank, and he paused to breathe at the top.
Имплементирайте функция `substituteWord`, която приема целия текст и две думи (низове без шпации).
В текстът, всяко срещане на първата дума е заменено с втората дума.
-&&question Какво ще стане с размера на един ред, ако някоя дума/някои думи трябва да се заменят?
+&:question Какво ще стане с размера на един ред, ако някоя дума/някои думи трябва да се заменят?
Добавете команда `s`, която приема две думи - низове без шпации.
Използвайки функцията `substituteWord` замества всяко срещане на първата дума с втората.
diff --git a/src/teaching/upp-2023/index.md b/src/teaching/upp-2023/index.md
index 9ef5d77..624a312 100644
--- a/src/teaching/upp-2023/index.md
+++ b/src/teaching/upp-2023/index.md
@@ -2,7 +2,7 @@
Материали на проведените през 2023/2024 практикуми по Увод в програмирането на Компютърни науки (2 поток), 8 група.
-&&warn От сега нататък ще може да продължите да предавате решения след крайния срок в classroom.
+&:warn От сега нататък ще може да продължите да предавате решения след крайния срок в classroom.
Не мога да гарантирам кога ще погледна предадени решения след срока, но ще ги погледна!
**Зала:** ФМИ 309 ||
@@ -26,5 +26,10 @@
|6 |10.11.2023|[Задачи](./week6) \|\| [Решения](https://github.com/Syndamia/upp-2023-solutions/tree/main/week06) \|\| [GitHub classroom](https://classroom.github.com/a/BBLlWMOy)|
|7 |17.11.2023|[Задачи](./week7) \|\| [Решения](https://github.com/Syndamia/upp-2023-solutions/tree/main/week07) \|\| [GitHub classroom](https://classroom.github.com/a/m5M2_CWD)|
|8 |24.11.2023|[Задачи](./week8) \|\| [Решения](https://github.com/Syndamia/upp-2023-solutions/tree/main/week08) \|\| [GitHub classroom](https://classroom.github.com/a/Big7FRUG)|
-|9 |01.12.2023|[Задачи](./week9) \|\| [GitHub classroom](https://classroom.github.com/a/lGXxCRZO)|
-| |04.12.2023|[Допълнително упражнение 2](./additional2/) \|\| [GitHub classroom](https://classroom.github.com/a/CrerXpf6)|
+|9 |01.12.2023|[Задачи](./week9) \|\| [Решения](https://github.com/Syndamia/upp-2023-solutions/tree/main/week09) \|\| [GitHub classroom](https://classroom.github.com/a/lGXxCRZO)|
+| |04.12.2023|[Допълнително упражнение 2](./additional2/) \|\| [Решения](https://github.com/Syndamia/upp-2023-solutions/tree/main/additional2) \|\| [GitHub classroom](https://classroom.github.com/a/CrerXpf6)|
+|10|15.12.2023|[Задачи](./week10) \|\| [Решения](https://github.com/Syndamia/upp-2023-solutions/tree/main/week10) \|\| [GitHub classroom](https://classroom.github.com/a/EJcTQRz4)|
+|11|22.12.2023|[Задачи](./week11) \|\| [Решения](https://github.com/Syndamia/upp-2023-solutions/tree/main/week11) \|\| [GitHub classroom](https://classroom.github.com/a/cZRnZj9y)|
+|12|05.01.2024|[Задачи](./week12) \|\| [Решения](https://github.com/Syndamia/upp-2023-solutions/tree/main/week12) \|\| [GitHub classroom](https://classroom.github.com/a/KEDSxDjl)|
+|13|12.01.2024|[Задачи](./week13) \|\| [GitHub classroom](https://classroom.github.com/a/bgiFD6SB)|
+|14|19.01.2024|[Задачи](./week14) \|\| [GitHub classroom](https://classroom.github.com/a/B08TtnnW)|
diff --git a/src/teaching/upp-2023/week1/setup.md b/src/teaching/upp-2023/week1/setup.md
index 73507a7..9327b2b 100644
--- a/src/teaching/upp-2023/week1/setup.md
+++ b/src/teaching/upp-2023/week1/setup.md
@@ -1,15 +1,16 @@
# Конфигуриране на GitHub classroom и Visual Studio - УПП, Седмица 1, 06.10.2023
-&&presentation
-&&clide &&centered
+&.presentation
+
+&[title
# Конфигуриране на GitHub classroom и Visual Studiо
-&&/centered &&/clide
+&]
-&&slide
+&[slide
## Теория относно GitHub classroom
@@ -26,15 +27,15 @@
- Обединението на труда на всички, особено в огромни екипи, става супер трудно
-&&/slide
+&]
-&&slide
+&[slide
### Git
-&&lineb1
+&.br1
git е програма (система) за [контрол на версиите](https://en.wikipedia.org/wiki/Distributed_version_control).
В един проект, git пази **списък от всички commit-и**.
@@ -47,15 +48,15 @@ git е програма (система) за [контрол на версииÑ
Така, когато смесваме кода от многото разработчици, ще можем да засечем **какви точно са различията** между работата на двама човека.
Често промените не си "противоречат" и могат да бъдат смесени директно, понякога се налага ръчно да решим какво точно да се случи с тези парчета код.
-&&/slide
+&]
-&&slide
+&[slide
### GitHub
-&&lineb5
+&.br5
Всички repository-та трябва да се пазят някъде и да може лесно да се споделят и гледат.
Има много сайтове за тази цел, най-популярния се нарича [GitHub](https://github.com).
@@ -63,11 +64,11 @@ git е програма (система) за [контрол на версииÑ
Напомням, че git и GitHub са напълно отделни неща, направени от различни хора с различни функционалности.
Свързаността с имената е както свързаността между думите "чар" и "чаршаф".
-&&/slide
+&]
-&&slide
+&[slide
## Сега всички трябва да си направят GitHub акаунти
@@ -75,24 +76,24 @@ git е програма (система) за [контрол на версииÑ
![](./img/github-signup.gif)
-&&/slide
+&]
-&&clide
+&[middle
След това, като влезете в акаунтите си (което става автоматично след регистрация), на заглавната страница ще имате нещо такова:
-&&width75 ![](./img/github-index.gif) &&/width
+&(width75% ![](./img/github-index.gif) &)
В горния десен ъгъл, където е иконката с квадрати на бял фон, след натискане получавате sidebar.
От него, може да достъпите профила си, repository-та които имате, и так. нат.
-&&/clide
+&]
-&&slide
+&[slide
### Проверете дали сте маркирани!
@@ -105,15 +106,15 @@ git е програма (система) за [контрол на версииÑ
![](./img/github-support-flagged.gif)
-&&/slide
+&]
-&&slide
+&[slide
## GitHub classroom
-&&lineb3
+&.br3
За всеки практикум ще ви направя линк, чрез който след малко кликане ще се създаде ново лично repository за всеки от вас.
@@ -124,38 +125,37 @@ GitHub предоставя лесни начини да правите пром
Те ще се намират в таба "Pull Requests" на конкретното repository.
Четете ги, отговаряйте, целта е да дискутираме какво сте направили.
-&&/slide
+&]
-&&slide
+&[slide
### Как ползваме GitHub classroom
За всяко упражнение ще има отделен линк.
Този за днеска е: [classroom.github.com/a/W7hZDMgC](https://classroom.github.com/a/W7hZDMgC)
-&&lineb1
+&.br1
-&&table
+&{row
След като го отворите, ще видите съобщение за разрешение, авторизирайте го.
![](./img/github-classroom-authorize.gif)
-&&/table
-
-&&/slide
+&}
+&]
-&&clide
+&[middle
-&&table
+&{row
-&&width60 ![](./img/join-the-classroom.gif) &&/width
+&(width60% ![](./img/join-the-classroom.gif) &)
-&&cont
+&{column
При първо влизане ще получите страница с имената и факултетните имена на всички студенти от групата.
@@ -163,30 +163,29 @@ GitHub предоставя лесни начини да правите пром
Това се прави само веднъж, и след това никога пак.
-&&/cont
-
-&&/table
+&}
-&&/clide
+&}
+&]
-&&slide
+&[slide
След това, би трябвало да видите страницата за "Приемане на заданието".
-&&width40 ![](./img/accept-assignment.gif) &&/width
+&(width40% ![](./img/accept-assignment.gif) &)
След като го приемете, на новата страница, изчакайте няколко секунди и презаредете.
Трябва да видите това:
-&&width40 ![](./img/ready-to-go.gif) &&/width
+&(width40% ![](./img/ready-to-go.gif) &)
-&&/slide
+&]
-&&clide
+&[middle
Сега сте готови, кликнете върху синия линк и ще стигнете във вашето GitHub repository.
@@ -197,28 +196,28 @@ GitHub предоставя лесни начини да правите пром
В края на презентация показвам как точно е най-лесно да качите работата си.
-&&/clide
+&]
-&&slide
+&[slide
В таба "Pull requests", още от началото, ще имате едно "Feedback".
В него ще ви връщам отзиви относно работата ви, и вие също можете да пишете неща и да ми отговаряте.
Целта е да видя какво правите и да ви помогна, моля проверявайте какво съм ви писал, по подразбиране би трябвало да получавате известия на имейл-а.
-&&centered &&width80 ![](./img/feedback.gif) &&/width &&/centered
+&(centered &(width80% ![](./img/feedback.gif) &) &)
-&&/slide
+&]
-&&slide
+&[slide
## Къде пишем код?
-&&lineb2
+&.br2
**Кодът е чисто и просто текст**, компилаторът е специалната програма, която превръща този текст в нещо, което може компютъра да изпълни.
@@ -228,11 +227,11 @@ GitHub предоставя лесни начини да правите пром
За някои и това не е било достатъчно удобно, затова са създадени **Integrated Development Environment** (IDE), програми които съдържат в себе си всичко нужно за разработка на код.
Тоест, те са текстови редактори, но "вградено" могат да компилират код, да менижират сегашното repository, ...
-&&/slide
+&]
-&&clide
+&[middle
Главно очакваме да пишете на IDE-то наречено Visual Studio.
Разработено е от Microsoft и е едно от най-използваните и развитите IDE-та на пазара.
@@ -246,15 +245,15 @@ GitHub предоставя лесни начини да правите пром
Извън това, по лично желание, с мен може да говорите за vim, а за neovim може би ще мога да ви насоча към някой с опит.
-&&/clide
+&]
-&&slide
+&[slide
### Инсталация
-&&lineb1
+&.br1
Намираме се в компютърна зала, така че всички предоставени компютри би трябвало вече да са налични на предоставените компютри.
За ваши лични машини, ще минем набързо през информацията тук.
@@ -265,79 +264,79 @@ GitHub предоставя лесни начини да правите пром
- Ако искате да ползвате по-стара ОС, като Windows 8.1 или Windows 7 ще трябва да използвате "Community 2019"[^vs-2022-old-win], разликата между версиите не е съществена, затова не се притеснявайте.
-&&/slide
+&]
-&&slide
+&[slide
След като изтеглите инсталатора за Visual Studio и след като изчакате да заредят работи, би трябвало да имате прозорец на име "Installing - Visual Studio Community 2022".
Единствено избирате "Desktop development with C++" в таба Worloads, и натискате "Install".
Би трябвало да заема към 11 GB памет и в моето тестване се инсталира за 10тина минути.
-&&centered &&width80 ![](./img/vs-install.gif) &&/width &&/centered
+&(centered &(width80% ![](./img/vs-install.gif) &) &)
-&&/slide
+&]
-&&slide
+&[slide
Когато е готово, би трябвало да се включи автоматично и да имате прозорец с име "Sign in to Visual Studio".
За сега това не е нужно, спокойно изберете "Not now, maybe later."
След това, на "Start with a familiar environment", отново, не е нужно да променяте нищо, просто натиснете "Start Visual Studio".
-&&centered &&width75 &&table
+&(centered &(width75% &{row
![](./img/vs-signin.gif)
![](./img/vs-start-env.gif)
-&&/table &&/width &&/centered
+&} &) &)
-&&/slide
+&]
-&&slide
+&[slide
### Как да създадем проект с Visual Studio
Това е първия прозорец, който се отваря.
В лявата колона имате скорошни проекти, в дясната имате начини да създадете нов проект.
-&&centered &&width80 ![](./img/vs-open-recent.gif) &&/width &&/centered
+&(centered &(width80% ![](./img/vs-open-recent.gif) &) &)
-&&/slide
+&]
-&&slide
+&[slide
Нека да направим нов проект, кликнете "Create a new project".
В този прозорец избирате началната "конфигурация" на проекта.
В този курс ще работим само и единствено с "Console App", затова изберете него и кликнете "Next".
-&&centered &&width75 ![](./img/vs-create-project.gif) &&/width &&/centered
+&(centered &(width75% ![](./img/vs-create-project.gif) &) &)
-&&/slide
+&]
-&&slide
+&[slide
Последния прозорец преди писането на код е за конфигурация на проекта.
Тук единствено може да искате да промените Project Name и Location, другото не е важно.
-&&centered &&width80 ![](./img/vs-configure-project.gif) &&/width &&/centered
+&(centered &(width80% ![](./img/vs-configure-project.gif) &) &)
-&&/slide
+&]
-&&slide
+&[slide
#### Бърза вметка, какво и защо конзолата?
@@ -351,50 +350,50 @@ GitHub предоставя лесни начини да правите пром
Чисто практически, ние това знаем като конзолата: устройство (или в модерно време, програма) което може да получи входен текст и да изкара текст.
-&&/slide
+&]
-&&slide
+&[slide
### Как да компилираме с Visual Studio
След малко чакане, най-после ще се намираме в средата за писане на код.
-&&centered &&width60 ![](./img/vs-general.gif) &&/width &&/centered
+&(centered &(width60% ![](./img/vs-general.gif) &) &)
В Solution Explorer имате всички файлове от проекта (Visual Studio позволява да групирате няколко проекта в едно, наречено Solution, не е нужно да се занимавате).
Тук **единственото важно за вас се намира в папката "Source Files"**.
В нея ще се намира вашия код, всичко останало са допълнителни неща, които са релевантни за по-големи проекти.
-&&/slide
+&]
-&&slide
+&[slide
-&&table
+&{row
Компилирането на код става от менюто "Debug" най-отгоре, и след това избиране на "Start Without Debugging".
-&&width50 &&fright ![](./img/vs-debug-menu.gif) &&/fright &&/width
+&(width50% &(fright ![](./img/vs-debug-menu.gif) &) &)
-&&/table
+&}
След малко чакане, би трябвало да излезе един прозорец, който изглежда горе-долу така:
![](./img/vs-console.gif)
-&&/slide
+&]
-&&slide
+&[slide
### Как да дебъгваме с Visual Studio
-&&lineb1
+&.br1
Bug е когато нещо непланирано се случи в кода.
Debuging е глаголът за откриване на причината за един bug.
@@ -406,11 +405,11 @@ Visual Studio предоставя много функционалности, к
![](./img/vs-build-errors.gif)
-&&/slide
+&]
-&&slide
+&[slide
Нека да натиснем "No" и да погледнем Visual Studio.
@@ -419,13 +418,13 @@ Visual Studio предоставя много функционалности, к
Грешки също се виждат в така наречения "Error List", който се намира директно под кода.
Той се появява когато при компилиране получим грешки и изчезва когато няма.
-&&centered &&width70 ![](./img/vs-errors.gif) &&/width &&/centered
+&(centered &(width70% ![](./img/vs-errors.gif) &) &)
-&&/slide
+&]
-&&slide
+&[slide
### Качване на решенията
@@ -443,14 +442,14 @@ Visual Studio предоставя много функционалности, к
Горе в дясно натискате "Commit changes...", в pop-up-a после пак натискате "Commit changes" (ако искате, променяйте "Commit message" и "Extended description", но не е нужно) и сте готови с този файл/задача.
-&&/slide
+&]
-&&clide
+&[middle
## Вече имате достатъчно информация да пишете код сами, [време е за задачи](./)
-&&/clide
+&]
[^vs-2022-old-win]: Може би има трикове с които да инсталирате 2022 версията, но те не са официални и затова няма да го преподам
diff --git a/src/teaching/upp-2023/week1/welcome.md b/src/teaching/upp-2023/week1/welcome.md
index dfa46f0..a1cb6a0 100644
--- a/src/teaching/upp-2023/week1/welcome.md
+++ b/src/teaching/upp-2023/week1/welcome.md
@@ -1,52 +1,52 @@
# Добре дошли - УПП, Седмица 1, 06.10.2023
-&&presentation
+&.presentation
-&&slide &&centered &&font35
+&[title35
# Добре дошли
-&&width65
+&(width65%
[![](https://upload.wikimedia.org/wikipedia/commons/3/3c/Chimpanzee_seated_at_typewriter.jpg)](https://en.wikipedia.org/wiki/Infinite_monkey_theorem)
-&&/width
+&)
-&&/font &&/centered &&/slide
+&]
-&&slide
+&[slide
## Кой съм аз
-&&lineb2
+&.br2
-&&font35
+&(font35
Казвам се Камен (моля не ми говорете на Вие), в момента съм третокурсник в КН2.
-&&lineb1
+&.br1
Ще водя практикуми - давам ви задачи, вие ги решавате и на живо оправяме проблеми.
-&&lineb1
+&.br1
Също ще проверявам част от домашните и контролните през семестъра.
-&&/font
+&)
-&&/slide
+&]
-&&slide
+&[slide
## Кои сте вие
Айде сега, ред по ред:
-&&lineb2
+&.br3
-&&font35
+&(font35
- Име
- Едва ли ще го запомня сега, не ми се сърдете :)
@@ -56,24 +56,24 @@
- в какво IDE/текстов редактор?
- как сте се научили (чрез интернет, курсове, ...)? Ходили ли сте на курсове? Къде?
-&&/font
+&)
-&&/slide
+&]
-&&slide
+&[slide
## Чисто организационно
-&&lineb3
+&.br3
-&&centered &&font35
+&(centered35
Задачи, презентации, ...
[syndamia.com/teaching/upp-2023](/teaching/upp-2023)
-&&/font &&/centered
+&)
-&&lineb3
+&.br3
- Не сме в училище, ако трябва да излезете за разговор или до тоалетна, просто си излезте (за предпочитане по-тихичко).
@@ -82,11 +82,11 @@
- Оценяване: ще разберете на първата лекция
-&&/slide
+&]
-&&slide
+&[slide
## Как можете да се свържете
@@ -101,11 +101,11 @@
Директни линкове към Facebook и Discord има на [профила ми в мудъл](https://learn.fmi.uni-sofia.bg/user/profile.php?id=23229).
-&&/slide
+&]
-&&slide
+&[slide
## Как ще протичат практикумите
@@ -121,11 +121,11 @@
- Ще качвам решения на задачите, заедно с подробно коментари върху тях, тук: [github.com/Syndamia/upp-2023-solutions](https://github.com/Syndamia/upp-2023-solutions).
Това ще се случва в началото на следващия практикум, тоест ще имате една седмица, от деня в който ви давам задачите, през която няма да имате решения.
-&&/slide
+&]
-&&clide
+&[middle
- Ще използваме GitHub classroom, където ще трябва да качите работата си през упражнението.
Целта е да видя какво сте правили и да връщам обратна връзка на всеки.
@@ -136,11 +136,11 @@
- Обратна връзка със сигурност ще правя за нещата, предадени по време на практикума.
Окуражавам ви да си решите всички задачи и след упражнението, обаче все пак имам лимитирано време, ако искате можете да се свържете с мен за работата ви по някоя от тях, но не гарантирам кога ще мога да го видя.
-&&/clide
+&]
-&&slide
+&[slide
## Оплаквайте се!
@@ -149,7 +149,7 @@
Ако задачите са трудни, зле направени, ако нещо не обяснявам като хората, изобщо ако нещо не е ок, свържете се с мен, ще го обсъдим.
-&&lineb3
+&.br3
## Помагайте си!
@@ -159,17 +159,17 @@
Със сигурност няма да успея да помогна на всеки по всяко време от практикума, не се страхувайте да питате съседите си за помощ.
-&&/slide
+&]
-&&slide
+&[slide
## Няколко съвета в позицията ми на третокурсник
-&&lineb2
+&.br2
-&&font35
+&(font35
- **НЕ плагиатствайте!**
**НЕ си качвайте решенията на контролни или домашни онлайн!**
@@ -179,47 +179,47 @@
За хората с опит, ще дойде време когато ще искате да приложите лични знания и практики.
Ако не е казано някъде, не го правите и не го обмисляте!
-&&/font &&/slide
+&) &]
-&&clide &&centered
+&[title
# Въпроси ?
-&&/centered &&/clide
+&]
-&&clide &&centered
+&[title
# ФМИ в контекста на програмирането
Или защо учим толкова много математика
-&&lineb2
+&.br2
-&&font22
+&(font22
Ще си позволя едно отклонение.
Искам да обясня как **аз лично** виждам
математиката в компютърния свят.
-&&/font
+&)
-&&/centered &&/clide
+&]
-&&slide
+&[slide
## В КН2 има много и трудна математика
-&&table
+&{row
-&&width35
+&(width35%
![](./img/u4-mat-hard.gif)
-&&/width
+&)
-&&cont
+&{column
- Жълто - математически предмет
- Червено - проблемни предмети
@@ -230,14 +230,14 @@
- Към половината предмети са математики
- Почти всички проблемни са наблъскани в 1ви курс
-&&/cont
+&}
-&&/table
-&&/slide
+&}
+&]
-&&slide
+&[slide
## Защо учим толкова много математика?
@@ -248,40 +248,38 @@
Смесица на уводите в няколко предмета:
-&&table
+&{row
-&&font35
+&(font35
![](https://upload.wikimedia.org/wikipedia/commons/9/99/ClaudeShannon_MFO3807.jpg?20190622223728)
Claude Shannon
-&&/font
+&)
-&&cont
+&{column
- **Булева алгебра**: как работим с истина/лъжа, с 0/1
- Доказана е [еквивалентност между ел. вериги и булевата алгебра](https://en.wikipedia.org/wiki/A_Symbolic_Analysis_of_Relay_and_Switching_Circuits).
- Много типове данни и математически операции могат да се сведат до булева алгебра и работа с памет.
-&&/cont
+&}
+&} &]
-&&/table &&/slide
-
-
-&&slide
+&[slide
### Дискретни структури (продължение)
-&&lineb1
+&.br1
- **Теория на множествата**: множество е някаква съвкупност от обекти
- Позволява ни да третираме колекция от математически обекти като математически обект[^importance-of-sets].
Използва се в основата на много математики; колкото са полезни те, толкова са и множествата.
-&&lineb2
+&.br2
- **Комбинаторика**[^importance-of-combinatorics]: изследва бройки на неща
@@ -289,55 +287,55 @@ Claude Shannon
- Употребява се при оптимизации и теория на кодирането (компресиране на данни, отстраняване на грешки, криптография)
- Есенциална в теория на графите
-&&/slide
+&]
-&&slide
+&[slide
### Дискретни структури (продължение)
-&&lineb5
+&.br5
- **Теория на графите**: граф е съвкупност от някакви обекти и връзки между тях.
- Позволява моделиране на много естествени структури: интернет мрежите, географски карти (места и пътищата между тях), йерархии, биологически мрежи и так. нат.
- Използва се във важни структури от данни като [heap](https://en.wikipedia.org/wiki/Heap_%28data_structure%29) (и интересната [fibonacci heap](https://www.youtube.com/watch?v=6JxvKfSV9Ns)) и [trie](https://en.wikipedia.org/wiki/Trie)
-&&/slide
+&]
-&&slide
+&[slide
### Езици, автомати и изчислимост
-&&lineb5
+&.br5
-&&table
+&{row
-&&font35
-&&width85 ![](https://upload.wikimedia.org/wikipedia/commons/thumb/1/1c/Kleene.jpg/421px-Kleene.jpg?20230630215747) &&/width
+&(font35
+&(width85% ![](https://upload.wikimedia.org/wikipedia/commons/thumb/1/1c/Kleene.jpg/421px-Kleene.jpg?20230630215747) &)
Stephen Kleene
-&&/font
+&)
-&&cont
+&{column
Това е част от материала в по-общото "theoretical computer science".
Можем формално да опишем и работим с теоретични компютри и програми.
- Позволява ни да използваме математика за създаване, обработка и доказване на програми
-&&/cont
+&}
-&&/table
-&&/slide
+&}
+&]
-&&slide
+&[slide
-&&lineb1
+&.br1
### Алгебра 1
@@ -347,7 +345,7 @@ Stephen Kleene
- Основоположна в компютърната графика
- Много използвана в machine learning
-&&lineb3
+&.br3
### Диференциално и интегрално смятане
@@ -357,11 +355,11 @@ Stephen Kleene
- Напреднал machine learning, главно заради употребата на статистиката (която на свой ред се основава на линейната алгебра)
- Анализ на алгоритми
-&&/slide
+&]
-&&slide &&font35
+&[slide35
## В по-общ план
@@ -378,11 +376,11 @@ Stephen Kleene
Математиката е **неразделима** част от софтуера!
Друг е въпросът дали на вас лично ще ви се налага да я използвате...
-&&/font &&/slide
+&]
-&&slide
+&[slide
## Какво означава да пишеш софтуер?
@@ -394,32 +392,32 @@ Stephen Kleene
- Най-великият труд на тази дисциплина е постигнат чрез **синхрон** между тези три предмета
- &&centered &&width60 &&table
+ &(centered &(width60% &{row
![](https://upload.wikimedia.org/wikipedia/commons/thumb/4/4f/Black_hole_-_Messier_87_crop_max_res.jpg/600px-Black_hole_-_Messier_87_crop_max_res.jpg)
![](https://upload.wikimedia.org/wikipedia/commons/thumb/d/d2/Internet_map_1024.jpg/600px-Internet_map_1024.jpg?20121030160606)
- &&/table &&/width &&/centered
+ &} &) &)
-&&/slide
+&]
-&&clide &&centered &&font35
+&[title35
# Означава да създадеш<br>deus ex machina
С други думи, позволява ни да разрешим неразрешими проблеми
-&&/font &&/centered &&/clide
+&]
-&&clide &&centered &&font35
+&[title35
# [Достатъчно философия, сега ще конфигурираме всичко нужно за първото ни упражнение](./setup.html)
-&&/font &&/centered &&/clide
+&]
### Употреба на изображения
diff --git a/src/teaching/upp-2023/week10/img/fib.png b/src/teaching/upp-2023/week10/img/fib.png
new file mode 100644
index 0000000..b0bc958
--- /dev/null
+++ b/src/teaching/upp-2023/week10/img/fib.png
Binary files differ
diff --git a/src/teaching/upp-2023/week10/index.md b/src/teaching/upp-2023/week10/index.md
new file mode 100644
index 0000000..722e705
--- /dev/null
+++ b/src/teaching/upp-2023/week10/index.md
@@ -0,0 +1,90 @@
+# Задачи - УПП, Седмица 10, 15.12.2023
+
+GitHub classroom: [classroom.github.com/a/EJcTQRz4](https://classroom.github.com/a/EJcTQRz4)
+
+&:important Във всички задачи **трябва** да използвате рекурсия!
+
+## Задача 1
+
+Най-големия общ делител на числата `a` и `b` е най-голямото, число което ги дели без остатък.
+Евклидовият алгоритъм се базира на факта, че за две положителни числа `a` и `b`, като `a > b`, НОД на `a` и `b` е същия като НОД на `a - b` и `b` и когато `a = b`, тогава НОД на `a` и `b` е тяхната стойност.
+
+От входа получавате две цели положителни числа и трябва да изкарате техния НОД, чрез алгоритъма на Евклид **имплементиран с рекурсия**.
+
+**Примери:**
+
+|Вход|Изход|
+|----|-----|
+|6 6 |6 |
+|48 18|6 |
+
+## Задача 2
+
+От входа получавате неотрицателно число `N`, което ще бъде някое число на Фибоначи.
+Трябва да върнете кое по ред е, като 0 е нулевото, 1 е първото, 2 е третото, 3 е четвъртото и так. нат.
+Напомням, че математически фибоначи се дефинира така:
+
+<!--
+\begin{align*}
+F_n = \left\{ \begin{array}{ll}
+0, & n=0 \\
+1, & n=1 \\
+F_{n-1} + F_{n-2} & \text{иначе} \\
+\end{array} \right.
+\end{align*}
+-->
+
+![F(0) = 0; F(1) = 1; F(n) = F(n-1) + F(n-2)](./img/fib.png)
+
+**Примери:**
+
+|Вход|Изход|
+|----|-----|
+|0 |0 |
+|1 |1 |
+|3 |4 |
+|144 |12 |
+|1597 |17 |
+|46368|24 |
+
+## Задача 3
+
+От входа получавате положително число `N`, трябва да изкарате на екрана "рисунка", показваща формата на пясъчен часовник с височина `2N` (вижте примерите).
+
+**Примери:**
+
+|Вход|Изход|
+|----|-----|
+|1 |<pre>+<br>#</pre>|
+|2 |<pre>+++<br> +<br> #<br>###</pre>|
+|3 |<pre>+++++<br> +++<br> +<br> #<br> ###<br>#####</pre>|
+|5 |<pre>+++++++++<br> +++++++<br> +++++<br> +++<br> +<br> #<br> ###<br> #####<br> #######<br>#########</pre>|
+
+## Задача 4
+
+От входа получавате число `N`, след това тябва да изкарате на нови редове, в нарастващ ред, всички двоични числа, които могат да се представят с `N`-бита.
+Вкарвате и водещи нули, тоест всяко число е съставено от точно `N` букви (`N` нули и единици).
+
+**Примери:**
+
+|Вход|Изход|
+|----|-----|
+|1 |0<br>1|
+|2 |00<br>01<br>10<br>11|
+|3 |000<br>001<br>010<br>011<br>100<br>101<br>110<br>111|
+|4 |0000<br>0001<br>...<br>0111<br>1000<br>1001<br>...<br>1101<br>1110<br>1111|
+
+## Задача 5
+
+Получавате един ред от терминала, в който ще имате скоби, знакът `+` и `*`, шпации и числа.
+Това е прост математически израз, трябва да изкарате резултата след неговото пресмятане, като винаги около `число + число` и `число * число` има скоби (тоест не е нужно да се притеснявате от приоритет и асоциативност).
+
+За удобство спокойно може да ползвате `atoi` за конверитране на числовите части от низа в числа.
+
+**Примери:**
+
+|Вход|Изход|
+|----|-----|
+|(1 + 2)|3 |
+|((2 + 9) * 3)|33|
+|(((8 * 1) * (56 + 4)) + (19 * 2))|518|
diff --git a/src/teaching/upp-2023/week11/index.md b/src/teaching/upp-2023/week11/index.md
new file mode 100644
index 0000000..92ce89e
--- /dev/null
+++ b/src/teaching/upp-2023/week11/index.md
@@ -0,0 +1,127 @@
+# Задачи - УПП, Седмица 11, 22.12.2023
+
+GitHub classroom: [classroom.github.com/a/cZRnZj9y](https://classroom.github.com/a/cZRnZj9y)
+
+&:important Във всички задачи **трябва** да използвате рекурсия!
+
+&:warn Някои задачи се повтарят с тези от миналия път, ако преди не сте ги решили, сега ги решете
+
+## Алтернативни задачи
+
+Считайте [задачите от семинара](https://github.com/ivanahristova/introduction-to-programming-2023-2024/tree/main/sem11#%D0%B7%D0%B0%D0%B4%D0%B0%D1%87%D0%B8) като задачи преди тези.
+Тоест, за хората които се затрудняват повечко, решете семинарните и след това се върнете тук.
+Разбира се, ще помагам и със семинарните задачи.
+
+## Задача 1
+
+От входа получавате неотрицателно число `N`, което ще бъде някое число на Фибоначи.
+Трябва да върнете кое по ред е, като 0 е нулевото, 1 е първото, 2 е третото, 3 е четвъртото и так. нат.
+
+Напомням, че нормално Фибоначи се дефинира като редица, която започва с числата 0 и 1, и всяко следващо е сумата на предходните две.
+Тоест, нулевото число е 0, първото 1, второто е `0 + 1 = 1` (понеже 1 се повтаря, зачитаме го за първото число), третото е `1 + 1 = 2`, четвъртото е `1 + 2 = 3` и так. нат.
+
+**Примери:**
+
+|Вход|Изход|
+|----|-----|
+|0 |0 |
+|1 |1 |
+|3 |4 |
+|144 |12 |
+|1597 |17 |
+|46368|24 |
+
+## Задача 2
+
+От входа получавате положително число `N`, трябва да изкарате на екрана "рисунка" на триъгълници.
+
+### a) горен триъгълник
+
+Рисунката е един правоъгълен равнобедрен триъгълник от знака `+`, като `N` определя размера на равнобедрените страни (вижте примерите).
+
+**Примери:**
+
+|Вход|Изход|
+|----|-----|
+|1 |<pre>+</pre>|
+|2 |<pre>+<br>++</pre>|
+|3 |<pre>+<br>++<br>+++</pre>|
+|5 |<pre>+<br>++<br>+++<br>++++<br>+++++</pre>|
+
+### б) долен триъгълник
+
+Подобно на предходната подточка, обаче обърнат по хоризонтала, и със знака `#`.
+
+**Примери:**
+
+|Вход|Изход|
+|----|-----|
+|1 |<pre>#</pre>|
+|2 |<pre>##<br>#</pre>|
+|3 |<pre>###<br>##<br>#</pre>|
+|5 |<pre>#####<br>####<br>###<br>##<br>#</pre>|
+
+### в) пълен триъгълник
+
+**Използвайки само една рекурсивна функция,** сега трябва да изкарате първо горния триъгълник и след това долния.
+Ако просто извикате предходните две функции една след друга, задачата се обезсмисля.
+
+**Примери:**
+
+|Вход|Изход|
+|----|-----|
+|1 |<pre>+<br>#</pre>|
+|2 |<pre>+<br>++<br>##<br>#</pre>|
+|3 |<pre>+<br>++<br>+++<br>###<br>##<br>#</pre>|
+|5 |<pre>+<br>++<br>+++<br>++++<br>+++++<br>#####<br>####<br>###<br>##<br>#</pre>|
+
+## Задача 3
+
+Направете програма която разрешава проблема с [възрастта на трите деца](https://en.wikipedia.org/wiki/Ages_of_Three_Children_puzzle).
+
+Една жена има три деца за които знаем три неща: умножението на техните възрасти, сбора на техните възрасти и факта, че има едно дете, което е най-голямо.
+Трябва да намерите възрастта на всяко дете, само по тази информация.
+
+Разбира се, от входа получавате две числа, съответно умножението и сбора на възрастите им.
+Трябва на екрана да изкарате три числа - възрастите на трите деца.
+
+**Подсказка:** най-лесното решение е да пробвате всички възможни възрасти, като избягвате техни пермутации
+
+**Примери:**
+
+|Вход|Изход|
+|----|-----|
+|72 14|3 3 8|
+|36 13|2 2 9|
+|350 42|2 5 35|
+
+## Задача 4
+
+От входа получавате число `N`, след това трябва да изкарате на нови редове, в нарастващ ред, всички двоични числа, които могат да се представят с `N`-бита.
+Вкарвате и водещи нули, тоест всяко число е съставено от точно `N` букви (`N` нули и единици).
+
+**Примери:**
+
+|Вход|Изход|
+|----|-----|
+|1 |0<br>1|
+|2 |00<br>01<br>10<br>11|
+|3 |000<br>001<br>010<br>011<br>100<br>101<br>110<br>111|
+|4 |0000<br>0001<br>...<br>0111<br>1000<br>1001<br>...<br>1101<br>1110<br>1111|
+
+## Задача 5
+
+Направете програма която разрешава [Такузо пъзели](https://en.wikipedia.org/wiki/Takuzu).
+
+Започвате с дъска 4х4, в тази дъска може да имате само цифрите 0 и 1, като няколко клетки вече идват с попълнени стойности (но повечето са празни).
+Обаче, на всяка колона и ред трябва да има еднакъв брой 0ли и 1ци, и не трябва да има повече от две последователни еднакви цифри (в реда или колоната).
+
+От входа получавате дъската, като с -1 обозначаваме празна клетка.
+
+**Примери:**
+
+|Вход|Изход|
+|----|-----|
+|-1 1 -1 0<br>-1 -1 0 -1<br>-1 0 -1 -1<br>1 1 -1 0|0 1 1 0<br>1 0 0 1<br>0 0 1 1<br>1 1 0 0|
+|-1 0 1 -1<br>1 -1 0 -1<br>0 1 -1 -1<br>0 0 1 -1|1 0 1 0<br>1 1 0 0<br>0 1 0 1<br>0 0 1 1|
+|-1 0 -1 -1<br>-1 0 0 -1<br>0 -1 -1 -1<br>-1 -1 -1 0|0 0 1 1<br>1 0 0 1<br>0 1 1 0<br>1 1 0 0|
diff --git a/src/teaching/upp-2023/week12/index.md b/src/teaching/upp-2023/week12/index.md
new file mode 100644
index 0000000..d914431
--- /dev/null
+++ b/src/teaching/upp-2023/week12/index.md
@@ -0,0 +1,109 @@
+# Задачи - УПП, Седмица 12, 05.01.2024
+
+GitHub classroom: [classroom.github.com/a/KEDSxDjl](https://classroom.github.com/a/KEDSxDjl)
+
+&:important Във всички задачи **трябва** да използвате рекурсия!
+
+## Алтернативни задачи
+
+Считайте [задачите от семинара](https://github.com/ivanahristova/introduction-to-programming-2023-2024/tree/main/sem12) и [тези от миналия път](../week11/) като част от днешните задачи.
+Тоест, за хората които се затрудняват повечко, решете ги и след това се върнете тук.
+Разбира се, ще помагам и с тях.
+
+## Задача 1
+
+Имате някакъв брой предмети, като всеки предмет има ценност (число) и тежест (число пак).
+Искате в раница да сложите предмети, като целта е ценността да бъде максимална, обаче раницата има капацитет на тежест, тоест тази ценност трябва да бъде спрямо максималната обща тежест.
+
+От входа получавате число N, след това толкова на брой предмета (тоест 2N на брой числа, като броейки от нула, четните са ценностти, а нечетните тежести).
+Накрая получавате максималната обща тежест за раницата.
+Трябва да изкарате на екрана максималната възможна обща ценност.
+
+**Примери:**
+
+|Вход|Изход|
+|----|-----|
+|3<br>1 4<br>2 5<br>3 1<br>4|3|
+|3<br>1 4<br>2 5<br>3 6<br>3|0|
+|6<br>50 56<br>50 59<br>64 80<br>46 64<br>50 75<br>5 17<br>190|150<!-- https://people.sc.fsu.edu/~jburkardt/datasets/knapsack_01/knapsack_01.html -->|
+
+
+## Задача 2
+
+Получавате N и M, съответно броя редове и колони в дъска.
+Всяка клетка от дъската е пълна или празна.
+След това получавате NxM на брой символа за всяка клетка, като `-` означава празна клетка, докато `#` означава пълна.
+Накрая получавате две числа - координати (започващи от нула, като 0,0 е горния-ляв ъгъл) в дъската.
+
+От подадените координати трябва да запълните "фигурата" в която се намира (фигурата която огражда) дадената плочка.
+С други думи, представете си че дъската е изображение, всяка клетка е пиксел, в изображението има бели и черни пиксели, и на дадените координати е кликнато с "Bucket fill" за да се оцвети в черно дадена фигура.
+
+Оцветяването да се случва само в 4те прави посоки (без диагонали).
+
+![](https://upload.wikimedia.org/wikipedia/commons/7/7e/Recursive_Flood_Fill_4_%28aka%29.gif)
+
+**Пример:**
+
+|Вход|Изход|
+|----|-----|
+|5 11<br><pre>- - # # - - - - - - -<br>- # - - # - - - - - -<br># - - - - # # # # # #<br>- # - - # - - - # - #<br>- - # # - - - - - - -</pre>2 2|<pre>- - # # - - - - - - -<br>- # # # # - - - - - -<br># # # # # # # # # # #<br>- # # # # - - - # - #<br>- - # # - - - - - - -</pre>|
+
+## Задача 3
+
+Имате шахматна дъска (8 на 8) и върху нея имате 8 царици.
+Напомням, че царицата в шаха може да се движи вертикално, хоризонтално и диагонално произволен брой клетки в един ход.
+
+Интересуваме се от такова поставяне на всички царици, че нито една няма да вземе никоя друга царица в един ход.
+Пример:
+
+![](https://upload.wikimedia.org/wikipedia/commons/6/69/Solution_A_for_8_Queen_Puzzles.png)
+
+Напишете програма, която намира броя на възможните такива поставяния на цариците.
+От входа не получавате нищо.
+
+**Пример:**
+
+|Вход|Изход|
+|----|-----|
+| |92 |
+
+**Бонус:** направете програмата да изкарва всяко решение
+
+## Задача 4
+
+<!-- https://mathcenter.oxford.emory.edu/site/cs171/probSetUsingStacks/ -->
+
+Нормално ние представяме математически операции чрез "инфиксен" запис, тоест операторът е по средата, между нещата върху които работи (пример: `1 + 2`).
+Обаче, това не е задължително, по обратната полска нотация винаги слагаме оператът след нещата върху които работи (пример: `1 2 +`).
+
+Бонусът на това, е че не ни трябва скобуване и ред на операциите.
+В инфиксния израз `(2 + 3) * (2 ^^ 2)`, без скобите, сбора ще се извърши след умножението и степенуването ще се извърши след умножението.
+Обаче, ако искаме да изразим това в обратен полски запис, просто правим `2 3 + 2 2 ^^ *`.
+А ако искаме оригиналното действие, без скоби, записваме `2 3 2 * 2 ^^ +`.
+
+Ако изглежда объркващо, идеята е че всеки оператор работи върху предходните две стойности, изчисляваме изразите от ляво надясно и заместваме веднага.
+Тоест, при последния пример, пропускаме първите три числа, стигаме до `*`, умножаваме последните две и заместваме трите неща (`3 2 *`) с резултата, следователно имаме `2 6 2 ^^ +`, пропускаме две, стигаме до `^^` и так.нат.
+
+Направете програма, която чисто рекурсивно изчислиява изрази в обратен полски запис, който поддържа цели числа и операциите събиране, умножение, деление, изваждане и степенуване (за степенуване ще използваме знакът `^`).
+
+&:important Обаче, за едно извикване на рекурсивната функция, може да пазите само един елемент на израза (число или оператор)!
+
+Изразът винаги завършва на знака `$`.
+
+&:warn Относно вход/изход, понеже няма как да знаем дали i-тата стойност е число или знак (операция), трябва да използваме функцията `std::cin.fail()`, която връща булева стойност, която ни казва дали записването на входа е било успешно.<br>
+ Тоест, може винаги да запазвате входа в целочислен тип, когато стигнете до знак `std::cin.fail()` ще върне `true`.
+ След това трябва да "забравите" за грешката чрез `std::cin.clear()` и може втори път да запазите входа (провалените данни ще се препрочетат) в променлива от знаков тип.<br>
+ Но това поражда друг проблем, понеже записваме в целочислен тип, когато въведем `+` или `-`, `std::cin` ще очаква това да е водещ знак на число, и ще продължи да чака входа докато не въведем друг знак, тоест `+` и `-` ще бъдат пропуснати.
+ Като компромисен вариант, просто пред тях винаги ще слагаме `'` и в кода ще го пропускаме.
+
+**Примери:**
+
+|Вход|Изход|
+|----|-----|
+|1 2 &apos;+ 3 / $|1|
+|1 4 3 2 ^ * &apos;+ 14 7 / &apos;- $|35|
+
+## Attribution
+
+- Анимация в [Задача 2](#2) от André Karwath (Aka) на [Уикипедия](https://commons.wikimedia.org/w/index.php?curid=481651) под лиценз CC BY-SA 2.5
+- Изображение на шахматна дъска в [Задача 3](#3) от Encik Tekateki в [Уикипедия](https://commons.wikimedia.org/w/index.php?curid=77832290) под лиценз CC BY-SA 4.0
diff --git a/src/teaching/upp-2023/week13/index.md b/src/teaching/upp-2023/week13/index.md
new file mode 100644
index 0000000..f0e4b9a
--- /dev/null
+++ b/src/teaching/upp-2023/week13/index.md
@@ -0,0 +1,145 @@
+# Задачи - УПП, Седмица 13, 12.01.2024
+
+GitHub classroom: [classroom.github.com/a/bgiFD6SB](https://classroom.github.com/a/bgiFD6SB)
+
+## Алтернативни задачи
+
+Считайте [задачите от семинара](https://github.com/ivanahristova/introduction-to-programming-2023-2024/tree/main/sem13) и [тези от миналия път](../week12/) като част от днешните задачи.
+Тоест, за хората които се затрудняват повечко, решете ги и след това се върнете тук.
+Разбира се, ще помагам и с тях.
+
+
+## 1 задача
+
+От входа получавате число N, това е броя на "пробни" думи.
+След тях получавате още една дума, която е желаната дума.
+Трябва да изкарате коя пробна дума е най-близка до (различава се с най-малко знаци с) желаната дума.
+
+Всяка дума е на нов ред и е съставена от малки латински букви.
+Ако има няколко думи с еднаква "близкост", изкарайте последната от тях.
+
+**Примери:**
+
+|Вход|Изход|
+|----|-----|
+|5<br>cate<br>cot<br>dog<br>cote<br>co<br>cat|cot|
+|4<br>nask<br>nmaskl<br>msdal<br>task<br>mask|task|
+
+## 2 задача
+
+В началото получавате неотрицателно цяло число N.
+След това получавате N на брой редове.
+Всеки ред е във формата "(Име) (Фамилия) (Брой продадени продукти)".
+
+Редовете са разбъркани, изкарайте първо име и фамилия на хората с най-много продадени продукти.
+Ако има няколко хора, които са продали най-много продукти, изкарайте имената им в азбучен ред, първо по фамилия, после по име.
+
+Използвайте **само една функция за сортиране!**
+Като подсказка, използвайте указатели към функции за да променяте как тя работи.
+
+&:question Какво свойство трябва да е изпълнено за сортиращата функция?
+
+**Примери:**
+
+|Вход|Изход|
+|----|-----|
+|Antony Garcia 10<br>John Doe 9<br>Joseph Carmichael 10<br>Steven Wayne 1<br>Bob Carmichael 10<br>Holy Wilson 9|Bob Carmichael<br>Joseph Carmichael<br>Antony Garcia|
+
+## 3 задача
+
+Ще дефинираме обвито изречение, като редица от букви, за които са изпълнени следните правила:
+
+- първата е главна
+- последната е точка
+- между тях има само малки букви, цифри и шпации
+- всяко изречение е "обвито" до някакъв брой колони
+
+ Тоест за всяко изречение са избрани максимален брой колони, и знаците са обвити, така че да се поберат.
+ Примерно, ако имахме изречението "Hello world." и бяхме избрали 5 колони, тогава получаваме:
+
+ ```
+ Hello
+ worl
+ d.
+ ```
+
+От входа получавате N и M, те съответстват на матрица от символи с N реда и M колони.
+В матрицата имате обвити изречения, подредени по такъв начин, че между съседни има със сигурност поне една шпация (която действа като разделител).
+Допускаме, че при "двусмислици" възможно най-много шпации са част от изречението (а не от разделителя), тоест ако имаме:
+
+```
+A B
+. .
+```
+
+тогава двете ни изречения са:
+
+```
+B.
+A .
+```
+
+Изкарайте на конзолата всички обвити изречения в матрицата (редът им няма значение).
+
+**Примери:**
+
+|Вход|Изход|
+|----|-----|
+|<pre>7 13<br>Thi A Someth<br>s i n ing. <br>s c . <br>ool <br>. Good Hel<br> luc lo.<br>Ha. k. <br></pre>|Something.<br>An.<br>This is cool.<br>Hello.<br>Good luck.<br>Ha.<br>|
+|<pre>2 7<br>B A.<br>. </pre>|<pre>A.<br>B .</pre>|
+|<pre>3 7<br> A.<br>B <br>. </pre>|<pre>A.<br>B .</pre>|
+|<pre>4 7<br> A.<br> <br>B <br>. </pre>|<pre>A.<br>B .</pre>|
+|<pre>3 6<br>Big <br>jumper<br>. </pre>|<pre>Big jumper.</pre>|
+
+## 4 задача
+
+В префиксния (или полския) запис слагаме оператора за смятане пред (в ляво от) елементите върху които работи (нормален запис - `1 + 2`, полски запис - `+ 1 2`).
+Ще разглеждаме "многоредови" изрази в полски запис, тоест изрази в които има няколко реда от целочислени стойности, така че трябва да се изчислят няколко израза с еднаква "форма", но различни стойности.
+
+Един такъв израз изглежда така:
+
+```
++ 1 2
+ 3 4
+ 5 6 .
+```
+
+Точката на края на последния ред задава край на израза.
+В този пример ще изчислим `1 + 2`, `3 + 4` и `5 + 6`, тоест ще "върне" три стойности: 3, 7 и 11.
+Всяка колона в израза е от един и същи "тип", тоест в една колона винаги ще има числова стойност или някакъв знак.
+С изключение на точката, всеки знак може да се постави на произволен ред (обаче в една колона не може да има повече от един знак).
+
+Примерно:
+
+```
+ 1 - 2 2 63
++ 3 4 7 7
+ 5 6 * 8 9 .
+```
+
+Това ще изчисли `1 + (2 - 2 * 63)`, `3 + (4 - 7 * 7)` и `5 + (6 - 8 * 9)`.
+Израза би направил същото нещо ако примерно всички знаци бяха на първия ред или на последния.
+
+От входа получавате няколко такива израза, докато не получите знака `$`.
+
+Може да достъпвате стойност от предходни изрази чрез синтаксиса "ИНДЕКС.ИНДЕКС", където индексите са от 0, първия определя номера на израза, докато втория определя коя стойност искаме.
+Примерно:
+
+```
+ 1 2
++ 3 4
+ 5 6 .
+* 0.0 0.2 .
+```
+
+В последния израз умножаваме от нулевия израз, първата и третата стойност, тоест умножаваме 3 и 11.
+
+Накрая трябва да изкарате всички стойности от последния израз.
+
+&:warn Погледнете пояснението за вход/изход от [последната задача от миналия път](../week12/#4).
+
+**Пример:**
+
+|Вход|Изход|
+|----|-----|
+|<pre> 1 5<br>+ 2 6<br> 3 7<br> 4 8 .<br>- 0.3 0.2 .<br>* 1.0 0.1 .<br> 1.0 3 0.2 3<br> - 3 0.3 0.1 1.0<br>* 0.0 2.0 / 2.0 0.1 .<br>$<br></pre>|-3 -36 -20|
diff --git a/src/teaching/upp-2023/week14/index.md b/src/teaching/upp-2023/week14/index.md
new file mode 100644
index 0000000..cf28fe7
--- /dev/null
+++ b/src/teaching/upp-2023/week14/index.md
@@ -0,0 +1,239 @@
+# Задачи - УПП, Седмица 14, 19.01.2024
+
+GitHub classroom: [classroom.github.com/a/B08TtnnW](https://classroom.github.com/a/B08TtnnW)
+
+Това е последния практикум, затова ви давам по-лесни и приятни задачи: имплементации на игри!
+Всичките са взети от [101 BASIC Computer Games](https://en.wikipedia.org/wiki/BASIC_Computer_Games) (книгата е налична в [archive.org](https://archive.org/details/bitsavers_decBooks10Mar75_26006648)).
+
+Разбира се, който иска, може да решава задачи от предходни практикуми, давал съм достатъчно задачи.
+
+## 1 задача - Ним
+
+Ним е една много стара игра за два играча.
+В произволен брой купчини са сложени произволен брой предмети (предметите не се различават, примерно камъни или пръчки).
+Алтернативно, всеки играч взема някакъв брой (поне един) предмети от една купчина.
+Играчът който вземе последния предмет печели.
+
+В нашия вариант, предметите са пръчки.
+Компютъра автоматично (и случайно) генерира между 5 и 20 купчини с между 1 и 10 пръчки.
+Разбира се, трябва компютъра да съобщи за конкретните стойности:
+
+```terminal
+X piles
+Y sticks in pile 1
+Z sticks in pile 2
+[...]
+K sticks in pile X
+```
+
+След това се редуват, първия играч, втория играч:
+
+```terminal
+Player 1 turn
+```
+
+Избирате купчина с пръчки:
+
+```terminal
+Which pile do you want sticks from? _
+```
+
+където _ е мястото на курсора.
+След това броя пръчки от купчината:
+
+```terminal
+How many sticks? _
+```
+
+Ако някоя стойност е невалидна, питате пак.
+След това идва редът на втория играч:
+
+```terminal
+Player 2 turn
+```
+
+Накрая, този който вземе последната пръчка печели играта и се пита дали искате наново да почнете играта:
+
+```terminal
+Player X won. Do you want to play again? _
+```
+
+## 2 задача - Хамураби
+
+Вие играете като древния Вавилонски цар Хамураби над своя малък град.
+Управлявате три ресурса във вашето царство: хора, земя и жито.
+Имате власт 10 години, обаче обществото може да ви изгони и преди това.
+
+Не е от голямо значение да знаете, но акър земя е приблизително 4000 квадратни метра, а бушел жито е приблизително 4 килограма жито.
+
+В началото вашия съветник казва:
+
+```terminal
+Hamurabi, I beg to report to you
+In year X, Y people starved, Z came to the city.
+```
+
+Разбира се, X, Y и Z са положителни целочислени стойности.
+По-късно ще определим как се изменят и какви са началните стойности.
+
+След това имате 1/7 шанс чума да сполети вашия град.
+Ако се случи, съветника ви съобщава за това и загубвате половината си население:
+
+```terminal
+A horrible plague struck! Half of the people died.
+```
+
+След това съветника ви дава информация за града:
+
+```terminal
+Population is now X.
+The city now owns X acres.
+You harvested Z bushels per acre.
+Rats ate K bushels.
+You now have L bushels in store.
+```
+
+Разбира се, X, Y, Z, K и L са целочислени стойности.
+
+Ако тази информация е в последната година от вашето царуване, играта свършва и получавате мнението на населението за вас.
+
+Иначе, сега съветника започва да ви дава информация и да ви пита за вашето действие:
+
+```terminal
+Land is trading at X bushels per acre.
+How many acres do you wish to buy? _
+```
+
+Където X е произволно цяло число между 17 и 27, долна черта показва мястото на курсора.
+Трябва да се въведе цяло число.
+В този случай, както и всеки други, ако то е отрицателно, съветника напуска и играта свършва:
+
+```terminal
+Hamurabi, I cannot do what you wish, get yourself another steward!!!!!
+So long for now.
+```
+
+Последния ред винаги се показва, когато играта свърши.
+
+Ако нямате достатъчно бушели в резерв, за да купите всичката въведена земя, съветника ви казва:
+
+```terminal
+Hamurabi, think again, you have only X bushels of grian. Now then,
+```
+
+и същото съобщение за "Land is trading at [...] How many acres ..." се изписва и приемате нов вход.
+
+Ако сте въвели 0, значи искате да продавате земя и съветника ви пита:
+
+```terminal
+How many acres do you wish to sell? _
+```
+
+Ако се въведе отрицателно число, случва се същото като при купуване на земя.
+
+Ако въведете повече земя, отколкото имате, съветника казва:
+
+```terminal
+Hamurabi think again, you own only X acres. Now then,
+```
+
+и пак пита "How many acres [...]".
+
+След като сте купили или продали земя, сега съветника ви пита колко бушели жито ще отделите за нахранване на населението:
+
+```terminal
+How many bushels do you wish to feed your people? _
+```
+
+Ако се въведе твърде голямо число, съветника предупреждава и пита пак:
+
+```terminal
+Hamurabi, think again, you have only X bushels of grain. Now then,
+How many bushels do you wish to feed your people? _
+```
+
+Остава последния въпрос от съветника за годината:
+
+```terminal
+How many acres do you wish to plant with seed? _
+```
+
+Разбира се, ако се въведат повече акри отколкото има, съветника предупреждава и пита пак:
+
+```terminal
+Hamurabi, think again, you own only X acres. Now then,
+How many acres do you wish to plant with seed? _
+```
+
+Предполагам може да се сетите какво съобщение съветника връща при отрицателни акри.
+
+Един бушел жито може да засее два акъра земя, ако няма достатъчно жито, съветника предупреждава и пита пак.
+Отнема 10 човека да се грижат за един акър земя, ако няма достатъчно хора, съветника предупреждава и пита пак:
+
+```terminal
+But you have only X people to tend the fields. Now then,
+```
+
+Това са въпросите на съветника, сега остава годината да се изиграе.
+Хората жънат (произволно число) между 1 и 6 бушела жито на всеки акър.
+
+След това избирате друго произволно число между 1 и 6.
+Ако числото е по-голямо от 1, тогава плъховете ще изядат по толкова голяма дроб бушели жито от резерва (при числото 5, плъховете изяждат 1/5; тук бушелите жито се смятат преди жътва).
+
+Сега населението расте, броя хора които са "дошли" в града се определя по формулата `R * (20 * АКРИ ЗЕМЯ + БУШЕЛИ ЖИТО) / БРОЙ ХОРА / 100 + 1`, където R е цяло число между 1 и 6.
+Бушелите жито се смятат след жътва.
+
+Предпоследно, определя се колко хора са умрели от глад, като всеки човек консумира 20 бушели жито.
+Ако над 45% от населението са умрели от глад, останалите хора ви свалят от власт и играта свършва:
+
+```terminal
+You starved X people in one year, due to this extreme mismanagement,
+you have not only been impeached and thrown out of office but you have
+also been declared national fink!
+So long for now.
+```
+
+Накрая на годината, трябва да обновите общия брой хора, които са умрели от глад, за цялото ви царуване, заедно със средния процент хора които са умирали на година.
+
+Ако успешно царувате 10 години, накрая съветника ви казва как сте се справили:
+
+```terminal
+In your 10-year term of office, X percent of the population starved per year on average,
+I.E., a total of Y people died.
+```
+
+Сега изчислявате пропорцията между земя и хора, съветника ви казва:
+
+```terminal
+You started with 10 acres per person and ended with X acres per person.
+```
+
+Ако средно над 33% от населението е умирало от глад всяка година или съотношението ви е под 7 акъра на човек, тогава се случва същото нещо, като когато над 45% от населението умира от глад.
+
+Ако средно над 10% (но под 34%) от населението е умирало от глад всяка година или съотношението ви е под 9 акъра на човек (но над 6), тогава оставате в историята като лош владетел:
+
+```terminal
+Your heavy-handed performance smacks of Nero and Ivan IV.
+The people (remaining) find you an unpleasant ruler, and frankly, hate your guts.
+So long for now.
+```
+
+Ако средно над 3% (но под 11%) от населението е умирало от глад всяка година или съотношението е между 9 и 10 акъра на човека, тогава оставате със средно впечатление:
+
+```terminal
+Your performance could have been somewhat better but really wasn't too bad at all.
+X people would dearly like to see you assassinated but we all have our trivial problems.
+So long for now.
+```
+
+Където х съответства на бройката, между 0 и 80 процента от населението.
+
+В противен случай, тоест средно под 4% от населението е умирало от глад всяка година или съотношението е над 10 акъра на човека, тогава хората ви харесват:
+
+```terminal
+A fantastic performance!!!
+Charlemange, Disraeli and Jefferson combined could not have done better.
+So long for now.
+```
+
+В началото на играта започвате с 100 човека население, като 5 от тях са дошли в града, 1000 акри земя, жътва от 3 бушела на акър, плъхове са изяли 200 бушела и имате 2800 бушела в хранилището.
diff --git a/src/teaching/upp-2023/week2/revision.md b/src/teaching/upp-2023/week2/revision.md
index ebf6db6..73e897f 100644
--- a/src/teaching/upp-2023/week2/revision.md
+++ b/src/teaching/upp-2023/week2/revision.md
@@ -1,20 +1,20 @@
# Преговор - УПП, Седмица 2, 13.10.2023
-&&presentation
+&.presentation
-&&clide &&centered
+&[title
# Конвертиране на данни, побитови оператори, условни оператори
-&&/centered &&/clide
+&]
-&&slide
+&[slide
## Конвертиране на данни
-&&lineb3
+&.br3
- Неявно (скрито, експлицитно): компилаторът сам се досеща да промени типа
@@ -30,13 +30,13 @@
int m = (int)a + (int)b;
```
-&&/slide
+&]
-&&slide
+&[slide
-&&lineb5
+&.br5
- Със загуба на информация (от по-голям тип в по-малък)
@@ -52,11 +52,11 @@
long b = a;
```
-&&/slide
+&]
-&&slide
+&[slide
## Побитови оператори
@@ -67,7 +67,7 @@
**Означавам побитовите числа с водеща буква "b"!**
Тоест, числото `b1001` е двоичното число `1001`, което е десетичното число `9`.
-&&lineb3
+&.br3
- Отрицание/негация, `~`: обръща 0 в 1 и 1 в 0
@@ -75,11 +75,11 @@
~ b0010 = b1101
```
-&&/slide
+&]
-&&slide
+&[slide
- Побитово "и", `&`: за два бита, ако и двете са 1, връща 1, иначе връща 0
@@ -102,11 +102,11 @@
b0011 ^ b0101 = b0110
```
-&&/slide
+&]
-&&clide &&font27
+&[middle27
- Побитово отместване на ляво, `<<`: отмества всеки бит с n позиции на ляво
Винаги "запълва" с нули (няма разлика между логическо и аритметично ляво отместване)
@@ -128,11 +128,11 @@
b1010 >> 3 = b0001 или пък b1111
```
-&&/font &&/clide
+&]
-&&clide
+&[middle
Примери с код:
@@ -156,19 +156,19 @@ int r4 = (unsigned int)b >> 1; // 2
int r5 = (unsigned int)-b >> 1; // 2147483645
```
-&&/clide
+&]
-&&slide
+&[slide
## Логически оператори
Много приличат на побитовите, обаче побитовите работят върху битове, докато логическите работят върху bool.
-&&lineb4
+&.br4
- `!`: обръща `true` във `false` и обратно
@@ -177,11 +177,11 @@ int r5 = (unsigned int)-b >> 1; // 2147483645
! false // true
```
-&&/slide
+&]
-&&clide
+&[middle
- `&&`: "логическо и", ако и двете стойности са `true`, тогава и резултатът е `true`
@@ -199,11 +199,11 @@ int r5 = (unsigned int)-b >> 1; // 2147483645
false || false // false
```
-&&/clide
+&]
-&&slide
+&[slide
## Условни конструкции
@@ -225,11 +225,11 @@ int r5 = (unsigned int)-b >> 1; // 2147483645
dootherthing;
```
-&&/slide
+&]
-&&clide &&font25
+&[middle25
- `if-else`: работи като `if`, обаче след къдравите скоби добавяме `else { ... }`.
@@ -256,11 +256,11 @@ int r5 = (unsigned int)-b >> 1; // 2147483645
dootherthing;
```
-&&/font &&/clide
+&]
-&&slide &&font25
+&[slide25
- благодарение на изпускането на къдрави скоби, можем да пишем
@@ -290,11 +290,11 @@ int r5 = (unsigned int)-b >> 1; // 2147483645
}
```
-&&/font &&/slide
+&]
-&&slide
+&[slide
- `expression` винаги се конвертира до тип `bool` (ако е нужно)
**Никога не правете такива неща:**
@@ -320,11 +320,11 @@ int r5 = (unsigned int)-b >> 1; // 2147483645
Просто правите `bool a = ! expression;`
-&&/slide
+&]
-&&slide
+&[slide
- Тернарен оператор: ако искате да имате такава условна конструкция като част от израз (който взема стойност) използвате
@@ -348,11 +348,11 @@ int r5 = (unsigned int)-b >> 1; // 2147483645
std::cout << ((grade < 300) ? 2.0 : grade / 100.0);
```
-&&/slide
+&]
-&&clide &&font27
+&[middle27
- `switch`: приема стойност и изпълнява случая, при който стойността съвпада с определената
@@ -377,12 +377,12 @@ int r5 = (unsigned int)-b >> 1; // 2147483645
Без `break` изпълнението продължава към следващия `case`
-&&/font &&/clide
+&]
-&&clide
+&[middle
```cpp
char characterInput;
@@ -395,4 +395,4 @@ switch(characterInput) {
}
```
-&&/clide
+&]
diff --git a/src/teaching/upp-2023/week3/revision.md b/src/teaching/upp-2023/week3/revision.md
index cb0ac61..b1dab08 100644
--- a/src/teaching/upp-2023/week3/revision.md
+++ b/src/teaching/upp-2023/week3/revision.md
@@ -1,17 +1,17 @@
# Преговор - УПП, Седмица 3, 20.10.2023
-&&presentation
+&.presentation
-&&clide &&font35 &&centered
+&[title35
# Цикли, assert
-&&/centered &&/font &&/clide
+&]
-&&slide &&font25
+&[slide25
## Бележки от миналия път
@@ -42,11 +42,11 @@
bool b = !condition;
```
-&&/font &&/slide
+&]
-&&clide
+&[middle
- второ:
@@ -64,15 +64,15 @@
a >= '0' && a <= '9'
```
-&&/clide
+&]
-&&slide
+&[slide
## С/без загуба на данни
-&&lineb3
+&.br3
Получи се малко разногласие между това, което Ивана ви е казала и това което аз ви казах.
В края на деня, **конвертиране от int към unsigned int не губи информация!**
@@ -83,11 +83,11 @@
Тоест, конвертирания при които не губиш битове, нямаш загуба на данни.
-&&/slide
+&]
-&&slide
+&[slide
## 2s compliment
@@ -109,11 +109,11 @@
000 0
```
-&&/slide
+&]
-&&clide
+&[middle
Това работи, обаче имаме един гигантски проблем: събирането не работи!
От математика знаем, че "2 - 1 = 2 + (-1)", тоест би трябвало да можем да съберем побитово 2 и -1 и да получим 1.
@@ -133,11 +133,11 @@
Да не говорим, че ние имаме -0, което не ни трябва много.
-&&/clide
+&]
-&&clide
+&[middle
Нека да помислим пак, да вземем само положителните:
@@ -156,11 +156,11 @@
Нека тогава "-1 = 111".
-&&/clide
+&]
-&&slide
+&[slide
Правейки същото за "2 + -2", намираме че
@@ -186,11 +186,11 @@
100 не сме го използвали, обаче намерихме отрицателното число за всяко положително.
Да видим как работим с него, побитово "100 + 001 = 101", тоест "x + 1 = -3", следователно x ще бъде -4.
-&&/slide
+&]
-&&clide
+&[middle
Това е идеята на "complements", дефинираме отрицателни числа, така че да използваме едно и също събиране между положителни и отрицателни.
@@ -212,15 +212,15 @@
11111111111111111111111111111110
```
-&&/clide
+&]
-&&slide
+&[slide
## Цикли
-&&lineb4
+&.br4
- `while` цикъл
@@ -232,11 +232,11 @@
"условие" е булева стойност, като ако е `false` цикъла спира, докато ако е `true` "тяло" се изпълнява и после пак се проверява условие
-&&/slide
+&]
-&&clide
+&[middle
- Може да си го представите като
@@ -258,11 +258,11 @@
...
```
-&&/clide
+&]
-&&slide
+&[slide
- `do-while` цикъл, като `while`, но "тяло" се изпълнява поне един път
@@ -289,11 +289,11 @@
...
```
-&&/slide
+&]
-&&clide
+&[middle
- `for` цикъл
@@ -307,11 +307,11 @@
"условие" се изпълнява преди всяка итерация, като ако е `false` цикъла спира, докато ако е `true` продължава
"инкрементация" се изпълнява след края на всяка итерация
-&&/clide
+&]
-&&slide
+&[slide
- Може да си представяте, че това на практика извършва:
@@ -336,11 +336,11 @@
...
```
-&&/slide
+&]
-&&clide
+&[middle
- или използвайки `while` цикъл:
@@ -352,36 +352,36 @@
}
```
-&&/clide
+&]
-&&slide
+&[slide
### Ключови думи
-&&lineb3
+&.br3
- `break`: моментално прекратява изпълнението на цикъла
При `for` цикли инкрементацията не се изпълнява след `break`
-&&lineb2
+&.br2
- `continue`: продължи след края на сегашната итерация; тоест изпълнението на тяло се прекратява и започваме нова итерация
При `for` цикли директно отива на инкрементация
-&&/slide
+&]
-&&slide
+&[slide
## Assert
-&&lineb3
+&.br3
Понякога е полезно да тестваме нашия код вътре в самия код.
Тоест, искаме на конкретно място в кода да проверим нещо.
@@ -394,4 +394,4 @@ assert(condition);
Използва се повече като програмистки уред, тоест ако програмата спре заради `assert`, това е защото има някаква програмистка грешка.
-&&/slide
+&]
diff --git a/src/teaching/upp-2023/week4/revision.md b/src/teaching/upp-2023/week4/revision.md
index b5de82d..3650875 100644
--- a/src/teaching/upp-2023/week4/revision.md
+++ b/src/teaching/upp-2023/week4/revision.md
@@ -1,16 +1,16 @@
# Преговор - УПП, Седмица 4, 27.10.2023
-&&presentation
+&.presentation
-&&clide &&font35 &&centered
+&[title35
# Функции и алгоритмични задачи
-&&/centered &&/font &&/clide
+&]
-&&slide &&font27
+&[slide27
## От сега нататък ще направим няколко промени
@@ -26,7 +26,7 @@
- Ще може да предавате задания след срока!
Искам да решите колкото се може повече вкъщи.
-&&/font &&/slide
+&]
@@ -34,7 +34,7 @@
-&&slide
+&[slide
## 2s compliment
@@ -56,11 +56,11 @@
000 0
```
-&&/slide
+&]
-&&clide
+&[middle
Това работи, обаче имаме един гигантски проблем: събирането не работи!
От математика знаем, че "2 - 1 = 2 + (-1)", тоест би трябвало да можем да съберем побитово 2 и -1 и да получим 1.
@@ -80,11 +80,11 @@
Да не говорим, че ние имаме -0, което не ни трябва много.
-&&/clide
+&]
-&&clide
+&[middle
Нека да помислим пак, да вземем само положителните:
@@ -103,11 +103,11 @@
Нека тогава "-1 = 111".
-&&/clide
+&]
-&&slide
+&[slide
Правейки същото за "2 + -2", намираме че
@@ -133,11 +133,11 @@
100 не сме го използвали, обаче намерихме отрицателното число за всяко положително.
Да видим как работим с него, побитово "100 + 001 = 101", тоест "x + 1 = -3", следователно x ще бъде -4.
-&&/slide
+&]
-&&clide
+&[middle
Това е идеята на "complements", дефинираме отрицателни числа, така че да използваме едно и също събиране между положителни и отрицателни.
@@ -159,7 +159,7 @@
11111111111111111111111111111110
```
-&&/clide
+&]
diff --git a/src/teaching/upp-2023/week6/index.md b/src/teaching/upp-2023/week6/index.md
index 991f987..34c3f53 100644
--- a/src/teaching/upp-2023/week6/index.md
+++ b/src/teaching/upp-2023/week6/index.md
@@ -189,7 +189,7 @@ $ 1 1
|6 1 3 7 3 0 958|959|
|17 5 9 8 6 1 8 3 9 5 9 9 2 7 8 0 91461 772000|863461|
-&&question Какво прави последната програма?
+&:question Какво прави последната програма?
**Бонус:** направете програми за симулаторния компютър, които
diff --git a/src/teaching/upp-2023/week7/index.md b/src/teaching/upp-2023/week7/index.md
index 329581c..b216992 100644
--- a/src/teaching/upp-2023/week7/index.md
+++ b/src/teaching/upp-2023/week7/index.md
@@ -10,7 +10,7 @@ GitHub classroom: [classroom.github.com/a/m5M2_CWD](https://classroom.github.com
Направете функция, която получава два двуизмерни координата, покомпонентно ги сумира и връща резултатните координати.
Няма как функцията да върне две стойности, затова добаваете още два аргумента, които да са указатели към променливи в които да запазим сумираните координати.
-&&warn **Трябва** да използвате референции вместо указатели!
+&:warn **Трябва** да използвате референции вместо указатели!
От входа получавате два координата, след това връщате тяхната покомпонентна сума **използвайки функцията**.
@@ -31,7 +31,7 @@ GitHub classroom: [classroom.github.com/a/m5M2_CWD](https://classroom.github.com
Ако буквата е `a`, `b` или `c`, тогава този продукт става "сегашния" продукт.
Ако буквата е `S`, тогава намаляте бройката на сегашния продукт с 1, а ако е `R` - увеличаваме с 10.
-&&warn **НЕ** може да използвате масиви! **Трябва** действията на `S` и `R` да се изкарат във функции!
+&:warn **НЕ** може да използвате масиви! **Трябва** действията на `S` и `R` да се изкарат във функции!
Когато получите `$`, изкарвате броя на всеки продукт и спирате програмата.
@@ -46,7 +46,7 @@ GitHub classroom: [classroom.github.com/a/m5M2_CWD](https://classroom.github.com
В началото получавате буква - тя съответства на дадена **функция**, след това получавате 5 числа с плаваща запетая.
След всяко въведено трябва да изкарате резултата от съответната функция при подадено входното число.
-&&warn **Трябва** да използвате указател към функция!
+&:warn **Трябва** да използвате указател към функция!
Буквите съответстват на следните функции:
diff --git a/src/teaching/upp-2023/week8/index.md b/src/teaching/upp-2023/week8/index.md
index f3ab415..561dc71 100644
--- a/src/teaching/upp-2023/week8/index.md
+++ b/src/teaching/upp-2023/week8/index.md
@@ -2,7 +2,7 @@
GitHub classroom: [classroom.github.com/a/Big7FRUG](https://classroom.github.com/a/Big7FRUG)
-&&warn **Трябва** да използвате възможно най-малко памет във всички задачи!
+&:warn **Трябва** да използвате възможно най-малко памет във всички задачи!
## Задача 1
@@ -77,7 +77,7 @@ GitHub classroom: [classroom.github.com/a/Big7FRUG](https://classroom.github.com
Друг начин по който да го разберем, е че първото число е на първа позиция, второто число е на последната, третото число е на втора позиция, четвъртото е на предпоследна и так. нат.
Обаче ние не знаем финалния размер на масива, затова се нуждаем от логиката с чертата.
-&&important Моля не правете решенето със запазване на входа и разместване на елементите
+&:important Моля не правете решенето със запазване на входа и разместване на елементите
Напомням, че тази права само си я представяте.
В началото масива е с размер 2.
diff --git a/src/teaching/upp-2023/week9/index.md b/src/teaching/upp-2023/week9/index.md
index 86e7cca..557b89a 100644
--- a/src/teaching/upp-2023/week9/index.md
+++ b/src/teaching/upp-2023/week9/index.md
@@ -2,7 +2,7 @@
GitHub classroom: [classroom.github.com/a/lGXxCRZO](https://classroom.github.com/a/lGXxCRZO)
-&&warn Освен ако не е казано друго, може да зачитате, че максималната дължина на един низ е 1024 знака.
+&:warn Освен ако не е казано друго, може да зачитате, че максималната дължина на един низ е 1024 знака.
## Задача 1
@@ -21,7 +21,7 @@ GitHub classroom: [classroom.github.com/a/lGXxCRZO](https://classroom.github.com
Изкарайте на екрана втората половина от низа и след това директно долепена първата половина.
Ако низа е с нечетна дължина, зачитаме средния елемент като част от втората половина.
-&&important Трябва да използвате динамична памет
+&:important Трябва да използвате динамична памет
**Примери:**