All pastes #499080 Raw Edit

Miscellany

public text v1 · immutable
·published 2007-05-20 21:16 UTC
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&#322;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;
}