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