Created
November 20, 2020 18:15
-
-
Save Animesh-Ghosh/a997a13018e1703fdb34bd44d6b440a4 to your computer and use it in GitHub Desktop.
BigInt XD
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <bits/stdc++.h> | |
| using namespace std; | |
| ostream& operator<<(ostream& os, const vector<int>& v) { | |
| for (const int& x : v) { | |
| os << x; | |
| } | |
| return os; | |
| } | |
| vector<int> vectorize(int x) { | |
| if (x == 0) return vector<int>{0}; | |
| vector<int> result; | |
| while (x > 0) { | |
| result.insert(result.begin(), x % 10); | |
| x /= 10; | |
| } | |
| return result; | |
| } | |
| vector<int> add(const vector<int>& x, const vector<int>& y) { | |
| vector<int> sum; | |
| vector<int> larger, smaller; | |
| if (x.size() > y.size()) { | |
| larger = x; | |
| smaller = y; | |
| } else { | |
| larger = y; | |
| smaller = x; | |
| } | |
| // std::cout << "Smaller: " << smaller << endl; | |
| // std::cout << "Larger: " << larger << endl; | |
| while (smaller.size() < larger.size()) { | |
| smaller.insert(smaller.begin(), 0); | |
| } | |
| // std::cout << "Smaller: " << smaller << endl; | |
| // std::cout << "Larger: " << larger << endl; | |
| int carry = 0; | |
| for ( | |
| auto lritr = larger.rbegin(), sritr = smaller.rbegin(); | |
| lritr != larger.rend() && sritr != smaller.rend(); | |
| ++lritr, ++sritr | |
| ) { | |
| int sum_ = *lritr + *sritr + carry; | |
| carry = sum_ / 10; | |
| sum_ %= 10; | |
| sum.insert(sum.begin(), sum_); | |
| } | |
| if (carry > 0) { | |
| sum.insert(sum.begin(), carry); | |
| } | |
| return sum; | |
| } | |
| vector<int> trim_leading_zeroes(vector<int>& v) { | |
| while (*v.begin() == 0) { | |
| v.erase(v.begin()); | |
| } | |
| return v; | |
| } | |
| // x is larger than y | |
| vector<int> subtract(const vector<int>& x, const vector<int>& y) { | |
| vector<int> difference; | |
| vector<int> minuend = x, subtrahend = y; | |
| while (subtrahend.size() < minuend.size()) { | |
| subtrahend.insert(subtrahend.begin(), 0); | |
| } | |
| // std::cout << "minuend: " << minuend << endl; | |
| // std::cout << "subtrahend: " << subtrahend << endl; | |
| int carry; | |
| for ( | |
| auto mritr = minuend.rbegin(), sritr = subtrahend.rbegin(); | |
| mritr != minuend.rend() && sritr != subtrahend.rend(); | |
| ++mritr, ++sritr | |
| ) { | |
| if (*mritr < *sritr) { | |
| carry = 10; | |
| --*next(mritr, 1); | |
| } else { | |
| carry = 0; | |
| } | |
| int difference_ = carry + *mritr - *sritr; | |
| difference.insert(difference.begin(), difference_); | |
| } | |
| if (difference.size() > 1) { | |
| difference = trim_leading_zeroes(difference); | |
| } | |
| return difference; | |
| } | |
| vector<int> multiply(const vector<int>& x, const vector<int>& y) { | |
| vector<int> product; | |
| vector<vector<int>> intermediate_products; | |
| int power = -1; | |
| for (auto yitr = y.rbegin(); yitr != y.rend(); ++yitr) { | |
| int carry = 0; | |
| vector<int> intermediate_product; | |
| for (auto xitr = x.rbegin(); xitr != x.rend(); ++xitr) { | |
| // cout << "Multiplying " << *yitr << " and " << *xitr << ".\n"; | |
| int result = (*yitr) * (*xitr) + carry; | |
| carry = result / 10; | |
| result %= 10; | |
| intermediate_product.insert(intermediate_product.begin(), result); | |
| } | |
| ++power; | |
| for (int i = 0; i < power; ++i) { | |
| intermediate_product.push_back(0); | |
| } | |
| if (carry > 0) { | |
| intermediate_product.insert(intermediate_product.begin(), carry); | |
| } | |
| intermediate_products.push_back(intermediate_product); | |
| } | |
| vector<int> accumulated_sum{0}; | |
| for (const vector<int>& intermediate_product : intermediate_products) { | |
| accumulated_sum = add(accumulated_sum, intermediate_product); | |
| // cout << intermediate_product << '\n'; | |
| } | |
| product = accumulated_sum; | |
| return product; | |
| } | |
| bool operator>(const vector<int>& x, const vector<int>& y) { | |
| bool is_greater = true; | |
| if (x.size() < y.size()) { | |
| is_greater = false; | |
| } | |
| if (x.size() == y.size()) { | |
| for ( | |
| auto it = x.begin(), nit = y.begin(); | |
| it != x.end() && nit != y.end(); | |
| ++it, ++nit | |
| ) { | |
| if (*it <= *nit) { | |
| is_greater = false; | |
| break; | |
| } | |
| } | |
| } | |
| return is_greater; | |
| } | |
| class BigInteger { | |
| private: | |
| vector<int> bigInteger; | |
| public: | |
| BigInteger(); | |
| BigInteger(int n); | |
| BigInteger operator=(int n); | |
| BigInteger operator+(const BigInteger& bi); | |
| BigInteger operator*(const BigInteger& bi); | |
| BigInteger operator*=(const BigInteger& bi); | |
| bool operator>(int n); | |
| BigInteger operator--(); | |
| friend ostream& operator<<(ostream& os, const BigInteger& bi); | |
| }; | |
| BigInteger::BigInteger() { | |
| BigInteger(0); | |
| } | |
| BigInteger::BigInteger(int n) { | |
| bigInteger = vectorize(n); | |
| // std::cout << this->bigInteger << '\n'; | |
| } | |
| BigInteger BigInteger::operator=(int n) { | |
| BigInteger bi(n); | |
| return bi; | |
| } | |
| bool BigInteger::operator>(int n) { | |
| BigInteger number = n; | |
| return this->bigInteger > number.bigInteger; | |
| } | |
| BigInteger BigInteger::operator+(const BigInteger& bi) { | |
| BigInteger result; | |
| result.bigInteger = add(this->bigInteger, bi.bigInteger); | |
| return result; | |
| } | |
| BigInteger BigInteger::operator*(const BigInteger& bi) { | |
| BigInteger result; | |
| result.bigInteger = multiply(this->bigInteger, bi.bigInteger); | |
| return result; | |
| } | |
| BigInteger BigInteger::operator*=(const BigInteger& bi) { | |
| BigInteger result = *this * bi; | |
| *this = result; | |
| return result; | |
| } | |
| BigInteger BigInteger::operator--() { | |
| this->bigInteger = subtract(this->bigInteger, vectorize(1)); | |
| return *this; | |
| } | |
| ostream& operator<<(ostream& os, const BigInteger& bi) { | |
| os << bi.bigInteger; | |
| return os; | |
| } | |
| void factorial(const unsigned long long& n) { | |
| unsigned long long factorial = 1, number = n; | |
| while (number > 0ull) { | |
| factorial *= number; | |
| --number; | |
| } | |
| std::cout << factorial << endl; | |
| } | |
| void extraLongFactorials(int n) { | |
| BigInteger factorial = 1; | |
| BigInteger number = n; | |
| while (number > 0) { | |
| BigInteger result = factorial * number; | |
| // std::cout << factorial << " * " << number << " = " << result << '\n'; | |
| factorial = result; | |
| --number; | |
| } | |
| cout << factorial << '\n'; | |
| } | |
| int main() { | |
| int n; | |
| std::cin >> n; | |
| extraLongFactorials(n); | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment