Skip to content

Instantly share code, notes, and snippets.

@shukob
Last active December 18, 2015 03:39
Show Gist options
  • Save shukob/5719839 to your computer and use it in GitHub Desktop.
Save shukob/5719839 to your computer and use it in GitHub Desktop.
C++: Simple 1d equation solver
#include <cstdio>
#include <string>
#include <sstream>
template<typename T>
class Fraction{
public:
typedef T number_type;
Fraction():
_numerator(0),
_denominator(0),
_requiresStringification(false),
_stringified(){
}
Fraction(T numerator, T denominator = 1):
_numerator(numerator),
_denominator(denominator),
_requiresStringification(true),
_stringified(){
reduce();
}
std::string to_s(){
if(_requiresStringification){
stringify();
_requiresStringification = false;
}
return _stringified;
}
void setNumerator(T numerator){
_numerator = numerator;
_requiresStringification = true;
reduce();
}
void setDenominator(T denominator){
_denominator = denominator;
_requiresStringification = true;
reduce();
}
protected:
T _numerator;
T _denominator;
bool _requiresStringification;
std::string _stringified;
void reduce(){
//transit sign to the numerator
if(_denominator * _numerator < 0){
_numerator = -abs(_numerator);
_denominator = abs(_denominator);
}else{
_numerator = abs(_numerator);
_denominator = abs(_denominator);
}
if(_numerator==0 || _denominator==1){ //no needs for reduction
return;
}else if(_denominator ==0){//this is nan
return;
}else{//reduce
T _gcd = gcd(abs(_numerator), abs(_denominator));
_numerator /= _gcd;
_denominator /= _gcd;
}
}
void stringify(){
std::ostringstream ost;
if(_denominator==1){
ost << _numerator;
}else if(_denominator==0){
ost << "NaN";
}else{
ost << _numerator << "/" << _denominator;
}
_stringified = ost.str();
}
//Taken from https://en.wikipedia.org/wiki/Binary_GCD_algorithm
static T gcd(T u, T v)
{
// simple cases (termination)
if (u == v)
return u;
if (u == 0)
return v;
if (v == 0)
return u;
// look for factors of 2
if (~u & 1) // u is even
if (v & 1) // v is odd
return gcd(u >> 1, v);
else // both u and v are even
return gcd(u >> 1, v >> 1) << 1;
if (~v & 1) // u is odd, v is even
return gcd(u, v >> 1);
// reduce larger argument
if (u > v)
return gcd((u - v) >> 1, v);
return gcd((v - u) >> 1, u);
}
};
//Solve ax + b = cx + d
static std::string solve(int a, int b, int c, int d){
if(a==0 && c!=0){
Fraction<int> frac(b-d, c);
return "x = " + frac.to_s();
}else if(a!=0 && c==0){
Fraction<int> frac(d-b, a);
return "x = " + frac.to_s();
}else if(a==0 && c ==0){
return "impossible";
}else if(a == c){
return "impossible";
}else{
Fraction<int> frac(b - d, c - a);
return "x = " + frac.to_s();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment