]> git.llucax.com Git - z.facultad/75.40/2do-cuat/polinomios.git/blob - poli_4.pas
Import inicial después del "/var incident". :(
[z.facultad/75.40/2do-cuat/polinomios.git] / poli_4.pas
1 program Polinomios;\r
2 \r
3 uses\r
4     CRT, DOS; { Declaracion de funciones predefinidas\r
5                 para crear la interfaz grafica }\r
6 \r
7 const\r
8      VERSION = '0.8.0a (POLI_4)'; { version del programa }\r
9 \r
10      TAM_MAX = 100; { Tama¤o maximo del vector que almacena\r
11                       la multiplicacion de polinomios }\r
12      TAM = TAM_MAX div 2; { Tama¤o maximo (virtual) del vector que contiene\r
13                             los vector con los que se va a operar }\r
14      CR = chr(13); { caracter de retorno del carro }\r
15      LF = chr(10); { caracter de nueva linea }\r
16      ENDF = chr(26); { caracter de fin del archivo }\r
17      TAB = chr(9); { caracter de tabulacion }\r
18      SPACE = chr(32); { caracter de espacio }\r
19 \r
20 type\r
21     { Tipo de dato para identificar el estado de la entrada de datos }\r
22     Estado = (INICIO, COEF_BUSCA, COEF, COEF_PUNTO, COEF_FIN, EXP_BUSCA, EXP, EXP_FIN, EXP_FIN_BUSCA, POLI_FIN, FIN, ERROR);\r
23     Vector = array [0..TAM_MAX-1] of real; { vector para almacenar los polinomios }\r
24 \r
25 \r
26   {########################################################}\r
27 \r
28   procedure inicializaVector(var v: Vector);\r
29   { procedimiento que inicializa un vector de tama¤o tam }\r
30 \r
31   var i: integer; { indice para usar en el ciclo for }\r
32 \r
33   begin { inicializaVector }\r
34        for i := 0 to TAM_MAX - 1 do { recorre el vector }\r
35            v[i] := 0;               { inicializa la variable actual en 0 }\r
36   end; { inicializaVector }\r
37 \r
38   {########################################################}\r
39 \r
40   function ObtenerNombreArchivo: String;\r
41   { funcion que obtiene un nombre de archivo valido (es decir, el nombre\r
42     de un archivo que exista) }\r
43 \r
44     {########################################################}\r
45 \r
46     function fileExists(FileName: String): Boolean;\r
47     { funcion extraida de la ayuda del Turbo Pascal 7\r
48       indica si el archivo existe }\r
49 \r
50       var\r
51          F: file;\r
52 \r
53       begin\r
54            {$I-}\r
55            Assign(F, FileName);\r
56            FileMode := 0;  { Set file access to read only }\r
57            Reset(F);\r
58            Close(F);\r
59            {$I+}\r
60            FileExists := (IOResult = 0) and (FileName <> '');\r
61       end;  { FileExists }\r
62 \r
63     {########################################################}\r
64 \r
65     { Continuacion de la funcion ObtenerNombreArchivo }\r
66     const\r
67          DEFAUL_FILE_NAME = 'datos.txt'; { nombre del archivo por defecto }\r
68 \r
69     var\r
70        tmp: String; { cadena para almacenar el resultado temporal }\r
71 \r
72     begin { ObtenerNombreArchivo }\r
73          { mensaje para entrada del nombre de archivo }\r
74          writeln('Ingrese el nombre del archivo con los datos (ENTER = ', DEFAUL_FILE_NAME, '):');\r
75          readln(tmp); { entrada del nombre de archivo }\r
76          if tmp = '' then tmp := DEFAUL_FILE_NAME; { se fija si no se ingreso nada y reasigana el nombre }\r
77          while not fileExists(tmp) do { repite el proceso hasta que el archivo exista }\r
78            begin\r
79                 write('El archivo ', tmp, ' no existe. Ingrese un nombre correcto');\r
80                 if tmp = DEFAUL_FILE_NAME { si es el nombre de archivo predeterminado }\r
81                    then                   { entonces, elije un mensaje apropiado }\r
82                        write(': ')\r
83                    else\r
84                      begin                { si no es el predeterminado, muestra otro mensaje }\r
85                           writeln('.');\r
86                           write('(ENTER = ', DEFAUL_FILE_NAME, '): ');\r
87                      end;\r
88                 readln(tmp); { vuelve a leer el nombre del archivo para ser verificado }\r
89                 if tmp = '' then tmp := DEFAUL_FILE_NAME; { asigna como nombre de archivo al predeterminado\r
90                                                             si no se escribio nada }\r
91            end; { fin del loop de verificacion }\r
92          ObtenerNombreArchivo := tmp; { asigna el nombre correcto al valor de salida de la funcion }\r
93     end; { ObtenerNombreArchivo }\r
94 \r
95     {########################################################}\r
96 \r
97     function trans(c: char; e: Estado): Estado;\r
98     { establece el estado en el que se encuentra la lectura }\r
99     { c es el caracter que se leyo, e es el estado actual de la lectura }\r
100 \r
101     begin { trans }\r
102          case e of { acciona segun es estado actual de la lectura }\r
103               INICIO: { estado de inicio de la lectura }\r
104                      case c of { acciona segun el caracter leido }\r
105                          '-', '0'..'9': trans := COEF; { si es un numero (o negativo), empieza a leer el coeficiente }\r
106                          SPACE, TAB, CR, LF: trans := COEF_BUSCA; { si es un caracter tipo "espacio", busca el prox. coef. }\r
107                          else trans := ERROR; { si es otro, da ERROR }\r
108                      end;\r
109               COEF_BUSCA: { estado de busqueda del primer ceoficiente del polinomio }\r
110                      case c of { acciona segun el caracter leido }\r
111                          '-', '0'..'9': trans := COEF; { si es un numero (o negativo), empieza a leer el coeficiente }\r
112                          SPACE, TAB, CR, LF: trans := COEF_BUSCA; { si es un caracter tupo "espacio", sigue buscando }\r
113                          ENDF: trans := FIN; { si es el caracter de fin de archivo, pasa al estado de tarea finalizada }\r
114                          else trans := ERROR; { si es otro, da ERROR }\r
115                      end;\r
116               COEF: { estado de lectura del coeficiente del termino del polinomio (sin punto decimal) }\r
117                    case c of { acciona segun el caracter leido }\r
118                         '0'..'9': trans := COEF; { si es un numero sigue con el mismo estado }\r
119                         '.': trans := COEF_PUNTO; { si es punto cambia al estado COEF_PUNTO }\r
120                         SPACE, TAB: trans := COEF_FIN; { si es un espacio o un tabulador, finaliza la lectura del coeficiente }\r
121                         else trans := ERROR; { si es otra cosa, pasa a estado de error }\r
122                    end;\r
123               COEF_PUNTO: { estado de lectura del coeficiente del termino del polinomio (con punto decimal) }\r
124                    case c of { acciona segun el caracter leido }\r
125                         '0'..'9': trans := COEF_PUNTO; { si es un numero sigue con el mismo estado }\r
126                         SPACE, TAB: trans := COEF_FIN; { si es un espacio o un tabulador, finaliza la lectura del coeficiente }\r
127                         else trans := ERROR; { si es otra cosa, pasa a estado de error }\r
128                    end;\r
129               COEF_FIN: { estado de fin de la lectura del coeficiente del termino del polinomio }\r
130                        case c of { acciona segun el caracter leido }\r
131                            '0'..'9': trans := EXP; { si el caracter es un numero establece el estado en EXP (exponente) }\r
132                            SPACE, TAB: trans := EXP_BUSCA; { si es un espacio o tabulador, pasa a buscar el proximo exponente }\r
133                            else trans := ERROR; { si no es ninguno de los anteriores, el estado pasa a ERROR }\r
134                        end;\r
135               EXP_BUSCA: { estado de busqueda del proximo exponente }\r
136                        case c of { acciona segun el caracter leido }\r
137                            '0'..'9': trans := EXP; { si el caracter es un numero, empieza a leer el exponente }\r
138                            SPACE, TAB: trans := EXP_BUSCA; { si es un espacio o tabulador, sigue buscando }\r
139                            else trans := ERROR; { si no es ninguno de los anteriores, el estado pasa a ERROR }\r
140                        end;\r
141               EXP: { estado de lectura del exponente del termino actual del polinomio }\r
142                   case c of { acciona segun el caracter leido }\r
143                        '0'..'9': trans := EXP; { si es un digito, sigue en el mismo estado }\r
144                        CR: trans := EXP_FIN; { si es un ratorno de carro, finaliza el exponente\r
145                                                (quiere decir que hubo un <ENTER>) }\r
146                        ENDF: trans := FIN; { si es el final del archivo, se indica que termino su tarea }\r
147                        else trans := ERROR; { si es otra cosa, devuelve ERROR }\r
148                   end;\r
149               EXP_FIN: { estado de fin de la lectura del exponente del termino actual del polinomio }\r
150                       if c = LF then trans := EXP_FIN_BUSCA { debe ser un caracter de nueva linea (para completar el <ENTER>) }\r
151                                 else trans := ERROR; { si no lo es, devuelve ERROR }\r
152               EXP_FIN_BUSCA: { estado de fin de lectura de la nueva linea (luego de finalizar el exponente\r
153                                ahora decide si termino el polinomio o si sigue leyendo el proximo coeficiente }\r
154                       case c of { acciona segun el caracter leido }\r
155                            '-', '0'..'9': trans := COEF; { si es un digito (o negativo), pasa a leer en proximo coeficiente }\r
156                            CR: trans := POLI_FIN; { si es un ratorno de carro o nueva linea, finaliza el polinomio }\r
157                            else trans := ERROR; { si es otra cosa, devuelve ERROR }\r
158                       end;\r
159               POLI_FIN: { estado de finalizacion del polinomio actual }\r
160                       if c = LF then trans := COEF_BUSCA { debe ser un caracter de nueva linea (para completar el <ENTER>),\r
161                                                            entonces pasa a buscar el primer coeficiente del nuevo polinomio }\r
162                                 else trans := ERROR; { si no lo es, devuelve ERROR }\r
163               FIN: { estado que adquiere cuando se finalizo la tarea }\r
164                   trans := FIN; { se queda en este estado avisando que termino su tarea }\r
165               else { otro estado, no deberia ocurrir, salvo que se le pase a la funcion un estado de ERROR }\r
166                   trans := ERROR; { si es otro, da ERROR }\r
167          end; { case }\r
168     end; { trans }\r
169 \r
170     {########################################################}\r
171 \r
172     function cargarVectores(var v1, v2: Vector): boolean;\r
173     { Funcion que abre el archivo de texto con los datos, lo carga en el vector procesandolo debidamente a medida\r
174       que lo lee y, al finalizar, cierra el archivo de texto.\r
175       v1 es el primer vector a cargar\r
176       v2 es el segundo vector a cargar\r
177       devuelve true si la lectura fue hecha con exito, false si hubo un error }\r
178 \r
179     var\r
180        f: Text; { archivo de texto con los datos }\r
181        c: char; { caracter que se extrae del archivo de texto }\r
182        nombreArchivo: String; { nombre del archivo de datos }\r
183        est: Estado; { Indicador del estado actual de la lectura }\r
184        seguir: boolean; { indicador para saber si debe seguir con el proceso }\r
185        i, { indice del vector del polinomio para ser inicializado }\r
186        iExp, { valor temporal para almacenar al exponente }\r
187        code, { almacena el resultado de la funcion val (no se usa porque los\r
188                datos ya estan validados }\r
189        poliN: integer; { numero del polinomio que se esta leyendo }\r
190        rCoef: real; { valor temporal para almacenar al coeficiente }\r
191        exponente, { string que representa al exponente leido }\r
192        coeficiente: String; { string que representa al coeficiente leido }\r
193 \r
194     begin { cargarVectores }\r
195          rCoef := 0.0; { inicializacion de variable }\r
196          iExp := 0;    { inicializacion de variable }\r
197          coeficiente := ''; { inicializacion de variable }\r
198          exponente := '';   { inicializacion de variable }\r
199          est := INICIO; { empieza con el estado de INICIO }\r
200          poliN := 1; { establece que se procesara el primer polinomio }\r
201          inicializaVector(v1); { inicializacion del vector 1 (primer polinomio) }\r
202          inicializaVector(v2); { inicializacion del vector 2 (segundo polinomio) }\r
203          nombreArchivo := ObtenerNombreArchivo; { obtiene el nombre del archivo }\r
204          assign(f, nombreArchivo); { asigna la variable al nombre del archivo }\r
205          reset(f); { abre el archivo para leerlo desde el principio }\r
206          seguir := true; { inicializa seguir e true para comenzar el bucle }\r
207          while seguir do begin { continua mientras seguir sea true }\r
208            read(f, c); { lee un caracter del archivo de texto }\r
209            est := trans(c, est); { establece el nuevo estado de lectura }\r
210            case est of { toma una desicion dependiendo del estado en que se encuentre }\r
211                 INICIO: ; { No hace nada, nunca toma este valor. Solo incica que empezo el proceso }\r
212                 COEF_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos }\r
213                 COEF, COEF_PUNTO: { Si esta leyendo el coeficiente ... }\r
214                    coeficiente := coeficiente + c; { concatena el caracter a la representacion\r
215                                                      de texto del coeficiente }\r
216                 COEF_FIN: ; { Si termino de leer el coeficiente, no hace nada, la asignacion\r
217                               se realiza cuando termina de leer el exponente (es necesario\r
218                               para establecer el indice del vector }\r
219                 EXP_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos }\r
220                 EXP: { Si esta leyendo el exponente ... }\r
221                    exponente := exponente + c; { concatena el caracter a la representacion\r
222                                                  de texto del exponente }\r
223                 EXP_FIN: { Si termino de leer el exponente, hace las asignaciones correspondientes }\r
224                         begin { convirtiendo las cadenas de texto en real e integer, segun el caso }\r
225                              val(coeficiente, rCoef, code); { convierte el coeficiente en real }\r
226                              val(exponente, iExp, code); { convierte el exponente en integer }\r
227                              if iExp < TAM { si el exponente es menor que el tama¤o maximo permitido ... }\r
228                                 then if poliN = 1 then v1[iExp] := rCoef { asigna el valor correspondiente }\r
229                                                   else v2[iExp] := rCoef { al polinomio correspondiente }\r
230                                 else est := ERROR; { si no es menor, pone el estado en ERROR }\r
231                              coeficiente := ''; { una vez asignados, vacia los valores del coeficiente y el }\r
232                              exponente := '';   { exponente para poder realizar las lecturas de los proximos }\r
233                         end;\r
234                 EXP_FIN_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos }\r
235                 POLI_FIN: { Si termino la lectura de un polinomio ... }\r
236                          if poliN = 1 then poliN := 2  { si se leyo el 1er polinomio, se indica que se leera el 2do }\r
237                                       else est := FIN; { si no (ya se leyo el segundo), pone el estado en FIN }\r
238                 FIN: { Si se finalizaron las tareas ... }\r
239                     begin\r
240                          { este codigo es el mismo que el de EXP_FIN, se repite aca solo por si el final del\r
241                            archivo esta pegado al fin del ultimo exponente, en cuyo caso no pasa por el estado\r
242                            de EXP_FIN (y, por ende, no se pueden hacer las asignaciones correspondientes }\r
243                          val(coeficiente, rCoef, code); { convierte el coeficiente en real }\r
244                          val(exponente, iExp, code); { convierte el exponente en integer }\r
245                          if iExp < TAM { si el exponente es menor que el tama¤o maximo permitido ... }\r
246                             then if poliN = 1 then v1[iExp] := rCoef { asigna el valor correspondiente }\r
247                                               else v2[iExp] := rCoef { al polinomio correspondiente }\r
248                             else est := ERROR; { si no es menor, pone el estado en ERROR }\r
249                          coeficiente := ''; { una vez asignados, vacia los valores del coeficiente y el }\r
250                          exponente := '';   { exponente para poder realizar las lecturas de los proximos }\r
251                          { fin del codigo identico a EXP_FIN }\r
252                          if poliN = 2 then cargarVectores := true { si se leyeron los 2 polinomios, devuelve true }\r
253                                       else cargarVectores := false; { si no se leyeron los dos, devuelve false }\r
254                          seguir := false; { poner seguir en false para que se termine el bucle }\r
255                     end;\r
256                 ERROR:  { Si hubo un error ... }\r
257                    begin\r
258                         cargarVectores := false; { Se devuelve false (hubo un ERROR, no se leyeron bien los vectores) }\r
259                         seguir := false; { seguir se pone en false para que termine el bucle }\r
260                    end;\r
261            end; { case }\r
262          end; { while }\r
263          close(f); { se cierra el archivo de lectura de datos }\r
264     end; { cargarVectores }\r
265 \r
266     {########################################################}\r
267 \r
268     procedure suma(v1, v2: Vector; var vr: Vector);\r
269     { procedimiento que suma dos polinomios.\r
270       v1: vector que contiene el primer polinomio a sumar\r
271       v2: vector que contiene el segundo polinomio a sumar\r
272       vr: vector donde se almacenara el resultado de la suma }\r
273 \r
274     var\r
275        i: integer; { indice para usar en el ciclo for }\r
276 \r
277     begin { suma }\r
278          inicializaVector(vr);        { inicializa al vector resultado en 0 para evitar que quede "basura" }\r
279          for i := 0 to TAM - 1 do     { recorre el vector (de tama¤o maximo TAM) }\r
280              vr[i] := v1[i] + v2[i];  { suma los coeficientes de los terminos con igual exponente }\r
281     end; { suma }\r
282 \r
283     {########################################################}\r
284 \r
285     procedure resta(v1, v2: Vector; var vr: Vector);\r
286     { procedimiento que resta dos polinomios.\r
287       v1: vector que contiene el primer polinomio\r
288       v2: vector que contiene el polinomio para restarle al primero\r
289       vr: vector donde se almacenara el resultado de la resta }\r
290 \r
291     var\r
292        i: integer; { indice para usar en el ciclo for }\r
293 \r
294     begin { resta }\r
295          inicializaVector(vr);        { inicializa al vector resultado en 0 para evitar que quede "basura" }\r
296          for i := 0 to TAM - 1 do     { recorre el vector (de tama¤o maximo TAM) }\r
297              vr[i] := v1[i] + v2[i];  { resta los coeficientes de los terminos con igual exponente }\r
298     end; { resta }\r
299 \r
300     {########################################################}\r
301 \r
302     procedure producto(v1, v2: Vector; var vr: Vector);\r
303     { procedimiento que multiplica dos polinomios.\r
304       v1: vector que contiene el primer polinomio a multiplicar\r
305       v2: vector que contiene el segundo polinomio a multiplicar\r
306       vr: vector donde se almacenara el resultado de la multiplicacion }\r
307 \r
308     var\r
309        i, j: integer; { indices para usar en los ciclos for }\r
310 \r
311     begin { producto }\r
312          inicializaVector(vr);        { inicializa al vector resultado en 0 para evitar que quede "basura" }\r
313          for i := 0 to TAM - 1 do     { recorre el 1er vector (de tama¤o maximo TAM) }\r
314              for i := 0 to TAM - 1 do { recorre el 2do vector (de tama¤o maximo TAM) }\r
315                  vr[i+j] := vr[i+j] + (v1[i] * v2[j]);\r
316                  { multiplica los coeficientes de los terminos y lo almacena en la posicion del exponente }\r
317                  { igual a la suma de los exponentes de v1 y v2, sumando el valor previo de dicha posicion }\r
318     end; { producto }\r
319 \r
320     {########################################################}\r
321 \r
322     procedure division(v1, v2: Vector; var vr, vResto: Vector);\r
323     { procedimiento que divide dos polinomios.\r
324       v1: vector que contiene el polinomio denominador\r
325       v2: vector que contiene el polinomio divisor\r
326       vr: vector donde se almacenara el resultado de la division\r
327       vResto: vector donde se almacenara el resto de la division }\r
328     var\r
329        i, j: integer; { indices para usar en los ciclos for }\r
330        vRTmp,         { vector auxuliares para almacenar el termino actual del resultado }\r
331        vTmp: Vector;  { vector auxuliares para almacenar el polinomio que es la multiplicacion del\r
332                         termino actual del resultado por el divisor }\r
333 \r
334     begin { division }\r
335          inicializaVector(vr);     { inicializa al vector resultado en 0 para evitar que quede "basura" }\r
336          inicializaVector(vResto); { inicializa al vector resultado en 0 para evitar que quede "basura" }\r
337          inicializaVector(vTmp);   { inicializa al vector resultado en 0 para evitar que quede "basura" }\r
338          inicializaVector(vRTmp);  { inicializa al vector resultado en 0 para evitar que quede "basura" }\r
339          for i := TAM - 1 downto 0 do  { recorre el 1er vector (de tama¤o maximo TAM) de atras para adelante }\r
340              if v1[i] <> 0 then break;\r
341              { busca empezando por el indice (exponete) mas alto el primer coeficiente no nulo }\r
342              { si lo encuentra sale del for dejando al valor de i como el de dicho inidice }\r
343          for j := TAM - 1 downto 0 do  { recorre el 2do vector (de tama¤o maximo TAM) de atras para adelante }\r
344              if v2[j] <> 0 then break;\r
345              { busca empezando por el indice (exponete) mas alto el primer coeficiente no nulo }\r
346              { si lo encuentra sale del for dejando al valor de j como el de dicho inidice }\r
347          while i >= j do\r
348            begin\r
349                 vr[i-j] := v1[i] / v2[j];\r
350                 vRTmp[i-j] := vr[i-j];\r
351                 producto(vRTmp, v2, vTmp);\r
352                 resta(v1, vTmp, v1);\r
353                 vRTmp[i-j] := 0;\r
354                 for i := i downto 0 do\r
355                     if v1[i] <> 0 then break;\r
356                     { busca empezando por el indice (exponete) mas alto el primer coeficiente no nulo }\r
357                     { si lo encuentra sale del for dejando al valor de i como el de dicho inidice }\r
358            end; { while }\r
359          vResto := v1;\r
360     end; { division }\r
361 \r
362     {########################################################}\r
363 \r
364 { Continuacion del programa principal }\r
365 \r
366 var\r
367    i: integer; { variable auxiliar }\r
368    v1, v2, vResult, vResto: Vector;\r
369    resultado: boolean;\r
370 \r
371 begin { Comienzo del programa principal }\r
372      resultado := cargarVectores(v1, v2);\r
373      {if not resultado then exit;}\r
374      writeln('Polinomio 1:');\r
375      for i := TAM - 1 downto 0 do\r
376             if v1[i] <> 0 then\r
377               begin\r
378                    if v1[i] < 0 then write(' - ', abs(v1[i]):1:2)\r
379                                 else write(' + ', v1[i]:1:2);\r
380                    if i <> 0 then write('*X^', i);\r
381               end;\r
382      writeln;\r
383      writeln('Polinomio 2:');\r
384      for i := TAM - 1 downto 0 do\r
385             if v2[i] <> 0 then\r
386               begin\r
387                    if v2[i] < 0 then write(' - ', abs(v2[i]):1:2)\r
388                                 else write(' + ', v2[i]:1:2);\r
389                    if i <> 0 then write('*X^', i);\r
390               end;\r
391      writeln;\r
392      writeln(ord(resultado));\r
393 end.