Summary Files Commits Branches @commit @diff @stats
path: root / src / teaching / upp-2023 / week3 / index.md
diff options
context:
space:
mode:
1 files changed, 285 insertions, 0 deletions
-rw-r--r--src/teaching/upp-2023/week3/index.md285
diff --git a/src/teaching/upp-2023/week3/index.md b/src/teaching/upp-2023/week3/index.md
new file mode 100644
index 0000000..2dd506a
--- /dev/null
+++ b/src/teaching/upp-2023/week3/index.md
@@ -0,0 +1,285 @@
+# Задачи - УПП, Седмица 3, 20.10.2023
+
+GitHub classroom: [classroom.github.com/a/JgMSXuCf](https://classroom.github.com/a/JgMSXuCf)
+
+## Тема: цикли
+
+<br>
+
+### Задача 1 - Степенуване
+
+Получавате цяло число `x` и цяло положително число `n`, трябва да върнете `x` на степен `n`-та.
+
+**Примери**
+
+|Вход|Изход|
+|----|-----|
+|0 0 |1 |
+|-2 3|-8 |
+|4 1 |4 |
+
+### Задача 2 - Progress bar
+
+Получавате цяло число `x`, което е по-голямо или равно на 1, и на всеки ред трябва да изкарате един "progress bar", чиято дължина се увеличава с всеки изминал ред.
+На практика, този "progress bar" трябва да бъде една права, съставена от знакът `#`, която трябва с всеки изминал ред да се удължава с един знак.
+В началото прогресът е 1 и продължава до `x` включително.
+
+**Примери**
+
+|Вход|Изход|
+|----|-----|
+|3 |#<br>##<br>###
+|5 |#<br>##<br>###<br>####<br>#####
+
+#### Бонус
+
+Направете дължината на този progress bar фиксирана на 10 знака, и въведеното `x` да определя след колко реда трябва да запълним progress bar-а.
+Този път, прогресът започва от 0.
+
+**Примери**
+
+|Вход|Изход|
+|----|-----|
+|1 |##########|
+|2 |#####<br>##########|
+|3 |###<br>######<br>##########|
+|10 |#<br>##<br>###<br>...|
+|20 |<br>#<br>#<br>##<br>##<br>###<br>...|
+
+### Задача 3 - Endless program with an end
+
+От входа получавате букви, не се знае колко.
+На нов ред, за всяка буква, трябва да върнете "letter" ако е латинска буква, "digit" ако е цифра и "other" ако не е нито едно от двете.
+Обаче, буквата `^` има специално значение, когато я получим трябва програмата да свърши изпълнение.
+
+**Примери**
+
+|Вход|Изход|
+|----|-----|
+|a 8 ) b ^|letter<br>digit<br>other<br>letter|
+
+### Задача 4 - Premature end
+
+Ще получите максимум 10 цели числа, трябва (целочислено) да разделите числото `65536` на всяко от въведените числа.
+Но, когато получите числото 0, веднага трябва да спрете вземане на числа от входа.
+Финално, изкарайте резултата от всички тези деления.
+
+**Упътване:** Използвайте `break`.
+
+**Примери**
+
+|Вход|Изход|
+|----|-----|
+|65536 0|1|
+|2 4 3 0|2730|
+|199 2 2 1 -1 1 3 1 10 1|-2|
+
+
+### Задача 5 - Stop test
+
+Получавате букви, незнайно колко.
+Трябва да броите колко от тях са малки букви, колко са главни и колко са цифри.
+
+В момента в който получите `$` трябва да спрете приемане на букви и да изкарате
+
+```
+Lowercase: X Uppercase: Y Digit: Z
+```
+
+където X, Y и Z са съответните бройки.
+Обаче, ако получите буква, която не е малка, главна, цифра или `$`, трябва моментално да спрете изпълнението на програмата, без да отпечатвате нищо.
+
+**Упътване:** Използвайте `return`.
+
+**Примери**
+
+|Вход|Изход|
+|----|-----|
+|a b A 9 n 3 $|Lowercase: 3 Uppercase: 1 Digit: 2|
+|J h 8 8 @||
+
+### Задача 6 - Глупави сметки
+
+От входа получавате букви, това ще са "команди", като при всяка буква трябва да направите различно действие:
+
+- `s`: след като я получите, трябва да вземете цяло число от входа и да го запазите (първоначалната стойност на числото е 15)
+- `l`: трябва побитово да отместите наляво запазеното число с един бит
+- `r`: трябва побитово да отместите надясно запазеното число с един бит
+- `q`: трябва да запазите сегашното число на втора степен
+- `c`: трябва да запазите сегашното число на трета степен
+- `m`: трябва да запазите сегашното число минус 351
+- `p`: трябва да запазите сегашното число плюс 94
+- `&`: прекратявате програмата
+
+След всяка операция трябва да изкарате сегашната стойност на числото.
+Обаче, ако се въведе буква, за която няма дефинирана операция (не е команда) трябва да изкарате "Invalid command!" и да **не** изкарвате сегашната стойност на числото.
+
+**Упътване:** Използвайте `switch`, `default` и `continue`.
+
+**Примери**
+
+|Вход|Изход|
+|----|-----|
+|l l m q r &|30<br>60<br>-291<br>84681<br>42340|
+|s 34 c p s 2 ^ r &|39304<br>39398<br>2<br>Invalid command!<br>1|
+
+### Задача 7 - Безсмислена "тивност"
+
+Получавате от входа число с плаваща запетая.
+Ако числото е положително изкарвате на екрана "Positive", ако е отрицателно "Negative" и ако е 0 спирате програмата.
+Тоест, докато числото на входа не е 0, продължавате да приемате вход и да изкарвате "Positive" и "Negative".
+
+Първоначалната стойност на числото е 3.14159 и трябва в началото да изкарате "Positive".
+
+**Упътване:** Използвайте `do-while`.
+
+**Примери**
+
+|Вход|Изход|
+|----|-----|
+|9.1 -22.0 0|Positive<br>Positive<br>Negative|
+
+
+### Задача 8 - Дигитален часовник
+
+Работите върху софтуер на един дигитален часовник, като ще трябва да запазите сегашния час и минути (които първоначално са "00:00").
+Получавате букви (команди), като на всяка трябва да извършите някакво действие:
+
+- `t` - увеличавате минутите с единица (не забравяйте, че ако времето е било "0:59", трябва да стане "1:00") и изкарвате сегашното време
+- `c` - в зависимост от предишни натискания, прави различни неща:
+ - ако преди не е натиснат, влизаме в режим на промяна на часовете, от входа приемаме число което ще бъде новия час и изкарваме сегашното време
+ - ако вече е натиснат, влизаме в режим на минутите, от входа приемаме число, което ще бъде новата стойност на минутите и изкарваме сегашното време
+ - ако вече два пъти е бил натиснат, излизаме от режима
+ - ако сме в някой от първите два режима и получим `t` преди да излезем, не увеличаваме минутите
+- `f` - променяме изкараното време от 12 часов формат на 24 часов и обратно, като първоначално започваме с 24 часов, и изкарваме сегашното време
+ - При 24 часов формат изкарваме "XX:YY", където `XX` е часа и `YY` са минутите
+ - При 12 часов формат е почти същото "XX:YY ZM" където ZM е PM или AM
+
+**Примери**
+
+|Вход|Изход|
+|----|-----|
+|t c 19 t c 3 t c f f f|0:1<br>19:1<br>19:3<br>7:3 PM<br>19:3<br>7:3 PM|
+
+### Задача 9 - BASIC maze
+
+Това е една популярна тестова програма на (много стари) компютри, които са идвали с интерпретатор на езика BASIC:
+
+```
+10 PRINT CHR$(205.5+RND(1));:GOTO 10
+```
+
+Задачата е да я пресъздадем, тоест на 20 реда трябва да има по 20 букви, като всяка буква е, на случаен принцип, `/` или `\` .
+
+**Упътване:** Формално никога не се преподават или изискват случайни стойности, затова ги показвам сега:
+
+Най-отгоре на сорс-файла добавете нужната библиотека:
+
+```cpp
+#include <stdlib.h>
+```
+
+След това, в `main`, преди да използвате случайни стойности, трябва да "инициализираме системата":
+
+```cpp
+srand(time(NULL));
+```
+
+С функцията `rand()` получавате случайна положителна стойност, може да я ограничите до две стойности с модулно деление, `rand() % 2`.
+
+**Примерен изход** *Нямаме вход, вашия изход няма да изглежда напълно еднакъв*
+
+```
+////\/\\////\\/////\
+\\/\\\\\\\/\////\///
+\\\///\\\//\\\/\//\/
+/\/\////\\\//\\\/\\\
+//\/\////\\\\\///\\/
+/\\\\\\/\\/\\\/\///\
+/////\\\\\\/\\/\////
+\//\//\\\///\\\\\\\\
+\\\\//\\////\///\/\\
+\//\//\////////\//\\
+\\///\\//\///\/\/\/\
+///\\\///////\\\\///
+/\\/\\//\///\\/\\\\/
+\///\/\\\/\\\\/\\\\\
+////\/\\/\\/////\/\/
+\\/\\\//\//\\//\\///
+////\\\\/\//\\\/\/\/
+\//\\\/\\\\///\////\
+///\///\\//\\\//\\/\
+\/\/\\\/////\//\\\\/
+```
+
+### Задача 10 - Елка
+
+*Решението на тази задача е по-дълго!*
+
+Сега имплементирате кода на една елка.
+Елката запазва две числа, първото е "сегашното" число с което правим нормалните операции и "виждаме" на екрана, и второто е отделна памет, в която можем да добавяме и изваждаме числа.
+Първоначално и двете числа са нули.
+
+На един ред се въвежда цяло число или буква, като се редуват, тоест първо е число, след това е буква, след това число, ...
+Първото въведено число директно става новата стойност на сегашното число.
+Буквата е команда, като може да бъде +,-,\*,/, които са обикновените операции с които променяме сегашното число, докато:
+
+- `a` - добавя сегашното число в отделната памет
+- `s` - изважда сегашното число от тази памет
+- `c` - занулява сегашното число
+- `m` - занулява числото в отделната памет
+
+След `a`, `s` и `m` трябва да изкарате числото в отделната памет, докато след всички други команди трябва да изкарате сегашното число.
+
+**Примери**
+
+|Вход|Изход|
+|----|-----|
+|5 + 5 * 2 a a - 6 c|10<br>20<br>20<br>40<br>14<br>0|
+
+## Тема: assert
+
+<br>
+
+### Задача 11 - Термостат
+
+Работите върху термостат, на входа получавате необработени данни от датчика, а ваш колега е написал функция, която превръща тези данни в градуси по Целзий между -20 и 40:
+
+```
+int parseSensor(int s) { return ((((s=(s>>1)&(~0xF617A100))<0x54)?s|0xF01:s&0xCBFF)>>2)-21; }
+```
+
+Все още не сме учили функции, затова просто пльоснете горното нещо във вашия сорс код, *над* `int main()` и *в* `main` може да я използвате чрез `parseSensor(inputValue)`.
+
+Вашата задача е при определени градуси да връщате съобщение на екрана:
+
+- между 30 и 40 връщате "Hot"
+- между 20 и 29 връщате "Warm"
+- между 11 и 20 връщате "Temperate"
+- между 0 и 10 връщате "Cold"
+- между -20 и -1 връщате "Freezing"
+
+Обаче, това не е всичко.
+Поглеждате функцията на вашия колега и не сте уверени в нея, обаче нямате документацията за обработка на входа.
+Единственото нещо, което знаете, е че стойностите от функцията не трябва да са извън обхвата -20 и 40, затова използвайте `assert` и проверете/тествайте дали това винаги е вярно.
+
+Ето стойности с които може да тествате:
+
+```
+-332447336
+-332447416
+-332447256
+-332447656
+-332447576
+-332447496
+-332447736
+```
+
+На кои стойности функцията на колегата не работи?
+
+**Примери** *Входът е различен от горепосочените стойности (и при него функцията работи коректно)*
+
+|Вход|Изход|
+|----|-----|
+|-332447376|Warm|
+|-332447536|Cold|