Skip to content

Instantly share code, notes, and snippets.

@Animesh-Ghosh
Created November 20, 2020 18:15
Show Gist options
  • Select an option

  • Save Animesh-Ghosh/a997a13018e1703fdb34bd44d6b440a4 to your computer and use it in GitHub Desktop.

Select an option

Save Animesh-Ghosh/a997a13018e1703fdb34bd44d6b440a4 to your computer and use it in GitHub Desktop.
BigInt XD
#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