/*
Podstawowe operacji na ułamkach.
Program prosi o podanie wyrazu z udziałem ułamków (tylko + - * /),
sprowadza podane wyrażenie do jednego ułamku.
np: po wprowadzeniu wyrażenia: 2/6+1/6
program wypisuje: 1/3+1/6=1/2
struktury, przekazywanie struktur do funkcji
cin.clear(ios::badbit);
instrukcja sterująca switch(...) { case: break; default: }
















*/
#include <iostream>
#include <limits>

using namespace std; // w starszych kompilatorach trzeba zakomentować ten wiersz

struct Ulamek { int Licznik,Mianownik; };

long NWD(long a,long b);

void Drukuj(Ulamek U) { cout<<U.Licznik<<'/'<<U.Mianownik; }

Ulamek Skroc(Ulamek U)
  {
   int n=NWD(U.Licznik,U.Mianownik);
   if((n<0)^(U.Mianownik<0)) n=-n; // aby mianownik był zawsze dodatni
   U.Licznik/=n;
   U.Mianownik/=n;
   return(U);
  }

Ulamek Wprowadz()
  {
   Ulamek U;
   char Lamana;
   cin>>U.Licznik>>Lamana>>U.Mianownik;
   if((cin)&&(Lamana!='/')) cin.clear(ios::badbit);
   return(Skroc(U));
  }

Ulamek Dodaj(Ulamek A,Ulamek B)
  {
   Ulamek U;
   U.Licznik=A.Licznik*B.Mianownik+B.Licznik*A.Mianownik;
   U.Mianownik=A.Mianownik*B.Mianownik;
   return(Skroc(U));
  }

Ulamek Odejmij(Ulamek A,Ulamek B)
  {
   Ulamek U;
   U.Licznik=A.Licznik*B.Mianownik-B.Licznik*A.Mianownik;
   U.Mianownik=A.Mianownik*B.Mianownik;
   return(Skroc(U));
  }

Ulamek Mnoz(Ulamek A,Ulamek B)
  {
   Ulamek U;
   U.Licznik=A.Licznik*B.Licznik;
   U.Mianownik=A.Mianownik*B.Mianownik;
   return(Skroc(U));
  }

Ulamek Dziel(Ulamek A,Ulamek B)
  {
   Ulamek U;
   U.Licznik=A.Licznik*B.Mianownik;
   U.Mianownik=A.Mianownik*B.Licznik;
   return(Skroc(U));
  }

int main()
  {
   while(true)
     {
      cout<<"Podaj wyraz ulamkowy (!-koniec): ";
      Ulamek A,B;
      char Operacja;
      A=Wprowadz();
      cin>>Operacja;
      B=Wprowadz();
      if(cin)
        {
         Ulamek U;
         switch(Operacja)
           {
            case '+': U=Dodaj(A,B);   break;
            case '-': U=Odejmij(A,B); break;
            case '*': U=Mnoz(A,B);    break;
            case ':': U=Dziel(A,B);   break;
            default: Operacja=0;      break;
           }
         if(Operacja)
           {
            Drukuj(A);
            cout<<Operacja;
            Drukuj(B);
            cout<<'=';
            Drukuj(U);
            cout<<endl;
           }
         else cout<<"Dozwolone operacje to: + - * :"<<endl;
        }
      else
        {
         cin.clear();
         if(cin.get()=='!') break;
         cout<<"Blad wprowadzenia"<<endl;
        }
      cin.ignore(INT_MAX,'\n');
      cout<<endl;
     }
   return 0;
  }

long NWD(long a,long b)
  {
   if(a)
     {
      if(!b) return(a);
      while(b) { int r=a%b; a=b; b=r; }
      return(a);
     }
   return(b?b:1);
  }


