]> git.llucax.com Git - z.facultad/75.40/2do-cuat/polinomios.git/blob - poli_3.pas
Se expanden keywords del svn.
[z.facultad/75.40/2do-cuat/polinomios.git] / poli_3.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.7.0a (POLI_3)'; { 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; t: integer);\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 t - 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          for i := 0 to TAM - 1 do { iteracion para inicializar los vectores a cero }\r
202            begin { para que los valores que no son especificados no contengan "basura" }\r
203                 v1[i] := 0; { inicializacion del vector 1 (primer polinomio) }\r
204                 v2[i] := 0; { inicializacion del vector 2 (segundo polinomio) }\r
205            end;\r
206          nombreArchivo := ObtenerNombreArchivo; { obtiene el nombre del archivo }\r
207          assign(f, nombreArchivo); { asigna la variable al nombre del archivo }\r
208          reset(f); { abre el archivo para leerlo desde el principio }\r
209          seguir := true; { inicializa seguir e true para comenzar el bucle }\r
210          while seguir do begin { continua mientras seguir sea true }\r
211            read(f, c); { lee un caracter del archivo de texto }\r
212            est := trans(c, est); { establece el nuevo estado de lectura }\r
213            case est of { toma una desicion dependiendo del estado en que se encuentre }\r
214                 INICIO: ; { No hace nada, nunca toma este valor. Solo incica que empezo el proceso }\r
215                 COEF_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos }\r
216                 COEF, COEF_PUNTO: { Si esta leyendo el coeficiente ... }\r
217                    coeficiente := coeficiente + c; { concatena el caracter a la representacion\r
218                                                      de texto del coeficiente }\r
219                 COEF_FIN: ; { Si termino de leer el coeficiente, no hace nada, la asignacion\r
220                               se realiza cuando termina de leer el exponente (es necesario\r
221                               para establecer el indice del vector }\r
222                 EXP_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos }\r
223                 EXP: { Si esta leyendo el exponente ... }\r
224                    exponente := exponente + c; { concatena el caracter a la representacion\r
225                                                  de texto del exponente }\r
226                 EXP_FIN: { Si termino de leer el exponente, hace las asignaciones correspondientes }\r
227                         begin { convirtiendo las cadenas de texto en real e integer, segun el caso }\r
228                              val(coeficiente, rCoef, code); { convierte el coeficiente en real }\r
229                              val(exponente, iExp, code); { convierte el exponente en integer }\r
230                              if iExp < TAM { si el exponente es menor que el tama¤o maximo permitido ... }\r
231                                 then if poliN = 1 then v1[iExp] := rCoef { asigna el valor correspondiente }\r
232                                                   else v2[iExp] := rCoef { al polinomio correspondiente }\r
233                                 else est := ERROR; { si no es menor, pone el estado en ERROR }\r
234                              coeficiente := ''; { una vez asignados, vacia los valores del coeficiente y el }\r
235                              exponente := '';   { exponente para poder realizar las lecturas de los proximos }\r
236                         end;\r
237                 EXP_FIN_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos }\r
238                 POLI_FIN: { Si termino la lectura de un polinomio ... }\r
239                          if poliN = 1 then poliN := 2  { si se leyo el 1er polinomio, se indica que se leera el 2do }\r
240                                       else est := FIN; { si no (ya se leyo el segundo), pone el estado en FIN }\r
241                 FIN: { Si se finalizaron las tareas ... }\r
242                     begin\r
243                          { este codigo es el mismo que el de EXP_FIN, se repite aca solo por si el final del\r
244                            archivo esta pegado al fin del ultimo exponente, en cuyo caso no pasa por el estado\r
245                            de EXP_FIN (y, por ende, no se pueden hacer las asignaciones correspondientes }\r
246                          val(coeficiente, rCoef, code); { convierte el coeficiente en real }\r
247                          val(exponente, iExp, code); { convierte el exponente en integer }\r
248                          if iExp < TAM { si el exponente es menor que el tama¤o maximo permitido ... }\r
249                             then if poliN = 1 then v1[iExp] := rCoef { asigna el valor correspondiente }\r
250                                               else v2[iExp] := rCoef { al polinomio correspondiente }\r
251                             else est := ERROR; { si no es menor, pone el estado en ERROR }\r
252                          coeficiente := ''; { una vez asignados, vacia los valores del coeficiente y el }\r
253                          exponente := '';   { exponente para poder realizar las lecturas de los proximos }\r
254                          { fin del codigo identico a EXP_FIN }\r
255                          if poliN = 2 then cargarVectores := true { si se leyeron los 2 polinomios, devuelve true }\r
256                                       else cargarVectores := false; { si no se leyeron los dos, devuelve false }\r
257                          seguir := false; { poner seguir en false para que se termine el bucle }\r
258                     end;\r
259                 ERROR:  { Si hubo un error ... }\r
260                    begin\r
261                         cargarVectores := false; { Se devuelve false (hubo un ERROR, no se leyeron bien los vectores) }\r
262                         seguir := false; { seguir se pone en false para que termine el bucle }\r
263                    end;\r
264            end; { case }\r
265          end; { while }\r
266          close(f); { se cierra el archivo de lectura de datos }\r
267     end; { cargarVectores }\r
268 \r
269     {########################################################}\r
270 \r
271     procedure suma(v1, v2: Vector; var vr: Vector);\r
272     { procedimiento que suma dos polinomios.\r
273       v1: vector que contiene el primer polinomio a sumar\r
274       v2: vector que contiene el segundo polinomio a sumar\r
275       vr: vector donde se almacenara el resultado de la suma }\r
276 \r
277     var\r
278        i: integer; { indice para usar en el ciclo for }\r
279 \r
280     begin { suma }\r
281          inicializaVector(vr);        { inicializa al vector resultado en 0 para evitar que quede "basura" }\r
282          for i := 0 to TAM - 1 do     { recorre el vector (de tama¤o maximo TAM) }\r
283              vr[i] := v1[i] + v2[i];  { suma los coeficientes de los terminos con igual exponente }\r
284     end; { suma }\r
285 \r
286     {########################################################}\r
287 \r
288     procedure resta(v1, v2: Vector; var vr: Vector);\r
289     { procedimiento que resta dos polinomios.\r
290       v1: vector que contiene el primer polinomio\r
291       v2: vector que contiene el polinomio para restarle al primero\r
292       vr: vector donde se almacenara el resultado de la resta }\r
293 \r
294     var\r
295        i: integer; { indice para usar en el ciclo for }\r
296 \r
297     begin { resta }\r
298          inicializaVector(vr);        { inicializa al vector resultado en 0 para evitar que quede "basura" }\r
299          for i := 0 to TAM - 1 do     { recorre el vector (de tama¤o maximo TAM) }\r
300              vr[i] := v1[i] + v2[i];  { resta los coeficientes de los terminos con igual exponente }\r
301     end; { resta }\r
302 \r
303     {########################################################}\r
304 \r
305     procedure producto(v1, v2: Vector; var vr: Vector);\r
306     { procedimiento que multiplica dos polinomios.\r
307       v1: vector que contiene el primer polinomio a multiplicar\r
308       v2: vector que contiene el segundo polinomio a multiplicar\r
309       vr: vector donde se almacenara el resultado de la multiplicacion }\r
310 \r
311     var\r
312        i, j: integer; { indices para usar en los ciclos for }\r
313 \r
314     begin { producto }\r
315          inicializaVector(vr);        { inicializa al vector resultado en 0 para evitar que quede "basura" }\r
316          for i := 0 to TAM - 1 do     { recorre el 1er vector (de tama¤o maximo TAM) }\r
317              for i := 0 to TAM - 1 do { recorre el 2do vector (de tama¤o maximo TAM) }\r
318                  vr[i+j] := vr[i+j] + (v1[i] * v2[j]);\r
319                  { multiplica los coeficientes de los terminos y lo almacena en la posicion del exponente }\r
320                  { igual a la suma de los exponentes de v1 y v2, sumando el valor previo de dicha posicion }\r
321     end; { producto }\r
322 \r
323     {########################################################}\r
324 \r
325     procedure division(v1, v2: Vector; var vr, vResto: Vector);\r
326     { procedimiento que divide dos polinomios.\r
327       v1: vector que contiene el polinomio denominador\r
328       v2: vector que contiene el polinomio divisor\r
329       vr: vector donde se almacenara el resultado de la division\r
330       vResto: vector donde se almacenara el resto de la division }\r
331     var\r
332        i, j: integer; { indices para usar en los ciclos for }\r
333        vRTmp,         { vector auxuliares para almacenar el termino actual del resultado }\r
334        vTmp: Vector;  { vector auxuliares para almacenar el polinomio que es la multiplicacion del\r
335                         termino actual del resultado por el divisor }\r
336 \r
337     begin { division }\r
338          inicializaVector(vr);     { inicializa al vector resultado en 0 para evitar que quede "basura" }\r
339          inicializaVector(vResto); { inicializa al vector resultado en 0 para evitar que quede "basura" }\r
340          inicializaVector(vTmp);   { inicializa al vector resultado en 0 para evitar que quede "basura" }\r
341          inicializaVector(vRTmp);  { inicializa al vector resultado en 0 para evitar que quede "basura" }\r
342          for i := TAM - 1 donwto 0 do  { recorre el 1er vector (de tama¤o maximo TAM) de atras para adelante }\r
343              if v1[i] <> 0 then break;\r
344              { busca empezando por el indice (exponete) mas alto el primer coeficiente no nulo }\r
345              { si lo encuentra sale del for dejando al valor de i como el de dicho inidice }\r
346          for j := TAM - 1 donwto 0 do  { recorre el 2do vector (de tama¤o maximo TAM) de atras para adelante }\r
347              if v2[j] <> 0 then break;\r
348              { busca empezando por el indice (exponete) mas alto el primer coeficiente no nulo }\r
349              { si lo encuentra sale del for dejando al valor de j como el de dicho inidice }\r
350          while i >= j do\r
351            begin\r
352                 vr[i-j] := v1[i] / v2[j];\r
353                 vRTmp[i-j] := vr[i-j];\r
354                 producto(vRTmp, v2, vTmp);\r
355                 resta(v1, vTmp, v1);\r
356                 vRTmp[i-j] := 0;\r
357                 for i := i downto 0 do\r
358                     if v1[i] <> 0 then break;\r
359                     { busca empezando por el indice (exponete) mas alto el primer coeficiente no nulo }\r
360                     { si lo encuentra sale del for dejando al valor de i como el de dicho inidice }\r
361            end; { while }\r
362          vResto := v1;\r
363     end; { division }\r
364 \r
365     {########################################################}\r
366 \r
367 { Continuacion del programa principal }\r
368 \r
369 var\r
370    i: integer; { variable auxiliar }\r
371    v1, v2, vResult, vResto: Vector;\r
372    resultado: boolean;\r
373 \r
374 begin { Comienzo del programa principal }\r
375      resultado := cargarVectores(v1, v2);\r
376      {if not resultado then exit;}\r
377      writeln('Polinomio 1:');\r
378      for i := TAM - 1 downto 0 do\r
379             if v1[i] <> 0 then\r
380               begin\r
381                    if v1[i] < 0 then write(' - ', abs(v1[i]):1:2)\r
382                                 else write(' + ', v1[i]:1:2);\r
383                    if i <> 0 then write('*X^', i);\r
384               end;\r
385      writeln;\r
386      writeln('Polinomio 2:');\r
387      for i := TAM - 1 downto 0 do\r
388             if v2[i] <> 0 then\r
389               begin\r
390                    if v2[i] < 0 then write(' - ', abs(v2[i]):1:2)\r
391                                 else write(' + ', v2[i]:1:2);\r
392                    if i <> 0 then write('*X^', i);\r
393               end;\r
394      writeln;\r
395      writeln(ord(resultado));\r
396 end.