online compiler and debugger for c/c++

code. compile. run. debug. share.
Source Code    Language
#include "fraction.h" #include <iostream> #include <set> #include <map> using Value = shk_fraction::Fraction; using Numbers = std::multiset<Value>; using Splited = std::pair<Numbers, Numbers>; using SplitedList = std::set<Splited>; using Results = std::set<Value>; SplitedList GenerateSplit(const Numbers& lst) { SplitedList ret; using LL = uintmax_t; LL max_i = (LL)1 << lst.size() - 2; LL min_i = 1; for (LL i = min_i; i <= max_i; ++i) { auto j = i; Splited splited; for (const auto& el : lst) { if (j%2) { splited.first.insert(el); } else { splited.second.insert(el); } j >>= 1; } ret.insert(std::move(splited)); } return ret; } Results Product(const Results& lhs, const Results& rhs) { Results ret; for (const auto& l : lhs) { for (const auto& r : rhs) { for (auto s : {-1, 1}) { ret.merge(Results{s*(l+r), s*(l-r), s*l*r}); if (r != 0) { ret.insert(s*l/r); } } } } return ret; } Results MakeResultsImpl(const Numbers& lst); Results MakeResults(const Numbers& lst) { static std::map<Numbers, Results> cache; if (cache.count(lst) == 1) { return cache[lst]; } auto ret = MakeResultsImpl(lst); cache[lst] = ret; return ret; } Results MakeResultsImpl(const Numbers& lst) { Results ret; if (lst.size() == 0) { return ret; } if (lst.size() == 1) { ret.insert(*lst.begin()); return ret; } for (const auto& [left, right] : GenerateSplit(lst)) { ret.merge( Product(MakeResults(left), MakeResults(right)) ); } return ret; } int main() { Numbers ticket = {1, 8, 9, 0, 6, 0}; for (const auto& el : MakeResults(ticket)) { std::cout << el << "\n"; } return 0; }
/********************************************************************** Project: C++ Fractional Arithmetic Library with Overflow Checking Language: C++ 2007 Author: Saied H. Khayat Date: March 2012 URL: https://github.com/saiedhk Copyright Notice: Free use of this library is permitted under the guidelines and in accordance with the MIT License (MIT). http://opensource.org/licenses/MIT **********************************************************************/ #include "typedefs.h" #ifndef SHK_FRACTION_H #define SHK_FRACTION_H // comment the following to disable run-time overflow checking #define OVFCHECK #include <iostream> using std::ostream; namespace shk_fraction { /** Defines 'Fraction' class. A fraction is the same as a rational number in mathematics. A rational number is a number that can be written as a ratio of two integers. In Fraction class, a Frction instance is always maintained in its reduced form. The reduced form of a Fraction consists of denominator and numerator that are relatively prime. This class is fully checked against overflow and divide-by-zero conditions. When such errors occur, an exception is generated to warn the caller. The integers representing the numerator and denomerator of a fraction are of type 'fint'. A 'fint' is a signed long long int. */ class Fraction { public: //--------------------------- // constructors //--------------------------- /** Contructs the default Fraction instance: 0/1. */ Fraction(void); /** Contructs the Fraction instance: a/1. @param a (of type fint) */ Fraction(fint a); /** Contructs the Fraction instance: a/1. @param a numerator (of type fint) @param b denominator (of type fint) */ Fraction(fint a, fint b); //--------------------------- // accessors //--------------------------- /** Gets the numerator of Fraction. */ fint numerator(void) const; // /** Gets the denominator of Fraction. */ fint denominator(void) const; /** Gets the sign of Fraction. */ int sign(void) const; /** Gets the floating-point value of Fraction. */ double realValue(void) const; /** Gets the integer part of the floating-point value of Fraction. */ fint integerPart(void) const; /** Gets the fractional part of the floating-point value of Fraction. */ double fractionalPart(void) const; //--------------------------- // mutators //--------------------------- /** Sets the numerator and denominator of Fraction. @param a numerator (of type fint) @param b denominator (of type fint) */ void set(fint a, fint b); /** Sets the numerator of Fraction. @param a numerator (of type fint) */ void setNum(fint a); /** Sets the numerator of Fraction. @param b denominator (of type fint) */ void setDenom(fint b); /** Negates the sign of Fraction. */ void negate(void); /** Converts Fraction to a proper fraction (i.e., a fraction that is less than 1). @returns the integer part of Fraction */ fint properize(void); //--------------------------- // Overloaded operators //--------------------------- /** Checks equality of two Fractions. @param left Fraction @param right Fraction @returns true if equal, false if not equal */ friend bool operator==(const Fraction& left, const Fraction& right); /** Checks inequality of two Fractions. @param left Fraction @param right Fraction @returns true if not equal, false if equal */ friend bool operator!=(const Fraction& left, const Fraction& right); /** Compares two Fractions. @param left Fraction @param right Fraction @returns true if left > right, false otherwise */ friend bool operator>(const Fraction& left, const Fraction& right); /** Compares two Fractions. @param left Fraction @param right Fraction @returns true if left < right, false otherwise */ friend bool operator<(const Fraction& left, const Fraction& right); /** Compares two Fractions. @param left Fraction @param right Fraction @returns true if left >= right, false otherwise */ friend bool operator>=(const Fraction& left, const Fraction& right); /** Compares two Fractions. @param left Fraction @param right Fraction @returns true if left <= right, false otherwise */ friend bool operator<=(const Fraction& left, const Fraction& right); /** Checks equality of a Fraction and a real. @param left Fraction @param right real @returns true if left=right, false otherwise */ friend bool operator==(const Fraction& left, real right); /** Checks inequality of a Fraction and a real. @param left Fraction @param right real @returns true if left != right, false otherwise */ friend bool operator!=(const Fraction& left, real right); /** Compares a Fraction with a real. @param left Fraction @param right real @returns true if left > right, false otherwise */ friend bool operator>(const Fraction& left, real right); /** Compares a Fraction with a real. @param left Fraction @param right real @returns true if left < right, false otherwise */ friend bool operator<(const Fraction& left, real right); /** Compares a Fraction with a real. @param left Fraction @param right real @returns true if left >= right, false otherwise */ friend bool operator>=(const Fraction& left, real right); /** Compares a Fraction with a real. @param left Fraction @param right real @returns true if left <= right, false otherwise */ friend bool operator<=(const Fraction& left, real right); /** Checks equality of a Fraction and a real. @param left real @param right Fraction @returns true if left=right, false otherwise */ friend bool operator==(real left, const Fraction& right); /** Checks equality of a Fraction and a real. @param left real @param right Fraction @returns true if left != right, false otherwise */ friend bool operator!=(real left, const Fraction& right); /** Compares a Fraction with a real. @param left real @param right Fraction @returns true if left > right, false otherwise */ friend bool operator>(real left, const Fraction& right); /** Compares a Fraction with a real. @param left real @param right Fraction @returns true if left < right, false otherwise */ friend bool operator<(real left, const Fraction& right); /** Compares a Fraction with a real. @param left real @param right Fraction @returns true if left >= right, false otherwise */ friend bool operator>=(real left, const Fraction& right); /** Compares a Fraction with a real. @param left real @param right Fraction @returns true if left <= right, false otherwise */ friend bool operator<=(real left, const Fraction& right); /** Adds two Fractions. @param left Fraction @param right Fraction @returns Fraction */ friend Fraction operator+(const Fraction& left, const Fraction& right); /** Subtracts two Fractions. @param left Fraction @param right Fraction @returns Fraction */ friend Fraction operator-(const Fraction& left, const Fraction& right); /** Mulitplies two Fractions. @param left Fraction @param right Fraction @returns Fraction */ friend Fraction operator*(const Fraction& left, const Fraction& right); /** Divides two Fractions. @param left Fraction @param right Fraction @returns Fraction */ friend Fraction operator/(const Fraction& left, const Fraction& right); /** Adds a Fraction and an integer @param left Fraction @param right fint @returns Fraction */ friend Fraction operator+(const Fraction& left, fint right); /** Subtracts an integer from a Fraction @param left Fraction @param right fint @returns Fraction */ friend Fraction operator-(const Fraction& left, fint right); /** Multiplies a Fraction by an integer @param left Fraction @param right fint @returns Fraction */ friend Fraction operator*(const Fraction& left, fint right); /** Divides a Fraction by an integer @param left Fraction @param right fint @returns Fraction */ friend Fraction operator/(const Fraction& left, fint right); /** Adds a Fraction and an integer @param left fint @param right Fraction @returns Fraction */ friend Fraction operator+(fint left, const Fraction& right); /** Subtracts a Fraction from an integer @param left fint @param right Fraction @returns Fraction */ friend Fraction operator-(fint left, const Fraction& right); /** Multiplies an integer by a Fraction @param left Fraction @param right fint @returns Fraction */ friend Fraction operator*(fint left, const Fraction& right); /** Divides an integer by a Fraction @param left Fraction @param right fint @returns Fraction */ friend Fraction operator/(fint left, const Fraction& right); /** Negates a Fraction @param a Fraction @returns Fraction */ friend Fraction operator-(const Fraction& f); /** Sends a Fraction to an output stream @param f Fraction @returns reference to an output stream */ friend ostream& operator<<(ostream& out, const Fraction& f); private: fint num; // numerator fint denom; // denominator void reduce(void); // reduces fraction to its irreducible form fint compare(Fraction f) const; // Compares fraction against another fraction f // returns 0 if equal, negative if less than r, // positive if greater than r }; } // namespace shk_fraction #endif // SHK_FRACTION_H
/********************************************************************** Project: C++ Fractional Arithmetic Library with Overflow Checking Language: C++ 2007 Author: Saied H. Khayat Date: March 2012 URL: https://github.com/saiedhk Copyright Notice: Free use of this library is permitted under the guidelines and in accordance with the MIT License (MIT). http://opensource.org/licenses/MIT **********************************************************************/ #include "fraction.h" #include "utility.h" #include <assert.h> namespace shk_fraction { //------------------------------------------------ // Constructors //------------------------------------------------ Fraction::Fraction(void) : num(0), denom(1) {} Fraction::Fraction(fint a) : num(a), denom(1) {} Fraction::Fraction(fint a, fint b) : num(a), denom(b) { reduce(); } //------------------------------------------------ // Accessors //------------------------------------------------ fint Fraction::numerator() const { return num; } fint Fraction::denominator() const { return denom; } int Fraction::sign(void) const { return (num>=0) ? 1 : -1; } double Fraction::realValue(void) const { return static_cast<double>(num)/denom; } fint Fraction::integerPart(void) const { return (num / denom); } double Fraction::fractionalPart(void) const { return static_cast<double>(num)/denom - (num/denom); } //------------------------------------------------ // Mutators //------------------------------------------------ // set numerator and denominator void Fraction::set(fint a, fint b) { num = a; denom = b; reduce(); } // set numerator void Fraction::setNum(fint a) { num = a; reduce(); } // set denominator void Fraction::setDenom(fint b) { denom = b; reduce(); } // change sign of fraction void Fraction::negate(void) { num = -num; } // converts fraction to a proper fraction (in which num<denom) // returns the integer part fint Fraction::properize(void) { fint quotient = num / denom; fint remainder = num % denom; num = remainder; return quotient; } //------------------------------------------------ // Operators //------------------------------------------------ // equality checker bool operator==(const Fraction& left, const Fraction& right) { return left.compare(right)==0; } // inequality checker bool operator!=(const Fraction& left, const Fraction& right) { return left.compare(right)!=0; } // greater checker bool operator>(const Fraction& left, const Fraction& right) { return left.compare(right) > 0; } // less checker bool operator<(const Fraction& left, const Fraction& right) { return left.compare(right) < 0; } // equal or greater checker bool operator>=(const Fraction& left, const Fraction& right) { return left.compare(right) >= 0; } // equal or less checker bool operator<=(const Fraction& left, const Fraction& right) { return left.compare(right) <= 0; } //------------------------ // equality checker bool operator==(real left, const Fraction& right) { return left == right.realValue(); } // inequality checker bool operator!=(real left, const Fraction& right) { return left != right.realValue(); } // greater checker bool operator>(real left, const Fraction& right) { return left > right.realValue(); } // less checker bool operator<(real left, const Fraction& right) { return left < right.realValue(); } // equal or greater checker bool operator>=(real left, const Fraction& right) { return left >= right.realValue(); } // equal or less checker bool operator<=(real left, const Fraction& right) { return left <= right.realValue(); } //----------------------- // equality checker bool operator==(const Fraction& left, real right) { return left.realValue() == right; } // inequality checker bool operator!=(const Fraction& left, real right) { return left.realValue() != right; } // greater checker bool operator>(const Fraction& left, real right) { return left.realValue() > right; } // less checker bool operator<(const Fraction& left, real right) { return left.realValue() < right; } // equal or greater checker bool operator>=(const Fraction& left, real right) { return left.realValue() >= right; } // equal or less checker bool operator<=(const Fraction& left, real right) { return left.realValue() <= right; } //---------------------------- // addition Fraction operator+(const Fraction& left, const Fraction& right) { fint temp1 = left.num * right.denom; fint temp2 = left.denom * right.num; fint a = temp1 + temp2; fint b = left.denom * right.denom; #ifdef OVFCHECK CheckMultOvf(left.num, right.denom, temp1); CheckMultOvf(left.denom, right.num, temp2); CheckAddOvf(temp1,temp2,a); CheckMultOvf(left.denom, right.denom, b); #endif return Fraction(a,b); } // subtraction Fraction operator-(const Fraction& left, const Fraction& right) { fint temp1 = left.num * right.denom; fint temp2 = left.denom * right.num; fint a = temp1 - temp2; fint b = left.denom * right.denom; #ifdef OVFCHECK CheckMultOvf(left.num, right.denom, temp1); CheckMultOvf(left.denom, right.num, temp2); CheckAddOvf(temp1, -temp2, a); CheckMultOvf(left.denom, right.denom, b); #endif return Fraction(a,b); } // Multiplication Fraction operator*(const Fraction& left, const Fraction& right) { fint temp = gcd( abs(left.num), abs(right.denom) ); fint a1 = left.num / temp; fint b1 = right.denom / temp; temp = gcd( abs(left.denom), abs(right.num) ); fint a2 = right.num / temp; fint b2 = left.denom / temp; fint temp1 = a1 * a2; fint temp2 = b1 * b2; #ifdef OVFCHECK CheckMultOvf(a1, a2, temp1); CheckMultOvf(b1, b2, temp2); #endif return Fraction(temp1, temp2); } // Division Fraction operator/(const Fraction& left, const Fraction& right) { if (right.num==0) throw ErrorDivideByZero; fint temp = gcd( abs(left.num), abs(right.num) ); fint a1 = left.num / temp; fint b1 = right.num / temp; temp = gcd( abs( left.denom), abs(right.denom) ); fint a2 = right.denom / temp; fint b2 = left.denom / temp; fint temp1 = a1 * a2; fint temp2 = b1 * b2; #ifdef OVFCHECK CheckMultOvf(a1, a2, temp1); CheckMultOvf(b1, b2, temp2); #endif return Fraction((a1 * a2), (b1 * b2)); } //---------------------- Fraction operator+(const Fraction& left, fint iright) { Fraction right(iright); return left + right; } Fraction operator-(const Fraction& left, fint iright) { Fraction right(iright); return left - right; } Fraction operator*(const Fraction& left, fint iright) { Fraction right(iright); return left * right; } Fraction operator/(const Fraction& left, fint iright) { Fraction right(iright); return left / right; } //---------------------- Fraction operator+(fint ileft, const Fraction& right) { Fraction left(ileft); return left + right; } Fraction operator-(fint ileft, const Fraction& right) { Fraction left(ileft); return left - right; } Fraction operator*(fint ileft, const Fraction& right) { Fraction left(ileft); return left * right; } Fraction operator/(fint ileft, const Fraction& right) { Fraction left(ileft); return left / right; } Fraction operator-(const Fraction& f) { Fraction result( -f.numerator(), f.denominator() ); return result; } //---------------------- ostream& operator<<(ostream &output, const Fraction& right) { if (right.denominator() != 1) { output << right.numerator() << "/" << right.denominator(); } else { output << right.numerator(); } return output; } //---------------------- // Private Functions // reduce fraction to simplest form void Fraction::reduce(void) { if (denom==0) throw ErrorDivideByZero; int sign = 1; if (num<0) { sign = -sign; num = -num; } if (denom<0) { sign = -sign; denom = -denom; } fint temp = gcd(num, denom); if (sign == -1) num = -num; num = num / temp; denom = denom / temp; } // compare two fractions fint Fraction::compare(Fraction r) const { fint temp1 = num * r.denom; fint temp2 = denom * r.num; fint temp = temp1 - temp2; #ifdef OVFCHECK CheckMultOvf(num, r.denom, temp1); CheckMultOvf(denom, r.num, temp2); CheckAddOvf(temp1,-temp2,temp); #endif return temp; } } // namespace saied_hk
/********************************************************************** Project: C++ Fractional Arithmetic Library with Overflow Checking Language: C++ 2007 Author: Saied H. Khayat Date: March 2012 URL: https://github.com/saiedhk Copyright Notice: Free use of this library is permitted under the guidelines and in accordance with the MIT License (MIT). http://opensource.org/licenses/MIT **********************************************************************/ #ifndef TYPEDEFS_H #define TYPEDEFS_H namespace shk_fraction { /** Defines 'fint', the main integer type used in Fraction class. */ typedef signed long long int fint; /** Defines 'real', the main floating-point type in Fraction class. */ typedef double real; /** Defines exception codes. */ typedef enum { Ok, ErrorDivideByZero, ErrorAddOverflow, ErrorMultOverflow } ErrorCode; } // namespace #endif
/********************************************************************** Project: C++ Fractional Arithmetic Library with Overflow Checking Language: C++ 2007 Author: Saied H. Khayat Date: March 2012 URL: https://github.com/saiedhk Copyright Notice: Free use of this library is permitted under the guidelines and in accordance with the MIT License (MIT). http://opensource.org/licenses/MIT **********************************************************************/ #include <assert.h> #include "typedefs.h" #ifndef UTILITY_H #define UTILITY_H namespace shk_fraction { // Utility functions /** Computes greatest common divisor of two integers (fints) @param a fint @param b fint @returns gcd of a and b (fint) */ inline fint gcd(fint a, fint b) { assert((a>=0)&&(b>=0)); fint r; if (a==0) return b; if (b==0) return a; while (r = a%b) { a = b; b = r; } return b; } // Overflow checking functions /** Checks for overflow in addition, produces exception if overflow happens @param a addend @param b addend @param c sum @throws ErrorAddOverflow */ inline void CheckAddOvf(fint a, fint b, fint c) { const fint MASK = ((static_cast<fint>(1)<<(sizeof(fint)*8-1))); if ( (~(a^b)) & (a^c) & MASK ) throw ErrorAddOverflow; } /** Checks for overflow in multiplication, produces exception if overflow happens @param a multiplicand @param b multiplicand @param c product @throws ErrorMultOverflow */inline void CheckMultOvf(fint a, fint b, fint c) { if (a == 0) { return; } if ( (c/a) != b ) throw ErrorMultOverflow; } } //namespace #endif

Compiling Program...

Command line arguments:
Standard Input: Interactive Console Text
×

                

                

Program is not being debugged. Click "Debug" button to start program in debug mode.

#FunctionFile:Line
VariableValue
RegisterValue
ExpressionValue