From 173c41e6f2e4f3ce750c33769b2e5a14f0cacbb7 Mon Sep 17 00:00:00 2001 From: Syndamia Date: Sun, 17 Aug 2025 18:52:44 +0300 Subject: feat(teaching/oop-2023): Converted to dunbar --- src/teaching/oop-2023/index.du | 64 ++++ src/teaching/oop-2023/index.md | 32 -- src/teaching/oop-2023/week1/good-software.du | 443 +++++++++++++++++++++++ src/teaching/oop-2023/week1/good-software.md | 519 --------------------------- src/teaching/oop-2023/week1/index.du | 160 +++++++++ src/teaching/oop-2023/week1/index.md | 111 ------ src/teaching/oop-2023/week1/organization.du | 54 +++ src/teaching/oop-2023/week1/organization.md | 61 ---- src/teaching/oop-2023/week10/index.du | 150 ++++++++ src/teaching/oop-2023/week10/index.md | 146 -------- src/teaching/oop-2023/week11/index.du | 210 +++++++++++ src/teaching/oop-2023/week11/index.md | 201 ----------- src/teaching/oop-2023/week12/index.du | 97 +++++ src/teaching/oop-2023/week12/index.md | 94 ----- src/teaching/oop-2023/week13/index.du | 141 ++++++++ src/teaching/oop-2023/week13/index.md | 138 ------- src/teaching/oop-2023/week14/index.du | 73 ++++ src/teaching/oop-2023/week14/index.md | 73 ---- src/teaching/oop-2023/week15/index.du | 39 ++ src/teaching/oop-2023/week15/index.md | 37 -- src/teaching/oop-2023/week16/index.du | 31 ++ src/teaching/oop-2023/week16/index.md | 30 -- src/teaching/oop-2023/week2/index.du | 196 ++++++++++ src/teaching/oop-2023/week2/index.md | 194 ---------- src/teaching/oop-2023/week3/index.du | 177 +++++++++ src/teaching/oop-2023/week3/index.md | 175 --------- src/teaching/oop-2023/week4/index.du | 115 ++++++ src/teaching/oop-2023/week4/index.md | 110 ------ src/teaching/oop-2023/week5/index.du | 118 ++++++ src/teaching/oop-2023/week5/index.md | 116 ------ src/teaching/oop-2023/week6/index.du | 104 ++++++ src/teaching/oop-2023/week6/index.md | 102 ------ src/teaching/oop-2023/week7/index.du | 85 +++++ src/teaching/oop-2023/week7/index.md | 83 ----- src/teaching/oop-2023/week8/index.du | 172 +++++++++ src/teaching/oop-2023/week8/index.md | 167 --------- src/teaching/oop-2023/week9/index.du | 114 ++++++ src/teaching/oop-2023/week9/index.md | 112 ------ 38 files changed, 2543 insertions(+), 2501 deletions(-) create mode 100644 src/teaching/oop-2023/index.du delete mode 100644 src/teaching/oop-2023/index.md create mode 100644 src/teaching/oop-2023/week1/good-software.du delete mode 100644 src/teaching/oop-2023/week1/good-software.md create mode 100644 src/teaching/oop-2023/week1/index.du delete mode 100644 src/teaching/oop-2023/week1/index.md create mode 100644 src/teaching/oop-2023/week1/organization.du delete mode 100644 src/teaching/oop-2023/week1/organization.md create mode 100644 src/teaching/oop-2023/week10/index.du delete mode 100644 src/teaching/oop-2023/week10/index.md create mode 100644 src/teaching/oop-2023/week11/index.du delete mode 100644 src/teaching/oop-2023/week11/index.md create mode 100644 src/teaching/oop-2023/week12/index.du delete mode 100644 src/teaching/oop-2023/week12/index.md create mode 100644 src/teaching/oop-2023/week13/index.du delete mode 100644 src/teaching/oop-2023/week13/index.md create mode 100644 src/teaching/oop-2023/week14/index.du delete mode 100644 src/teaching/oop-2023/week14/index.md create mode 100644 src/teaching/oop-2023/week15/index.du delete mode 100644 src/teaching/oop-2023/week15/index.md create mode 100644 src/teaching/oop-2023/week16/index.du delete mode 100644 src/teaching/oop-2023/week16/index.md create mode 100644 src/teaching/oop-2023/week2/index.du delete mode 100644 src/teaching/oop-2023/week2/index.md create mode 100644 src/teaching/oop-2023/week3/index.du delete mode 100644 src/teaching/oop-2023/week3/index.md create mode 100644 src/teaching/oop-2023/week4/index.du delete mode 100644 src/teaching/oop-2023/week4/index.md create mode 100644 src/teaching/oop-2023/week5/index.du delete mode 100644 src/teaching/oop-2023/week5/index.md create mode 100644 src/teaching/oop-2023/week6/index.du delete mode 100644 src/teaching/oop-2023/week6/index.md create mode 100644 src/teaching/oop-2023/week7/index.du delete mode 100644 src/teaching/oop-2023/week7/index.md create mode 100644 src/teaching/oop-2023/week8/index.du delete mode 100644 src/teaching/oop-2023/week8/index.md create mode 100644 src/teaching/oop-2023/week9/index.du delete mode 100644 src/teaching/oop-2023/week9/index.md (limited to 'src') diff --git a/src/teaching/oop-2023/index.du b/src/teaching/oop-2023/index.du new file mode 100644 index 0000000..20e5282 --- /dev/null +++ b/src/teaching/oop-2023/index.du @@ -0,0 +1,64 @@ +# Обектно-ориентирано програмиране - практикум, Компютърни науки, 8 група + +Материали на проведените през 2023/2024 практикуми по Обектно-ориентирано програмиране на Компютърни науки (2 поток), 8 група. + +=[Зала:]= ФМИ 120 || +=[Време:]= 13:15 - 15:00 || +=[Ден:]= Четвъртък +\n +=[Директни връзки:]= +[url ../upp-2023/week1/welcome.html?a#section-4 Контакт с мен] | +[url https://github.com/Syndamia/oop-2023-solutions Решения на задачи] | +[url https://github.com/Aleksis99/Object-Oriented-Programming_FMI_2023-2024 Материали от семинари] | +[url https://learn.fmi.uni-sofia.bg/course/view.php?id=10041 Курс в мудъл] + +:table +|=№=||=Дата=||=Материали=| + +|:1 :||:22.02.2024:| +|:[url ./week1/organization.html?a Организационно] \|\| [url ./week1/good-software.html?a Основни добри софтуерни практики] \|\| [url ./week1/ Задачи] \|\| [url https://github.com/Syndamia/oop-2023-solutions/tree/main/week01 Решения] \|\| [url https://classroom.github.com/a/UPJOzHty GitHub classroom]:| + +|:2 :||:29.02.2024:| +|:[url ./week2/ Задачи] \|\| [url https://github.com/Syndamia/oop-2023-solutions/tree/main/week02 Решения] \|\| [url https://classroom.github.com/a/3qPsfyyI GitHub classroom]:| + +|:3 :||:07.03.2024:| +|:[url ./week3/ Задачи] \|\| [url https://github.com/Syndamia/oop-2023-solutions/tree/main/week03 Решения] \|\| [url https://classroom.github.com/a/KPMqXsFp GitHub classroom]:| + +|:4 :||:14.03.2024:| +|:[url ./week4/ Задачи] \|\| [url https://github.com/Syndamia/oop-2023-solutions/tree/main/week04 Решения] \|\| [url https://classroom.github.com/a/qa_FfWeG GitHub classroom]:| + +|:5 :||:21.03.2024:| +|:[url ./week5/ Задачи] \|\| [url https://github.com/Syndamia/oop-2023-solutions/tree/main/week05 Решения] \|\| [url https://classroom.github.com/a/42ZZ56Mg GitHub classroom]:| + +|:6 :||:28.03.2024:| +|:[url ./week6/ Задачи] \|\| [url https://github.com/Syndamia/oop-2023-solutions/tree/main/week06 Решения] \|\| [url https://classroom.github.com/a/rzSTn5pu GitHub classroom]:| + +|:7 :||:04.04.2024:| +|:[url ./week7/ Задачи] \|\| [url https://github.com/Syndamia/oop-2023-solutions/tree/main/week07 Решения] \|\| [url https://classroom.github.com/a/vvZENbkX GitHub classroom]:| + +|:8 :||:11.04.2024:| +|:[url ./week8/ Задачи] \|\| [url https://github.com/Syndamia/oop-2023-solutions/tree/main/week08 Решения] \|\| [url https://classroom.github.com/a/7d0MBjcK GitHub classroom]:| + +|:9 :||:18.04.2024:| +|:[url ./week9/ Задачи] \|\| [url https://github.com/Syndamia/oop-2023-solutions/tree/main/week09 Решения] \|\| [url https://classroom.github.com/a/wlL1oUg2 GitHub classroom]:| + +|:10:||:25.04.2024:| +|:[url ./week10/ Задачи] \|\| [url https://github.com/Syndamia/oop-2023-solutions/tree/main/week10 Решения] \|\| [url https://classroom.github.com/a/PbkITWhF GitHub classroom]:| + +|:11:||:09.05.2024:| +|:[url ./week11/ Задачи] \|\| [url https://github.com/Syndamia/oop-2023-solutions/tree/main/week11 Решения] \|\| [url https://classroom.github.com/a/oYQehcnN GitHub classroom] =[Това упражнение е от 11:15 до 13:15]=:| + +|:12:||:09.05.2024:| +|:[url ./week12/ Задачи] \|\| [url https://github.com/Syndamia/oop-2023-solutions/tree/main/week12 Решения] \|\| [url https://classroom.github.com/a/o7hNz1pr GitHub classroom]:| + +|:13:||:16.05.2024:| +|:[url ./week13/ Задачи] \|\| [url https://github.com/Syndamia/oop-2023-solutions/tree/main/week13 Решения] \|\| [url https://classroom.github.com/a/GvV1wrC1 GitHub classroom]:| + +|:14:||:23.05.2024:| +|:[url ./week14/ Задачи] \|\| [url https://classroom.github.com/a/K0XomKEP GitHub classroom]:| + +|:15:||:30.05.2024:| +|:[url ./week15/ Задачи] \|\| [url https://classroom.github.com/a/z2QadyEE GitHub classroom] =[Това упражнение е от 11:15 до 13:15]=:| + +|:16:||:06.06.2024:| +|:[url ./week16/ Задачи] \|\| [url https://classroom.github.com/a/BWjw2dUC GitHub classroom]:| diff --git a/src/teaching/oop-2023/index.md b/src/teaching/oop-2023/index.md deleted file mode 100644 index 63acb0f..0000000 --- a/src/teaching/oop-2023/index.md +++ /dev/null @@ -1,32 +0,0 @@ -# Обектно-ориентирано програмиране - практикум, Компютърни науки, 8 група - -Материали на проведените през 2023/2024 практикуми по Обектно-ориентирано програмиране на Компютърни науки (2 поток), 8 група. - -**Зала:** ФМИ 120 || -**Време:** 13:15 - 15:00 || -**Ден:** Четвъртък -
-**Директни връзки:** -[Контакт с мен](../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) - -|№|Дата|Материали| -|-------|----|---------| -|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/) \|\| [GitHub classroom](https://classroom.github.com/a/K0XomKEP)| -|15|30.05.2024|[Задачи](./week15/) \|\| [GitHub classroom](https://classroom.github.com/a/z2QadyEE) **Това упражнение е от 11:15 до 13:15**| -|16|06.06.2024|[Задачи](./week16/) \|\| [GitHub classroom](https://classroom.github.com/a/BWjw2dUC)| diff --git a/src/teaching/oop-2023/week1/good-software.du b/src/teaching/oop-2023/week1/good-software.du new file mode 100644 index 0000000..ce36c28 --- /dev/null +++ b/src/teaching/oop-2023/week1/good-software.du @@ -0,0 +1,443 @@ +# Основни добри софтуерни практики - ООП, Седмица 1, 22.02.2024 + +\n + +Миналия семестър не ни стигна времето да обсъдим домашното по-сериозно. +Главния проблем, който забелязах, беше колко грозно и нагласено бяха написани решенията. +Като въведение в ООП, ще поговорим по тази тема. + +[$presentation-controller] + +:title_slide + +# Основни идеи\n + при добро писане на код + + +:slide35 + +## Какво прави програмиста с чужд код? + +[$br4] + +.numbered +1. Чете +2. Разучава как се ползва/какво прави +3. Използва го/Модифицира го + +.p Добър код прави тези задачи лесни! + + +:slide35 + +## Подобряване на четене + +[$br4] + +.unordered +- Лично вярвам, че четимост е по-важна от конвенции +- Човек вижда най-лесно "контрастни" шаблони + +``` + . . 0.00.0 010010 815213 + 000000 000000 738438 +. . .0000. 100001 122481 + .... 0....0 011110 511119 + + +Както виждате, в примера има усмихнато личице, "закодирано" по различни начини. +С точка и шпации е най-ясно, като заменим шпациите с нули става по-неясно, като заменим точките с единици става още повече и като заменим нулите със случайни не-единични цифри, става пък съвсем невидимо. +Важното е шаблона да се намира в среда на други шаблони, иначе трудно се забелязва. + +При код, ще илюстрирам идеята си с един пример, но няма да задълбавам, следващата секция е много по-важна. +Пък и тази тема е малко религиозна и ще чувате различни мнения според човека който питате. + +:middle_slide + +Труден за четене код *[(забелязвате ли грешките?)]*: + +.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_slide + +По-лесен за четене код *[(а сега виждат ли се по-лесно?)]*: + +:font18 +:code +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] + +.bulleted +- Разделяме обработване на стойностите от директната имплементацията +- Създаваме нови "машинни инструкции" + +[$br1] + +.bulleted +- `[doX()]` е по-лошо от `[do(X)]` + .unordered + - можем да преизползваме `[do()]` за неща, различни от `[X]` + - един път разбрано, всяка употреба на `[do()]` също е разбрана; този стил кара `[do()]` да бъде по-обща функция, което я прави по-лесна за разбиране + - модификация на `[do(X)]` се свежда до заменяне на `[do()]` с `[doOther()]` или до заменяне на `[X]` с `[Y]`; променяме "инструкцията" или променяме данната + + +Нека сега разгледаме няколко примера, първият е много груб и елементарен, но служи за добро начало: + +:middle_slide + +```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; +} │ } + + +Би трябвало да е супер очевидно, никой няма да пише отделна функция на Фибоначи за всяко число. + +Нека сега да разгледаме няколко "реални" примера, свързани с домашното (за припомняне, условието се намира [url 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_slide + +Добро - `[do(X)]` + +:code_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_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++) { + // appendToMatrix(mat,rows,cols,fill,max): + // замества първите (най-много) max празни клетки с fill + // връща колко клетки наистина е заместило + appendToMatrix(layer, rows, cols, + tiles[i], tileCounts[i]); + } + shuffleMatrix(layer, rows, cols); +} + +=[Бонус:]= работи по-коректно от преди + + +В предходния вариант, ако примерно цялата е пълна освен една клетка, и трябва да поставим една финална плочка, тогава трябва да чакаме докато случайните стойности се напаснат точно с координатите на тази една клетка. +Това може да се случи след половин секунда, но може да отнеме и един час докато се случи. +Даже, този проблем става все по-тегав с времето: с всяка запълнена клетка, шанса случайните стойности да ударят на заети координати се увеличава. + +Докато тук, нямаме този проблем, отнема някакво консистентно предопределено време да разбъркаме матрицата. +Как имплементираме `[shuffleMatrix]` си има и своите тънкости, но най-елементарния начин е просто да направим сортираш алгоритъм, при който вместо да сравним две стойности, използваме случайна стойност, която определя дали ще разменим плочките. + +Друго хубаво нещо на решения с абстракция, е един лек лавинен ефект, където веднъж като почнем да мислим за абстракции, намираме къде да ги ползваме навсякъде. +Да разгледаме същата функция, обаче при D подточка. + +:middle_slide + +Решения със слоеве правят същото. Лошо - `[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]`, не е нужно нищо специално да правим! + +:middle_slide35 + +### Абстракцията - подобрява и коментари + +.unordered +- Целта на коментарите е да направи разбиране и модификация на код по-лесни. +- В повечето случаи, коментарът трябва да ни дава *[нова]* информация или да *[свърже]* парчета информация + + +Да разгледаме следния пример. + +:middle_slide + +Лошо: + +```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']`. +В лошия можем да стигнем до същото заключение като погледнем самия код. + + + +Умението да разрешиш един проблем *[не те]* прави добър програмист, да го разрешиш по четим, разширяем, лесен, ефикасен, ... начин *[те]* прави добър програмист. + +:slide35 + +## Изводи + +[$br4] + +.unordered +- Форматирайте/подравнявайте си кода, искате лесно четене +- Вдигайте абстракция + .unordered + - Обширни функции > код за конкретни стойности + - Преизползване на възможно най-много код + - Коментари които дават или разширяват знание diff --git a/src/teaching/oop-2023/week1/good-software.md b/src/teaching/oop-2023/week1/good-software.md deleted file mode 100644 index 79a51b0..0000000 --- a/src/teaching/oop-2023/week1/good-software.md +++ /dev/null @@ -1,519 +0,0 @@ -# Основни добри софтуерни практики - ООП, Седмица 1, 22.02.2024 - -Миналия семестър не ни стигна времето да обсъдим домашното по-сериозно. -Главния проблем, който забелязах, беше колко грозно и нагласено бяха написани решенията. -Като въведение в ООП, ще поговорим по тази тема. - -&.presentation - -&[title - -# Основни идеи
при добро писане на код - -&] - - - -&[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'`. -В лошия можем да стигнем до същото заключение като погледнем самия код. - - - -Умението да разрешиш един проблем *не те* прави добър програмист, да го разрешиш по четим, разширяем, лесен, ефикасен, ... начин *те* прави добър програмист. - - - -&[slide35 - -## Изводи - -&.br4 - -- Форматирайте/подравнявайте си кода, искате лесно четене -- Вдигайте абстракция - - Обширни функции > код за конкретни стойности - - Преизползване на възможно най-много код - - Коментари които дават или разширяват знание - -&] diff --git a/src/teaching/oop-2023/week1/index.du b/src/teaching/oop-2023/week1/index.du new file mode 100644 index 0000000..dc3346b --- /dev/null +++ b/src/teaching/oop-2023/week1/index.du @@ -0,0 +1,160 @@ +# Задачи - ООП, Седмица 1, 22.02.2024 + +\n + +GitHub classroom: [url https://classroom.github.com/a/UPJOzHty classroom.github.com/a/UPJOzHty] + +## Задача 1 + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week01/Exercise1.cpp Решение] + +Имплементирайте низ чрез структура. +В структурата трябва да запазвате указател към низа и неговата дължина. + +Имплементирайте функция `[concatString]`, която приема две структури от този тип и връща низ, пак в същата структура, който е конкатенация (слепване) на първите два низа. + +.question Има ли значение дали типовете на аргументите, или на върнатата стойност, са референции или указатели (или нито едното)? + +В самия код тествайте функциите (не е нужен потребителски вход). + +## Задача 2 + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week01/Exercise2.cpp Решение] + +Имплементирайте структура за динамично-заделен масив от целочислени числа. +Тя трябва да запазва указател към масива, размера на масива и бройката на елементи в масива. + +Заделянето на динамична памет е бавна операция, затова винаги ще заделяме повече клетки, отколкото са ни нужни. + +Имплементирайте функция `[resize]`, която удвоява размера на масива (нека първоначалния размер на масива е 2), на подадена стойност от тип вашата структура. + +Имплементирайте функция `[addToEnd]`, която приема (инстанция на) структурата ви и вмъква елемент в първата незаета позиция. + +В самия код тествайте функциите (не е нужен потребителски вход). + +## Задача 3 + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week01/Exercise3.cpp Решение] + +Разглеждате "пакети" (логове) информация от редица датчици. +Един пакет запазва времето, когато информацията е била отчетена от датчиците, и стойностите на всички датчици: температура, атмосферно налягане, влажност и надморска височина. +Всички типове данни са целочислени. + +От входа получавате N, броя пакети, които трябва да запазите, и след това 5N на брой целочислени стойности. +Накрая получавате буква: `[t]`, `[p]`, `[h]`, `[e]`, всяка съответства на някоя отделна стойност от датчиците. + +Трябва да изкарате на екрана всичките стойности от пакетите, подредени в нарастващ ред на времето, като всички след първата са разликите им спрямо първата. + +=[Пример:]= + +.table +|=Вход=||=Изход=| +|:6\n + 56 45 64 -8 98\n + 14 40 -15 -18 -1\n + 22 89 72 62 4\n + 85 44 60 17 13\n + 75 18 -12 48 21\n + 27 10 94 -5 16\n + p:| +|:-15 87 109 79 3 75:| + +## Задача 4 + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week01/Exercise4.cpp Решение] + +'footnote sabre Защото една от първите индустрии, които са се нуждаели от компютърни системи, била [url https://en.wikipedia.org/wiki/Sabre_%28travel_reservation_system%29#History авиационната индустрия]. + +Направете структура за съхранение на полети[$sabre]. +Трябва да запазите имената на началния и крайния град като низове (допускаме, че няма шпации в имената на градовете), часът на излитане и на кацане в целочислен формат (като на циферблат на дигитален часовник, без разделителното двоеточие) и цената на полета в тип с плаваща запетая (в долари). + +### а) въвеждане + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week01/Exercise4.cpp#L15-L36 Решение] + +От входа получавате N, това определя броя полети, които трябва да се добавят в системата. +Всеки полет е редица от 5 стойности, в реда в който са дефинирани. + +*[Напомням, че това е нагласено да ползвате `[std::cin]` вместо ръчно да обработвате целия ред.]* + +Изкарайте началните и крайните градове, както и цената на полетите, подредени в нарастващ ред на час на излитане. + +=[Пример:]= + +.table +|=Вход=||=Изход=| +|:5\n + Berlin Paris 1105 1255 140\n + Sofia Paris 0915 1115 140\n + Paris NewYork 1225 1610 500\n + Sofia NewYork 0610 1345 800\n + Sofia Berlin 1020 1130 200:| +|:Sofia NewYork 800\n + Sofia Paris 140\n + Sofia Berlin 200\n + Berlin Paris 140\n + Paris NewYork 500:| + +### б) търсене + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week01/Exercise4.cpp#L38-L247 Решение] + +След като се въведат всички полети, получавате от входа два низа - имена на градове. +Трябва да изкарате най-евтиния, и след него най-бързия, вариант за пътуване от първия град към втория. + +Прикачване между полети е позволено, така че под "вариант" трябва да изкарате всичките полети, които са решение. +За един полет е нужно да изкарате само началния град, крайния град, час на излитане и цена, като градовете трябва да са подредени в нарастващ ред на часа на излитане. + +=[Пример:]= + +.table +|=Вход=||=Изход=| +|:5\n + Berlin Paris 1105 1255 140\n + Sofia Paris 0915 1115 140\n + Paris NewYork 1225 1610 500\n + Sofia NewYork 0610 1245 800\n + Sofia Berlin 1020 1130 200\n + Sofia NewYork:| +|:Cheapest:\n + Sofia Paris 0915 140\n + Paris NewYork 1225 500\n + Quickest:\n + Sofia NewYork 0610 800:| + + +## Задача 5 + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week01/Exercise5.cpp Решение] + +Имате система за потребители, всеки потребител си има име и приятели (един приятел е =[указател към потребител]=). + +В началото се въвежда N, това е броят потребители в системата. +За един потребител, първо се въвежда на нов ред името му, след това броя на неговите приятели и накрая, на отделни редове, имената на всички тези приятели. + +Накрая получавате едно име, това е началния потребител. +Трябва да намерите, започвайки от него, с колко други потребителя има някаква приятелска връзка (директна, приятел на приятел, приятел на приятел на приятел, ...). + +=[Пример:]= + +.table +|=Вход=||=Изход=| +|:5\n + Георги\n + 2\n + Асен Гьонов\n + Майстора\n + Асен Гьонов\n + 2\n + Георги\n + др. Божидаров\n + Майстора\n + 1\n + Георги\n + др. Божидаров\n + 1\n + Асен Гьонов\n + Павел\n + 0\n + Майстора:| +|:3:| diff --git a/src/teaching/oop-2023/week1/index.md b/src/teaching/oop-2023/week1/index.md deleted file mode 100644 index df05b2e..0000000 --- a/src/teaching/oop-2023/week1/index.md +++ /dev/null @@ -1,111 +0,0 @@ -# Задачи - ООП, Седмица 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
56 45 64 -8 98
14 40 -15 -18 -1
22 89 72 62 4
85 44 60 17 13
75 18 -12 48 21
27 10 94 -5 16
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
Berlin Paris 1105 1255 140
Sofia Paris 0915 1115 140
Paris NewYork 1225 1610 500
Sofia NewYork 0610 1345 800
Sofia Berlin 1020 1130 200|Sofia NewYork 800
Sofia Paris 140
Sofia Berlin 200
Berlin Paris 140
Paris NewYork 500| - -### б) търсене - -&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week01/Exercise4.cpp#L38-L247) - -След като се въведат всички полети, получавате от входа два низа - имена на градове. -Трябва да изкарате най-евтиния, и след него най-бързия, вариант за пътуване от първия град към втория. - -Прикачване между полети е позволено, така че под "вариант" трябва да изкарате всичките полети, които са решение. -За един полет е нужно да изкарате само началния град, крайния град, час на излитане и цена, като градовете трябва да са подредени в нарастващ ред на часа на излитане. - -**Пример:** - -|Вход|Изход| -|----|-----| -|5
Berlin Paris 1105 1255 140
Sofia Paris 0915 1115 140
Paris NewYork 1225 1610 500
Sofia NewYork 0610 1245 800
Sofia Berlin 1020 1130 200
Sofia NewYork|Cheapest:
Sofia Paris 0915 140
Paris NewYork 1225 500
Quickest:
Sofia NewYork 0610 800| - - -## Задача 5 - -&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week01/Exercise5.cpp) - -Имате система за потребители, всеки потребител си има име и приятели (един приятел е **указател към потребител**). - -В началото се въвежда N, това е броят потребители в системата. -За един потребител, първо се въвежда на нов ред името му, след това броя на неговите приятели и накрая, на отделни редове, имената на всички тези приятели. - -Накрая получавате едно име, това е началния потребител. -Трябва да намерите, започвайки от него, с колко други потребителя има някаква приятелска връзка (директна, приятел на приятел, приятел на приятел на приятел, ...). - -**Пример:** - -|Вход|Изход| -|----|-----| -|5
Георги
2
Асен Гьонов
Майстора
Асен Гьонов
2
Георги
др. Божидаров
Майстора
1
Георги
др. Божидаров
1
Асен Гьонов
Павел
0
Майстора|3| - -[^sabre]: Защото една от първите индустрии, които са се нуждаели от компютърни системи, била [авиационната индустрия](https://en.wikipedia.org/wiki/Sabre_%28travel_reservation_system%29#History). diff --git a/src/teaching/oop-2023/week1/organization.du b/src/teaching/oop-2023/week1/organization.du new file mode 100644 index 0000000..40abea9 --- /dev/null +++ b/src/teaching/oop-2023/week1/organization.du @@ -0,0 +1,54 @@ +# Организация - ООП, Седмица 1, 22.02.2024 + +\n + +[$presentation-controller] + +:title_slide35 + +# Добре дошли в ООП + + +За разлика от Увод в програмиране, по ООП практикума е малко по-специален. + +:middle_slide35 + +:unordered +- ООП практикум е избираема, която няма смисъл да не запишете + .unordered + - Само плюсове за вас + +- Оценката е според контролни/изпити по ООП + + + +Така ви помагаме с избираемите: по учебен план трябва да имате поне 2 практикума, сравнително безплатно получавате единия. +Относно оценяване: + +:middle_slide35 + +.unordered +- Освобождаване от изпит според работата ви по време на практикум +- Няма намаляване на оценка +- Оценявам общите ви умения + .p Важното е да умеете да сте програмисти: коректност, брой и трудност на решени задачи се зачитат по-малко отколкото успех да напишете прилично-изглеждаща програма (дори с малко мой тласък) + + +Все пак не може да ви даваме безплатни оценки, затова: + +:middle_slide35 + +:unordered +- Зачитат се =[единствено нещата, качени в GitHub classroom, качени в срок]= + .unordered + - До =[15]= минути след края на часа + +- Както преди, не е нужно да присъствате, за да качвате решения +- Ако случайно някой не знае как се ползва: + + +.centered [url ../upp-2023/week1/setup.html?a syndamia.com/upp-2023/week1/setup.html?a] + + +Който по време на УП е използвал GitHub classroom не би трябвало да прави нещо, продължавате си по старо му, със същите акаунти. +Разбира се, за всякакви проблеми се [url ../upp-2023/week1/welcome.html?a#section-4 свържете с мен]. diff --git a/src/teaching/oop-2023/week1/organization.md b/src/teaching/oop-2023/week1/organization.md deleted file mode 100644 index 92fdcc8..0000000 --- a/src/teaching/oop-2023/week1/organization.md +++ /dev/null @@ -1,61 +0,0 @@ -# Организация - ООП, Седмица 1, 22.02.2024 - -&.presentation - -&[title35 - -# Добре дошли в ООП - -&] - - - -За разлика от Увод в програмиране, по ООП практикума е малко по-специален. - - - -&[middle35 - -- ООП практикум е избираема, която няма смисъл да не запишете - - Само плюсове за вас -- Оценката е според контролни/изпити по ООП - -&] - - - -Така ви помагаме с избираемите: по учебен план трябва да имате поне 2 практикума, сравнително безплатно получавате единия. -Относно оценяване: - - - -&[middle35 - -- Освобождаване от изпит според работата ви по време на практикум -- Няма намаляване на оценка -- Оценявам общите ви умения
- Важното е да умеете да сте програмисти: коректност, брой и трудност на решени задачи се зачитат по-малко отколкото успех да напишете прилично-изглеждаща програма (дори с малко мой тласък) - -&] - - - -Все пак не може да ви даваме безплатни оценки, затова: - - - -&[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.du b/src/teaching/oop-2023/week10/index.du new file mode 100644 index 0000000..dfff7fc --- /dev/null +++ b/src/teaching/oop-2023/week10/index.du @@ -0,0 +1,150 @@ +# Задачи - ООП, Седмица 10, 25.04.2024 + +\n + +GitHub classroom: [url https://classroom.github.com/a/PbkITWhF classroom.github.com/a/PbkITWhF] + +## Преговорни + +.warn Моля, не отделяйте на преговорните задачи повече от 30мин + +### Задача 1 - Шаблони + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week10/Exercise01 Решение] + +Реализирайте шаблонен клас `[Array]`, който запазва динамично-заделен и оразмеряем масив от елементи с подаден тип. +Имплементирайте голяма четворка. + +### Задача 2 - Оператори + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week10/Exercise02 Решение] + +За предходния шаблонен клас имплементирайте оператори: + +.unordered +- [], който връща референция към елемента на подадения индекс +- == и !=, които сравняват поелементно +- +, += които конкатенират (слепват) два масива + +### Задача 3 - Грешки + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week10/Exercise03 Решение] + +Имплементирайте функция, която приема име на текстов файл и изкарва на екрана първия ред от него. +Ако файлът не може да бъде отворен, хвърлете грешка - низ. +Ако във файлът няма други редове (няма знакът `['\\n']`), тогава хвърлете грешка число - размерът на файла. + +В главната функция, приемете името на файла от потребителския вход и извикайте функцията. +Ако файлът не може да бъде отворен, тогава изкарайте хвърлената грешка на терминала и приключете програмата (успешно). +Ако няма други редове в него, тогава изкарайте съобщението "In X characters, there is no newline!", където X е хвърленото число, и пробвайте да приемете пак име на файла от потребителския вход. + +## Лесни + +### Задача 4 + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week10/Exercise04 Решение] + +Реализирайте клас `[Time24]`, който запазва час и минути (в 24-часов формат) в две отделни целичислени член-данни. +Имплементирайте член-функция `[Print24]`, която изкарва часа на екрана в 24-часов формат. +Нека конструкторът му приема две целочислени променливи, една за часа и втора за минутите. + +Реализирайте негов наследник `[Time12]`, който имплементира метод `[Print12]`, принтиращ часа в 12-часов формат. +Имплементирайте и негов конструктор, който приема две целочислени променливи (една за часа и една за минутите), заедно с булева променлива описваща дали часа е следобеден или не. + +### Задача 5 + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week10/Exercise05 Решение] + +Реализирайте клас `[FN]`, който запазва факултетен номер като неотрицателно цяло число от 5 цифри. +Реализирайте негов наследник `[ModernFN]`, който запазва и начален (префиксен) низ, състоящ се от цифра, две букви и още две цифри. + +Имплементирайте конструктори, като този на `[FN]` приема число, докато този на `[ModernFN]` приема низ, състоящ се от целия факултетен номер (и трябва да конвертирате последните 5 цифри към число). +Имплементирайте метод `[PrintOldFN]` на класа `[FN]` и метод `[PrintNewFN]` на класа `[ModernFN]`, които изкарват целия факултетен номер на съответния клас. + +### Задача 6 + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week10/Exercise06 Решение] + +Реализирайте клас `[Grade]`, който запазва оценка (от 2 до 6) като неотрицателна целочислена член-данна. +Реализирайте и негов наследник `[GradeWithName]`, който запазва и името на оценката като низ с произволна дължина. + +Конструктора на `[Grade]` приема само числовата стойност, докато този на наследника приема и името на оценката. +Имплементирайте голяма петица на `[GradeWithName]`. + +### Задача 7 + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week10/Exercise07 Решение] + +Реализирайте клас `[String]`, който запазва низ с произволна дължина. +Имплементирайте голяма петица и член-функция `[At]`, която приема индекс и връща референция към буквата на този индекс (при невалиден индекс хвърляте грешка). + +Реализирайте негов наследник `[FileString]`, който запазва и името на текстов файл като низ с произволна дължина. +Ако е нужно, имплементирайте голяма петица. + +Самия низ в `[FileString]` е първия низ (начало първата буква и край `['\\n']`) от файла с подадено име. + +Имплементирайте метод `[ChangeAt]`, който приема индекс и нова буква, променя буквата на дадения индекс с подадената и обновява файла със запазеното име. + +### Задача 8 + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week10/Exercise08 Решение] + +Реализирайте клас `[User]`, който запава име и парола като два низа с произволна дължина. +Реализирайте негов наследник `[Moderator]`, който запазва и подпис, който също е низ с произволна дължина. +Реализирайте наследник `[Administrator]` на `[Moderator]`, който запазва и оразмеряващ се масив от цели числа. + +Идеята е, че всяко действие от модератор или администратор се "подписва" публично (за да се знае, че той го е направил, дори да си смени името), а за администратор допълнително пазим масив от идентификатори на форуми, които администрира. + +За всеки клас имплементирайте голяма петица и гетъри и сетъри за името и паролата, когато е нужно. +За `[Moderator]` имплементирайте гетър за подписа, но без сетър. +За `[Administrator]` имплементирайте методи за добавяне и премахване на идентификатор на форум. + +### Задача 9 + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week10/Exercise09 Решение] + +Реализирайте клас `[CommunicationPacket]`, който запазва начален и краен адрес като две неотрицателни цели числа, заедно с трето число за размера на данните. +В този клас никога няма данни, затова размера винаги е нула. + +Реализирайте негови наследници `[StringPacket]` и `[IntPacket]`, където първия запазва и низ с произволна дължина (и дължината му е размера на данните) докато втория запазва и едно цяло число (и размера на `[int]` е размера на данните). + +Размерът не се подава на конструктори, а се изчислява в конструктори. +Имплементирайте голяма петица и конструктори с нужните параметри. + +### Задача 10 + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week10/Exercise10 Решение] + +Реализирайте клас `[String]`, който запазва низ с произволна дължина, и имплементира оператори ==, !=, + (който връща нов низ с конкатенацията на двата низа). + +Реализирайте негов наследник `[ModifiableString]`, който имплементира оператор[] (връщащ референция към буквата на дадения индекс) и оператор+=. + +Реализирайте наследник на `[ModifiableString]`, `[ShowableString]`, който имплементира оператори << и >>. +Реализирайте наследник на `[ModifiableString]`, `[SaveableString]`, който имплементира методи write и read, приемащи име на двоичен файл и записващи или четещи низа от този файл. + +За всички класове имплементирайте голяма петица, когато е нужно. + +## Трудни + +### Задача 11 + +Реализирайте шаблонен клас `[Array]`, който запазва оразмеряем масив с елементи от подаден тип. +Имплементирайте оператор== и оператор!=, заедно с метод `[isEmpty]`. +Концептуално идеята е, че този масив не може да се променя след като му се въведат стойностите от конструктора. + +Реализирайте негов наследник `[PrintableArray]`, който имплементира оператори << и >>. +Реализирайте наследник `[SaveableArray]` на `[Array]`, който имплементира методи write и read, приемащи име на файл и булева стойност дали е двоичен или не, и съответно прочитат или запазват елементите от този масив във файла. + +Реализирайте трети наследник, `[ModifiableArray]`, на `[Array]`, в който са имплементирани член-функции: + +.unordered +- `[push]`, която приема елемент и го вмъква в (десния) края на масива +- `[pop]`, който премахва елемент от (десния) края на масива +- `[last]`, който връща последния елемент от масива + +Може да се налага масива да се оразмерява. +Като подсказка, имплементирайте си метод, наличен за класа и наследници, който вмъква елемент на произволен индекс. + +Реализирайте наследник `[IndexableArray]` на `[ModifiableArray]`, който имплементира оператор[]. +Ако индекса е след края, тогава "вмъквате" елементи по подразбиране между края и подадения индекс, и връщате елемента от сега новия край. +Реализирайте наследник `[FrontableArray]` на `[ModifiableArray]`, който имплементира методи `[pushf]` и `[popf]`, които работят като `[push]` и `[pop]`, но с елемента в началото на масива (първия елемент). diff --git a/src/teaching/oop-2023/week10/index.md b/src/teaching/oop-2023/week10/index.md deleted file mode 100644 index 06d9a7b..0000000 --- a/src/teaching/oop-2023/week10/index.md +++ /dev/null @@ -1,146 +0,0 @@ -# Задачи - ООП, Седмица 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`, който имплементира оператор[] (връщащ референция към буквата на дадения индекс) и оператор+=. - -Реализирайте наследник на `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.du b/src/teaching/oop-2023/week11/index.du new file mode 100644 index 0000000..5fd580b --- /dev/null +++ b/src/teaching/oop-2023/week11/index.du @@ -0,0 +1,210 @@ +# Задачи - ООП, Седмица 11, 09.05.2024 + +\n + +GitHub classroom: [url https://classroom.github.com/a/oYQehcnN classroom.github.com/a/oYQehcnN] + +## Преговорни + +.warn Моля, не отделяйте на преговорните задачи повече от 30мин + +.important Всеки бащин клас, във всички случаи, трябва да има виртуален деструктор (`[virtual ~ClassName();]`). + +### Задача 1 - Шаблони и оператори + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week11/Exercise01 Решение] + +Реализирайте шаблонен клас множество, който запазва фиксиран брой елементи от подаден тип. +Реализирайте голяма петица и оператори: +.bulleted +- `[+]`, `[+=]` които действат като обединение +- `[*]`, `[*=]` които действат като сечение +- `[-]`, `[-=]` които действат като допълнение + +### Задача 2 - Наследяване + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week11/Exercise02 Решение] + +Реализирайте клас `[Employee]`, съхраняващ име на човек, позиция и департамент като низове със съответно дължина 512, 128 и 64, заедно със заплата като число с плаваща запетая. + +Реализирайте негов наследник `[Manager]`, който допълнително пази масив с фиксиран размер от Employee. + +Реализирайте наследника на `[Employee]`, `[Developer]`, който допълнително пази брой проекти върху който работи. + +Наследниците не могат да достъпят заплатата, но трябва да могат да достъпят другите данни на `[Employee]`. + +## Лесни + +### Задача 3 + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week11/Exercise03 Решение] + +.comment Динамично свързване, Inherit 3 + +Реализирайте клас `[Electronics]`, който съдържа модел (низ с максимална дължина от 255 знака), `[needsVolts]` и `[needsAmps]` (стойности с плаваща запетая). + +Имплементирайте негови наследници: +.bulleted +- `[Laptop]`, който допълнително съхранява размер на екрана като число с плаваща запетая +- `[WashingMachine]`, който допълнително запазва максимално тегло на прането, като цяло неотрицателно число +- `[Camera]`, която допълнително запазва резолюция като число с плаваща запетая (в мегапиксели) + +За всеки клас реализирайте член-функция `[Print]`, която изкарва всички данни на екрана. + +&:question Чрез статично или динамично свързване сте имплементирали `[Print]`? Каква е разликата? + +### Задача 4 + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week11/Exercise04 Решение] + +.comment Dynamic linking, Inherit 2 + +Реализирайте клас `[String]`, който запазва динамично-заделен масив. + +Имплементирайте негов наследник `[Name]`, който допълнително запазва число: номер на името (първо име, бащино име (второ име), фамилия (трето име)). + +Имплементирайте втори наследник на `[String]`, `[Street]`, който запазва и число: номер на улицата. + +Във всеки клас имплементирайте голяма петица, член-функция `[Length]`, като: +.bulleted +- в `[String]` връща дължината на низа, +- в `[Name]` връща дължината на името умножена по номера си и +- в `[Street]` връща дължината на името на улицата плюс броя цифри в номера на улицата. + +Самият низ в `[String]` =[не]= може да се достъпва от наследниците. + +### Задача 5 + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week11/Exercise05 Решение] + +.comment Templates 1 type + +Реализирайте шаблонен клас `[Counted]`, който запазва елемент от подаден тип и неговата бройка (цяло неотрицателно число). +Имплементирайте оператори `[++]`, `[--]`, `[+=]`, `[-=]`, които променят бройката, както и гетъри за елемента и бройката. + +### Задача 6 + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week11/Exercise06 Решение] + +.comment Templates 2 types + +Реализирайте шаблонен клас `[TwoArray]`, който запазва два динамично-заделени масива с подадени типове. +Масивите не могат да се оразмеряват и имат еднаква дължина. + +Имплементирайте: +.bulleted +- голяма петица, +- оператор `[[]]`, който по подаден индекс връща елемент от първия масив, и +- оператор `[()]`, който по подаден индекс връща елемент от втория масив. + +### Задача 7 + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week11/Exercise07 Решение] + +.comment Abstract class + +Реализирайте абстрактен клас `[DynamicArray]`, който задължава наследниците да имплементират оператор `[[]]` и оператор `[+=]`. + +Реализирайте негови наследници: + +:unordered +- `[Numbers]`, който "имплементира" динамично-заделен масив от цели числа, като + + .bulleted + - оператор `[[]]` връща първия елемент, по-малък от подадения индекс. Ако няма такъв, връщате първия елемент. + - оператор `[+=]` вмъква елементите в началото на масива + +- `[String]`, който "имплементира" динамично-заделен масив от букви, като + + .bulleted + - оператор `[[]]` връща индекс на брой (първата, втората, ...) главна буква в низа. Ако няма такава, тогава връща последната буква. + - оператор `[+=]` вмъква елементите в края на масива + + +Имплементирайте голяма петица. + +.question Къде ще имплементирате динамичния масив и голямата петица? + +.question Можем ли да използваме оператор `[+=]` в полиморфна йерархия? + +### Задача 8 + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week11/Exercise08 Решение] + +.comment Abstract class + +Имплементирайте абстрактен клас `[Message]`, който съдържа динамично-заделен низ (текстово съобщение, което се показва на екрана) и задължава наследниците да имплементират: +.unordered +- метод `[size]`, който връща общия размер на всички данни в байтове. + +Реализирайте негов наследник `[Link]` (хипервръзка), който запазва и втори динамично-заделен низ, запазващ адресът към който линкът сочи. + +Реализирайте втори негов наследник `[Location]`, чието текстово съдържание е адрес, и който допълнително запазва две стойности с плаваща запетая: една за географска ширина и втора за географска дължина. + +За всички класове реализирайте член-функция `[Length]`, която връща размера на =[текстовото съобщение]= и оператор `[<<]`. + +.question Има ли разлика между оператор `[<<]` на трите класа? + +### Задача 9 + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week11/Exercise09 Решение] + +Реализирайте абстрактен шаблонен клас `[MixedArray]`, който съхранява алтерниращи елементи от два типа. +Тоест, на индекс 0 имаме елемент от първия тип, на индекс 1 от втория, на индекс 2 от първи и так. нат. + +Елементите не е нужно да могат да се конвертират помежду си (тоест не може да използвате полиморфен контейнер), затова се достъпват с член функция `[At]`, приемаща индекс и референции към указатели към всеки тип. +При подаден индекс, на единия указател се записва адресът на съответната стойност, а на другия `[nullptr]`. + +Също имплементира голяма петица и задължава наследниците да имплементират оператори `[+=]`, върщащи указател. + +Реализирайте негов наследник `[DirectConcat]`, който реализира `[+=]` като директно слепване (конкатениране). + +Реализирайте втори негов наследник, `[MixedConcat]`, който реализир `[+=]` като алтернира елемент от първия масив с елемент от втория. + +## Трудни + +### Задача 10 + +Реализирайте система за документ с форматиран текст. +В нея всеки елемент от документа е от тип Node, като за един Node трябва да имате: +.bulleted +- id, автоматично-избрано число, с което отличава Node +- operator<< +- operator[] + +Реализирайте следните типове Node: +.bulleted +- paragraph, това е най-обикновен низ +- anchor, това е хипервръзка (линк), която съхранява видимо съдържание и уеб адрес +- emplaced link, това е хипервръзка при която видимото съдържание съвпада с уеб адреса +- заглавие, което е като хипервръзка, но уеб адресът започва с '#' и останалото съвпада със текстовото съдържание, като всяка буква е малка и вместо шпации има тирета +- bulletpoint list, който съхранява редица Node-ове и ги изкарва на екрана, всяко на нов ред, започващи с '-' +- table, която съхранява таблица с Node-ове + +Имплементирайте клас Document, който запазва масив от Node-ове и за който са имплементирани: +.bulleted +- методи save и load, които запазват и четат цялото съдържание на документа в =[текстов]= файл с произволен формат. + +### Задача 11 + +Ще реализирате система за изпълнение на крайни автомати (от Теоретични Компютърни науки, ЕАИ). + +За тази цел е нужен абстрактен шаблонен клас State, чиито тип определя азбуката, който съхранява динамично-заделен масив от преходи (Transition) и задължава protected имплементация на член-функцията equal, която приема два елемента от азбуката и връща дали са равни. +Имплементирайте голяма петица и оператор +=, който вмъква нов преход в състоянието. + +Реализирайте абстрактен шаблонен клас Transition, чиито тип определя азбуката, и който съхранява елемент от този тип (стойността, която ако е равна на подадената ще изпълним прехода) и указател към следващо състояние. +Класът задължава имплементацията на оператор [], който по подаден елемент от азбуката или връща указателя към следващото състояние, или връща nullptr. + +Реализирайте наследник на State, ArrayState, който (допускате че) приема указател на динамичо-заделен масив. + +Реализирайте наследник на Transition, PrintedTransition, който при всяко извикване на оператор [] също изкарва съобщение на екрана. + +Реализирайте клас FiniteStateMachine, който съхранява динамичен масив от състояния. +За него имплементирайте голяма петица и конструктор, приемащ име на текстов файл в CSV формат, в който са запазени: +.bulleted +- на първия ред обща информация във формата "Transitions,StartStateName", след това +- състояния и преходи във формата "StateName,OnValue,TransitionTo", после +- финални състояния във формата "FinalStateName1,FinalStateName2,...", и накрая +- входни букви от азбуката "Letter1,Letter2,...". + +Имплементирайте метод Run, който изпълнява автомата и връща булева стойност: дали приема входните букви или не. diff --git a/src/teaching/oop-2023/week11/index.md b/src/teaching/oop-2023/week11/index.md deleted file mode 100644 index 8ac676b..0000000 --- a/src/teaching/oop-2023/week11/index.md +++ /dev/null @@ -1,201 +0,0 @@ -# Задачи - ООП, Седмица 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) - - - -Реализирайте клас `Electronics`, който съдържа модел (низ с максимална дължина от 255 знака), `needsVolts` и `needsAmps` (стойности с плаваща запетая). - -Имплементирайте негови наследници: - -- `Laptop`, който допълнително съхранява размер на екрана като число с плаваща запетая -- `WashingMachine`, който допълнително запазва максимално тегло на прането, като цяло неотрицателно число -- `Camera`, която допълнително запазва резолюция като число с плаваща запетая (в мегапиксели) - -За всеки клас реализирайте член-функция `Print`, която изкарва всички данни на екрана. - -&:question Чрез статично или динамично свързване сте имплементирали `Print`? Каква е разликата? - -### Задача 4 - -&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week11/Exercise04) - - - -Реализирайте клас `String`, който запазва динамично-заделен масив. - -Имплементирайте негов наследник `Name`, който допълнително запазва число: номер на името (първо име, бащино име (второ име), фамилия (трето име)). - -Имплементирайте втори наследник на `String`, `Street`, който запазва и число: номер на улицата. - -Във всеки клас имплементирайте голяма петица, член-функция `Length`, като: - -- в `String` връща дължината на низа, -- в `Name` връща дължината на името умножена по номера си и -- в `Street` връща дължината на името на улицата плюс броя цифри в номера на улицата. - -Самият низ в `String` **не** може да се достъпва от наследниците. - -### Задача 5 - -&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week11/Exercise05) - - - -Реализирайте шаблонен клас `Counted`, който запазва елемент от подаден тип и неговата бройка (цяло неотрицателно число). -Имплементирайте оператори `++`, `--`, `+=`, `-=`, които променят бройката, както и гетъри за елемента и бройката. - -### Задача 6 - -&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week11/Exercise06) - - - -Реализирайте шаблонен клас `TwoArray`, който запазва два динамично-заделени масива с подадени типове. -Масивите не могат да се оразмеряват и имат еднаква дължина. - -Имплементирайте: - -- голяма петица, -- оператор `[]`, който по подаден индекс връща елемент от първия масив, и -- оператор `()`, който по подаден индекс връща елемент от втория масив. - -### Задача 7 - -&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week11/Exercise07) - - - -Реализирайте абстрактен клас `DynamicArray`, който задължава наследниците да имплементират оператор `[]` и оператор `+=`. - -Реализирайте негови наследници: - -- `Numbers`, който "имплементира" динамично-заделен масив от цели числа, като - + оператор `[]` връща първия елемент, по-малък от подадения индекс. Ако няма такъв, връщате първия елемент. - + оператор `+=` вмъква елементите в началото на масива -- `String`, който "имплементира" динамично-заделен масив от букви, като - + оператор `[]` връща индекс на брой (първата, втората, ...) главна буква в низа. Ако няма такава, тогава връща последната буква. - + оператор `+=` вмъква елементите в края на масива - -Имплементирайте голяма петица. - -&:question Къде ще имплементирате динамичния масив и голямата петица? - -&:question Можем ли да използваме оператор `+=` в полиморфна йерархия? - -### Задача 8 - -&::solution-link [Решение](https://github.com/Syndamia/oop-2023-solutions/blob/main/week11/Exercise08) - - - -Имплементирайте абстрактен клас `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.du b/src/teaching/oop-2023/week12/index.du new file mode 100644 index 0000000..b0384e5 --- /dev/null +++ b/src/teaching/oop-2023/week12/index.du @@ -0,0 +1,97 @@ +# Задачи - ООП, Седмица 12, 09.05.2024 + +\n + +GitHub classroom: [url https://classroom.github.com/a/o7hNz1pr classroom.github.com/a/o7hNz1pr] + +### Задача 1 + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week12/Exercise1 Решение] + +.comment Multiple inheritance + +Реализирайте клас `[Publication]`, който пази: + +.bulleted +- низ от максимална дължина 1023, съхраняващ автори и +- втори низ с максимална дължина от 255, съхраняващ име на (научно) списание. + +Реализирайте клас `[TextDocument]`, който пази неоразмеряем низ с текстово съдържание и неговия размер. + +Реализирайте наследник на двата класа `[ScientificPaper]`, който допълнително пази и низ от максимално 511 знака, съдържащ име на научна дисциплина. +За всички класове реазлизирайте оператор <<. + +### Задача 2 + +*[Не говорим за нея, условието беше толкова сбъркано, че се наложи да я сваля]* + +### Задача 3 + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week12/Exercise3 Решение] + +Реализирайте абстрактен клас `[MobileDevice]`, който запазва: +.bulleted +- телефонен номер като цяло неотрицателно число и +- масив с максимална дължина от 511 знака за текстово съобщение. + +Допълнително нека: +.bulleted +- класът да задължава имплементацията на метод `[Show]`, +- да има член-функция `[CanAccept]`, която по подадено "хиперсъобщение" връща дали неговия номер съвпада с този на класа.\n + Под "хиперсъобщение" имаме предвид низ, който започва с телефонния номер, след това има шпация и след това е самото съобщение. +- да има член-функция `[Accept]`, която по подадено "хиперсъобщение" запазва текстовото съобщение. + Ако номерът не съответства тогава хвърля грешка. + +Реализирайте негов наследник `[Telephone]`, за който `[Show]` изкарва съобщението на екрана. + +'footnote pager От времето без мобилни телефони, хората са си купували пейджъри, които ти пращат нотификация ако някой ти звънне и не вдигнеш. Пейджърите са "заключени" за определени региони, тоест някой ти се обажда, не вдигаш, и всички телекомуникционни кули в региона изпращат съобщение "на теб ти звънна този", и пейджъра като засече сигнала ти писука. Мисля че също можеш да пращаш кратки съобщения. Не е било хич сигурна система, все още се ползва от болници в някои държави. + +Реализирайте втори негов наследник `[Pager]` [$pager], който съхранява име на файл (като динамично-заделен низ) и `[Show]` изкарва съобщението в съответния файл. +Разбира се, имплементирайте голяма петица. + +Реализирайте клас `[TelecommunicationCompany]`, който съхранява динамично-заделен и оразмеряем масив от (указатели към) `[MobileDevice]`. +Имплементирайте всичко от голяма петица. + +### Задача 4 + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week12/Exercise4 Решение] + +.comment Multiple inheritance with mixed class types, polymorphic container, and copying + +Реализирайте клас `[Employee]`, който запазва: +.bulleted +- заплата като число с плаваща запетая и +- производителост също като число с плаваща запетая. + +Производителността е множител на заплатата, тоест ако има производителност 0.5 значи работи като човек на който му плащат с половината заплата. + +Реализирайте абстрактен клас `[Person]`, който запазва: +.bulleted +- име като низ с произволна дължина и +- възраст като цяло неотрицателно число + +Допълнително задължава реализацията на член-функция `[Workload]`, връщаща стойност с плаваща запетая. +Разбира се имплементирайте голяма петица. + +Реализирайте наследник на двата класа на име `[Developer]`, който допълнително запазва: +.bulleted +- цяло неотрицателно число - брой проекти в които участва, и +- второ което е брой проекти на които ще се пуска нова версия. + +Реализирайте оператори `[++]` и `[--]`, като префиксните променят броя проекти на които ще се пуска нова версия, докато постфиксните променя броя проекти в които участва.\n +За него `[Workload]` се определя като 1.1 по всеки проект и допълнително по 2.3 за всеки проект на който ще се пуска нова версия. + +Реализирайте наследник на двата класа на име `[Manager]`, който допълнително запазва динамично-заделен и оразмеряем масив от `[Person]`, които менижира. + +Имплементирайте голяма петица и: +.bulleted +- оператори `[==]` и `[!=]`, сравняващи хора по име +- член-функция `[StartManaging]`, която приема `[Person]` и го запазва, и +- член-функция `[StopManaging]`, която приема `[Person]` и го премахва от масива ако съществува в него. + +`[Workload]` се определя като 0.6 на човек който менижира. + +Финално реализирайте клас `[Company]`, който запазва масив от 128 указателя `[Person]` в компанията. +Имплементирайте негова член-функция: +.bulleted +- `[PaymentDifference]`, която връща с колко платената заплата на всички служители се отличава с тази според тяхната производителност diff --git a/src/teaching/oop-2023/week12/index.md b/src/teaching/oop-2023/week12/index.md deleted file mode 100644 index b492678..0000000 --- a/src/teaching/oop-2023/week12/index.md +++ /dev/null @@ -1,94 +0,0 @@ -# Задачи - ООП, Седмица 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) - - - -Реализирайте клас `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) - - - -Реализирайте клас `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.du b/src/teaching/oop-2023/week13/index.du new file mode 100644 index 0000000..936f34b --- /dev/null +++ b/src/teaching/oop-2023/week13/index.du @@ -0,0 +1,141 @@ +# Задачи - ООП, Седмица 13, 16.05.2024 + +\n + +GitHub classroom: [url https://classroom.github.com/a/GvV1wrC1 classroom.github.com/a/GvV1wrC1] + +.warn Навсякъде, където е нужно, реализирайте голяма петица. + +## Преговорни + +### Задача 1 - Множествено наследяване + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week13/Exercise1 Решение] + +Реализирайте клас `[String]`, който запазва динамичен низ с фиксиран размер. + +Реализирайте клас `[IndexArray]`, който запазва динамичен масив с фиксиран размер от цели числа - индекси. + +.warn =[Не]= правете общ родител, който имплементира динамичен масив! + +Реализирайте наследник на двата класа, `[WordsString]`, при който индексите определят началото на всяка дума от запазения низ. +Индексите се дефинират при конструктора. + +## Лесни + +### Задача 2 + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week13/Exercise2 Решение] + +.comment Диамант + +Реализирайте шаблонен клас `[Container]`, който съхранява масив с фиксиран размер от елементи с подаден тип. +=[Не]= трябва да реализирате нищо повече от задължителните компоненти (голяма петица). + +Реализирайте негов наследник `[Indexable]`, който реализира оператор[]. + +Реализирайте втори негов наследник `[Resizeable]`, който реализира член-функция `[InsertAt]`, приемаща елемент и индекс, и която вмъква елемента на даден индекс. +Разбира се, може да се наложи оразмеряване на масива. + +Реализирайте наследник `[Vector]` на `[Indexable]` и `[Resizeable]`, който реализира оператор[] и член-функции: +.bulleted +- `[pop_back]`, премахваща последния елемент +- `[pop_front]`, премахваща първия елемент +- `[push_back]`, приемаща елемент който се вкарва в края на масив +- `[push_front]`, приемаща елемент който се вкарва в началото на масив + +.important Не забравяйте за диамантния проблем! + +### Задача 3 + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week13/Exercise3 Решение] + +.comment Диамант + +Реализирайте клас `[User]`, който запазва потребителско име и парола като низове с произволна дължина, заедно с булев флаг `[banned]`, определящ дали акаунтът може да прави действия. +Потребителско име не може да съдържа шпации. + +Реализирайте клас `[Thread]`, който запазва масив с произволна дължина, от низове с произволна дължина. +Имплементирайте член-функция: + +.bulleted +- `[PostMessage]`, която приема потребител и негово съобщение и добавя съобщението с потребителското име като един низ. + Ако потребителя е `[banned]`, тогава хвърлете грешка. + +Реализирайте наследник `[ThreadModerator]` на `[User]`, който може да променя `[Thread]` обекти, без да се нуждае от публични член-функции в `[Thread]`. +Имплементирайте методи: +.bulleted +- `[RemoveMessage]`, който приема `[Thread]` и индекс на съобщение и премахва съответното съобщение +- `[RemoveByUser]`, който приема `[Thread]` и потребител, и премахва всички съобщения, направени от дадения потребител + +Реализирайте наследник `[UserModerator]` на `[User]`, който може да променя `[User]` обекти, без да се нуждае от публични член-функции в `[User]`. +Имплементирайте методите: +.bulleted +- `[BanUser]`, който приема потребител и вдига `[banned]` флага +- `[UnbanUser]`, който приема потребител и сваля `[banned]` флага + +Реализирайте наследник `[Administrator]` на `[ThreadModerator]` и `[UserModerator]`, който може да прави всичко, което и родителите могат. + +.important Не забравяйте за диамантния проблем! + +## Трудни + +### Задача 4 + +Реализирайте абстрактен клас `[ShopLocation]`, който съхранява член-данни: +.bulleted +- адрес като низ с максимална дължина от 511 знака. + Всеки адрес съдържа произволни символи и задължително завършва на число, определящо неговия район. +- време на отваряне и време на затваряне + +Имплементирате методи: +.bulleted +- `[IsOpen]`, който връща по подаден час дали локацията е отворена +- `[InCenter]`, който връща дали локацията се намира в центъра на града. + Всички адреси с регион, по-малък от 11, се намират в центъра. + +Реализирайте шаблонен клас `[Inventory]`, който съхранява =[фиксиран]= брой елементи и техните неотрицателни бройки (количества). +Имплементирайте член-функции: +.bulleted +- оператор[], който връща елемент на дадения индекс +- оператор(), който връща бройка на елемент на дадения индекс +- `[Stock]`, приемащ индекс на елемент и бройка (положителна/отрицателна) с която бройката на дадения елемент се променя. + Бройката може да бъде най-малко 0. +- `[List]`, който връща всички елементи и техните индекси + +Реализирайте абстрактен шаблонен наследник `[DeliverableInventory]` на `[Inventory]`, който е инвентар с максимум 2048 елемента и допълнително задължава имплементацията на: +.bulleted +- `[ShippingDelay]`, който приема адрес и връща времето в което ще може да се достави обекта + +Реализирайте наследник на `[DeliverableInventory]`, склад `[Warehouse]`, който допълнително запазва разстояние от града в километри и имплементира `[ShippingDelay]` по следната логика: +.bulleted +- доставки в центъра отнемат един ден + регионът в който се доставя +- доставки извън центъра отнемат толкова време, колкото е нужно да се стигне до града ако пътува с 80 километра в час + времето което ще отнеме да се измине номер на региона на брой километри при скорост от 20 километра в час + +Доставка не може да се случи преди 9 сутринта и след 18 вечерта. +Ако попадне в този диапазон, тогава се отлага за най-скорошния следващ възможен час. + +Реализирайте шаблонен наследник магазин `[Shop]` на `[ShopLocation]` и `[Inventory]`, който е инвентар с максимум 256 елемента, запазващ: +.bulleted +- =[оразмеряем]= масив от низове с произволен размер, всеки низ който е "отчет на продажба" +- общо бройка продажби + +и който имплементира методи: +.bulleted +- `[SellItems]`, който приема масив от идентификатори на обекти, намалява бройката на всеки от тях и създава нов отчет. + Отчета е в произволен формат, но трябва да съдържа идентификаторите и бройките на всеки обект. + Ако за някой обект няма достатъчно бройки или изобщо не се пази, хвърлете грешка. + +Реализирайте шаблонен клас `[WebStore]`, който запазва оразмеряеми масиви от `[Shop]` и `[Warehouse]`. +Имплементирайте: +.bulleted +- оператор<<, който изкарва всички уникални (unique) обекти от всички магазини и складове, с индекс до тях +- `[GetEstimate]`, който приема индекс на уникален обект от всички магазини и складове, сегашно време и адрес, и изкарва на екрана всички магазини които са отворени в дадения час и кое е най-скорошното време в което може обектът да се достави от склад. + Ако няма отворени магазини, ако няма магазин с наличност и так. нат. изкарайте съответно съобщение. + +Последно реализирайте клас `[Book]`, който запазва заглавие на книга и име на автор като низове с максимална дължина от 127 знака. +Имплементирайте оператор<<, който изкарва съответната книга в произволен формат. + +В главната функция реализирайте `[WebStore]` от книги, заедно с набор от книги, магазини и складове по ваш избор. +Нека в началото на програмата да приемате от потребителя сегашното време и адрес, след това изкарайте на екрана всички ункални книги с индекси. +Накрая потребителя може да въведе индекс на книга и да получи информация кои отворени сега магазини имат съответната книга и кога най-скоро може да бъде доставена от склад. diff --git a/src/teaching/oop-2023/week13/index.md b/src/teaching/oop-2023/week13/index.md deleted file mode 100644 index 5d2ad35..0000000 --- a/src/teaching/oop-2023/week13/index.md +++ /dev/null @@ -1,138 +0,0 @@ -# Задачи - ООП, Седмица 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.du b/src/teaching/oop-2023/week14/index.du new file mode 100644 index 0000000..761edd5 --- /dev/null +++ b/src/teaching/oop-2023/week14/index.du @@ -0,0 +1,73 @@ +# Задачи - ООП, Седмица 14, 23.05.2024 + +\n + +GitHub classroom: [url https://classroom.github.com/a/K0XomKEP classroom.github.com/a/K0XomKEP] + +## Задача + +В тази задача се оставя голямо количество свобода на имплементация, за всяко нещо сами преценете типове, помощни класове/член функции, оператори и так. нат. +Както винаги, реализирайте голяма петица където е нужно. + +Препоръчително е първо да изчетете цялото условие и след това да пишете код. + +Реализирайте система като СУСИ. +Преди да стигнем до потребителите, ще се нуждаем от някои други компоненти. + +Реализирайте предмет, като в един предмет се пазят: +.bulleted +- име +- тип (задължителен/избираем) +- брой ECTS кредити, които носи +- код, комбинация от главна буква и 3-цифрено число + +Реализирайте семестър, като в един семестър се пазят: +.bulleted +- учебната година +- тип (зимен/летен) +- учебния план (низ във формата "СПЕЦИАЛННОСТ(УЧЕБЕН КУРС)") +- предмети; разбира се един предмет може да се споделя от няколко семестъра + +Реализирайте специалност, която пази: +.bulleted +- свое име +- катедра към която е свързана +- всички семестри, в които е (била) активна +- предмети, съответстващи на всеки тип семестър + +и имплементира метод: +.bulleted +- `[NewSemester]`, който приема учебна година и тип, и връща нов обект от семестър с попълнени данни + +Имаме потребители, като всеки си има роля, определяща неговите способности в системата. +Ролята може да бъде студент, преподавател или администратор, като при конкретизиране в условието на някои от тях трябва да се извършат съответните проверки. +Ваш избор е какво да бъде ролята. + +За един потребител със сигурност се пазят: +.bulleted +- име +- факултетен номер (от модерния стил) +- потребителско име, което се определя като първата буква от първото име, конкатенирана с фамилията. + Ако съществува потребител с такова потребителско име, тогава добавяте букви от бащиното име, и накрая в краен случай, от първото име. +- парола +- година на учебния план +- име на сегашна специалност + +.bulleted +- данни за контакт, като една данна съдържа тип и описание (произволни низове) + +.bulleted +- семестри, в които е (бил) включен +- изпити, които са комбинация от предмети, преподаватели и оценки (която е възможно да не е въведена) + +Реализирайте мениджър на факултета, който съхранява, създава, обновява и премахва всички потребители и специалности. +Имплементирайте съответни член-функции, които да правят тези действия. + +Имплементирйате и методи, приемащи потребителско име, които: +.bulleted +- за един потребител изкарва всички негови лични данни, заедно с кратко описание на семестрите в които е включен +- за един студент изкарва всички изпити, заедно със семестрите към които са свързани и сума на всички успешно получени кредити за дадения семестър (кредитите се броят само когато има оценка, която не е двойка) +- един преподавател може да създаде нов предмет +- един администратор може да създаде нов потребител, специалност, семестър, както и да свързва предмети със семестри и специалности + +Реализирайте конзолен интерфейс. diff --git a/src/teaching/oop-2023/week14/index.md b/src/teaching/oop-2023/week14/index.md deleted file mode 100644 index 917c11b..0000000 --- a/src/teaching/oop-2023/week14/index.md +++ /dev/null @@ -1,73 +0,0 @@ -# Задачи - ООП, Седмица 14, 23.05.2024 - -GitHub classroom: [classroom.github.com/a/K0XomKEP](https://classroom.github.com/a/K0XomKEP) - -## Задача - -В тази задача се оставя голямо количество свобода на имплементация, за всяко нещо сами преценете типове, помощни класове/член функции, оператори и так. нат. -Както винаги, реализирайте голяма петица където е нужно. - -Препоръчително е първо да изчетете цялото условие и след това да пишете код. - -Реализирайте система като СУСИ. -Преди да стигнем до потребителите, ще се нуждаем от някои други компоненти. - -Реализирайте предмет, като в един предмет се пазят: - -- име -- тип (задължителен/избираем) -- брой ECTS кредити, които носи -- код, комбинация от главна буква и 3-цифрено число - -Реализирайте семестър, като в един семестър се пазят: - -- учебната година -- тип (зимен/летен) -- учебния план (низ във формата "СПЕЦИАЛННОСТ(УЧЕБЕН КУРС)") -- предмети; разбира се един предмет може да се споделя от няколко семестъра - -Реализирайте специалност, която пази: - -- свое име -- катедра към която е свързана -- всички семестри, в които е (била) активна -- предмети, съответстващи на всеки тип семестър - -и имплементира метод: - -- `NewSemester`, който приема учебна година и тип, и връща нов обект от семестър с попълнени данни - -Имаме потребители, като всеки си има роля, определяща неговите способности в системата. -Ролята може да бъде студент, преподавател или администратор, като при конкретизиране в условието на някои от тях трябва да се извършат съответните проверки. -Ваш избор е какво да бъде ролята. - -За един потребител със сигурност се пазят: - -- име -- факултетен номер (от модерния стил) -- потребителско име, което се определя като първата буква от първото име, конкатенирана с фамилията. - Ако съществува потребител с такова потребителско име, тогава добавяте букви от бащиното име, и накрая в краен случай, от първото име. -- парола -- година на учебния план -- име на сегашна специалност - -
- -- данни за контакт, като една данна съдържа тип и описание (произволни низове) - -
- -- семестри, в които е (бил) включен -- изпити, които са комбинация от предмети, преподаватели и оценки (която е възможно да не е въведена) - -Реализирайте мениджър на факултета, който съхранява, създава, обновява и премахва всички потребители и специалности. -Имплементирайте съответни член-функции, които да правят тези действия. - -Имплементирйате и методи, приемащи потребителско име, които: - -- за един потребител изкарва всички негови лични данни, заедно с кратко описание на семестрите в които е включен -- за един студент изкарва всички изпити, заедно със семестрите към които са свързани и сума на всички успешно получени кредити за дадения семестър (кредитите се броят само когато има оценка, която не е двойка) -- един преподавател може да създаде нов предмет -- един администратор може да създаде нов потребител, специалност, семестър, както и да свързва предмети със семестри и специалности - -Реализирайте конзолен интерфейс. diff --git a/src/teaching/oop-2023/week15/index.du b/src/teaching/oop-2023/week15/index.du new file mode 100644 index 0000000..7bf678f --- /dev/null +++ b/src/teaching/oop-2023/week15/index.du @@ -0,0 +1,39 @@ +# Задачи - ООП, Седмица 15, 30.05.2024 + +\n + +GitHub classroom: [url https://classroom.github.com/a/z2QadyEE classroom.github.com/a/z2QadyEE] + +## Задача + +В тази задача се оставя голямо количество свобода на имплементация, за всяко нещо сами преценете типове, помощни класове/член функции, оператори и так. нат. +Както винаги, реализирайте голяма петица където е нужно. + +Препоръчително е първо да изчетете цялото условие и след това да пишете код. + +Реализирайте система за чат. +В нея имаме съобщения, като едно съобщение може да бъде: +.bulleted +- текст, като низ +- локация, като съвкупност от държава, град, област (число), улица и номер на улица +- линк (хипервръзка) като текст и (уеб) адрес +- време: дата и час + +Всеки тип трябва да имплементира `[Print]` член-функция, която изкарва текстово съдържание на съобщението. +За текстово съобщение това е самия текст, за локация това е низ във формата "[ДЪРЖАВА] ГРАД(ОБЛАСТ) УЛИЦА NoНОМЕР НА УЛИЦА", за линк е самия текст и за време е "ЧАС:МИНУТИ ДЕН.МЕСЕЦ.ГОДИНА". + +Реализирайте потребители, като за всеки потребител имаме потребителско име и парола. + +Реализирайте чатруум, който съхранява записани потребители в групата, съобщения и съответните потребителски имена на авторите. +Един потребител може да се добави в чатруум, да създава нови съобщения и може да излезе, като един излязъл потребител може да вижда историята на чата до момента в който е излязъл. +Ако обратно бъде вкаран, тогава пак може да вижда всички съобщения от историята и да създава нови. + +Всеки потребител може да създаде чатруум и да запише хора в него (по потребителски имена), и може да излезе. +Допълнително собственика на чатруум може да изтрие самия чатруум и да премахва хора. +Ако собственикът се отпише тогава новият собственик е следващия по ред записан потребител. + +Реализирайте "платформа" в която се съхраняват всички чатове и потребители, от която също се създават потребители. + +Имплементирайте конзолен интерфейс, от който може да създадете потребител, да влезете в акаунта на потребител, след като сте влезли да разглеждате всички налични чатове. +Ако сте член на даден чат да създавате ново съобщение и да излезете. +Ако сте собственик да изтриете чат и да премахвате потребители от чата. diff --git a/src/teaching/oop-2023/week15/index.md b/src/teaching/oop-2023/week15/index.md deleted file mode 100644 index 6719bf0..0000000 --- a/src/teaching/oop-2023/week15/index.md +++ /dev/null @@ -1,37 +0,0 @@ -# Задачи - ООП, Седмица 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.du b/src/teaching/oop-2023/week16/index.du new file mode 100644 index 0000000..da0c1d6 --- /dev/null +++ b/src/teaching/oop-2023/week16/index.du @@ -0,0 +1,31 @@ +# Задачи - ООП, Седмица 16, 06.06.2024 + +\n + +GitHub classroom: [url https://classroom.github.com/a/BWjw2dUC classroom.github.com/a/BWjw2dUC] + +## Задача + +Първо си разпишете структурата, след това пишете код. +НЕ е нужно да реализирайте пълно решение, това е по-блико до архитектурното контролно, не е нужно да конкретизирате всички член-функции. + +В добре реализираните операционни системи, комуникация със свързани устройства се свежда до работа с файлове: ако искаш да кажеш устройството да прави нещо, ти пишеш във файла, ако устройството иска да ти каже на тебе нещо, четеш от файла. +Разбира се, отдолу няма истински файлове които се запазват в харддиск (примерно), просто ОС превежда всички тези операции върху файлове със съответни действия към устройството. + +Реализирайте подобна система. +Първо трябва ни обща схема за файлове, за всеки файл имаме `[Read]` и `[Write]` методи, и пазим името на файла. + +За всяко устройство само по себе си знаем, че трябва да използваме определен драйвър (по име) и че то има малко информация за себе си: марка като низ и модел като цяло число. +По-конкретно разглежаме два основни типа устройства: индексируемо и поточно (streamable). + +Първия тип са устройства като харддиск, където можем да си изберем индекс в който да запазваме или четем данни. +Втория тип са устройства като клавиатура или тонколони, можем или да прочетем или пишем по един байт, и този байт "изчезва" (клавиатурата изпраща байт като е натиснат бутон, тонколоните изкарват звук според байт, но никъде тази информация не се запазва дълготрайно). +Имплементирйате съответните оператори. + +Допълнително имаме поточно-индексируеми устройства, това са примерно фенси дигитални камери, които позволяват да се свържат като нормални уеб камери (тоест серийни устройства, изпращат данни за сегашния кадър) и могат да пазят снимки (тоест индексируеми устройства). + +Последно, с популярността на интернетът е добавен мрежов интерфейс, за който трябва да реализираме член-функции за изпращане и приемане на пакет с данни. +Един пакет съдържа начален и краен адрес като цели неотрицателни числа, име на протокола (низ с 4 знака) и данни (масив от байтове). + +Имаме и конкретен тип поточно устройство: мрежов адаптер. +Разбира се, той е и мрежов интерфейс, като идеята е, че по файловия интерфейс се предават статистични и информативни данни, но не и пакети. diff --git a/src/teaching/oop-2023/week16/index.md b/src/teaching/oop-2023/week16/index.md deleted file mode 100644 index f95271d..0000000 --- a/src/teaching/oop-2023/week16/index.md +++ /dev/null @@ -1,30 +0,0 @@ -# Задачи - ООП, Седмица 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.du b/src/teaching/oop-2023/week2/index.du new file mode 100644 index 0000000..6302ac0 --- /dev/null +++ b/src/teaching/oop-2023/week2/index.du @@ -0,0 +1,196 @@ +# Задачи - ООП, Седмица 2, 29.02.2024 + +\n + +GitHub classroom: [url https://classroom.github.com/a/3qPsfyyI classroom.github.com/a/3qPsfyyI] + +## Задача 0 - Преговорна + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week02/Exercise0.cpp Решения] + +Ще работим върху N-мерен [url https://en.wikipedia.org/wiki/Tic-tac-toe морски шах], тоест ще имаме дъска за морски шах, която може да е по-голяма от 3 на 3 (примерно 5 на 5, 7 на 7 и т.н.). +Няма да се занимаваме с проверки дали (и кой) е спечелил след даден ход, интересуваме се само от запазването на данни. + +Основната логика е следната, като във всяка подточка правила по имплементацията са зададени. + +.warn Не почвайте веднага да имплементирайте, погледнете подточките! + +В началото от входа се въвеждат два реда, всеки съответстващ на имената на даден играч (в тези имена може да има шпации). +Първият играч винаги играе като X, вторият винаги като O. + +След това се въвежда цяло число N, това е размерът на дъската. +Накрая се въвеждат NxN на брой X-ове и O-та. + +За всеки играч трябва съответно да изкарате общия брой X-ове или броя O-та в цялата дъска, както и дължината на най-дългата последователност от Х-ове или О-та в един реда на дъската (примерно за първия играч, търсим реда с най-много последователни X-ове, и изкарваме тяхната бройка). + +=[Пример:]= + +.table +|=Вход=||=Изход=| +|:Emil Petkov\nBoburaBG\n5\nX X O O O\nO X O X X\nO X X X O\nO X X X X\nO X O O O\n:||:Emil Petkov: Total - 13, Longest - 4\nBoburaBG: Total - 12, Longest - 3:| + +### а) без структури + +.solution-link [url 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 [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week02/Exercise0.cpp#L85-L166 Решение] + +"Слепете" в една съвкупност (структура) указателя към самата дъска за морски шах, както и нейния размер N. +Нека името на структурата да бъде `[GameBoard]`. + +Обновете `[boardCounts]`, така че вместо да приема дъската и размера ѝ чрез две променливи, да ги приема чрез една променлива от тип `[GameBoard]`. + +### в) структура за числата + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week02/Exercise0.cpp#L168-L255 Решение] + +"Слепете" в една съвкупност (структура) на име `[BoardCounts]` четирите променливи, които `[boardCounts]` връща. + +Обновете `[boardCounts]` да връща една стойност от тип `[BoardCounts]`, вместо да връща четирите бройки като отделни числа. +Обновете `[printResult]` да приема стойност от тип `[BoardCounts]`, вместо да приема четирите бройки като отделни числа. + +### г) структура за цялата игра + +.solution-link [url 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 [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week02/Exercise1.cpp Решение] + +Работите върху система за инвентар на книжарница. + +.warn Не е задължително, но е препоръчително да си направите и една структура `[String]` с конструктор и деструктор + +Създайте структура `[Book]` със скрити (private) данни за: +.bulleted +- заглавие, като един низ +- автори, като масив от низове +- година на публикация, като целочислено число +- цена, като число с плаваща запетая + +За всяка от тях създайте съответните публични селектор (get-ър) и мутатор (set-ър) член-функции (методи). +Set-ърите трябва да записват стойности в данните, само когато съответните проверки са изпълнени: +.bulleted +- заглавието не може да бъде празния низ +- трябва да има поне един автор, името на даден автор не може да бъде празния низ +- годината на публикация не може да надвишава 2024, не може да е по-малка от -2100 (2100 п.н.е.) и не може да бъде нула +- цената не може да е отрицателна + +Всеки от мутаторите трябва да връща булева стойност, `[true]` ако проверките са изпълнени (и запазването на данни е извършено) и `[false]` ако съответната проверка не е изпълнена (и няма промяна в данните). +Създайте съответните конструктори и деструктори. + +След това направете структура `[Library]`, която държи масив от книги и бройката за всяка книга (отново като скрити данни). +Най-лесния вариант е да имате втори масив, като за всеки индекс в масива с книги, на същия индекс в масива за бройки се намира съответната бройка. +Можете и да го направите чрез структура `[Pair]` и да имате един масив. + +Като публични методи на `[Library]` имплементирайте `[AddBook]`, която вмъква нова книга в масива, и `[RemoveBook]` която съответно "премахва" книга по заглавие и година. +Допълнително направете член-функция `[StockBook]`, която приема заглавие на книга, годината ѝ, и цяло число с което наличната бройка се увеличава. +Аналогично направете и `[SellBook]`. +За всики тези методи трябва да имате съответните проверки: +.bulleted +- ако напълно идентична книга вече съществува, `[AddBook]` не трябва да я добавя на ново +- `[RemoveBook]` не трябва да "гърми" ако книгата не съществува +- бройката на добавени/продадени книги, подадени на `[SellBook]` и `[StockBook]`, трябва да бъдат положителни, както и книгите да съществуват + +Аналогично като при `[Book]`, тези функции трябва да връщат булева стойност, дали проверките са изпълнени. +Не забравяйте за конструктор и деструктор! + +.question Можете ли да си улесните работата, ако използвате скрити член-функции? + +Не е нужно да правите потребителски вход/изход, но тествайте ръчно кода си в `[main]`. + +## Задача 2 + +.solution-link [url 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 [url 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 [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week02/Exercise4.cpp Решение] + +Имате фабрика, цялата ѝ структура се разглежда като един конвейер, тоест като една редица машини, всяка от които приема някакъв материал и връща този материал преобразуван. + +Един материал се определя с три целочислени стойности: идентификационен номер, начален тип (тоест като какво се подава) и краен тип (тоест в какво се очаква да се преобразува). + +Една машина се характеризира с ефикасност спрямо материали: представете си една таблица, от едната колона има идентификационни номера на материали, от друга има числа с плаваща запетая, определящи процент ефикасност. +Допълнително за нея знаем колко материал може да преобразува, преди да се нуждае от ремонт. + +Когато даден материал е подаден на машината, тя го преобразува в материал от дадения краен тип. +Типовете на материалите са отделни стойности от идентификационните номера, тоест като е подаден материал, той се превръща в крайния тип, и трябва да намерите на кой материал точва число е началния тип. + +Всички тези данни трябва да са скрити, трябва за съответните структури да присъстват конструктори и деструктори. +Допълнително при машините трябва да има член-функция `[convertMaterial]`, която получава идентификационен номер на материал и бройка, и връща колко от резултатния материал е успяла да създаде (спрямо ефикасността, закръглена надолу, и дали се нуждае от ремонт по средата на работата). + +Ще получите данни за всички материали и машини, както и задачи, тоест идентификационни номера на начален и краен материал, както и бройката на началния материал. +Трябва да намерите редицата от машини, които ще създадат възможно най-много краен материал. diff --git a/src/teaching/oop-2023/week2/index.md b/src/teaching/oop-2023/week2/index.md deleted file mode 100644 index f8f27d9..0000000 --- a/src/teaching/oop-2023/week2/index.md +++ /dev/null @@ -1,194 +0,0 @@ -# Задачи - ООП, Седмица 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
BoburaBG
5
X X O O O
O X O X X
O X X X O
O X X X X
O X O O O
|Emil Petkov: Total - 13, Longest - 4
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.du b/src/teaching/oop-2023/week3/index.du new file mode 100644 index 0000000..44d23f7 --- /dev/null +++ b/src/teaching/oop-2023/week3/index.du @@ -0,0 +1,177 @@ +# Задачи - ООП, Седмица 3, 07.03.2024 + +\n + +GitHub classroom: [url https://classroom.github.com/a/KPMqXsFp classroom.github.com/a/KPMqXsFp] + +## Преговорни + +### Задача 1 - Структури + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week03/Exercise1.cpp Решение] + +Имплементирайте структура `[Lightbulb]`, която запазва идентифициращите данни за една крушка: +.bulleted +- диаметър и дължина: и двете са целочислени стойности +- тип: низ с максимална дължина от 100 знака +- серия: буква на латиница + +### Задача 2 - Капсулация + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week03/Exercise2.cpp Решение] + +Имплементирайте структура `[Alarm]`, която съдържа следните =[скрити]= данни: +.bulleted +- име на модел: низ с максимална дължина от 1024 знака +- пин код: целочислено число +- ревизия на модела: число с плаваща запетая + +За всяка данна трябва да създадете съответните get-ъри и set-ъри: публични член-функции, които съответно връщат и записват всяка от изброените скрити стойности. + +При set-ърите имплементирайте следните проверки: +.bulleted +- името на модела може да има само главни букви +- пин кода трябва да бъде 4 цифри (нули са позволени) +- ревизията трябва да бъде положително число + +Ако дадена проверка не е изпълнена, не записвате новата стойност (и оставяте старата). + +### Задача 3 - Капсулация с динамична памет + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week03/Exercise3.cpp Решение] + +Имплементирайте структура `[Person]`, която запазва двете имена на човек, възраст като целочислено число и неговия имейл. +Имената и имейла са низвое с произволна дължина. + +Направете конструктор, който приема възрастта и тези три низа, и =[копира]= стойностите им в динамичната памет. +Също напишете и деструктор, който коректно трие нужните данни. + +### Задача 4 - Динамично-заделени структури в други структури + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week03/Exercise4.cpp Решение] + +Имплементирайте структура `[Bus]`, която публично запазва капацитета хора и километража на един автобус. + +Имплементирайте структура `[BusWarehouse]`, която запазва динамично-заделен масив от автобуси. +В конструктора се въвежда максималния брой автобуси, който може един `[BusWarehouse]` да съдържа. + +Имплементирайте конструктор, който само инициализира нужните данни, и деструктор който трие каквото трябва. +Имплементирайте член-функция `[AddBus]`, която добавя автобус в инстанция на `[BusWarehouse]`, ако има място за него. + +## Лесни задачи + +### Задача 5 + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week03/Exercise5.cpp Решение] + +Имплементирайте структура `[Car]`, всяка кола пази скрито своя модел като низ с произволна дължина, брой врати и брой седалки като целочислени числа. +Направете съответните get-ъри, set-ъри, конструктор и деструктор. + +Имплементирайте структура `[TrafficJam]`, която пази произволно дълга редица коли в задръстване. +Направете и член-функция `[AddCar]`, която вмъква кола в края на редицата. +Тази функция може да се извиква произволен брой пъти, затова имплементирайте и оразмеряване на вътрешната редица. + +`[TrafficJam]` трябва да има конструктор, деструктор и тази член-функция. + +### Задача 6 + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week03/Exercise6.cpp Решение] + +Ще работите с N-мерна шахматна дъска. + +Направете структура `[ChessPiece]`, която запазва цвета и типа на фигурата от шах, като първото е целочислена стойност, второто е буква. + +Направете структура `[ChessBoard]`, която по подадено N в конструктора създава шахматна дъска с размер NxN с =[указатели]= към съответните фигури на дъската. +Разбира се, някои от тези указатели трябва да сочат към някакви създадени шахматни фигури. + +При създаване на дъската, трябва да подредите фигурите. +На най-долните два реда присъстват белите фигури, на най-горните два - черните. +За дъска 8х8, фигурите са подредени както нормално: + +[image 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 [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week03/Exercise7.cpp Решение] + +Имате затворени интервали от целочислени числа. +Разглеждаме смесване на интервали: +.bulleted +- смеската на допиращи се интервали е тяхното слепване, тоест смеската на `[[0, 3]]` и `[[3, 5]]` е `[[0, 5]]` +- смеската на препокриващи се интервали е тяхното обединение, тоест смеската на `[[0, 5]]` и `[[3, 8]]` е `[[0, 8]]` + +В противен случай не можем да смесим интервалите (примерно не можем да смесим `[[0, 3]]` и `[[4, 8]]`). + +Започвайки от някакво множество с интервали, смесете колкото се може повече от тях и изкарайте всичките резултатни интервали, които не могат повече да се смесят. +Използвайте структури и член-функции. + +### Задача 8 + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week03/Exercise8.cpp Решение] + +"Моделирайте" (тоест сами се сетете за типовете данни и нужните структури) един град със следните харакетристики. + +В града имате два типа сгради: жилищни и търговски. +.bulleted +- Жилищните се харакетиризират с цена на апратамент, бройката етажи, количеството хора, които се побират на един етаж (една стойност за всички етажи) и дали имат мазе, паркомясто и/или таван. +- Търговските се характеризират с цена на магазин, бройка етажи с паркинг, бройка етажи с магазини и максимално количество магазини, които се побират на един етаж (една стойност за всички етажи). + +Градът трябва да пази всички отделни сгради, като допълнително за всяка жилищна трябва да съхранява общата бройка жители, 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 за [url https://commons.wikimedia.org/w/index.php?curid=106440749 Уикипедия] под лиценз CC BY-SA 4.0 diff --git a/src/teaching/oop-2023/week3/index.md b/src/teaching/oop-2023/week3/index.md deleted file mode 100644 index c9b4963..0000000 --- a/src/teaching/oop-2023/week3/index.md +++ /dev/null @@ -1,175 +0,0 @@ -# Задачи - ООП, Седмица 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/index.du b/src/teaching/oop-2023/week4/index.du new file mode 100644 index 0000000..a6e02b9 --- /dev/null +++ b/src/teaching/oop-2023/week4/index.du @@ -0,0 +1,115 @@ +# Задачи - ООП, Седмица 4, 14.03.2024 + +\n + +GitHub classroom: [url https://classroom.github.com/a/qa_FfWeG classroom.github.com/a/qa_FfWeG] + +## Преговорни + +### Задача 1 - Капсулация + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week04/Exercise1.cpp Решение] + +Имплементирайте структура `[Smartphone]`, която запазва =[скрито]=: +.bulleted +- марка, низ с максимална дължина от 128 знака +- модел, низ с максимална дължина от 512 знака +- година на произвеждане, неотрицателно целочислено число +- резолюция на камера, число с плаваща запетая (обозначаващо мегапиксели) + +За всяка стойност напревете съответните get-ъри и set-ъри, правейки следните проверки при set-ърите: +.bulleted +- марката и моделът не могат да бъдат празни низове, или пък да надвишават максималната дължина +- годината трябва да бъде между 2000 и 2024 +- резолюцията не може да бъде отрицателна (може да бъде нула, което показва, че смартфонът няма камера) + +При неизпълнено условие, хвърляте грешка. + +### Задача 2 - Капсулация с динамична памет + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week04/Exercise2.cpp Решение] + +Имплементирайте структура `[Bee]`, която запазва възрастта на пчела чрез число с плаваща запетая и типа пчела с буква. + +Имплементирайте структура `[BeeHive]`, която запазва динамично-заделен масив с всички реещи се пчели и друг динамично-заделен масив с всички яйца в кошера. +Размерите на двата масива се подават на конструктора. +Имплементирайте нужните конструктор и деструктор. + +## Лесни задачи + +### Задача 3 + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week04/Exercise3.cpp Решение] + +Имплементирайте структура `[Paper]`, която запазва своето текстово съдържание като низ от максимум 1024 знака и положително цяло число, определящо номера на страницата. + +От входа получавате на един ред цялото текстото съдържание за един обект от тип `[Paper]` и на следващия ред - бройките копия `[N]` на дадения обект. + +Създайте `[Paper]` обект със съответното съдържание и номер на страницата `[1]`. +Създайте динамично-заделен масив от `[Paper]` с размер `[N]`, като първия му елемент е новосъздадения обект, докато останалите са =[копия]= на първия обект. + +При всяко копие, трябва да увеличите номера на страницата. +Имплементирейте логиката чрез копиращ конструктор. + +### Задача 4 + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week04/Exercise4.cpp Решение] + +Създайте структура `[DynamicString]`, чиито конструктор приема низ с терминираща нула, заделя точно толкова динамична памет, колкото е нужно да се запази целия низ и копира буквите на низа в тази памет. +Имплементирайте оператор равно. + +.question Какви данни трябва `[DynamicString]` да запазва скрито? + +:question +Какво трябва оператор равно да направи, ако записваме в `[DynamicString]` с вече заделена памет?\n + +Тоест ако имахме:\n +`[DynamicString s1("Hello"); DynamicString s2("World"); s2 = s1;]` + + +### Задача 5 + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week04/Exercise5.cpp Решение] + +Имплементирайте структура `[TVProgram]`, която запазва името на предаването като низ от максимум 1024 знака, начало на излъчване и край на излъчване като неотрицателни целочислени числа (като примерно 1347 е един часа и 47 минути следобед). +Имплементирайте конструктор, деструктор, оператор равно и копиращ конструктор. + +Имплементирайте структура `[TVChannel]`, която запазва динамично заделен масив от `[TVProgram]`, размера на динамично заделената памет и броя "ненулеви" елементи (програми, добавени с `[AddProgram]`). + +Имплементирайте нейн метод `[AddProgram]`, който приема `[TVProgram]` =[по копие]= и го вмъква на последната свободна позиция в масива. +Ако масива е пълен, трябва да го "оразмерите" (да направите нов, по-голям масив, да копирате данните от стария в новия, да изтриете стария и да обновите указателя да сочи към новия). + +.question Кога използвате копиращия конструктор на `[TVProgram]` и кога използвате оператор равно? + +## Трудни задачи + +### Задача 6 + +Ще разработим (изключително груба) симулация на вселената. +За нас, гравитацията няма да бъде сила, която просто привлича тела към себе си, а сила която кара телата около нея да се въртят ("орбитират") в перфектен кръг. +Имаме много звезди и една планета, като звездите са винаги неподвижни, а планетата се влияе от тях. + +Гравитационното привличане на звезда в своя център се определя от ъгъла θmax (в градуси). +Планетата се върти около една звезда, използвайки стандартната матрица за ротация: + +[image ./img/Rotation_matrix.png] + +Ъгълът на въртене θ, спрямо разстоянието до една звезда, се определя чрез [url https://en.wikipedia.org/wiki/Inverse-square_law закона на обратните квадрати], тоест в зависимост от разстоянието `[d]` между центъра на звездата и центъра на планетата, то истинският ъгъл на завъртане е θ = θmax * 1 / d^2. + +Допълнително, ако имаме повече от една звезда, тогава ще използваме θ' = max(θi - average(θ1, ..., θn)), където θi е намереният ъгъл θ за i-тата звезда и имаме n на брой звезди. + +Ефектът на това е, че ако имаме две звезди на еднакво разстояние с еднакъв ъгъл, тогава планетата е неподвижна, а ако някоя планета е с малко по-близка, тогава се върти около нея и то съвсем бавно. + +Приемаме, че отнема единица време планетата да се завърти с ъгъл θ', без значение размера на ъгъла. +Целта на задачата е да върнете при коя звезда и за колко единици време планетата е успяла да извърши пълна ротация (разбира се, θ' и планетата може да се измени след всяка ротация). + +Имплементирайте структури: +.bulleted +- `[Matrix2x2]` и `[Matrix2x1]`, чиито стойности са числа с плаваща запетая, и с член функции за събиране и умножение (не оператор+, оператор\*) +- `[Coordinate]`, която запазва (=[не наследява]=) точките в пространството като `[Matrix2x1]` и имплементира събиране, умножение и разстояние между координати и матрици +- `[Star]`, запазваща координатата на своя център (`[Matrix2x1]`) и ъгълът θmax като число с плаваща запетая. + Имплементирайте и метод, който приема планета и връща ъгълът θ. +- `[Planet]`, запазваща своите координати (`[Matrix2x1]`) и изминалото време (тоест колко пъти се е движела от началото на симулацията). + Имплементирайте метод `[OrbitPlanet]`, която приема планета и ъгъл θ', и се завърта около нея. +- `[Universe]`, запазваща всички звездите и планетата. + Имплементирайте метод `[FullOrbit]`, която връща звездата около която планетата е успяла да извърши пълна ротация и времето за което това се е случило. diff --git a/src/teaching/oop-2023/week4/index.md b/src/teaching/oop-2023/week4/index.md deleted file mode 100644 index b89a7a6..0000000 --- a/src/teaching/oop-2023/week4/index.md +++ /dev/null @@ -1,110 +0,0 @@ -# Задачи - ООП, Седмица 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 - -Ще разработим (изключително груба) симулация на вселената. -За нас, гравитацията няма да бъде сила, която просто привлича тела към себе си, а сила която кара телата около нея да се въртят ("орбитират") в перфектен кръг. -Имаме много звезди и една планета, като звездите са винаги неподвижни, а планетата се влияе от тях. - -Гравитационното привличане на звезда в своя център се определя от ъгъла θmax (в градуси). -Планетата се върти около една звезда, използвайки стандартната матрица за ротация: - -![](./img/Rotation_matrix.png) - -Ъгълът на въртене θ, спрямо разстоянието до една звезда, се определя чрез [закона на обратните квадрати](https://en.wikipedia.org/wiki/Inverse-square_law), тоест в зависимост от разстоянието `d` между центъра на звездата и центъра на планетата, то истинският ъгъл на завъртане е θ = θmax * 1 / d^2. - -Допълнително, ако имаме повече от една звезда, тогава ще използваме θ' = max(θi - average(θ1, ..., θn)), където θi е намереният ъгъл θ за i-тата звезда и имаме n на брой звезди. - -Ефектът на това е, че ако имаме две звезди на еднакво разстояние с еднакъв ъгъл, тогава планетата е неподвижна, а ако някоя планета е с малко по-близка, тогава се върти около нея и то съвсем бавно. - -Приемаме, че отнема единица време планетата да се завърти с ъгъл θ', без значение размера на ъгъла. -Целта на задачата е да върнете при коя звезда и за колко единици време планетата е успяла да извърши пълна ротация (разбира се, θ' и планетата може да се измени след всяка ротация). - -Имплементирайте структури: - -- `Matrix2x2` и `Matrix2x1`, чиито стойности са числа с плаваща запетая, и с член функции за събиране и умножение (не оператор+, оператор\*) -- `Coordinate`, която запазва (**не наследява**) точките в пространството като `Matrix2x1` и имплементира събиране, умножение и разстояние между координати и матрици -- `Star`, запазваща координатата на своя център (`Matrix2x1`) и ъгълът θmax като число с плаваща запетая. - Имплементирайте и метод, който приема планета и връща ъгълът θ. -- `Planet`, запазваща своите координати (`Matrix2x1`) и изминалото време (тоест колко пъти се е движела от началото на симулацията). - Имплементирайте метод `OrbitPlanet`, която приема планета и ъгъл θ', и се завърта около нея. -- `Universe`, запазваща всички звездите и планетата. - Имплементирайте метод `FullOrbit`, която връща звездата около която планетата е успяла да извърши пълна ротация и времето за което това се е случило. diff --git a/src/teaching/oop-2023/week5/index.du b/src/teaching/oop-2023/week5/index.du new file mode 100644 index 0000000..f159418 --- /dev/null +++ b/src/teaching/oop-2023/week5/index.du @@ -0,0 +1,118 @@ +# Задачи - ООП, Седмица 5, 21.03.2024 + +\n + +GitHub classroom: [url https://classroom.github.com/a/42ZZ56Mg classroom.github.com/a/42ZZ56Mg] + +## Преговорни + +### 1 задача - Капсулация с динамична памет + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week05/Exercise1.cpp Решение] + +Пациент в болница се характеризира с идентификационен номер (неотрицателно целочислено число) и име (низ от максимум 1024 знака). +Една болница има максимален капацититет на болни, които може да държи (максимален брой легла за тях). + +Конструктора за болницата приема максималния капацитет, като структурата за болницата пази всичките си пациенти. +Имплементирайте методи `[AddPatient]`, който добавя нов пациент и `[RemovePatient]`, който го премахва от болницата. + +Не е нужно данните за пациентите да са скрити, но данните в болницата трябва да са. + +### 2 задача - Копиращ конструктор и оператор= + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week05/Exercise2.cpp Решение] + +Имплементирайте структура `[FloatArray]`, която запазва динамично-заделен масив от `[float]` стойности. +Размерът на масива се подава в конструктора. + +Имплементирайте копиращ конструктор, оператор= и get-ър/set-ър за елемент на индекс `[i]`. + +## Лесни задачи + +### 3 задача + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week05/Exercise3.cpp Решение] + +Имейл се характеризира с две стойности: адресът от който е изпратен (низ с максимална дължина от 128 знака) и съдържание (низ с неограничен размер). +Съобщението се подава като указател към знак, и трябва да заделите точно толкова динамична памет, колкото ви трябва за целия текст. + +Имплементирайте голяма четворка за имейла. + +### 4 задача + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week05/Exercise4.cpp Решение] + +Имплементирайте структура за касов бон, която запазва скрит динамично-заделен масив от цени (числа с плаваща запетая). +Можете да добавяте неограничен брой цени в края на касовия бон (ако масива е пълен, създавате по-голям и пренасяте стойностите). +Можете да премахвате цени според индекс (и всички следващи се преместват с една позиция назад). + +Имплементирайте тези функционалности в методи. +Имплементирайте голяма четворка. + +### 5 задача + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week05/Exercise5.cpp Решение] + +Един контролен списък (checklist) пази няколко неща: булева стойност, дали е избран или не, текстово съдържание (низ с "произволна" дължина) и масив от контролни списъци (всеки списък от този масив ще наричам "подсписък" за удобство). +Нека текстовото съдържание да не може да се редактира (задава се в конструктора и няма set-ър). + +Имплементирайте добавяне и премахване на подсписък, както и придвижване на подсписък с една позиция наляво или надясно. +Имплементирайте голяма четворка. + +### 6 задача + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week05/Exercise6.cpp Решение] + +Имате телефонен указател, който запазва масив от имена (низове). +В началото винаги започва празен. +Имплементирайте голяма четворка. + +Имплементирайте метод `[InsertPerson]`, който вмъква ново име в указателя, като вмъкването запазва сортировка по азбучен ред. +Тоест ако указателя беше `[{ "Atanas", "Yavor" }]`, тогава след вмъкване на `[Boris]` ще имаме `[{ "Atanas", "Boris", "Yavor" }]`. + +.important Имплементирайте вмъкване, запазващо "сортираност" без функция за сортиране! + +### 7 задача + +.solution-link [url 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/week5/index.md b/src/teaching/oop-2023/week5/index.md deleted file mode 100644 index be66316..0000000 --- a/src/teaching/oop-2023/week5/index.md +++ /dev/null @@ -1,116 +0,0 @@ -# Задачи - ООП, Седмица 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.du b/src/teaching/oop-2023/week6/index.du new file mode 100644 index 0000000..9a2947e --- /dev/null +++ b/src/teaching/oop-2023/week6/index.du @@ -0,0 +1,104 @@ +# Задачи - ООП, Седмица 6, 28.03.2024 + +\n + +GitHub classroom: [url https://classroom.github.com/a/rzSTn5pu classroom.github.com/a/rzSTn5pu] + +.warn В задачите за файлове имплементирайте всички нужни проверки и затваряния + +## Преговорни + +### 1 задача - Копиращ конструктор и оператор= + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week06/Exercise01.cpp Решение] + +Имплементирайте структура `[WoodenPlank]`, която скрито запазва ширина, дължина и височина на дъската (целочислено), цената ѝ (число с плаваща запетая) и типа дърво (низ с максимум 1024 знака). + +Имплементирайте get-ъри, set-ъри, копиращ конструктор, оператор= + +### 2 задача - Голяма четворка + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week06/Exercise02.cpp Решение] + +Имплементирайте структура `[DynamicString]`, която скрито запазва указател към низ (в динамичната памет) и неговия размер. + +Имплементирайте голяма четворка. + +## Лесни задачи + +### 3 задача + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week06/Exercise03.cpp Решение] + +Имплементирайте програма, която отваря файл (създава го, ако вече не е създаден) и вкарва текста "Hello World!" във файла. +Името на файла се подава от стандартния вход на един ред. + +### 4 задача + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week06/Exercise04.cpp Решение] + +Имплементирайте програма, която приема име на файл от стандартния вход. +Изкарайте последния ред от файла. + +Редовете са разделени със знака `[\\n]`. + +### 5 задача + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week06/Exercise05.cpp Решение] + +Имплементирайте програма, която приема име на файл от стандартния вход. +Изкарайте броя редове и броя думи във файла. + +### 6 задача + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week06/Exercise06.cpp Решение] + +От стандартния вход получавате, на два отделни реда, две имена на файлове. +Вмъкнете съдържанието на втория файл по средата на първия файл. + +### 7 задача + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week06/Exercise07.cpp Решение] + +От стандартния вход получавате числата m и n, както и името на файл (на свой си ред). +Изкарайте на екрана от m-тата до n-тата буква (включително) от всеки ред във файла. +Първата буква на един ред е на индекс 1. + +### 8 задача + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week06/Exercise08.cpp Решение] + +Имплементирайте структура `[FileBuffer]`, която в конструктора си приема име на файл, отваря го и запазва (копира) цялото му съдържание в динамичната памет (с указател член-данна). + +.question Кога трябва да затворим файла? + +Имплементирайте голяма четворка. + +### 9 задача + +.solution-link [url 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/week6/index.md b/src/teaching/oop-2023/week6/index.md deleted file mode 100644 index c5bd777..0000000 --- a/src/teaching/oop-2023/week6/index.md +++ /dev/null @@ -1,102 +0,0 @@ -# Задачи - ООП, Седмица 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.du b/src/teaching/oop-2023/week7/index.du new file mode 100644 index 0000000..04800db --- /dev/null +++ b/src/teaching/oop-2023/week7/index.du @@ -0,0 +1,85 @@ +# Задачи - ООП, Седмица 7, 04.04.2024 + +\n + +GitHub classroom: [url https://classroom.github.com/a/vvZENbkX classroom.github.com/a/vvZENbkX] + +## Преговорни + +### Задача 1 - Голяма петица + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week07/Exercise1.cpp Решение] + +Една съставка е композирана от низ (с максимална дължина от 511 знака) определящ името ѝ и грамаж (число с плаваща запетая). + +Създайте клас `[Recipe]`, към който могат да се прибавят и премахват произволен брой съставки. +Имплементирайте голяма петица (голяма четворка плюс move семантики) за него. + +### Задача 2 - Работа с файлове + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week07/Exercise2.cpp Решение] + +От един ред на входа получавате името на текстови файл. +Изкарайте на екрана средната една трета от файла, като буквите са в обратен ред. + +## Лесни задачи + +### Задача 3 + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week07/Exercise3.cpp Решение] + +Имплементирайте клас `[Thermometer]`, който запазва максималната и минималната възможна температура за измерване, както и сегашната температура, всичките които са цели неотрицателни числа. + +Имплементирайте методи `[SaveText]` и `[LoadText]`, които съответно записват и четат (тоест член-данните стават равни на тези от файла) данните си в/от =[текстови]= файл с подадено име. +Аналогично имплементирайте `[SaveBinary]` и `[LoadBinary]`, които работят с =[двоични]= файлове. + +### Задача 4 + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week07/Exercise4.cpp Решение] + +Имплементирайте клас `[Street]`, който запазва скрито името на улицата като низ с произволна дължина и номер като цяло число. +Имплементирайте голяма петица. + +Имплементирайте методите `[SaveText]`, `[LoadText]`, `[SaveBinary]`, `[LoadBinary]`. + +### Задача 5 + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week07/Exercise5.cpp Решение] + +За един транспортен билет е нужно скрито да пазим началната и крайната дестинация като динамично-заделени низове с произволна дължина, неговата цена като число с плаваща запетая и идентификационен номер като цяло неотрицателно число. + +Имплементирайте голяма петица и четирите функции за запазване и четене от файлове на съответния клас. + +### Задача 6 + +.solution-link [url 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/week7/index.md b/src/teaching/oop-2023/week7/index.md deleted file mode 100644 index 0eb3899..0000000 --- a/src/teaching/oop-2023/week7/index.md +++ /dev/null @@ -1,83 +0,0 @@ -# Задачи - ООП, Седмица 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.du b/src/teaching/oop-2023/week8/index.du new file mode 100644 index 0000000..6d48934 --- /dev/null +++ b/src/teaching/oop-2023/week8/index.du @@ -0,0 +1,172 @@ +# Задачи - ООП, Седмица 8, 11.04.2024 + +\n + +GitHub classroom: [url https://classroom.github.com/a/7d0MBjcK classroom.github.com/a/7d0MBjcK] + +## Преговорни + +### Задача 1 - Голяма петица + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week08/Exercise1.cpp Решение] + +Имплементирайте клас `[StreetList]`, който запазва имената на улици (низове с произволна дължина) в динамичен масив. +Може да се добавят нови имена в края на списъка, като съответния (вътрешен) масив трябва да се уголеми. + +Имплементирайте голяма петица за класа. + +### Задача 2 - Файлове и класове + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week08/Exercise2.cpp Решение] + +Имплементирайте клас `[Person]`, който запазва трите имена (низове с произволна дължина) и идентификационния номер (цяло неотрицателно число) на човек. +Имплементирайте голяма петица. + +Имплементирайте методи `[SaveText]` и `[LoadText]`, които съответно записват и четат (тоест член-данните стават равни на тези от файла) данните си в/от =[текстови]= файл с подадено име. +Аналогично имплементирайте `[SaveBinary]` и `[LoadBinary]`, които работят с =[двоични]= файлове. + +## Лесни + +### Задача 3 + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week08/Exercise3.hpp Решение] + +Имплементирайте шаблонната структура `[Pair]`, която приема два типа и запазва по една стойност от всеки тип. + +### Задача 4 + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week08/Exercise4.cpp Решение] + +Имплементирайте клас `[FloatArray]`, който съдържа списък с числа с плаваща запетая. +Може да добавяте нови числа в края на този списък. +Имплементирйате голяма петица. + +Имплементирайте оператори: +.bulleted +- += и +, които конкатенират два FloatArray-я. += вмъква елементите от десния масив в края на левия, + връща нов масив в който първо са елементите от левия масив и след тях са тези от десния. +- += и +, които приемат FloatArray и число (с плаваща запетая) и го прибавят към всеки елемент на FloatArray-я +- [], които връщат референция към елементът на подадения индекс. При невалиден хвърлят грешка. +- == и !=, които сравняват два FloatArray-я покомпонентно. + Ако се различават по брой елементи или ако имат две различни стойности на еднакъв индекс, тогава не са равни. +- <<, който вмъква всички стойности в подадения поток, разделени с шпация +- >>, който презаписва всички стойности, разделени с шпация, четейки от подадени поток + +### Задача 5 + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week08/Exercise5.hpp Решение] + +Имплементирайте класът и неговите оператори от предходната задача като темплейтен (шаблонен) клас с име `[DynamicArray]`. +Очевидно шаблонния тип определя типа на списъка с елементи. + +### Задача 6 + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week08/Exercise6.cpp Решение] + +Имплементирайте клас `[NumberInput]`, който запазва целочислена стойност. +В конструктора се подава минимална и максимална възможна стойност, след това (все още в конструктора) се изкарва на екрана съответно съобщение и се приема потребителски вход. +Ако той не е валиден или е извън подадения обхват, трябва да хвърлите грешка. + +В main създайте обект от този клас. +Ако се хвърли грешка, прихванете я, изкарайте на екрана съответното съобщение и пробвайте пак. +Това се повтаря докато обекта не е успешно създаден, след което изкарвате въведената стойност по две. + +### Задача 7 + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week08/Exercise7.cpp Решение] + +Имплементирайте клас `[UserError]`, чиято употреба е да се хвърля като грешка. +За тази цел нека да запазва два низа, които се приемат в конструктора: името на клас и името на член-данната. + +Имплементирайте голяма петица и оператор<<, който изкарва съобщение с информация за класа и член-данната в подадения поток. +Следете бройката на създадени `[UserError]` инстанции в самия клас (статична променлива) и имплементирате нужната (статична) член-функция, която връща този брой. + +Преобразувайте последната задача, така че да хвърля грешка от този клас. +В края на програмата изкарайте колко грешки са се хвърлили =[използвайки статичните членове на UserError]=. + +## Трудни задачи + +### Задача 8 + +Имплементирайте шаблонен клас `[UserInput]`, който запазва стойност от подадения тип. +Ако типа е указател, тогава заделяте динамична памет за един такъв елемент. +За проверка на типа използвайте [url https://en.cppreference.com/w/cpp/language/partial_specialization partial template specialization]. + +В шаблона (`[template <...>]`) се приема указател към валидираща функция, която приема стойността от съответния тип и връща булева стойност. +В конструктора се приема от входа нужната стойност и ако стойността е неуспешно приета или валидиращата функция върне false, тогава хвърляте грешка. +Ако типа е указател, не забравяйте да освободите паметта. + +В класа следете статично за броя пъти когато е хвърлена грешка. + +### Задача 9 + +.important В тази задача се изикват помощни класове, прочетете цялото условие преди имплементиране! + +Имплементирайте шаблонен клас `[Dictionary]`, който запазва два динамично-заделени масива: първия е със стойност от подадения тип, втория е с низове. +Низовете ще се използват за индексиране, вместо числа. +Разбира се, очаквайте да може да се уразмерява. +Имплементирайте голяма петица. + +Имплементирайте оператор: + +:bulleted +- <<=, който вмъква всички стойности от десния `[Dictionary]` в левия +- [], който приема низ и връща референция "към" стойността. + Ако няма записана стойност на съответния индекс, тогава връщате референция в която може да се запише стойност. +- [], който приема число, което се конвертира до низ и работи както предходния оператор +- [], който приема низове (или числа), разделени със запетая и връща "масив" само с тези стойности +- delete, който приема стойност, върната от оператор[] и "премахва" съответната стойност от `[Dictionary]` +- префиксен++, префиксен+ и префиксен-, които ще се използват за итериране. + .bulleted + - ++ връща инкрементира индекса на сегашната стойност. + Ако индекса е равен на броя запазени стойности, тогава става нула. + По подразбиране индекса е броя. + Връща true ако след инкрементиране индекса не е броя. + - + връща референция към стойността на сегашния индекс + - - връща сегашния (низов) индекс + +- ->, такъв че можем да правим `[a->(&func1)->(&func2)]` и `[a->[&func3]->[&func4]]`.\n + Върху всяка двойка индекс-стойност се прилагат &func1 и &func2 (приемат индекс и стойност като параметри), които връщат нова стойност, заместваща сегашната.\n + &func3, &func4 аналогично приемат индекс и стойност, но връщат нов индекс. + + +В края на задачата трябва да можете да правите: + +:code_c++ +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 a; + a["first"] = 8; + a[2] = 13; + a[89] = -68; + + Dictionary 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/week8/index.md b/src/teaching/oop-2023/week8/index.md deleted file mode 100644 index be78f9f..0000000 --- a/src/teaching/oop-2023/week8/index.md +++ /dev/null @@ -1,167 +0,0 @@ -# Задачи - ООП, Седмица 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 a; - a["first"] = 8; - a[2] = 13; - a[89] = -68; - - Dictionary 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.du b/src/teaching/oop-2023/week9/index.du new file mode 100644 index 0000000..56ac747 --- /dev/null +++ b/src/teaching/oop-2023/week9/index.du @@ -0,0 +1,114 @@ +# Задачи - ООП, Седмица 9, 18.04.2024 + +\n + +На днешното упражнение ще решаваме [url https://learn.fmi.uni-sofia.bg/mod/resource/view.php?id=311448 задачата от Контролно 1], затова задачите ще са в същия дух (макар и да не включват най-новия материал). + +Решението, което писахме по време на практикума, с някои разширения и коментари, може да намерите [url https://github.com/Syndamia/oop-2023-solutions/tree/main/week09/Exam1 тук]. + +GitHub classroom: [url https://classroom.github.com/a/wlL1oUg2 classroom.github.com/a/wlL1oUg2] + +## Преговорни + +### Задача 1 - Голяма петица + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week09/Exercise1 Решение] + +Реализирайте клас Printer, който съдържа модел като низ с произволна дължина и брой принтирани страници като неотрицателно цяло число. +Имплементирайте голяма петица. + +### Задача 2 - Файлове и класове + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week09/Exercise2 Решение] + +Реализирайте клас Date, който съдържа номера на деня, месеца и годината в три отделни целочислени член-данни. +Имплементирайте член-методи `[storeText]`, `[storeBinary]`, които съответно запазват данните в текстов файл (във формата "YEAR MONTH DAY") и в двоичен файл с подадени имена. +Аналогично имплементирайте `[loadText]` и `[loadBinary]`, които презаписват член-данните с тези от подадените (имена на) файлове. + +В главната функция създайте 5 дати, запазете всяка в =[един и същ текстов файл]=, след това прочетете датите в =[нови]= 5 променливи и изкарайте датите в обратен ред. + +## Лесни + +### Задача 3 + +.solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week09/Exercise3 Решение] + +Реализирайте клас Train, който съдържа: +.bulleted +- модел като низ с максимална дължина от 127 знака +- идентификационен номер на релсовата линия върху която се намира, като целочислена неотрицателна стойност +- име на текстов файл, съдържащ всички райони от сегашната релсова линия, всеки на нов ред. + Самото име представяйте като низ с произволна дължина. +- сегашна локация (район) от релсовата линия като низ с произволна дължина. + Тази локация не се подава, и при създаване на обекта винаги е първата във файла. + +Имплементирайте методите: +.bulleted +- от голямата петица +- `[TransferNextRegion]`, който променя сегашната локация на следващата по ред в текстовия файл (чието име е подадено в конструктор). + Ако няма следващо по ред, тогава локацията да си остане същата и да се хвърли грешка. + Ако се срещнат проблеми с файла, хвърлете грешка. +- `[SwitchRailLine]`, който приема идентификационен номер на релсовата линия и име на текстов файл, и променя вътрешните стойности. + Съответно локацията трябва да бъде първата в подадения файл. + Ако се срещнат проблеми с файла, хвърлете грешка. + +Реализирайте клас TrainNetwork, който съдържа: +.bulleted +- идентификационен код, като низ с максимална дължина от 7 знака +- масив, запазващ максимум 511 влака (типа се оставя по ваша преценка) + +За този клас имплементирайте методите: +.bulleted +- `[HaveCollided]`, който приема индекс на два влака и връща дали са се блъснали. + Това се случва ако в една и съща релсова линия и един и същи регион, когато регионът не е последния възможен. +- `[RunTrains]`, който придвижва напред всички влакове, докато не стигнат финалната си възможна дестинация. + Влакове които са се ударили не се придвижват напред. + Връщате броя ударили се влакове. + +Да се имплементира главна функция, в която приемате име на двоичен файл от потребителя. +В този файл имате някакъв брой редици с идентификационен номер на релсова линия, брой локации върху съответната линия и всички локации като нормални низове, разделени с нови редове. + +Допълнително в главната функция приемайте от потребителя влаковете, като имената на текстовите файлове се избират от програмата (=[НЕ]= от потребителя) според идентификационния номер на релсовата линия и информацията във файла с редиците. +=[Не може да променяте Train класа!]= + +Последно в главната функция създайте обект от тип TrainNetwork и изкарайте резултата от `[RunTrains]` на екрана. + +## Трудни + +### Задача 4 + +Реализирайте клас Car, в който се запазват: +.bulleted +- марка като низ с максимум 31 знака +- модел като низ с произволна дължина +- брой седалки като положително цяло число +- гладност на човека на всяка седлка като целочислен масив с размер броя седалки + +Имплементирайте методи: +.bulleted +- от голямата петица +- `[AddPassenger]`, който добавя нов човек на дадения индекс на седалка +- `[RemovePassenger]`, който премахва човека от дадения индекс +- `[TotalHunger]`, който връща общото количество гладност в колата +- `[StoreData]`, който запазва всички данни от колата в =[двоичен]= файл с подадено име +- `[LoadData]`, който презаписва всички данни с тези от подадения по име =[двоичен]= файл + +Реализирайте клас DriveThrough, в който се запазват: +.bulleted +- име на ресторант, към който е свързано съответния проход, като низ с произволна дължина +- коли на опашка, като масив с коли с произволна дължина + +Имплементирайте методи: +.bulleted +- от голяма петица +- `[QueueUp]`, който приема кола и я вкарва в края на опашката. + Разбира се, масивът се уголемява ако е нужно. +- `[Serve]`, който изпълнява поръчката на най-предната кола в опашката. + За единица глад, ресторанта може да сготви достатъчно храна (за да нахрани клиента с "единица" храна) за единици време между половината от дължината на името на ресторанта и три пъти дължината на името на ресторанта време.\n + Максималното възможно количество време за изпълнение на поръчката варира и според броя коли в опашка: ако са под 6 на брой, тогава тогава се увеличава с 10%, а ако са над 10 тогава се намалява с по 5% за всяка кола след десетата. +- `[EfficiencyService]`, който изпълнява поръчките на всички коли в опашката и връща средно колко време е отнело на поръчка. +- `[StoreData]`, който запазва всички данни в =[текстов]= файл с подадено име +- `[LoadData]`, който презаписва всички данни с тези от подадения по име =[текстов]= файл + +Имплементирайте главна функция, в която от потребителския вход приемате име на текстов файл. +Създайте обект от тип DriveThrough, който да запълни своите стойности с тези от подадения файл и изкарайте на екрана стойността от `[EfficiencyService]`. diff --git a/src/teaching/oop-2023/week9/index.md b/src/teaching/oop-2023/week9/index.md deleted file mode 100644 index 50cea93..0000000 --- a/src/teaching/oop-2023/week9/index.md +++ /dev/null @@ -1,112 +0,0 @@ -# Задачи - ООП, Седмица 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`. -- cgit v1.3.1-23-gd82d