Part 1 done

Co-authored-by: sigonasr2 <sigonasr2@gmail.com>
master
sigonasr2 2 years ago
parent 50d0a0fa27
commit 6552fb154b
  1. 368
      BigInt.cpp
  2. 70
      BigInt.h
  3. BIN
      C++ProjectTemplate
  4. 55
      input
  5. 143
      main.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<int> 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<int> 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<int> 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;
}

@ -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);
};

Binary file not shown.

55
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

@ -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<BigInt> 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<float> 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<float>{originPoint+velocity,5},olc::utils::geom2d::rect<float>{{32,32},{64,32}})) {
originPoint+=velocity;
DrawCircle(originPoint,5);
} else {
DrawCircle(originPoint,5,RED);
std::vector<Monkey> 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<monkeys.size();i++){
Monkey&m=monkeys[i];
m.inspAmt+=m.items.size();
for (int j=0;j<m.items.size();j++){
BigInt worryLevel=m.items[j];
std::cout<<worryLevel<<std::endl;
if (m.operation=='+'){
if (m.operation_amt!=-1){
worryLevel+=m.operation_amt;
} else {
worryLevel*=2;
}
} else {
if (m.operation_amt!=-1){
worryLevel*=m.operation_amt;
} else {
worryLevel*=worryLevel;
}
}
//worryLevel/=3;
BigInt zero{"0"};
if (worryLevel%m.divisible==zero){
Monkey&newMonkey=monkeys[m.trueThrow];
newMonkey.items.push_back(worryLevel);
m.items.erase(m.items.begin());
j--;
} else {
Monkey&newMonkey=monkeys[m.falseThrow];
newMonkey.items.push_back(worryLevel);
m.items.erase(m.items.begin());
j--;
}
}
}
DrawLine(originPoint,GetMousePos());
DrawRect({32,32},{64,32},RayVsRect(originPoint, GetMousePos()-originPoint, olc::utils::geom2d::rect<float>{{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<first.inspAmt;});
for (int i=0;i<monkeys.size();i++){
Monkey&m=monkeys[i];
std::cout<<"Monkey "<<i<<": "<<m.inspAmt<<" inspections"<<std::endl;
}
int main()
{
Example demo;
if (demo.Construct(128, 120, 8, 8))
demo.Start();
std::cout<<(monkeys[0].inspAmt*monkeys[1].inspAmt)<<std::endl;
return 0;
}

Loading…
Cancel
Save