program fraction; uses crt; type cislo=longint; {cisla obsazena v citateli i jmenovateli)} type fract=record {typ zlomek} cit: cislo; {citatel} jmen: cislo; {jmenovatel} end; var err, fileout, vstup: boolean; var pokus:fract; tmp: string; vysledek: array [1..3] of string; klavesa: char; priklad: byte; nula, jedna, deset, MAXCISLO: cislo; vnoreni: integer; preteceni: integer; pozice: integer; rozpoznavam, rounded: boolean; F,inp: text; const vystup='output.txt'; {seznam funkci} {funkce cisel} procedure init; forward; {inicializuje globalni promenne} procedure nuluj(var co:cislo);forward; {nastavi dane cislo na nulu} procedure mydiv(var vysl: cislo; co, cim:cislo);forward; {celociselne deleni} function getrad(co:cislo):longint;forward; {zjisti rad cisla} function vetsi(co, nezco:cislo):boolean;forward; {zjisti, co je vetsi} procedure mymod(var vysl:cislo; co, cim: cislo);forward; {vrati modulo} procedure vydel(var vysl:cislo; co, cim:cislo); forward; {deleni cisel} procedure nsd(var vysl:cislo; co1, co2: cislo); forward; {vrati nejvetsi spolecny delitel} procedure secti(var vysl:cislo; co, scim:cislo);forward; {scitani cisel} procedure odecti(var vysl:cislo; co, odceho:cislo);forward; {odcitani cisel} function rovna(co, cemu:cislo):boolean;forward; {zjisti, jestli se cisla vzajemne rovnaji} procedure nasob(var vysl:cislo; co, cim:cislo);forward; {nasobeni cisel} procedure zmenrad(var vysl:cislo; okolik:integer);forward; {zmeni rad cisla} procedure prirad(var vysl:cislo; co:string);forward; {rozpoznani cisel v textovem retezci(zavisi na hodnotach rozpoznavam a pozice) a pracuje s promenou preteceni} function vypis(co: cislo):string;forward; {vypise cislo} {funkce zlomku} procedure fsecti(var vysl:fract; co:fract; scim:fract);forward; {scitani zlomku} procedure fodecti(var vysl:fract; co, odceho:fract); forward; {odcitani zlomku - prevede se na scitani} procedure fnasob(var vysl:fract; co, cim:fract);forward; {nasobeni zlomku} procedure fvydel(var vysl:fract; co, cim:fract);forward; {deleni zlomku - prevede se na nasobeni} procedure fkrat(var co:fract);forward; {kraceni zlomku} function fvypis(co:fract):string;forward; {vypsani zlomku(do stringu)} procedure fprirad(var vysl:fract; co:string);forward; {rozpoznani zlomku} procedure vyraz(var co: string; var vysl: fract);forward; {rozpozna a vyhodnoti zadany vyraz} {funkce TeXu} function totex(co:string):string; forward; {prevod vypisu do TeXu} procedure hlavicka(var F: text); forward; {zapise TeXovou hlavicku} {vlastni funcke} {funkce obycejnych cisel} procedure init; {inicializuje globalni promenne} begin nula:=0; jedna:=1; deset:=10; MAXCISLO:=32000; vstup:=false; rounded:=false; fileout:=false; vnoreni:=0; end; procedure nuluj(var co:cislo); {nastavi dane cislo na nulu} begin secti(co, nula, nula); end; procedure mydiv(var vysl: cislo; co, cim:cislo); {celociselne deleni} begin vysl:= co div cim; end; function getrad(co:cislo):longint; {zjisti rad cisla} var tmp:cislo; i:longint; begin i:=0; while not rovna(co,nula) do begin mydiv(co, co, deset); inc(i); end; getrad:=i; end; function vetsi(co, nezco:cislo):boolean; {zjisti, co je vetsi} begin if co>nezco then begin vetsi:=true; end else vetsi:=false; end; procedure mymod(var vysl:cislo; co, cim: cislo); {vrati modulo} begin mydiv(vysl, co, cim); nasob(vysl, vysl, cim); odecti(vysl, vysl, co); end; procedure vydel(var vysl:cislo; co, cim:cislo); {deleni cisel} var tmp1, tmp2:cislo; begin mydiv(vysl, co, cim); secti(tmp1, jedna, jedna); {zaokrouhlovani} mymod(tmp2, co, cim); mydiv(tmp1, cim, tmp1); if vetsi(tmp2, tmp1) then secti(vysl, vysl, jedna); end; procedure nsd(var vysl:cislo; co1, co2: cislo); {vrati nejvetsi spolecny delitel} var zbytek1, zbytek2, zbytek3: cislo; begin zbytek3:=jedna; if vetsi(co1, co2) then begin secti(zbytek1, nula, co1); secti(zbytek2, nula, co2); end else begin secti(zbytek1, nula, co2); secti(zbytek2, nula, co1); end; while vetsi(zbytek3, nula) do begin mymod(zbytek3, zbytek1, zbytek2); secti(zbytek1, nula, zbytek2); secti(zbytek2, nula, zbytek3); end; secti(vysl, zbytek1, nula); end; procedure secti(var vysl:cislo; co, scim:cislo); {scitani cisel} begin vysl:=co+scim; end; procedure odecti(var vysl:cislo; co, odceho:cislo); {odcitani cisel} begin vysl:=odceho-co; end; function rovna(co, cemu:cislo):boolean; {zjisti, jestli se cisla vzajemne rovnaji} begin if co=cemu then begin rovna:=true; end else rovna:=false; end; procedure nasob(var vysl:cislo; co, cim:cislo); {nasobeni cisel} begin vysl:=co*cim; end; procedure zmenrad(var vysl:cislo; okolik:integer); {zmeni rad cisla} var i:integer; begin if okolik<>0 then begin if okolik>0 then begin for i:=1 to okolik do nasob(vysl, vysl, deset); end else begin for i:=-1 downto okolik do vydel(vysl, vysl, deset); if rovna(vysl, nula) then secti(vysl, vysl, jedna); end; end; end; procedure prirad(var vysl:cislo; co:string); {rozpoznani cisel v textovem retezci(zavisi na hodnotach rozpoznavam a pozice) a pracuje s promenou preteceni} var i,tmp,MAXRAD: integer; begin MAXRAD:=2*getrad(MAXCISLO)-1; if rozpoznavam then begin i:=pozice-1; end else i:=0; nuluj(vysl); while (i='0') and (co[i+1]<='9') do begin i:=i+1; if getrad(vysl)'_') or (pozice>(length(co)-1)) or ((co[pozice]='_') and (co[mez]='('))) then begin inc(pozice); prirad(vysl.jmen, co); end else secti(vysl.jmen, jedna, nula); if (pret1>0) and (pret1>preteceni) then begin zmenrad(vysl.jmen, preteceni-pret1); rounded:=true; end; if (preteceni>0) and (pret10 then pozice:=tmp; end; procedure vyraz(var co: string; var vysl: fract); {rozpozna a vyhodnoti zadany vyraz} var konec: integer; zlomek1, zlomek2: fract; tmp: string; last, state: boolean; id: integer; begin tmp:='('; state:=rozpoznavam; inc(vnoreni); id:=vnoreni; inc(pozice); nuluj(vysl.cit); fkrat(vysl); nuluj(zlomek1.cit); fkrat(zlomek1); rozpoznavam:=true; {precte se vstupujici string a do stringu tmp se ulozi tak, ze se vypocitaji veskere zavorky, nasobeni a deleni. Je-li mezi vyrazy znak pro zlomek, nahradi se delenim} while (co[pozice]<>')') and (pozice')') and (pozice')') do begin case co[kde] of '(' : begin cislo:='{({'+vyraztotex(co)+'})}'; inc(kde); last:=true; end; '0'..'9': begin cislo:=''; last:=true; while (co[kde]<='9') and (co[kde]>='0') and (kde='0') and (co[kde]<='9') then begin while (co[kde]<='9') and (co[kde]>='0') and (kde'X') do begin {zobrazeni uvodni nabidky} clrscr; priklad:=0; tmp:=''; while length(tmp)<30 do tmp:=tmp+' '; tmp:=tmp+'Fractions'; writeln(tmp); writeln(''); writeln('Ovladani:'); tmp:=' m - Zobrazovat mezivysledky'; if vnoreni=0 then begin tmp:=tmp+' [X]'; end else tmp:=tmp+' [ ]'; writeln(tmp); tmp:=' i - Vstup ze souboru '; if vstup then begin tmp:=tmp+' [X]'; end else tmp:=tmp+' [ ]'; writeln(tmp); tmp:=' o - Vystup do souboru '; if fileout then begin tmp:=tmp+' [X]'; end else tmp:=tmp+' [ ]'; writeln(tmp); writeln(' c - Vycistit vystupni soubor'); writeln(' t - Export do TeXu'); writeln(' p - Pocitat'); writeln(' x - Konec'); writeln(''); writeln('- - - - - - - - - - - - - - - - - - - - -'); writeln(''); klavesa:=readkey; if (klavesa>'Z') then klavesa:=chr(ord(klavesa)-ord('a')+ord('A')); case klavesa of {po stisku klavesy se rozhodne, co dal} 'P': {vse je nastaveno a jde se pocitat} begin if vstup then begin err:=false; Assign(inp, 'input.txt'); {vstup ze souboru} {$I-} reset(inp); if eof(inp) {$I+} or (IOResult<>0) then begin Write(IOResult); Writeln(' - RUNTIME ERROR!!!'); writeln('Vstupni soubor neexistuje, nebo je prazdny!'); err:=true; end; end; if not err then begin repeat if not vstup then begin writeln('Zadej vyraz:'); {vstup z klavesnice} readln(tmp); end else Readln(inp, tmp); pozice:=1; rozpoznavam:=true; pozice:=1; vysledek[2]:=''; vysledek[1]:=tmp; tmp:='('+tmp+')'; vyraz(tmp, pokus); rozpoznavam:=false; vysledek[3]:=(fvypis(pokus)); if fileout then begin Assign(F, vystup); {vystup do souboru} {$I-} Append(F); {$I+} if IOResult<>0 then begin Rewrite(F); end; Writeln(F, ''); Writeln(F, 'Vyraz'); Writeln(F, 'Zadani:'); writeln('Zadani:'); Writeln(F, '='+vysledek[1]); writeln(vysledek[1]); if not (vysledek[2]='') then begin Writeln(F, 'Mezivysledek:'); Writeln(F, '='+vysledek[2]); end; Writeln(F, 'Vysledek:'); Writeln(F, '='+vysledek[3]); Close(F); end; if not (vysledek[2]='') then begin Writeln('Mezivysledek:'); Writeln(vysledek[2]); end; Writeln('Vysledek:'); Writeln(vysledek[3]); writeln(''); until not(vstup and (not(eof(inp)))); if vstup then close(inp); end; klavesa:=readkey; klavesa:=' '; end; 'O': begin fileout:= not fileout; {vystup do souboru (zap/vyp)} end; 'I': begin vstup:= not vstup; {vstup ze souboru (zap/vyp)} end; 'C': begin Assign(F, vystup); {vycisteni vystupniho souboru} Rewrite(F); writeln(F, ''); close(F); writeln('soubor byl vycisten...'); klavesa:=readkey; klavesa:=' '; end; 'M': begin {nastaveni zobrazovani mezivysledku} if vnoreni>0 then vnoreni:=-1; inc(vnoreni); end; 'T': begin Assign(F, vystup); {uzavreni souboru a vypis} {$I-} Append(F); {$I+} if IOResult<>0 then begin write(IOResult); Writeln(' - RUNTIME ERROR!!!'); writeln('soubor vysledku neexistuje, nebo se pouziva!'); end else begin close(F); Assign(inp, vystup); Reset(inp); assign(F, 'Vysledky.tex'); rewrite(F); hlavicka(F); while not eof(inp) do begin readln(inp, tmp); writeln(F, totex(tmp)); end; writeln(F,'\end{document}'); close(F); close(inp); { assign(F, vystup); rewrite(F); writeln(F,''); close(F);} writeln('Soubor byl zapsan jako Vysledky.tex'); end; klavesa:=readkey; klavesa:=' '; end; end; end; end.