diff --git a/BigInt.cpp b/BigInt.cpp new file mode 100644 index 0000000..b9299ee --- /dev/null +++ b/BigInt.cpp @@ -0,0 +1,368 @@ +#include "BigInt.h" + +BigInt::BigInt(std::string & s){ + digits = ""; + int n = s.size(); + for (int i = n - 1; i >= 0;i--){ + if(!isdigit(s[i])) + throw("ERROR"); + digits.push_back(s[i] - '0'); + } +} +BigInt::BigInt(unsigned long long nr){ + do{ + digits.push_back(nr % 10); + nr /= 10; + } while (nr); +} +BigInt::BigInt(const char *s){ + digits = ""; + for (int i = strlen(s) - 1; i >= 0;i--) + { + if(!isdigit(s[i])) + throw("ERROR"); + digits.push_back(s[i] - '0'); + } +} +BigInt::BigInt(BigInt & a){ + digits = a.digits; +} + +bool Null(const BigInt& a){ + if(a.digits.size() == 1 && a.digits[0] == 0) + return true; + return false; +} +int Length(const BigInt & a){ + return a.digits.size(); +} +int BigInt::operator[](const int index)const{ + if(digits.size() <= index || index < 0) + throw("ERROR"); + return digits[index]; +} +bool operator==(const BigInt &a, const BigInt &b){ + return a.digits == b.digits; +} +bool operator!=(const BigInt & a,const BigInt &b){ + return !(a == b); +} +bool operator<(const BigInt&a,const BigInt&b){ + int n = Length(a), m = Length(b); + if(n != m) + return n < m; + while(n--) + if(a.digits[n] != b.digits[n]) + return a.digits[n] < b.digits[n]; + return false; +} +bool operator>(const BigInt&a,const BigInt&b){ + return b < a; +} +bool operator>=(const BigInt&a,const BigInt&b){ + return !(a < b); +} +bool operator<=(const BigInt&a,const BigInt&b){ + return !(a > b); +} + +BigInt &BigInt::operator=(const BigInt &a){ + digits = a.digits; + return *this; +} + +BigInt &BigInt::operator++(){ + int i, n = digits.size(); + for (i = 0; i < n && digits[i] == 9;i++) + digits[i] = 0; + if(i == n) + digits.push_back(1); + else + digits[i]++; + return *this; +} +BigInt BigInt::operator++(int temp){ + BigInt aux; + aux = *this; + ++(*this); + return aux; +} + +BigInt &BigInt::operator--(){ + if(digits[0] == 0 && digits.size() == 1) + throw("UNDERFLOW"); + int i, n = digits.size(); + for (i = 0; digits[i] == 0 && i < n;i++) + digits[i] = 9; + digits[i]--; + if(n > 1 && digits[n - 1] == 0) + digits.pop_back(); + return *this; +} +BigInt BigInt::operator--(int temp){ + BigInt aux; + aux = *this; + --(*this); + return aux; +} + +BigInt &operator+=(BigInt &a,const BigInt& b){ + int t = 0, s, i; + int n = Length(a), m = Length(b); + if(m > n) + a.digits.append(m - n, 0); + n = Length(a); + for (i = 0; i < n;i++){ + if(i < m) + s = (a.digits[i] + b.digits[i]) + t; + else + s = a.digits[i] + t; + t = s / 10; + a.digits[i] = (s % 10); + } + if(t) + a.digits.push_back(t); + return a; +} +BigInt operator+(const BigInt &a, const BigInt &b){ + BigInt temp; + temp = a; + temp += b; + return temp; +} + +BigInt &operator-=(BigInt&a,const BigInt &b){ + if(a < b) + throw("UNDERFLOW"); + int n = Length(a), m = Length(b); + int i, t = 0, s; + for (i = 0; i < n;i++){ + if(i < m) + s = a.digits[i] - b.digits[i]+ t; + else + s = a.digits[i]+ t; + if(s < 0) + s += 10, + t = -1; + else + t = 0; + a.digits[i] = s; + } + while(n > 1 && a.digits[n - 1] == 0) + a.digits.pop_back(), + n--; + return a; +} +BigInt operator-(const BigInt& a,const BigInt&b){ + BigInt temp; + temp = a; + temp -= b; + return temp; +} + +BigInt &operator*=(BigInt &a, const BigInt &b) +{ + if(Null(a) || Null(b)){ + a = BigInt(); + return a; + } + int n = a.digits.size(), m = b.digits.size(); + std::vector v(n + m, 0); + for (int i = 0; i < n;i++) + for (int j = 0; j < m;j++){ + v[i + j] += (a.digits[i] ) * (b.digits[j]); + } + n += m; + a.digits.resize(v.size()); + for (int s, i = 0, t = 0; i < n; i++) + { + s = t + v[i]; + v[i] = s % 10; + t = s / 10; + a.digits[i] = v[i] ; + } + for (int i = n - 1; i >= 1 && !v[i];i--) + a.digits.pop_back(); + return a; +} +BigInt operator*(const BigInt&a,const BigInt&b){ + BigInt temp; + temp = a; + temp *= b; + return temp; +} + +BigInt &operator/=(BigInt& a,const BigInt &b){ + if(Null(b)) + throw("Arithmetic Error: Division By 0"); + if(a < b){ + a = BigInt(); + return a; + } + if(a == b){ + a = BigInt(1); + return a; + } + int i, lgcat = 0, cc; + int n = Length(a), m = Length(b); + std::vector cat(n, 0); + BigInt t; + for (i = n - 1; t * 10 + a.digits[i] < b;i--){ + t *= 10; + t += a.digits[i] ; + } + for (; i >= 0; i--){ + t = t * 10 + a.digits[i]; + for (cc = 9; cc * b > t;cc--); + t -= cc * b; + cat[lgcat++] = cc; + } + a.digits.resize(cat.size()); + for (i = 0; i < lgcat;i++) + a.digits[i] = cat[lgcat - i - 1]; + a.digits.resize(lgcat); + return a; +} +BigInt operator/(const BigInt &a,const BigInt &b){ + BigInt temp; + temp = a; + temp /= b; + return temp; +} + +BigInt &operator%=(BigInt& a,const BigInt &b){ + if(Null(b)) + throw("Arithmetic Error: Division By 0"); + if(a < b){ + a = BigInt(); + return a; + } + if(a == b){ + a = BigInt(1); + return a; + } + int i, lgcat = 0, cc; + int n = Length(a), m = Length(b); + std::vector cat(n, 0); + BigInt t; + for (i = n - 1; t * 10 + a.digits[i] < b;i--){ + t *= 10; + t += a.digits[i]; + } + for (; i >= 0; i--){ + t = t * 10 + a.digits[i]; + for (cc = 9; cc * b > t;cc--); + t -= cc * b; + cat[lgcat++] = cc; + } + a = t; + return a; +} +BigInt operator%(const BigInt &a,BigInt &b){ + BigInt temp; + temp = a; + temp %= b; + return temp; +} + +BigInt &operator^=(BigInt & a,const BigInt & b){ + BigInt Exponent, Base(a); + Exponent = b; + a = 1; + while(!Null(Exponent)){ + if(Exponent[0] & 1) + a *= Base; + Base *= Base; + divide_by_2(Exponent); + } + return a; +} +BigInt operator^(BigInt & a,BigInt & b){ + BigInt temp(a); + temp ^= b; + return temp; +} + +void divide_by_2(BigInt & a){ + int add = 0; + for (int i = a.digits.size() - 1; i >= 0;i--){ + int digit = (a.digits[i] >> 1) + add; + add = ((a.digits[i] & 1) * 5); + a.digits[i] = digit; + } + while(a.digits.size() > 1 && !a.digits.back()) + a.digits.pop_back(); +} + +BigInt sqrt(BigInt & a){ + BigInt left(1), right(a), v(1), mid, prod; + divide_by_2(right); + while(left <= right){ + mid += left; + mid += right; + divide_by_2(mid); + prod = (mid * mid); + if(prod <= a){ + v = mid; + ++mid; + left = mid; + } + else{ + --mid; + right = mid; + } + mid = BigInt(); + } + return v; +} + +BigInt NthCatalan(int n){ + BigInt a(1),b; + for (int i = 2; i <= n;i++) + a *= i; + b = a; + for (int i = n + 1; i <= 2 * n;i++) + b *= i; + a *= a; + a *= (n + 1); + b /= a; + return b; +} + +BigInt NthFibonacci(int n){ + BigInt a(1), b(1), c; + if(!n) + return c; + n--; + while(n--){ + c = a + b; + b = a; + a = c; + } + return b; +} + +BigInt Factorial(int n){ + BigInt f(1); + for (int i = 2; i <= n;i++) + f *= i; + return f; +} + +std::istream &operator>>(std::istream &in,BigInt&a){ + std::string s; + in >> s; + int n = s.size(); + for (int i = n - 1; i >= 0;i--){ + if(!isdigit(s[i])) + throw("INVALID NUMBER"); + a.digits[n - i - 1] = s[i]; + } + return in; +} + +std::ostream &operator<<(std::ostream &out,const BigInt &a){ + for (int i = a.digits.size() - 1; i >= 0;i--) + std::cout << (short)a.digits[i]; + return std::cout; +} \ No newline at end of file diff --git a/BigInt.h b/BigInt.h new file mode 100644 index 0000000..72d6369 --- /dev/null +++ b/BigInt.h @@ -0,0 +1,70 @@ +#include "pixelGameEngine.h" + +class BigInt{ + std::string digits; +public: + + //Constructors: + BigInt(unsigned long long n = 0); + BigInt(std::string &); + BigInt(const char *); + BigInt(BigInt &); + + //Helper Functions: + friend void divide_by_2(BigInt &a); + friend bool Null(const BigInt &); + friend int Length(const BigInt &); + int operator[](const int)const; + + /* * * * Operator Overloading * * * */ + + //Direct assignment + BigInt &operator=(const BigInt &); + + //Post/Pre - Incrementation + BigInt &operator++(); + BigInt operator++(int temp); + BigInt &operator--(); + BigInt operator--(int temp); + + //Addition and Subtraction + friend BigInt &operator+=(BigInt &, const BigInt &); + friend BigInt operator+(const BigInt &, const BigInt &); + friend BigInt operator-(const BigInt &, const BigInt &); + friend BigInt &operator-=(BigInt &, const BigInt &); + + //Comparison operators + friend bool operator==(const BigInt &, const BigInt &); + friend bool operator!=(const BigInt &, const BigInt &); + + friend bool operator>(const BigInt &, const BigInt &); + friend bool operator>=(const BigInt &, const BigInt &); + friend bool operator<(const BigInt &, const BigInt &); + friend bool operator<=(const BigInt &, const BigInt &); + + //Multiplication and Division + friend BigInt &operator*=(BigInt &, const BigInt &); + friend BigInt operator*(const BigInt &, const BigInt &); + friend BigInt &operator/=(BigInt &, const BigInt &); + friend BigInt operator/(const BigInt &, const BigInt &); + + //Modulo + friend BigInt operator%(const BigInt &, const BigInt &); + friend BigInt &operator%=(BigInt &, const BigInt &); + + //Power Function + friend BigInt &operator^=(BigInt &,const BigInt &); + friend BigInt operator^(BigInt &, const BigInt &); + + //Square Root Function + friend BigInt sqrt(BigInt &a); + + //Read and Write + friend std::ostream &operator<<(std::ostream &,const BigInt &); + friend std::istream &operator>>(std::istream &, BigInt &); + + //Others + friend BigInt NthCatalan(int n); + friend BigInt NthFibonacci(int n); + friend BigInt Factorial(int n); +}; \ No newline at end of file diff --git a/C++ProjectTemplate b/C++ProjectTemplate index c1aa29d..c747ac0 100755 Binary files a/C++ProjectTemplate and b/C++ProjectTemplate differ diff --git a/input b/input new file mode 100644 index 0000000..6085097 --- /dev/null +++ b/input @@ -0,0 +1,55 @@ +Monkey 0: + Starting items: 89, 95, 92, 64, 87, 68 + Operation: new = old * 11 + Test: divisible by 2 + If true: throw to monkey 7 + If false: throw to monkey 4 + +Monkey 1: + Starting items: 87, 67 + Operation: new = old + 1 + Test: divisible by 13 + If true: throw to monkey 3 + If false: throw to monkey 6 + +Monkey 2: + Starting items: 95, 79, 92, 82, 60 + Operation: new = old + 6 + Test: divisible by 3 + If true: throw to monkey 1 + If false: throw to monkey 6 + +Monkey 3: + Starting items: 67, 97, 56 + Operation: new = old * old + Test: divisible by 17 + If true: throw to monkey 7 + If false: throw to monkey 0 + +Monkey 4: + Starting items: 80, 68, 87, 94, 61, 59, 50, 68 + Operation: new = old * 7 + Test: divisible by 19 + If true: throw to monkey 5 + If false: throw to monkey 2 + +Monkey 5: + Starting items: 73, 51, 76, 59 + Operation: new = old + 8 + Test: divisible by 7 + If true: throw to monkey 2 + If false: throw to monkey 1 + +Monkey 6: + Starting items: 92 + Operation: new = old + 5 + Test: divisible by 11 + If true: throw to monkey 3 + If false: throw to monkey 0 + +Monkey 7: + Starting items: 99, 76, 78, 76, 79, 90, 89 + Operation: new = old + 7 + Test: divisible by 5 + If true: throw to monkey 4 + If false: throw to monkey 5 diff --git a/main.cpp b/main.cpp index 8ab7e53..88f303b 100644 --- a/main.cpp +++ b/main.cpp @@ -1,89 +1,80 @@ #define OLC_PGE_APPLICATION #include "pixelGameEngine.h" #include "olcutils.h" +#include "BigInt.h" using namespace olc; +// C++ program to implement +// the above approach + +struct Monkey{ + std::vector items; + char operation; + int operation_amt; + int divisible; + int trueThrow; + int falseThrow; + int inspAmt; +}; -class Example : public olc::PixelGameEngine +int main() { -public: - Example() - { - sAppName = "Example"; - } - -public: - bool RayVsRect(const vf2d ray_origin, const vf2d ray_dir, const olc::utils::geom2d::rect target, vf2d&contact_point, vf2d&contact_normal, float&t_hit_near){ - - contact_normal = { 0, 0 }; - contact_point = { 0, 0 }; - - vf2d t_near = {(target.pos.x - ray_origin.x) / ray_dir.x, (target.pos.y - ray_origin.y) / ray_dir.y}; - vf2d t_far = {(target.pos.x + target.size.x - ray_origin.x) / ray_dir.x, (target.pos.y + target.size.y - ray_origin.y) / ray_dir.y}; - - if (t_near.x > t_far.x) {float b; b = t_near.x; t_near.x = t_far.x; t_far.x = b;}; - if (t_near.y > t_far.y) {float b; b = t_near.y; t_near.y = t_far.y; t_far.y = b;}; - - if (t_near.x > t_far.y || t_near.y > t_far.x) return false; - - t_hit_near = fmax(t_near.x, t_near.y); - float t_hit_far = fmin(t_far.x, t_far.y); - - if (t_hit_far < 0) return false; - - contact_point.x = ray_origin.x + t_hit_near * ray_dir.x; - contact_point.y = ray_origin.y + t_hit_near * ray_dir.y; - - if (t_near.x > t_near.y) - if ( 1.0f / ray_dir.x < 0) - contact_normal = { 1, 0 }; - else - contact_normal = { -1, 0}; - else - if ( t_near.x < t_near.y) - if ( 1.0f / ray_dir.y < 0) - contact_normal = { 0, 1 }; - else - contact_normal = { 0, -1 }; - - return true; - - - } - vf2d originPoint={16,16}; - bool OnUserCreate() override - { - // Called once at the start, so create things here - return true; - } - - bool OnUserUpdate(float fElapsedTime) override - { - vf2d velocity={(GetKey(D).bHeld-GetKey(A).bHeld)*20*fElapsedTime,(GetKey(S).bHeld-GetKey(W).bHeld)*20*fElapsedTime}; - vf2d contact_point; - vf2d contact_normal; - float t_hit_near; - - Clear(Pixel(64,64,255)); - if (!olc::utils::geom2d::overlaps(olc::utils::geom2d::circle{originPoint+velocity,5},olc::utils::geom2d::rect{{32,32},{64,32}})) { - originPoint+=velocity; - DrawCircle(originPoint,5); - } else { - DrawCircle(originPoint,5,RED); + std::vector monkeys; + std::ifstream file("input"); + + monkeys.push_back({{89,95,92,64,87,68},'*',11,2,7,4}); + monkeys.push_back({{87,67},'+',1,13,3,6}); + monkeys.push_back({{95, 79, 92, 82, 60},'+',6,3,1,6}); + monkeys.push_back({{67, 97, 56},'*',-1,17,7,0}); + monkeys.push_back({{80, 68, 87, 94, 61, 59, 50, 68},'*',7,19,5,2}); + monkeys.push_back({{73, 51, 76, 59},'+',8,7,2,1}); + monkeys.push_back({{92},'+',5,11,3,0}); + monkeys.push_back({{99, 76, 78, 76, 79, 90, 89},'+',7,5,4,5}); + + for (int round=0;round<10000;round++){ + for (int i=0;i{{32,32},{64,32}},contact_point,contact_normal,t_hit_near)&&t_hit_near<1?YELLOW:WHITE); - return true; - } -}; + } + std::sort(monkeys.begin(),monkeys.end(),[](Monkey&first,Monkey&second){return second.inspAmt