Summary Files Commits Branches @commit @diff @stats
path: root / Year 1 / Object-oriented Programming
diff options
context:
space:
mode:
Commit96964a7af584d5acda6a02a594e8f4fb45da8dc3 (patch)
Author
 Syndamia <kamen.d.mladenov@protonmail.com>
2022-03-23 11:11:58 +0200
Committer
 Syndamia <kamen.d.mladenov@protonmail.com>
2022-03-23 11:11:58 +0200
Files1b51697149142491716c8e8c1ea999d3aaa53b6d /Year 1/Object-oriented Programming
uni-projects-96964a7af584d5acda6a02a594e8f4fb45da8dc3.tar
uni-projects-96964a7af584d5acda6a02a594e8f4fb45da8dc3.tar.gz
uni-projects-96964a7af584d5acda6a02a594e8f4fb45da8dc3.zip
Parentac13a906211d854f602b856dfc2e061bd2ec7410 (diff)
Added solutions for oop seminar 5
diff --git a/Year 1/Object-oriented Programming/Solutions Sem. 05/ex1-time.cpp b/Year 1/Object-oriented Programming/Solutions Sem. 05/ex1-time.cpp
new file mode 100644
index 0000000..b7b736e
--- /dev/null
+++ b/Year 1/Object-oriented Programming/Solutions Sem. 05/ex1-time.cpp
@@ -0,0 +1,192 @@
+/* FORK of Angel's work! */
+
+#include <iostream>
+using namespace std;
+
+class Time
+{
+ size_t seconds; //[0...59]
+ size_t mins; //0...59
+ size_t hours; // 0...23
+
+ size_t convertToSeconds() const
+ {
+ return 3600 * hours + 60 * mins + seconds;
+ }
+
+
+public:
+ Time(); // 00:00:00
+ Time(size_t hours, size_t mins, size_t seconds);
+ Time(size_t seconds);
+
+
+ size_t getSeconds() const;
+ size_t getMins() const;
+ size_t getHours() const;
+
+ void setSeconds(size_t seconds);
+ void setMins(size_t mins);
+ void setHours(size_t hours);
+
+ void tick();
+
+ int compare(const Time& other) const;
+ Time getDiff(const Time& other) const;
+
+ Time getToMidnight() const;
+ bool isPartyTime() const;//23:00 05;00
+ bool isDinnerTime() const;//19:30 21:30
+
+ void print(bool is12hoursclock) const;
+
+};
+Time::Time(size_t hours, size_t mins, size_t seconds)
+{
+ setHours(hours);
+ setMins(mins);
+ setSeconds(seconds);
+}
+
+Time::Time() : Time(0,0,0)
+{}
+
+Time::Time(size_t seconds)
+{
+ hours = seconds / 3600;
+ seconds %= 3600;
+
+ mins = seconds / 60;
+ seconds %= 60;
+
+ this->seconds = seconds;
+}
+
+
+size_t Time::getSeconds() const
+{
+ return seconds;
+}
+size_t Time::getMins() const
+{
+ return mins;
+}
+size_t Time::getHours() const
+{
+ return hours;
+}
+
+void Time::setSeconds(size_t seconds)
+{
+ if (seconds > 59)
+ seconds = 59;
+ this->seconds = seconds;
+}
+void Time::setMins(size_t mins)
+{
+ if (mins > 59)
+ mins = 59;
+ this->mins = mins;
+}
+void Time::setHours(size_t hours)
+{
+ if (hours > 23)
+ hours = 23;
+ this->hours = hours;
+}
+
+void Time::tick()
+{
+ size_t seconds = convertToSeconds();
+ seconds++;
+ Time newObj(seconds);
+
+ *this = newObj; //копие
+}
+
+int Time::compare(const Time& other) const
+{
+ size_t mySeconds = convertToSeconds();
+ size_t otherSeconds = other.convertToSeconds();
+
+ if (mySeconds > otherSeconds)
+ return 1;
+ else if (mySeconds < otherSeconds)
+ return -1;
+ else
+ return 0;
+}
+Time Time::getDiff(const Time& other) const
+{
+ size_t mySeconds = convertToSeconds();
+ size_t otherSeconds = other.convertToSeconds();
+
+ size_t diff;
+
+ if (mySeconds > otherSeconds)
+ diff = mySeconds - otherSeconds;
+ else
+ diff = otherSeconds - mySeconds;
+
+ return Time(diff);
+}
+
+Time Time::getToMidnight() const
+{
+ Time midnight(23, 59, 59);
+ Time diff = getDiff(midnight);
+ diff.tick();
+ return diff;
+}
+bool Time::isDinnerTime() const
+{
+ Time lowerBound(20, 30, 0);
+ Time upperBound(22, 0, 0);
+ return compare(lowerBound) >= 0 && compare(upperBound) <= 0;
+}
+bool Time::isPartyTime() const
+{
+ Time lowerBound(23, 0, 0);
+ Time upperBound(6, 0, 0);
+ return compare(lowerBound) >= 0 || compare(upperBound) <= 0;
+}
+
+void Time::print(bool is12hoursclock) const
+{
+ if (hours < 10)
+ std::cout << 0;
+ std::cout << ((is12hoursclock && hours > 12) ? hours - 12 : hours) << ":";
+ if (mins < 10)
+ std::cout << 0;
+ std::cout << mins << ":";
+ if (seconds < 10)
+ std::cout << 0;
+ std::cout << seconds;
+ if (is12hoursclock)
+ std::cout << ((hours > 12) ? "PM" : "AM");
+ std::cout << std::endl;
+}
+
+void timeBubbleSort(Time* arr, size_t arrLen)
+{
+ for (int i = 0; i < arrLen; i++)
+ {
+ for (int j = 0; j < arrLen - 1; j++)
+ {
+ if (arr[j].compare(arr[j + 1]) > 0)
+ {
+ Time temp = arr[j];
+ arr[j] = arr[j + 1];
+ arr[j + 1] = temp;
+ }
+ }
+ }
+}
+
+int main()
+{
+ Time times[10] = { Time(11, 30, 0), Time(12, 44, 29), Time(), Time(17, 15, 23), Time(23, 60, 0), Time(3, 14, 15), Time(2, 71, 82), Time(21, 22, 3), Time(17, 15, 23), Time(7, 31, 43) };
+ timeBubbleSort(times, 10);
+ for (int i = 0; i < 10; i++)
+ times[i].print(false);
+}
diff --git a/Year 1/Object-oriented Programming/Solutions Sem. 05/ex2-interval.cpp b/Year 1/Object-oriented Programming/Solutions Sem. 05/ex2-interval.cpp
new file mode 100644
index 0000000..44f26d6
--- /dev/null
+++ b/Year 1/Object-oriented Programming/Solutions Sem. 05/ex2-interval.cpp
@@ -0,0 +1,236 @@
+#include <iostream> // cin, cout
+#include <math.h> // sqrt
+
+/* Generic functions */
+
+bool isPowerOf2(int x)
+{
+ return x > 0 && // No (normal) power of 2 creates negatives or 0
+ (x & (x - 1)) == 0; // Thanks https://stackoverflow.com/a/600306/12036073, original implementation was a lot less efficient
+}
+
+bool isPrime(int num) // Forked from my own implementation - https://gitlab.com/Syndamia/algorithms/-/blob/master/C/IsPrime.c
+{
+ if (num < 0) num *= -1; // This is required, since we calculate sqrt(num)
+
+ if (num == 2 || num == 3 || num == 5 || num == 7 || num == 11 || num == 13)
+ return true;
+
+ // A lot of numbers are divisible by these ones, so we're going to do a bit of simple optimization
+ if (num == 0 || num == 1 || num % 2 == 0 || num % 3 == 0 || num % 5 == 0 || num % 7 == 0 || num % 11 == 0 || num % 13 == 0)
+ return false;
+
+ // All primes follow the formula 6n +- 1 (where n >= 1). Since we've already checked up to 13, we're going to
+ // start with 18 - 1 = 17. Also using root of number to eliminate a lot of checks.
+ // Primary source: https://en.wikipedia.org/wiki/Primality_test#Simple_methods
+ for (int i = 18, root = sqrt(num); i - 1 <= root; i += 6)
+ {
+ if (num % (num - 1) == 0 || num % (num + 1) == 0)
+ return false;
+ }
+ return true;
+}
+
+bool isPalindrome(int num)
+{
+ if (num < 0)
+ return false;
+
+ int buff = 0, tNum = num;
+ while (tNum != 0)
+ {
+ buff = buff * 10 + (tNum % 10);
+ tNum /= 10;
+ }
+ return buff == num;
+}
+
+bool hasRepeatingDigits(int num)
+{
+ if (num < 0) num *= -1; // if num is negative, num % 10 will also be negative, which mustn't happen
+
+ bool digitOccur[] = { false, false, false, false, false, false, false, false, false, false };
+ while (num != 0)
+ {
+ if (digitOccur[num % 10])
+ return false;
+ digitOccur[num % 10] = true;
+ num /= 10;
+ }
+ return true;
+}
+
+bool hasNotRepeatingDigits(int num)
+{
+ return !hasRepeatingDigits(num);
+}
+
+/* Class Interval */
+
+class Interval
+{
+ int a;
+ int b;
+
+ // "Caches" for the heavy operations
+ int primeNumbersCount;
+ int palindromeNumbersCount;
+ int nonRepeatingDigitsNumbersCount;
+ bool edgesPowersOf2;
+
+ int counter(bool (comparator)(int)) const
+ {
+ int count = 0;
+ for (int i = a; i <= b; i++)
+ {
+ if (comparator(i))
+ count++;
+ }
+ return count;
+ }
+
+ void calculateCounts()
+ {
+ this->primeNumbersCount = counter(isPrime);
+ this->palindromeNumbersCount = counter(isPalindrome);
+ this->nonRepeatingDigitsNumbersCount = counter(hasNotRepeatingDigits);
+ }
+
+public:
+ Interval();
+ Interval(int a, int b);
+
+ int get_a() const;
+ void set_a(int a);
+
+ int get_b() const;
+ void set_b(int b);
+
+ int getLen() const;
+ bool hasInInterval(int x) const;
+
+ // The operations for each one are "heavy" so we calculated them on interval
+ // edges set and return the "cached" value
+ int primesCount() const;
+ int palindromesCount() const;
+ int nonRepeatingDigitsCount() const;
+ bool edgesArePowersOf2() const;
+
+ Interval intersect(const Interval& inter) const;
+ bool isSupInterval(const Interval& inter) const;
+};
+
+Interval::Interval() : Interval(0, 0)
+{}
+Interval::Interval(int a, int b)
+{
+ if (a > b) a = b = 0;
+
+ this->edgesPowersOf2 = isPowerOf2(a) && isPowerOf2(b);
+ this->a = a; // We can't use setter here, since it will try to calculate the counts, and we don't want to do that yet.
+ this->set_b(b);
+}
+
+int Interval::get_a() const
+{
+ return this->a;
+}
+void Interval::set_a(int a)
+{
+ this->a = a;
+ if (a > b) this->b = a; // Note: behaviour not defined in task
+
+ this->calculateCounts();
+ this->edgesPowersOf2 &= isPowerOf2(a);
+}
+
+int Interval::get_b() const
+{
+ return this->b;
+}
+void Interval::set_b(int b)
+{
+ this->b = b;
+ if (b < a) this->a = b; // Note: behaviour not defined in task
+
+ this->calculateCounts();
+ this->edgesPowersOf2 &= isPowerOf2(b);
+}
+
+int Interval::getLen() const
+{
+ return this->get_a() - this->get_b();
+}
+bool Interval::hasInInterval(int x) const
+{
+ return this->get_a() <= x && x <= this->get_b();
+}
+
+int Interval::primesCount() const
+{
+ return this->primeNumbersCount;
+}
+int Interval::palindromesCount() const
+{
+ return this->palindromeNumbersCount;
+}
+int Interval::nonRepeatingDigitsCount() const
+{
+ return this->nonRepeatingDigitsNumbersCount;
+}
+bool Interval::edgesArePowersOf2() const
+{
+ return this->edgesPowersOf2;
+}
+
+Interval Interval::intersect(const Interval& inter) const
+{
+ // [ ] { } or { } [ ] where [] is this, {} is inter
+ if (this->b < inter.get_a() || this->a > inter.get_b())
+ return Interval();
+
+ // [ { ] } where [] is this, {} is inter
+ if (this->a <= inter.get_a())
+ return Interval(inter.a, this->b);
+ // { [ } ] where [] is this, {} is inter
+ else
+ return Interval(this->a, inter.b);
+}
+bool Interval::isSupInterval(const Interval& inter) const
+{
+ return this->a >= inter.a && inter.b <= this->b;
+}
+
+/* Main */
+
+void printInter(const Interval& inter)
+{
+ std::cout << "[" << inter.get_a() << "," << inter.get_b() << "]" << std::endl;
+}
+
+int main()
+{
+ /* Стойчо ни беше направил документ за unit тестове, но имайки предвид, че формално ги няма в задачата, не съм правил */
+
+ Interval t1(3, 10), t2(4, 14), t3;
+ printInter(t1);
+ printInter(t2);
+ printInter(t3);
+
+ Interval intT1T2 = t1.intersect(t2);
+ printInter(intT1T2); // [4,10]
+
+ std::cout << t2.isSupInterval(intT1T2) << std::endl; // true
+ std::cout << intT1T2.primesCount() << std::endl; // 2 (5 and 7)
+ std::cout << t2.hasInInterval(14) << " " << t2.hasInInterval(15) << std::endl; // "1 0"
+
+ Interval t4(0, 100), t5(-100, 0);
+ std::cout << "Pal: " << t4.palindromesCount() << " " << t5.palindromesCount() << std::endl; // "19 1" (negatives arent palindromes)
+ std::cout << "Primes: " << t4.primesCount() << " " << t5.primesCount() << std::endl; // "25 25"
+ std::cout << "Non repeat: " << t4.nonRepeatingDigitsCount() << " " << t5.nonRepeatingDigitsCount() << std::endl; // "10 10"
+
+ std::cout << t5.hasInInterval(-99) << t5.hasInInterval(0) << t5.hasInInterval(1) << std::endl; // "110"
+
+ Interval t6(256, 1024), t7(-1024, -256);
+ std::cout << "Two Power Ends: " << t4.edgesArePowersOf2() << " " << t5.edgesArePowersOf2() << " " << t6.edgesArePowersOf2() << " " << t7.edgesArePowersOf2() << std::endl; // "0 0 1 0"
+}