Skip to content

Instantly share code, notes, and snippets.

@kLiHz
Created May 6, 2023 10:13
Show Gist options
  • Save kLiHz/65215e3dc865ba3be746cd6167e3ce19 to your computer and use it in GitHub Desktop.
Save kLiHz/65215e3dc865ba3be746cd6167e3ce19 to your computer and use it in GitHub Desktop.
#include <algorithm>
#include <string>
#include <iostream>
template<typename IntType>
class fraction {
IntType A;
IntType B;
public:
static IntType gcd(IntType x, IntType y) {
do {
x %= y;
std::swap(x, y);
} while (y);
return x;
}
static IntType lcm(IntType a, IntType b) {
if (a == 0 || b == 0) return 0;
a /= gcd(a, b);
return a * b;
}
fraction(IntType a, IntType b) : A(a), B(b) {}
fraction & reduce() {
bool negative = false;
if (this->A == 0) { this->B = 1; return *this; }
if ((this->A < 0 && this->B > 0) || (this->A > 0 && this->B < 0)) negative = true; // A*B < 0
this->A = std::abs(this->A);
this->B = std::abs(this->B);
auto d = gcd(this->A, this->B);
this->A /= d;
this->B /= d;
if (negative) this->A = -(this->A);
return *this;
}
fraction& add(const fraction & other) {
if (this->B == other.B) { this->A += other.A; }
else if (other.B == 1) { this->A += (other.A * this->B); }
else {
auto lcm_of_denominators = lcm(B, other.B);
auto multiplier_for_this = lcm_of_denominators / B;
auto multiplier_for_other = lcm_of_denominators / other.B;
this->A *= multiplier_for_this;
this->B *= multiplier_for_this;
A += multiplier_for_other * other.A;
this->reduce();
}
return *this;
}
fraction operator+(const fraction & other) const {
return fraction(this->A, this->B).add(other);
}
bool operator==(const fraction & other) const { return this->A * other.B == this->B * other.A; }
bool operator< (IntType val) const { return A < val * this->B; }
bool operator> (IntType val) const { return A > val * this->B; }
bool is_int() const {
auto a = std::abs(A);
return a == 0 || (a >= B && a % B == 0);
}
std::string to_string() const {
std::string str;
if ( *this < static_cast<IntType>(0) ) str += "-";
if ( this->is_int() ) {
str += std::to_string( std::abs(this->A) / this->B );
} else {
str += std::to_string( std::abs(this->A) );
str += "/";
str += std::to_string( this->B );
}
return str;
}
};
template <typename IntType>
std::ostream & operator<<(std::ostream & stream, const fraction<IntType> & f)
{
stream << f.to_string();
return stream;
}
int main() {
std::string s = "123456789";
do {
if (s[3-1] == '0' || s[6-1] == '0' || s[9-1] == '0' || s[0] == '0' || s[3] == '0' || s[6] == '0') {
continue;
}
auto adder = fraction(std::stoi(s.substr(0, 2)), s[2] - '0');
auto added = fraction(std::stoi(s.substr(3, 2)), s[5] - '0');
auto sum = fraction(std::stoi(s.substr(6, 2)), s[8] - '0');
if (adder + added == sum) {
std::cout << adder << " + " << added << " = " << sum << "\t("
<< s.substr(0, 2) + "/" + s[2]
<< " + "
<< s.substr(3, 2) + "/" + s[5]
<< " = "
<< s.substr(6, 2) + "/" + s[8] << ")\n";
}
}
while (std::next_permutation(s.begin(), s.end()));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment