diff options
Added solutions for oop seminar 5
2 files changed, 428 insertions, 0 deletions
| -rw-r--r-- | Year 1/Object-oriented Programming/Solutions Sem. 05/ex1-time.cpp | 192 | ||||
| -rw-r--r-- | Year 1/Object-oriented Programming/Solutions Sem. 05/ex2-interval.cpp | 236 |
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" +} |
