#include #include using namespace std; struct reader { string input; int pos, len; reader(string s) { input = s; pos = 0; len = s.length(); } void skip_spaces() { while (pos < len && input[pos] == ' ') pos += 1; } char take_char() { if (pos >= len) return '\n'; char c = input[pos]; pos += 1; return c; } char see_char() { if (pos >= len) return '\n'; return input[pos]; } string whats_next() { skip_spaces(); if (pos >= len) return "end"; char c = see_char(); if (c == '+' || c == '-' || c == '/') return string(1, c); if (c >= '0' && c <= '9') return "digit"; if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z') return "letter"; if (c <= ' ') return "space"; return "other"; } int take_int() { skip_spaces(); string n = whats_next(); if (n != "digit") { cerr << "\ntake_int called when int not present\n"; return -1; } int value = 0; while (true) { string n = whats_next(); if (n != "digit") break; char c = take_char(); value = value * 10 + c - '0'; } return value; } }; int gcd(int a, int b) { for (int pd = min(a, b); pd > 1; pd -= 1) if (a % pd == 0 && b % pd == 0) return pd; return 1; } struct rational { int top, bot; void simplify() { if (top == 0) { bot = 1; return; } int d = gcd(top, bot); if (d != 1) { top /= d; bot /= d; } if (bot < 0) { bot = - bot; top = - top; } } rational(int t, int b) { top = t; bot = b; simplify(); } rational(string s) { reader r(s); bool neg = false, error = false; int wholepart = 0; string n = r.whats_next(); if (n == "-") { neg = true; r.take_char(); } else if (n == "+") r.take_char(); else if (n != "digit") error = true; int x = r.take_int(); n = r.whats_next(); if (n == "end") // whole thing is just a single int { top = x; bot = 1; } else if (n == "+") { wholepart = x; // must now see top / bot r.take_char(); n = r.whats_next(); if (n != "digit") error = true; top = r.take_int(); n = r.whats_next(); // still need / bot if (n != "/") error = true; r.take_char(); bot = r.take_int(); } else if (n == "/") // whole thing is top / bot { top = x; r.take_char(); bot = r.take_int(); } else error = true; if (error) { cerr << "\nimproper number " << r.input << "\n"; top = 0; bot = 0; } if (wholepart != 0) top += wholepart * bot; if (neg) top = - top; simplify(); } void print(ostream & out) { if (top < 0) { out << "-"; top = - top; } if (bot == 1) out << top; else if (top > bot) { int whole = top / bot; int newtop = top - whole * bot; out << whole << "+" << newtop << "/" << bot; } else out << top << "/" << bot; } rational operator*(rational b) { return rational(top * b.top, bot * b.bot); } rational operator/(rational b) { return rational(top * b.bot, bot * b.top); } rational operator+(rational b) { return rational(top * b.bot + b.top * bot, bot * b.bot); } rational operator-(rational b) { return rational(top * b.bot - b.top * bot, bot * b.bot); } rational & operator*=(rational b) { top *= b.top; bot *= b.bot; simplify(); return * this; } rational & operator/=(rational b) { top *= b.bot; bot *= b.top; simplify(); return * this; } rational & operator+=(rational b) { int newbot = bot * b.bot; top = top * b.bot + b.top * bot; bot = newbot; simplify(); return * this; } rational & operator-=(rational b) { int newbot = bot * b.bot; top = top * b.bot - b.top * bot; bot = newbot; simplify(); return * this; } bool operator<(rational b) { return top * b.bot < b.top * bot; } bool operator>(rational b) { return top * b.bot > b.top * bot; } bool operator<=(rational b) { return top * b.bot <= b.top * bot; } bool operator>=(rational b) { return top * b.bot >= b.top * bot; } bool operator==(rational b) { return top == b.top && bot == b.bot; } bool operator!=(rational b) { return top != b.top || bot != b.bot; } }; ostream & operator<<(ostream & out, rational a) { a.print(out); return out; } void one_test(string s, rational a, rational b, rational c) { cout << a << " " << s << " " << b << " is " << c << "\n"; } void test(rational a, rational b) { one_test("plus", a, b, a + b); one_test("minus", a, b, a - b); one_test("times", a, b, a * b); one_test("divided by", a, b, a / b); one_test("complicated thing", a, b, (a + b) * (a - b)); } rational ask(string prompt) { int t, b; cout << prompt << ", top then bottom: "; cin >> t >> b; return rational(t, b); } int mainx() { rational w(3, 4); rational x(7, 8); rational y(1, 10); rational z(3, 2); w += x; w -= y; w *= z; cout << "(3/4 + 7/8 - 1/10) * 3/2 = " << w << "\n"; cout << "is 7/8 > 1/10? "; if (x < y) cout << "yes\n"; else cout << "no\n"; while (true) { rational a = ask("A"); rational b = ask("B"); test(a, b); } } int main() { cout << "1/2: " << rational("1/2") << "\n"; cout << "123/124: " << rational("123/124") << "\n"; cout << "1+2/3: " << rational("1+2/3") << "\n"; cout << "123+17/101: " << rational("123+17/101") << "\n"; cout << "-12+1/4: " << rational("-12+1/4") << "\n"; cout << "-1/3: " << rational("-1/3") << "\n"; cout << "-1/371: " << rational("-1/371") << "\n"; }