#include #include #include struct string { char dane[40001]; int len; int ilosc_dzialan; int sort_order; // w tej zmiennej przechowywany bedzie index przed sortowaniem w celu odtworzenia }; //////////////////////////////////////////////////////// inline void suma(struct string *, struct string *, struct string *, int);//suma inline void odejmowanie(struct string *, struct string *, struct string *, int); inline void mnozenie(struct string *, struct string *, struct string *); inline void dzielenie(struct string *, struct string *, struct string *, int); inline void modulo(struct string *, struct string *, struct string *); inline int wieksze(struct string *, struct string *, int); //////////////////////////////////////////////////////// inline void streplace(struct string *, struct string *, struct string *, int); // streplace('poszukiwany struct string', struct string do zastapienia) inline void reverse(struct string *); inline void strcut(int, int , struct string *, struct string *); inline void strset(struct string *, struct string *, int); inline void int2str(int, struct string *); int str2int(struct string *); int pow2(int, int); //////////////////////////////////////////////////////// int cmp_str(const void *, const void *); //////////////////////////////////////////////////////// struct string * nww(struct string *, struct string *); struct string * nwd(struct string *, struct string *); int onp(struct string **, struct string **, struct string **, int); // argument <- rownianie z ulamkami w onp, wyjscie -> ulamek nieskracalny // zwraca 0 gdy rownanie jest ok, 1 gdy bledne inline void action(struct string **, struct string **, int ,struct string **, struct string **, int , struct string *, struct string *, char, int); inline void push(struct string *); inline void pop(struct string *); struct string stos; int main () { struct string tmp; #ifndef ONLINE_JUDGE //freopen("stos.txt","r",stdin); freopen("in2.txt","r",stdin); //freopen("out2.txt","w",stdout); #endif struct string ** rownania = (struct string**)malloc(sizeof(struct string*)); rownania[0] = (struct string*)malloc(sizeof(struct string)); struct string ** zmienne = (struct string**)malloc(sizeof(struct string*)); zmienne[0] = (struct string*)malloc(sizeof(struct string)); struct string ** wynikL = (struct string**)malloc(sizeof(struct string*)); wynikL[0] = (struct string*)malloc(sizeof(struct string)); struct string ** wynikM = (struct string**)malloc(sizeof(struct string*)); wynikM[0] = (struct string*)malloc(sizeof(struct string)); int n=0, m=0, mn=0, zestaw, terminate=0, marker, slesz; int zaalokowane=1; scanf("case %d\n",&zestaw); //1 zestaw struct string search, replace; search.dane[0] = '_'; replace.dane[0] = 0; search.len = 1; replace.len = 0; while (terminate!=EOF) { while (1) { mn = 0; marker = 0; slesz = 0; while(1) { if (marker == 0) { //terminate = scanf("%c", &zmienne[n]->dane[mn]); terminate = (zmienne[n]->dane[mn] = getchar()); if (terminate == EOF) break; if (zmienne[n]->dane[mn] == '=' || zmienne[n]->dane[mn] == ' ') { zmienne[n]->dane[mn] = 0; zmienne[n]->len = mn; rownania[n]->ilosc_dzialan=0; marker = 1; } } else if (marker == 1) { if (zmienne[n]->dane[0] == 'c' && zmienne[n]->dane[1] == 'a' && zmienne[n]->dane[2] == 's' && zmienne[n]->dane[3] == 'e') break; //terminate = scanf("%c", &rownania[n]->dane[mn-zmienne[n]->len-1]); terminate = (rownania[n]->dane[mn-zmienne[n]->len-1] = getchar()); if (rownania[n]->dane[mn-zmienne[n]->len-1] == '*' || rownania[n]->dane[mn-zmienne[n]->len-1] == '+' || rownania[n]->dane[mn-zmienne[n]->len-1] == '/') rownania[n]->ilosc_dzialan++; if ((rownania[n]->dane[mn-zmienne[n]->len-1] >= '0' && rownania[n]->dane[mn-zmienne[n]->len-1] <= '9') || rownania[n]->dane[mn-zmienne[n]->len-1] == '/') { if (slesz == 0) { //licznik if (rownania[n]->dane[mn-zmienne[n]->len-1] == '/') { slesz = 1; wynikL[n]->dane[mn-zmienne[n]->len-1] = 0; //licznik wynikL[n]->len = mn-zmienne[n]->len-1; } else { wynikL[n]->dane[mn-zmienne[n]->len-1] = rownania[n]->dane[mn-zmienne[n]->len-1]; //licznik wynikL[n]->len = mn-zmienne[n]->len-1; } } else { //mianownik wynikM[n]->dane[mn-zmienne[n]->len-2-wynikL[n]->len] = rownania[n]->dane[mn-zmienne[n]->len-1]; //mianownik wynikM[n]->len = mn-zmienne[n]->len-2-wynikL[n]->len; } } else if (rownania[n]->dane[mn-zmienne[n]->len-1] == '\n') { if (slesz==1) { wynikM[n]->dane[mn-zmienne[n]->len-2-wynikL[n]->len] = 0; //licznik wynikM[n]->len = mn-zmienne[n]->len-2-wynikL[n]->len; } rownania[n]->dane[mn-zmienne[n]->len-1] = 0; rownania[n]->len = mn-zmienne[n]->len-1; break; } } mn++; } zmienne[n]->sort_order = n; if (zaalokowane < n+2) { rownania = (struct string**)realloc(rownania, (n+2)*sizeof(struct string*)); rownania[n+1] = (struct string*)malloc(sizeof(struct string)); zmienne = (struct string**)realloc(zmienne, (n+2)*sizeof(struct string*)); zmienne[n+1] = (struct string*)malloc(sizeof(struct string)); wynikL = (struct string**)realloc(wynikL, (n+2)*sizeof(struct string*)); wynikL[n+1] = (struct string*)malloc(sizeof(struct string)); wynikM = (struct string**)realloc(wynikM, (n+2)*sizeof(struct string*)); wynikM[n+1] = (struct string*)malloc(sizeof(struct string)); zaalokowane++; } if (zmienne[n]->dane[0] == 'c' && zmienne[n]->dane[1] == 'a' && zmienne[n]->dane[2] == 's' && zmienne[n]->dane[3] == 'e') break; if (terminate == EOF) break; n++; } n--; int ilosc_rownan = n; struct string * wynik; reverse(wynikL[n]); reverse(wynikM[n]); wynik = nwd(wynikL[n],wynikM[n]); //tmp wspolny dzielnik dzielenie(wynikL[n], wynik, wynikL[n], 0); //tmp2 nowy licznik dzielenie(wynikM[n], wynik, wynikM[n], 0); // tmp3 nowy mianownik n--; int m=0; for (n; n >=0; n--) { for (m=0; m < ilosc_rownan-n ; m++) { int2str(n+m+1, &tmp); streplace(zmienne[n+m+1], &tmp, rownania[n], 1); } onp(rownania, wynikL, wynikM, n); } printf("case %d ", zestaw); printf("Y\n"); for (n=0; n < ilosc_rownan+1; n++) streplace(&search, &replace, zmienne[n], 0); qsort(zmienne, ilosc_rownan+1, sizeof (zmienne[0]), cmp_str); for (n=0; n < ilosc_rownan+1; n++) { printf("%s ", zmienne[n]->dane); int i; for (i = wynikL[zmienne[n]->sort_order]->len-1 ; i >= 0; i--) { putchar(wynikL[zmienne[n]->sort_order]->dane[i]); } putchar(' '); for (i = wynikM[zmienne[n]->sort_order]->len-1 ; i >= 0; i--) { putchar(wynikM[zmienne[n]->sort_order]->dane[i]); } putchar('\n'); } scanf("%d\n", &zestaw); n=0; if (zestaw == 927) break; } int i; for(i=0; ilen/2; n++) { tmp = str->dane[n]; str->dane[n] = str->dane[str->len-n-1]; str->dane[str->len-n-1] = tmp; } } inline void streplace(struct string * search, struct string * replace, struct string * source, int rodzaj) { // streplace('szukany struct string', struct string do zastapienia) // rodzaj -> 1 dla podmieniania w rownaniach (zabezpieczenie przed podmienieniem czesci nazwy innej zmiennej) // 0 normalnie if( rodzaj == 1 ) { if (search->dane[0]!='_') { strset( search, search, 1); search->dane[0]='_'; } if (replace->dane[0]!='_') { strset( replace, replace, 1); replace->dane[0]='_'; } } int n, s_n=0, tmp_n, match=0; for (n=0; n <= source->len; n++) { if (source->dane[n] == ' ') continue; if (source->dane[n]==search->dane[s_n]) { tmp_n = n; while(s_n < search->len) { // mechanizm dopasowywania if (source->dane[tmp_n]==search->dane[s_n]) { match++; tmp_n++; s_n++; } else { match = 0; tmp_n = 0; s_n =0; break; } } if (rodzaj == 1 && (source->dane[tmp_n] >= 'a')) {//rownania (zmienna moze konczyc sie tylko na _ lub znak dzialania) match = 0; tmp_n = 0; s_n =0; } if (match > 0) { //zacznij podmieniac int start2,i; start2 = tmp_n-search->len; if (search->len == replace->len) { for (i=0; i < replace->len; i++) source->dane[start2+i] = replace->dane[i]; match = 0; tmp_n = 0; s_n =0; } else if (search->len > replace->len) { if (rodzaj==1) { for (i=0; i < replace->len; i++) source->dane[start2+i] = replace->dane[i]; for (i=0; i < search->len - replace->len; i++) source->dane[start2+replace->len+i] = ' '; } else { for (i=0; i < replace->len; i++) source->dane[start2+i] = replace->dane[i]; for (i=0; i < source->len - (start2 + replace->len); i++) { //tmp_n-search->len poz.pocz. szukanego slowa source->dane[start2+replace->len+i] = source->dane[start2+replace->len+i+(search->len - replace->len)]; } source->len = source->len - (search->len - replace->len); source->dane[source->len] = 0; } match = 0; tmp_n = 0; s_n =0; n+= replace->len-1; } else if (search->len < replace->len) { source->dane[source->len+(replace->len - search->len)] =0; for (i=source->len-1; i >= tmp_n; i--) // zrob miejsce dla znakow source->dane[i+ (replace->len - search->len)] = source->dane[i]; for (i=0; i < replace->len; i++) source->dane[start2+i] = replace->dane[i]; source->len = source->len + (replace->len -search->len ); match = 0; tmp_n = 0; s_n =0; n+= replace->len-1; } } } } } inline void strset(struct string * source, struct string * destination, int przesuniecie) { int n; for (n=source->len+przesuniecie; n >=0; n--) if (n < przesuniecie) destination->dane[n] = '0'; else destination->dane[n] = source->dane[n-przesuniecie]; destination->dane[source->len+przesuniecie]=0; destination->len = source->len+przesuniecie; } struct string * nwd(struct string * a, struct string * b) { int n, w; static struct string tmp2, tmp3, tmp4; struct string * zief,* zief2; struct string * wsk1, * wsk2; wsk1 = a; wsk2 = b; zief = &tmp2; n = 0; while (1) { w = ((wsk2->dane[0] == '0' && wsk2->dane[1] == 0 && wsk2->len==1) == 1 ? 1 : 0); if (w != 1) {//rozne od zera modulo(wsk1, wsk2, zief); if (n==0) { wsk1 = &tmp3; } if (n==1) { wsk1 = &tmp4; } zief2 = wsk1; wsk1 = wsk2; wsk2 = zief; zief = zief2; n++; } else if (w == 1) { return wsk1; } } } struct string * nww(struct string * a, struct string * b) // zródło wikipedia //arg liczba,liczba -> liczba //algorytm euklidesa 2 { int n=0; struct string ab; static struct string tmp, tmp2, tmp3; struct string * wsk1, * wsk2, * wsk3, * wsk4; wsk1 = a; wsk2 = b; wsk3 = &tmp; mnozenie(a,b,&ab); while (!(wsk2->dane[0] == '0' && wsk2->dane[1] == 0)) { modulo(wsk1,wsk2,wsk3); if (n==0) wsk1 = &tmp2; if (n==1) wsk1 = &tmp3; wsk4 = wsk1; wsk1 = wsk2; wsk2 = wsk3; wsk3 = wsk4; n++; } dzielenie(&ab,wsk1,wsk2, 0); return wsk2; } inline int wieksze (struct string * liczba1, struct string * liczba2, int przesuniecie) { //1 jak 1 > 2 /// 0 jak 1 < 2 /// 2 dla 1=2 int n=0; static int q=0; if (przesuniecie == 0){ if (liczba1->len==liczba2->len) { for (n=liczba1->len-1; n >= 0; n--) { if (liczba1->dane[n]== liczba2->dane[n]) { continue; } else if (liczba1->dane[n] < liczba2->dane[n]) { return 0; } else if (liczba1->dane[n] > liczba2->dane[n]) { return 1; } } return 2; } else if (liczba1->len < liczba2->len+przesuniecie) { return 0; } else return 1; } else { if (liczba1->len==liczba2->len+przesuniecie) { for (n=liczba1->len-1; n >= przesuniecie; n--) { if (liczba1->dane[n]==liczba2->dane[n-przesuniecie]) { continue; } else if (liczba1->dane[n] < liczba2->dane[n-przesuniecie]) { return 0; } else if (liczba1->dane[n] > liczba2->dane[n-przesuniecie]) { return 1; } } return 2; } else if (liczba1->len < liczba2->len+przesuniecie) { return 0; } else return 1; } } inline void modulo(struct string * dzielna, struct string * dzielnik, struct string * wynik) { if (dzielnik->dane[0] == '1' && dzielnik->dane[1] == 0 && dzielnik->len==1) { wynik->dane[0] = '0'; wynik->dane[1] = 0; wynik->len = 1; return; } int n, m, tmp; if (dzielna!=wynik) strset(dzielna, wynik, 0); for (n=wynik->len-dzielnik->len; n >= 0; n--) { while ((tmp = wieksze(wynik,dzielnik, n)) >= 1) { if (tmp == 2 && n==0) { wynik->dane[0]='0'; wynik->dane[1]=0; wynik->len=1; break; } else if (tmp == 2) { wynik->dane[n]=0; wynik->len=n; for (m=wynik->len-1; m > 0 ;m--) { if (wynik->dane[m]!=48) { break; } } wynik->dane[m+1]=0; wynik->len=m+1; } else { odejmowanie(wynik, dzielnik, wynik, n); } } } } inline void suma(struct string * liczba1, struct string * liczba2, struct string * wynik, int przesuniecie) { if (liczba1->dane[0]=='0' && liczba1->dane[1]==0 && liczba2->dane[0]=='0' && liczba2->dane[1]==0) {//obie dodawane liczby sa zerami wynik->dane[0] = '0'; wynik->dane[1]=0; // zabezpieczenie przed sumowaniem przesunietych 0 wg. siebie } else if (liczba1->dane[0]=='0' && liczba1->dane[1]==0) { //jak jedna z liczby = 0 to wynik = druga liczba strset(liczba2, wynik, przesuniecie); } else if (liczba2->dane[0]=='0' && liczba2->dane[1]==0) { if (liczba1!=wynik) strset(liczba1, wynik, 0); } else { int n, p=0; struct string * dluzszy, * krotszy; struct string * tmp_wynik; tmp_wynik = wynik; liczba2->len+=przesuniecie; if (liczba1->len > liczba2->len) { dluzszy = liczba1; krotszy = liczba2; } else { dluzszy = liczba2; krotszy = liczba1; } for (n=0; n < dluzszy->len; n++) { tmp_wynik->dane[n] = ((n < liczba1->len ) ? liczba1->dane[n]-48 : 0 ) + (((n-przesuniecie>=0 && n < liczba2->len ) ? liczba2->dane[n-przesuniecie]-48 : 0))+p; p=0; if (tmp_wynik->dane[n] >= 10) { p = tmp_wynik->dane[n]/10; tmp_wynik->dane[n] %= 10; } tmp_wynik->dane[n]+=48; } if (p > 0) { tmp_wynik->dane[n]=p+48; tmp_wynik->dane[n+1]=0; tmp_wynik->len=n+1; } else { tmp_wynik->dane[n]=0; tmp_wynik->len=n; } liczba2->len-=przesuniecie; } } inline void odejmowanie(struct string * liczba1, struct string * liczba2, struct string * wynik, int przesuniecie) { int tmp; liczba2->len+=przesuniecie; int n, p=0; if (liczba1 == wynik && przesuniecie > 0) { // for (n=przesuniecie; n < liczba2->len; n++) { tmp = liczba1->dane[n]-48+p; p=0; if (n-przesuniecie>=0 && n < liczba2->len) tmp-=(liczba2->dane[n-przesuniecie]-48); if (tmp < 0) { tmp+=10; p=-1; } wynik->dane[n]=tmp+48; } if (p < 0) { do { wynik->dane[n]+=p; if (wynik->dane[n] < 48) { p = -1; wynik->dane[n]+=10; } else p = 0; n++; } while (p); } liczba2->len-=przesuniecie; for (n=liczba1->len-1; n > 0 ;n--) if (wynik->dane[n]==48) { wynik->dane[n]=0; wynik->len = n; } else break; } else { for (n=0; n < liczba1->len; n++) { tmp = liczba1->dane[n]-48+p; p=0; if (n-przesuniecie>=0 && n < liczba2->len) tmp-=(liczba2->dane[n-przesuniecie]-48); if (tmp < 0) { tmp+=10; p=-1; } wynik->dane[n]=tmp+48; } liczba2->len-=przesuniecie; wynik->dane[n]=0; wynik->len = n ; n--; for (n; n > 0 ;n--) if (wynik->dane[n]==48) { wynik->dane[n]=0; wynik->len = n; } else break; } } inline void mnozenie(struct string * liczba1, struct string * liczba2, struct string * suma_wynikow) { suma_wynikow->dane[0]= '0'; suma_wynikow->dane[1]= 0; suma_wynikow->len = 1; struct string wynik; int n; int p=0; //przeniesienie struct string * dluzszy, * krotszy; if (liczba1->len > liczba2->len) { dluzszy = liczba1; krotszy = liczba2; } else { dluzszy = liczba2; krotszy = liczba1; } int m; for (n=0; n < krotszy->len; n++) { //n index ktorszej liczby if (krotszy->dane[n]-48 == 0) { wynik.dane[0] = '0'; wynik.dane[1] = 0; wynik.len =1; continue; } for (m=0; m < dluzszy->len; m++) { //m index dluzszej liczby wynik.dane[m] = (dluzszy->dane[m]-48) * (krotszy->dane[n]-48)+p;//48 zero ascii p=0; if (wynik.dane[m] >= 10) { p = wynik.dane[m]/10; wynik.dane[m] = wynik.dane[m]%10; //48 zero ascii } wynik.dane[m]+=48; } if (p>0) { wynik.dane[m] = p+48; wynik.dane[m+1] = 0; wynik.len = m+1; p=0; } else { wynik.dane[m] = 0; wynik.len = m; } suma(suma_wynikow, &wynik, suma_wynikow, n); } } inline void dzielenie(struct string * dzielna, struct string * dzielnik, struct string * wynik, int przesuniecie) { int tmp; tmp = wieksze(dzielna,dzielnik, 0); if (dzielnik->dane[0]=='1' && dzielnik->dane[1]==0) { // jak dzielnik jest 1 to wynik = dzielna if (dzielna!=wynik) strset(dzielna, wynik, 0); } else if (tmp == 0) {//0 dla L1 < L2 wynik->dane[0]='0'; wynik->dane[1]=0; wynik->len=1; } else if (tmp == 2) { // 2 dla L1 == L2 wynik->dane[0]='1'; wynik->dane[1]=0; wynik->len=1; } else if (tmp == 1) { //1 dla L1 > L2 --> dziel int n, m, p=0, tmp2; struct string tmp_dzielna, tmp_wynik; if (dzielna!=wynik) strset(dzielna, &tmp_dzielna, 0); tmp = dzielna->len - dzielnik->len; for (n=dzielna->len - dzielnik->len ; n >= 0; n--) { while ((tmp2 = wieksze(dzielna,dzielnik, n)) >= 1) { if (tmp2 == 2 && n==0) { dzielna->dane[0]='0'; dzielna->dane[1]=0; dzielna->len=1; p++; break; } else if (tmp2 == 2) { dzielna->dane[n]=0; dzielna->len=n; for (m=dzielna->len-1; m > 0 ;m--) { if (dzielna->dane[m]!=48) { break; } } dzielna->dane[m+1]=0; dzielna->len=m+1; p++; } else { odejmowanie(dzielna, dzielnik, dzielna, n); p++; } } tmp_wynik.dane[n] = p + 48; p = 0; } tmp_wynik.len = tmp+1; tmp_wynik.dane[tmp_wynik.len]=0; for (n=tmp; n > 0 ;n--) if (tmp_wynik.dane[n]==48) { tmp_wynik.dane[n]=0; tmp_wynik.len = n; } else break; strset(&tmp_wynik, wynik, 0); // if (dzielna != wynik) strset(&tmp_dzielna, dzielna, 0); } } inline void strcut(int start2, int end, struct string * source, struct string * destination) { int n; for (n=start2; n<=end;n++) { destination->dane[n-start2] = source->dane[n]; } destination->dane[n-start2]=0; destination->len = n-start2; } inline void int2str(int liczba, struct string * str) { int n, m=0; for (n=9; n >= 0 ; n--) { if (liczba/(int)pow2(10,n) > 0 || (liczba/(int)pow2(10,n) == 0 && m>0)) { str->dane[m] = liczba/(int)pow2(10,n)+48; liczba-= liczba/(int)pow2(10,n)*(int)pow2(10,n); m++; } } str->dane[m]=0; str->len=m; } int pow2 (int liczba, int potega) { int n, tmp=liczba; if (potega == 0) return 1; for (n = 1; n < potega; n++) tmp *= liczba; return tmp; } int str2int(struct string * str) { int n, tmp=0; for (n=0; n < str->len; n++) { if (str->dane[n] == 0) break; tmp += (str->dane[n]-48)*pow2(10,str->len-n-1); } return tmp; } int cmp_str(const void * a, const void * b) { struct string * x = *(struct string * const *)a; struct string * y = *(struct string * const *)b; return (strcmp(x->dane,y->dane)); } int onp (struct string ** rownania, struct string ** wynikLicz, struct string ** wynikMian, int id) { // do funkcji trafia str. postaci np.(_10_12+_1_2**) gdzie liczba to nr. indexu struct string tmp, tmp2, tmp3; int n,m=0, id1, id2; int n_wynik=0; int flaga, zwolnione=0; struct string ** licznikk1, ** mianownikk1, ** licznikk2, ** mianownikk2; int * wsk_id; struct string **wynikL = (struct string**)malloc(rownania[id]->ilosc_dzialan*sizeof(struct string*)); struct string **wynikM = (struct string**)malloc(rownania[id]->ilosc_dzialan*sizeof(struct string*)); for (n=0; n < rownania[id]->ilosc_dzialan; n++) { wynikL[n] = (struct string*)malloc(sizeof(struct string)); wynikM[n] = (struct string*)malloc(sizeof(struct string)); } for (n=0; n < rownania[id]->len; n++) { if (rownania[id]->dane[n] == ' ') continue; if (rownania[id]->dane[n] == '_') { //pocz. ulamka! n++; while(rownania[id]->dane[n]!= '_' && rownania[id]->dane[n]!= '+' && rownania[id]->dane[n]!= ' ' && rownania[id]->dane[n]!= '*' && rownania[id]->dane[n]!= '/') { //wycinanie ulamka tmp.dane[m] = rownania[id]->dane[n]; m++; n++; } n--; tmp.dane[m]=0; tmp.len = m; m=0; push(&tmp); } else if (rownania[id]->dane[n] == '+' || rownania[id]->dane[n] == '/' || rownania[id]->dane[n] == '*') { pop(&tmp); //a pop(&tmp2); //b -> b(op)a //id id1 = str2int(&tmp); id2 = str2int(&tmp2); if (id1 >= 10000 && id2 >= 10000) {//zakladam ze nie bedzie wiecej niz 10000 dzialan 10000x10kB ~ 100mB ramu id1-=10000; id2-=10000; licznikk1 = wynikL; mianownikk1 = wynikM; licznikk2 = wynikL; mianownikk2 = wynikM; flaga = 2; } else if (id1 >= 10000) { id1-=10000; licznikk1 = wynikL; mianownikk1 = wynikM; licznikk2 = wynikLicz; mianownikk2 = wynikMian; flaga = 1; wsk_id = &id1; } else if (id2 >= 10000) { id2-=10000; licznikk1 = wynikLicz; mianownikk1 = wynikMian; licznikk2 = wynikL; mianownikk2 = wynikM; flaga = 1; wsk_id = &id2; } else { licznikk1 = wynikLicz; mianownikk1 = wynikMian; licznikk2 = wynikLicz; mianownikk2 = wynikMian; flaga = 0; } if (flaga == 0) { // nowy wynik if (n+1 == rownania[id]->len) action(licznikk1, mianownikk1, id1, licznikk2, mianownikk2, id2, wynikLicz[id], wynikMian[id], rownania[id]->dane[n], 0); else action(licznikk1, mianownikk1, id1, licznikk2, mianownikk2, id2, wynikL[n_wynik], wynikM[n_wynik], rownania[id]->dane[n], 0); int2str(n_wynik+10000, &tmp3); n_wynik++; } else if (flaga == 1) { //do starej komorki if (n+1 == rownania[id]->len) action(licznikk1, mianownikk1, id1, licznikk2, mianownikk2, id2, wynikLicz[id], wynikMian[id], rownania[id]->dane[n], 1); else action(licznikk1, mianownikk1, id1, licznikk2, mianownikk2, id2, wynikL[*wsk_id], wynikM[*wsk_id], rownania[id]->dane[n], 1); int2str(*wsk_id+10000, &tmp3); } else { // zwolnij jeden wynik if (n+1 == rownania[id]->len) action(licznikk1, mianownikk1, id1, licznikk2, mianownikk2, id2, wynikLicz[id], wynikMian[id], rownania[id]->dane[n], 1); else action(licznikk1, mianownikk1, id1, licznikk2, mianownikk2, id2, licznikk2[id2], mianownikk2[id2], rownania[id]->dane[n], 1); int2str(id2+10000, &tmp3); n_wynik--; } push(&tmp3); } } //pop(&tmp); //wynik //sfd=0; stos.dane[0]=0; stos.len=0; for (n=0; n < rownania[id]->ilosc_dzialan; n++) { free(wynikL[n]); free(wynikM[n]); } free(wynikM); free(wynikL); return 0; //ok } inline void action(struct string ** licznik1, struct string ** mianownik1, int id1, struct string ** licznik2, struct string ** mianownik2, int id2, struct string * wynikL, struct string * wynikM, char dzialanie, int flaga) { //bez szukania najmniejszego mianownika struct string tmp, tmp2, tmp3, tmp_licznik1, tmp_licznik2, tmp_mianownik1, tmp_mianownik2; struct string * wynik, * wynik2, * wsk_licznik1, * wsk_licznik2, * wsk_mianownik1, * wsk_mianownik2; wsk_licznik1 = licznik1[id1]; wsk_licznik2 = licznik2[id2]; wsk_mianownik1 = mianownik1[id1]; wsk_mianownik2 = mianownik2[id2]; if (dzialanie == '+') { //sprowadzic do wspolnego mianownika //jezeli takie same mianowniki if (id1 == id2 && flaga == 0) { suma(wsk_licznik1, wsk_licznik2, &tmp2 , 0); //suma wynik = nwd(mianownik1[id1], &tmp2); dzielenie(mianownik1[id1], wynik, wynikM, 0); dzielenie(&tmp2, wynik, wynikL, 0); // return; } else { wynik2 = nww(mianownik1[id1],mianownik2[id2]); //tmp - wspolny mianownik if (wieksze(mianownik1[id1], mianownik2[id2], 0)!=2) { //jesli mianowniki nie sa rowne wsk_licznik1 = &tmp_licznik1; wsk_licznik2 = &tmp_licznik2; dzielenie(wynik2, mianownik1[id1], &tmp2, 0); //tmp2 - liczba przez ktora trzeba pomnozyc licznik1 mnozenie(licznik1[id1], &tmp2, wsk_licznik1); // tmp3 nowy licznik //strset(&tmp3, wsk_licznik1, 0); // tmp3 -> licznik1 dzielenie(wynik2, mianownik2[id2], &tmp2, 0); //tmp2 - liczba przez ktora trzeba pomnozyc licznik2 mnozenie(licznik2[id2], &tmp2, wsk_licznik2); // tmp3 nowy licznik //strset(&tmp3, wsk_licznik2, 0);// tmp3 -> licznik2 } suma(wsk_licznik1, wsk_licznik2, &tmp2 , 0); //suma wynik = nwd(wynik2, &tmp2); dzielenie(wynik2, wynik, wynikM, 0); dzielenie(&tmp2, wynik, wynikL, 0); } } else if (dzialanie == '*') { mnozenie(licznik1[id1], licznik2[id2], &tmp2); // mnozenie(mianownik1[id1], mianownik2[id2], &tmp); wynik = nwd(&tmp, &tmp2); // skraca przez 1 dzielenie(&tmp, wynik, wynikM, 0); dzielenie(&tmp2, wynik, wynikL, 0); } else if (dzialanie == '/') { //skracanie if (id1 == id2 && flaga == 0) { wynikL->dane[0] = '1'; wynikL->dane[1] = 0; wynikL->len = 1; wynikM->dane[0] = '1'; wynikM->dane[1] = 0; wynikM->len = 1; return; } else { if (wieksze(licznik1[id1],licznik2[id2], 0) == 2) {//jesli sa takie same wsk_licznik1 = &tmp_licznik1; wsk_licznik2 = &tmp_licznik2; wsk_licznik1->dane[0] = '1'; wsk_licznik1->dane[1] = 0; wsk_licznik1->len = 1; wsk_licznik2->dane[0] = '1'; wsk_licznik2->dane[1] = 0; //skracaja sie do 1 wsk_licznik2->len = 1; } else { //skracanie przez wspolny dzielnik } //skracanie end if (wieksze(mianownik1[id1],mianownik2[id2], 0) == 2) { wsk_mianownik1 = &tmp_mianownik1; wsk_mianownik2 = &tmp_mianownik2; wsk_mianownik1->dane[0] = '1'; wsk_mianownik1->dane[1] = 0; wsk_mianownik1->len = 1; wsk_mianownik2->dane[0] = '1'; wsk_mianownik2->dane[1] = 0; //skracaja sie do 1 wsk_mianownik2->len = 1; } mnozenie(wsk_licznik1, wsk_mianownik2, &tmp); //mnozenie przez odwrotnosc mnozenie(wsk_licznik2, wsk_mianownik1, &tmp2); wynik = nwd(&tmp, &tmp2); dzielenie(&tmp, wynik, wynikM, 0); dzielenie(&tmp2, wynik, wynikL, 0); // } } } inline void pop(struct string * ulamek) { // # marker int n, len_ulamka=0; n=stos.len-2; while (stos.dane[n]!='#' && n >=0) { len_ulamka++; n--; } for (n=len_ulamka-1; n >= 0; n--) { ulamek->dane[n] = stos.dane[(stos.len-2)-(len_ulamka-1-n)]; } ulamek->dane[len_ulamka]=0; ulamek->len = len_ulamka; stos.dane[stos.len-len_ulamka-1] = 0; stos.len = stos.len-len_ulamka-1; } inline void push (struct string * ulamek) { // # marker int n; for (n=stos.len; n < stos.len+ulamek->len; n++) { stos.dane[n] = ulamek->dane[n-stos.len]; } stos.dane[n]='#'; //marker stos.dane[n+1]=0; // koniec struct stringu stos.len = n+1; }