rendered paste body#include <stdlib.h>
#include <stdio.h>
#include <string.h>
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; i<zaalokowane; i++) {
free(rownania[i]);
free(zmienne[i]);
free(wynikL[i]);
free(wynikM[i]);
}
//free(rownania[0]);
//free(zmienne[0]);
free(rownania);
free(zmienne);
free(wynikL);
free(wynikM);
for (n=927; n < 1001; n++)
printf("case %d N\n", n);
return 0;
}
inline void reverse (struct string * str) {
int n;
char tmp;
for (n = 0; n < str->len/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); //<to do>
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 <brak warunku> <to do>
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); // <brak warunku> skraca przez 1 <to do>
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 <to do>
}
//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;
}