aboutsummaryrefslogtreecommitdiff
path: root/week02
diff options
context:
space:
mode:
Diffstat (limited to 'week02')
-rw-r--r--week02/exercise01.cpp17
-rw-r--r--week02/exercise02.cpp20
-rw-r--r--week02/exercise03.cpp15
-rw-r--r--week02/exercise04.cpp18
-rw-r--r--week02/exercise05.cpp11
-rw-r--r--week02/exercise06.cpp10
-rw-r--r--week02/exercise07.cpp29
-rw-r--r--week02/exercise08.cpp20
-rw-r--r--week02/exercise09.cpp29
-rw-r--r--week02/exercise10.cpp21
-rw-r--r--week02/exercise11.cpp21
11 files changed, 211 insertions, 0 deletions
diff --git a/week02/exercise01.cpp b/week02/exercise01.cpp
new file mode 100644
index 0000000..539fa14
--- /dev/null
+++ b/week02/exercise01.cpp
@@ -0,0 +1,17 @@
+#include <iostream>
+
+int main() {
+ int n;
+ std::cin >> n;
+
+ std::cout << "Със загуба bool " << (bool)n << std::endl;
+ std::cout << "Без загуба long long int " << (long long int)n << std::endl;
+ // Беше малко спорно дали от int към unsigned int губим информация
+ // Накрая приехме, че не губи, понеже всеки бит се запазва
+ std::cout << "Без загуба unsigned int " << (unsigned int)n << std::endl;
+ std::cout << "Със загуба char " << (char)n << std::endl;
+ std::cout << "Със загуба short int " << (short int)n << std::endl;
+ std::cout << "Без загуба double " << (double)n << std::endl;
+ std::cout << "Без загуба long int " << (long int)n << std::endl;
+ std::cout << "Със загуба unsigned char " << (unsigned char)n << std::endl;
+}
diff --git a/week02/exercise02.cpp b/week02/exercise02.cpp
new file mode 100644
index 0000000..7589576
--- /dev/null
+++ b/week02/exercise02.cpp
@@ -0,0 +1,20 @@
+#include <iostream>
+
+int main() {
+ unsigned int n;
+ std::cin >> n;
+ // Чрез побитовото и (&) можем лесно да направим "филтър", ако бита в дясно е единица приемаме бита в ляво, иначе връщаме 0.
+ // От неговата дефиниция, ако имаме някакъв входен бит X, тогава X & 1 винаги ще връща X
+ // С примери: ако X=0, тогава 0 & 1 = 0; ако X=1, тогава 1 & 1 = 1
+ // Обаче X & 0 винаги връща0
+ // С примери: ако X=0, то 0 & 0 = 0; ако X = 1, то 1 & 0 = 0
+ // Понеже не правим "сметкаджийска" операция, а повече използваме & за филтър, общоприето е да наричаме бита след & "маска".
+ //
+ // Тоест, да вземем най-десните 6 бита, означава да занулим останалите, тоест ще ползваме &, като в нашата маска
+ // трябва при най-десните 6 бита да са 1, докато останалите да са 0
+ //
+ // Най-десните 6 бита съответстват на 2^5, 2^4, 2^3, 2^2, 2^1 и 2^0
+ // Тоест, търсената маска е сумата на тези степени, което като го сметнем, излиза 31
+ // Има и по-лесен начин да го изчислим, като забележим, че тази сума е равна на 2^6 - 1
+ std::cout << (n & 31) << std::endl;
+}
diff --git a/week02/exercise03.cpp b/week02/exercise03.cpp
new file mode 100644
index 0000000..009cf71
--- /dev/null
+++ b/week02/exercise03.cpp
@@ -0,0 +1,15 @@
+#include <iostream>
+
+int main() {
+ unsigned int a;
+ std::cin >> a;
+ // Отместването на дясно с всяка единица дели числото на 2, докато отместването на ляво умножава по 2
+ // Нарочно 16 и 8 са степени на двойката
+ //
+ // Защо това се получава, еми, всеки бит се съпоставя с 2 на някаква степен, когато превръщаме в десетичен запис
+ // Примерно, да погледнем 101, десетично това е 1 * 2^2 + 0 * 2^1 + 1 * 2^0
+ // Нека да разделим това уравнение на 2, това е 0 * 2^2 + 1 * 2^1 + 0 * 2^0
+ // Нека сега да умоножим оригиналното по 2, 1 * 2^3 + 0 * 2^2 + 1 * 2^1 + 0 * 2^0
+ // Сравнително очевидно се вижда, че деление и умножение на 2 измества битвоете надясно и наляво
+ std::cout << (a >> 4) << ' ' << (a << 3) << std::endl;
+}
diff --git a/week02/exercise04.cpp b/week02/exercise04.cpp
new file mode 100644
index 0000000..2e83fbb
--- /dev/null
+++ b/week02/exercise04.cpp
@@ -0,0 +1,18 @@
+#include <iostream>
+
+int main() {
+ unsigned int address;
+ std::cin >> address;
+ // Искаме най-левите 8 бита, означава че искаме да "издръпнем" десните 32-8=24 бита
+ int firstOctet = (address >> 24);
+ // Искаме вторите най-леви 8 бита, така че издръпваме най-левите 16 бита (32-16=16)
+ // и от тези 16 бита използваме маска, за да вземем най-десните 8
+ // Маската ни десетично е 2^7 + 2^6 + 2^5 + 2^4 + 2^3 + 2^2 + 2^1 + 2^0
+ // За подробности с маски, вижте решението на 2ра задача
+ int secondOctet = (address >> 16) & 255;
+ // Същата идея, искаме третите най-леви 8 бита, така че дръпваме отдясно битвоте, така че
+ // търсените битове да са в най-дясно и с маска премахваме всичко освен тези 8 бита
+ int thirdOctet = (address >> 8) & 255;
+ int fourthOctet = address & 255;
+ std::cout << firstOctet << '.' << secondOctet << '.' << thirdOctet << '.' << fourthOctet << std::endl;
+}
diff --git a/week02/exercise05.cpp b/week02/exercise05.cpp
new file mode 100644
index 0000000..059b530
--- /dev/null
+++ b/week02/exercise05.cpp
@@ -0,0 +1,11 @@
+#include <iostream>
+
+int main() {
+ int a, n;
+ std::cin >> a >> n;
+ // Булевите стойности true и false се изкарват на екрана като 1 и 0 съответно
+ // Има и по-кратък вариант на този израз, който е !(a % n), понеже ! e булев оператор, неговата
+ // стойност трябва да бъде булева, a % n се конвертира в булева стойност, като ако е 0 става false, иначе е true
+ // Така дефакто имаме, че ако а се дели на n имаме false, иначе имаме true, с една негация обръщаме това
+ std::cout << (a % n == 0) << std::endl;
+}
diff --git a/week02/exercise06.cpp b/week02/exercise06.cpp
new file mode 100644
index 0000000..8261301
--- /dev/null
+++ b/week02/exercise06.cpp
@@ -0,0 +1,10 @@
+#include <iostream>
+
+int main() {
+ char input;
+ std::cin >> input;
+ // Някои хора използваха конкретните числови ASCII стойности в сравнението
+ // Бих казал че това е грешка, фундаментално знаците са числа, '0' и '9' се "превеждат"
+ // до конкретните ASCII стойности от C++
+ std::cout << ('0' <= input && input <= '9') << std::endl;
+}
diff --git a/week02/exercise07.cpp b/week02/exercise07.cpp
new file mode 100644
index 0000000..708ff20
--- /dev/null
+++ b/week02/exercise07.cpp
@@ -0,0 +1,29 @@
+#include <iostream>
+
+int main() {
+ int a, b, c;
+ std::cin >> a >> b >> c;
+ // Най-ефикасния начин да направим това, е да използваме 3 if-a и в тях да разменяме стойностите,
+ // така че накрая винаги a, b и c са в нарастващ ред
+ // Най лесния начин да обясня логиката е следния:
+ // Искаме a < b < c, това може да го сведем до точно 3 сравнение между две стойности,
+ // a < b, b < c и това което е изпълнено поради дефиницията на <, a < c
+ // a < b < c може да не е изпълнено, когато a < b, b < c и/или a < c не е изпълнено
+ // Затова разглеждаме точно тези случаи, които не биха били изпълнени, и с размяна ги правим изпълнени
+ if (a > b) {
+ int temp = a;
+ a = b;
+ b = temp;
+ }
+ if (b > c) {
+ int temp = b;
+ b = c;
+ c = temp;
+ }
+ if (a > c) {
+ int temp = a;
+ a = c;
+ c = temp;
+ }
+ std::cout << a << ' ' << b << ' ' << c << std::endl;
+}
diff --git a/week02/exercise08.cpp b/week02/exercise08.cpp
new file mode 100644
index 0000000..e092134
--- /dev/null
+++ b/week02/exercise08.cpp
@@ -0,0 +1,20 @@
+#include <iostream>
+
+int main() {
+ int month;
+ std::cin >> month;
+ switch (month) {
+ case 1: std::cout << "January"; break;
+ case 2: std::cout << "February"; break;
+ case 3: std::cout << "March"; break;
+ case 4: std::cout << "April"; break;
+ case 5: std::cout << "May"; break;
+ case 6: std::cout << "June"; break;
+ case 7: std::cout << "July"; break;
+ case 8: std::cout << "August"; break;
+ case 9: std::cout << "September"; break;
+ case 10: std::cout << "October"; break;
+ case 11: std::cout << "November"; break;
+ case 12: std::cout << "December"; break;
+ }
+}
diff --git a/week02/exercise09.cpp b/week02/exercise09.cpp
new file mode 100644
index 0000000..e53d427
--- /dev/null
+++ b/week02/exercise09.cpp
@@ -0,0 +1,29 @@
+#include <iostream>
+
+int main() {
+ double price;
+ std::cin >> price;
+
+ // Има два метода да се реши тази задача
+ // или (int)(price * 100) и price % x (където x е 50 или 20 или 10 или 5 или 1)
+ // или (int)(price / 0.x) и price -= (int)(price / 0.x) (където х е 5 или 2 или 1 или 05 или 01)
+ // Втория вариант е малко по-общ, затова него ще имплементирам
+ int divided = price / 0.5;
+ std::cout << "0.5 " << divided;
+ price -= divided * 0.5;
+
+ divided = price / 0.2;
+ std::cout << " 0.2 " << divided;
+ price -= divided * 0.2;
+
+ divided = price / 0.1;
+ std::cout << " 0.1 " << divided;
+ price -= divided * 0.1;
+
+ divided = price / 0.05;
+ std::cout << " 0.05 " << divided;
+ price -= divided * 0.05;
+
+ divided = price / 0.01;
+ std::cout << " 0.01 " << divided << std::endl;
+}
diff --git a/week02/exercise10.cpp b/week02/exercise10.cpp
new file mode 100644
index 0000000..434aaa0
--- /dev/null
+++ b/week02/exercise10.cpp
@@ -0,0 +1,21 @@
+#include <iostream>
+
+int main() {
+ int signals;
+ std::cin >> signals;
+
+ int leftSignal = signals / 1000;
+ int rightSignal = signals % 1000;
+
+ // difference е дефакто абсолютната стойност на leftSignal - rightSignal
+ int difference = leftSignal - rightSignal;
+ if (difference < 0)
+ difference *= -1;
+
+ if (difference <= 3)
+ std::cout << "Follow heading" << std::endl;
+ else if (leftSignal < rightSignal)
+ std::cout << "Turn left" << std::endl;
+ else
+ std::cout << "Turn right" << std::endl;
+}
diff --git a/week02/exercise11.cpp b/week02/exercise11.cpp
new file mode 100644
index 0000000..7d1de63
--- /dev/null
+++ b/week02/exercise11.cpp
@@ -0,0 +1,21 @@
+#include <iostream>
+
+int main() {
+ // Много не съм ползвал константи в решенията, не защото няма смисъл да се прави, а така някои неща по-лесно се виждат
+ const int LIGHT_SPEED = 29;
+
+ int timeSent, firstSatelliteCoord, firstSatelliteTimeRecv, secondSatelliteCoord, secondSatelliteTimeRecv;
+ std::cin >> timeSent >> firstSatelliteCoord >> firstSatelliteTimeRecv >> secondSatelliteCoord >> secondSatelliteTimeRecv;
+
+ int distanceToFirst = (firstSatelliteTimeRecv - timeSent) / 2 * LIGHT_SPEED;
+ int distanceToSecond = (secondSatelliteTimeRecv - timeSent) / 2 * LIGHT_SPEED;
+
+ // Повтарям логиката тука: имаме 4 възможни точни, първия сателит +- дистаниця и втория сателит +- дистанция
+ // Понеже данните не лъжат, трябва две от тези 4 възможности да съвпадат, и това проверяваме
+ // Допускаме че входа е валиден, така че това работи
+ if (firstSatelliteCoord + distanceToFirst == secondSatelliteCoord + distanceToSecond ||
+ firstSatelliteCoord + distanceToFirst == secondSatelliteCoord - distanceToSecond)
+ std::cout << (firstSatelliteCoord + distanceToFirst) << std::endl;
+ else
+ std::cout << (firstSatelliteCoord - distanceToSecond) << std::endl;
+}