Created
May 6, 2023 10:13
-
-
Save kLiHz/65215e3dc865ba3be746cd6167e3ce19 to your computer and use it in GitHub Desktop.
This file contains 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 <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