From 424321af7b0cfa93b9b71d0d66b97ee1d5975514 Mon Sep 17 00:00:00 2001 From: Leandro Lucarella Date: Sun, 23 Mar 2003 07:10:16 +0000 Subject: [PATCH] =?utf8?q?Import=20inicial=20despu=C3=A9s=20del=20"/var=20?= =?utf8?q?incident".=20:(?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- HISTORIAL.TXT | 154 ++++++++++ Poli_Matematica.txt | 34 +++ datos.txt | 103 +++++++ datos2.txt | 13 + datos3.txt | 7 + datos4.txt | 7 + datos5.txt | 10 + poli.pas | 633 +++++++++++++++++++++++++++++++++++++++++ poli_10.pas | 501 +++++++++++++++++++++++++++++++++ poli_11.pas | 498 +++++++++++++++++++++++++++++++++ poli_12.pas | 611 ++++++++++++++++++++++++++++++++++++++++ poli_13.pas | 633 +++++++++++++++++++++++++++++++++++++++++ poli_14.pas | 633 +++++++++++++++++++++++++++++++++++++++++ poli_2.pas | 338 ++++++++++++++++++++++ poli_3.pas | 396 ++++++++++++++++++++++++++ poli_4.pas | 393 ++++++++++++++++++++++++++ poli_5.pas | 401 ++++++++++++++++++++++++++ poli_6.pas | 432 ++++++++++++++++++++++++++++ poli_7.pas | 441 +++++++++++++++++++++++++++++ poli_8.pas | 444 +++++++++++++++++++++++++++++ poli_9.pas | 474 +++++++++++++++++++++++++++++++ term.pas | 665 ++++++++++++++++++++++++++++++++++++++++++++ term_0.pas | 525 ++++++++++++++++++++++++++++++++++ term_1.pas | 549 ++++++++++++++++++++++++++++++++++++ term_2.pas | 442 +++++++++++++++++++++++++++++ term_3.pas | 530 +++++++++++++++++++++++++++++++++++ term_4.pas | 665 ++++++++++++++++++++++++++++++++++++++++++++ term_5.pas | 665 ++++++++++++++++++++++++++++++++++++++++++++ 28 files changed, 11197 insertions(+) create mode 100644 HISTORIAL.TXT create mode 100644 Poli_Matematica.txt create mode 100644 datos.txt create mode 100644 datos2.txt create mode 100644 datos3.txt create mode 100644 datos4.txt create mode 100644 datos5.txt create mode 100644 poli.pas create mode 100644 poli_10.pas create mode 100644 poli_11.pas create mode 100644 poli_12.pas create mode 100644 poli_13.pas create mode 100644 poli_14.pas create mode 100644 poli_2.pas create mode 100644 poli_3.pas create mode 100644 poli_4.pas create mode 100644 poli_5.pas create mode 100644 poli_6.pas create mode 100644 poli_7.pas create mode 100644 poli_8.pas create mode 100644 poli_9.pas create mode 100644 term.pas create mode 100644 term_0.pas create mode 100644 term_1.pas create mode 100644 term_2.pas create mode 100644 term_3.pas create mode 100644 term_4.pas create mode 100644 term_5.pas diff --git a/HISTORIAL.TXT b/HISTORIAL.TXT new file mode 100644 index 0000000..91c3891 --- /dev/null +++ b/HISTORIAL.TXT @@ -0,0 +1,154 @@ +POLI_2 (0.6.0a): + Funcionamiento basico de lectura de los polinomios desde el archivo de texto. + +POLI_3 (0.7.0a): + Se le agragan los procedimientos pensados en la clase para operar entre polinomios + ("suma", "resta", "producto" y "division"). + Se le agrega un procedimiento para inicializar los vectores. + Se unifica el tipo de vectores, desapareciendo "VectorResultado" y pasando el tipo + "Vector" a tener el tamaño maximo (TAM_MAX). + Se borran las lineas para DEBUG (refinar) y el tipo de dato "Termino". + Por ahora no compila ... + +POLI_4 (0.8.0a): + Compila pero no fueron probadas las operaciones (solo se arreglo el codigo erroneo + que no permitia compilar). + +POLI_5 (0.8.2a): + Se testeo la suma y funciona correctamente. Tambien se agrega un procedimiento para mostrar + los polinomios por pantalla ("muestraVector"). + +POLI_6 (0.8.4a): + Se mejora notablemente el procedimiento , agregandole una funcion "exponente" + para mejorar la presentacion de los polinomios por pantalla. Ahora la salida es mas limpia + y legible. + +POLI_7 (0.8.5a): + Se testea la resta y se arregla la dicho procedimiento porque tenia un operador mal, lo que hacia + que se sume en vez de que se reste. + Se cambia: + vr[i] := v1[i] + v2[i]; { resta los coeficientes de los terminos con igual exponente } + === + por: + vr[i] := v1[i] - v2[i]; { resta los coeficientes de los terminos con igual exponente } + === + +POLI_8 (0.9.0b): + Se testea el producto y se arregla la dicho procedimiento porque tenia una nombre de variable mal, + lo que hacia que la variable j no se incremente y que i pierda su valor, dando un resultado erroneo. + Se cambia: + for i := 0 to TAM - 1 do { recorre el 2do vector (de tamaño maximo TAM) } + === + por: + for j := 0 to TAM - 1 do { recorre el 2do vector (de tamaño maximo TAM) } + === + +POLI_9 (0.9.8b): + Se corrije nuevamente el procedimiento "muestraVector" para que si el polinomio es nulo, + se presente en pantalla un cero en vez de no presentar nada como se hacia antes. + Se testea la division y se encuentra que si el segundo polinomio es nulo, da un error de + ejecucion (runtime error). Para evitarlo, se transforma el procedimiento en funcion, haciendo + que devuelva true si se efectuo con exito (el segundo polinomio no es nulo) o false si no + se pudo efectuar (el segundo polinomio es nulo). De esta manera el bloque que llame a esta + funcion puede decidir que hacer en caso de que el segundo polinomio sea nulo. + Tambien se agregan los comentarios a esta funcion. + +POLI_10 (1.0.1r): + Se agrega una descripcion del programa indicando el formato que debe tener el archivo con los datos. + Tambien se agrega a esta y todas las versiones anteriores una constante llamada VERSION, que + almacena un String con la version del programa para ser mostrada cuando se mejore la salida. + Tambien se modifica el nombre del programa como PolinomiosEnVector para diferenciarlo de la nueva + implementacion con un record (TERM o PolinomiosEnTermino). + +POLI_11 (1.0.5r): + Se corrije el case en la seccion FIN de la funcion cargarVectores: + Se reescribe por casi completo porque tenía varias lineas que no aportaban nada y un par + de errores por los cuales la funcion devolvia verdadero sin que se hayan leido ambos polinomios. + Ahora es mas concisa, legible y eficiente. + +POLI_12 (1.1.3b): + Se mejora la interfaz para el usuario. Ahora se basa en menues a color con diferentes opciones. + Tambien se agrega un procedimiento para presentar un mensaje en la salida pero aún no está + implementado. + +POLI_13 (1.2.3r): + Se implementa el mensaje de salida y se corrigen algunas pequeñas lineas del bloque principal del + programa. Tambien se corrijen algunos mensajes para que la salida sea mas prolija. Entre las + correcciones se encuentra la funcion obtenerNombreArchivo que en ciertas circunstancias se + superponian los mensajes. + +POLI_14 (1.2.5r): + Se corrijen algunos otros mensajes de pantalla y se cambia el titulo del programa por el nombre + del mismo. + +========================================================================================================== +========================================================================================================== + +TERM_0 (0.0.1a): + Se empiezan a hacer los cambios para transformar el programa POLI en TERM, programa similar pero + que guarda los datos en un record llamado Termino: + type + Termino = record + coef: real; + exp: integer; + end; + El nombre del programa es: PolinomiosEnTermino. + Hasta ahora se modifico hasta la linea 330 aproximadamente y dudo que compile (de hacerlo seria una + coincidencia). + +TERM_1 (0.1.0a): + Se agregan 2 variables en la funcion cargarVectores: + n: integer -> indica el termino actual del polinomio para hacer las asignaciones. + asignado: boolean -> indica si ya se hizo la asignacion. + Se agrega una condicion mas para el formato del archivo con los datos (el orden de los terminos + segun el exponente). + Se hace una cantidad de cambios considerables al case en sus secciones: + COEF_FIN: se inicializan las nuevas variables. + EXP_FIN: se corrije el metodo de asignacion para funcionar con la nueva estructura Termino. + POLI_FIN: se cambian y agregan algunas asignaciones para funcionar con la nueva implementacion. + FIN: se efectuan cambios considerables para adaptarlo al nuevo sistema. + Finalmente se sacan las antiguas funciones suma, resta, producto y division. Tambien se pone en + comentarios sus llamadas desde el bloque principal para lograr que el codigo compile. + El programa compila y supuestamente deberia funcionar la lectura de datos. No se hizo ninguna + prueba de ejecucion del programa a esta altura... + +TERM_2 (0.2.0a): + Se agregan un par de lineas de DEBUG y con esto se ve que la funcion muestraVector funciona + correctamente. Se arreglan un par de lineas en el case de cargarVectores, en la seccion EXP_FIN: + En las lineas 346/7 decia: + v1[n].coef := rCoef; + v1[n].exp := iExp; + y fue reemplazado por + v2[n].coef := rCoef; + v2[n].exp := iExp; + Gracias a esto antes se reemplazaba los valores de v1 y nunca se le asignaba nada a v2 (con una + excepcion). + Aparentemente, con estas correcciones ya funciona la parte de lectura. + +TERM_3 (0.9.0b): + Se cambia toda la forma de encarar el problema. Practicamente se anulan todas las modificaciones + hechas en las versiones TERM_1 y TERM_2. Ahora la implementacion de este programa es mucho mas + similar a la de POLI, ya que se estaba haciendo cada vez mas compleja sin necesidad y sin proporcionar + beneficios (ni de espacio, ni de velocidad, ni de memoria). + Los cambios con respecto a POLI son minimos, solo se modifican las funciones mostrarVector (sigue + igual que en TERM_0), la funcion cargarVectores (en las secciones EXP_FIN y FIN, de manera + practicamente identica), en la funcion inicializaVector y en las funciones de operaciones (suma, + resta, producto y division). + Los cambios se centran en su mayoria (casi en su totalidad) en el reemplazo de instrucciones como + esta: + vr[i-j] := v1[i] / v2[j]; + + por instrucciones de este estilo: + + vr[i-j].coef := v1[i].coef / v2[j].coef; + vr[i-j].exp := v1[i].exp - v2[j].exp; + + Todavia no se probó el funcionamiento del programa pero se espera que no haya grandes problemas. + +TERM_4 (1.2.0r): + Se implementa la misma interfaz grafica que se utilizo en POLI. Ademas se prueba la funcionalidad + del programa. + +TERM_5 (1.2.2r): + Se corrijen algunos otros mensajes de pantalla y se cambia el titulo del programa por el nombre + del mismo. diff --git a/Poli_Matematica.txt b/Poli_Matematica.txt new file mode 100644 index 0000000..5b953ca --- /dev/null +++ b/Poli_Matematica.txt @@ -0,0 +1,34 @@ +Calculo con el Matematica de polinomios de Datos2.txt + +PolynomialQuotient[1.99x^5+x^4+1.76x^3+0.5x^2+2x-1.2,-2.98x^5-1.23x^4-3.1x^3+2x^2+0.2x-6.1,x] +-0.667785 + +PolynomialRemainder[1.99x^5+x^4+1.76x^3+0.5x^2+2x-1.2,-2.98x^5-1.23x^4-3.1x^3+2x^2+0.2x-6.1,x] + 2 3 4 +-5.27349 + 2.13356 x + 1.83557 x - 0.310134 x + 0.178624 x + ^ + Leandro Fijate que ahi segun nuestro + programa en pascalito va un 2.01 ??!? + No creo que hinchen las bolas por eso + +Che, Javier, tengo una buena noticia y una mala noticia. +La buena es que nuestro programa de pascalito anda JOYA y la mala es que tu programa matematica anda +como el ort...o. Lo probe a mano y esta bien el nuestro, fijate: + + 1.99 X^5 + X^4 + 1.76 X^3 + 0.50 X² + 2 X - 1.20 | -2.98 X^5 - 1.23 X^4 - 3.10 X^3 + 2 X² + 0.02 X - 6.10 + +-------------------------------------------------------- +- -0.667785... + + 1.99X^5 + 0.82X^4 + 2.07X^3 - 1.33X^2 - 0.01X + 4.07 +----------------------------------------------------------- + + 0 X^5 + 0.18 X^4 - 0.31 X^3 + 1.83 X^2 + 2.01 X - 5.27 + ========== + + Ahora que acabo de terminar esta porquería, me doy cuenta que tipeaste mal el polinomio asi que cambio el + titular de la mala noticia: + EL QUE ESTA COMO EL ORT....O SOS VOS!!! + + Al segundo polinomio le mandaste ... + 0.2 X - ... en vez de ... + 0.02 X - ... + + Bueno, lo importante es que el programa anda JOYA PERLA!!! \ No newline at end of file diff --git a/datos.txt b/datos.txt new file mode 100644 index 0000000..80daac1 --- /dev/null +++ b/datos.txt @@ -0,0 +1,103 @@ +-1 0 +2 1 +0 2 +1 3 +1 4 +1 5 +6 6 +5.6 7 +4.23 8 +-4.55 9 +3.3443 10 +-343.233 11 +3 12 +3 13 +223.122 14 +12.123 15 +1.123 16 +12 17 +54.3 18 +42 19 +0.54 20 +-3.22 21 +23.4 22 +1.7 23 +76.4 24 +-4 25 +48.4437833254562 26 +33.2 27 +-23 28 +-52 29 +68 30 +23.45 31 +-787.5 32 +33.434 33 +-4232.234 34 +3345.6334 35 +-4564 36 +4 37 +4.31 38 +0.2 39 +2 40 +-23.32 41 +12.31125656 42 +-6.0 43 +0.1 44 +2.2 45 +-3.3 46 +-1.4 47 +-2.5 48 +1123.233 49 + + + +-1 0 +2 1 +0 2 +1 3 +1 4 +1 5 +6 6 +5.6 7 +4.23 8 +-4.55 9 +3.3443 10 +-343.233 11 +3 12 +3 13 +223.122 14 +12.123 15 +1.123 16 +12 17 +54.3 18 +42 19 +0.54 20 +-3.22 21 +23.4 22 +1.7 23 +76.4 24 +-4 25 +48.4437833254562 26 +33.2 27 +-23 28 +-52 29 +68 30 +23.45 31 +-787.5 32 +33.434 33 +-4232.234 34 +3345.6334 35 +-4564 36 +4 37 +4.31 38 +0.2 39 +2 40 +-23.32 41 +12.31125656 42 +-6.0 43 +0.1 44 +2.2 45 +-3.3 46 +-1.4 47 +-2.5 48 +1123.233 49 \ No newline at end of file diff --git a/datos2.txt b/datos2.txt new file mode 100644 index 0000000..4388642 --- /dev/null +++ b/datos2.txt @@ -0,0 +1,13 @@ +-1.2 0 +2 1 +0.5 2 +1.76 3 +1 4 +1.9887 5 + +-6.1 0 +0.02 1 +2 2 +-3.1 3 +-1.23 4 +-2.98251 5 \ No newline at end of file diff --git a/datos3.txt b/datos3.txt new file mode 100644 index 0000000..e016269 --- /dev/null +++ b/datos3.txt @@ -0,0 +1,7 @@ +-1 0 +5 2 +2 4 + +-6 0 +2 1 +1 4 \ No newline at end of file diff --git a/datos4.txt b/datos4.txt new file mode 100644 index 0000000..c3754d8 --- /dev/null +++ b/datos4.txt @@ -0,0 +1,7 @@ +1 0 +3 1 +1 2 + +0 0 +0 1 +0 2 \ No newline at end of file diff --git a/datos5.txt b/datos5.txt new file mode 100644 index 0000000..14decb6 --- /dev/null +++ b/datos5.txt @@ -0,0 +1,10 @@ +0 0 +-6 1 +10 3 +-3 2 +a5 4 + + +0 0 +2 1 +1 2 \ No newline at end of file diff --git a/poli.pas b/poli.pas new file mode 100644 index 0000000..53e3f55 --- /dev/null +++ b/poli.pas @@ -0,0 +1,633 @@ +program PolinomiosEnVector; +{ Programa que lee 2 polinomios desde un archivo de texto para luego + hacer operaciones basicas entre estos (suma, resta, multiplicacion + y division). + El formato del archivo de texto debe ser de la siguiente manera: + + * Se ingresan cada polinomio en lineas sucesivas. + * El primer polinomio puede comenzar a ingresarse en cualquier lugar + del archivo de texto. + * El fin del primer polinomio (y comienzo del segundo) se indica por + medio de 1 o mas lineas en blanco. + * El segundo polinomio puede comenzar a ingresarse en cualquier lugar + del archivo de texto a partir de dicha(s) linea(s) en blanco. + * Cada termino de un polinomio debe estar en la misma linea y comenzar + al principio de esta (excepto el primer termino). + * En cada linea se ingresa primero el coeficiente real (puede tener un + signo '-' al comenzar y/o un punto, y solamente uno) y luego el + exponente entero positivo. + * La separacion entre el coeficiente y el exponente debe estar dada por + uno o mas espacios o tabuladores. + * Cualquier caracter incluido en el texto que no sea un digito (0..9), + un punto ('.'), un signo menos ('-'), un espacio (' '), un tabulador + o alguno de los caracteres de nueva linea, dara un error en la + lectura. + * El archivo de texto debe tener formato DOS (es decir, el indicador de + nueva linea debe ser primero un caracter de retorno del carro + seguido inmediatamente por uno de avance de linea). +} + +uses + CRT, DOS; { Declaracion de funciones predefinidas + para crear la interfaz grafica } + +const + VERSION = '1.2.5r (POLI_14)'; { version del programa } + + TAM_MAX = 100; { Tama¤o maximo del vector que almacena + la multiplicacion de polinomios } + TAM = TAM_MAX div 2; { Tama¤o maximo (virtual) del vector que contiene + los vector con los que se va a operar } + CR = chr(13); { caracter de retorno del carro } + LF = chr(10); { caracter de nueva linea } + ENDF = chr(26); { caracter de fin del archivo } + TAB = chr(9); { caracter de tabulacion } + SPACE = chr(32); { caracter de espacio } + +type + { Tipo de dato para identificar el estado de la entrada de datos } + Estado = (INICIO, COEF_BUSCA, COEF, COEF_PUNTO, COEF_FIN, EXP_BUSCA, EXP, EXP_FIN, EXP_FIN_BUSCA, POLI_FIN, FIN, ERROR); + Vector = array [0..TAM_MAX-1] of real; { vector para almacenar los polinomios } + + + {########################################################} + + procedure muestraVector(var v: Vector; s: String); + { procedimiento que imprime el polinomio 'v' en pantalla con un titulo 's' } + + {########################################################} + + function exponente(exp: integer): String; + + var + s: String; { variable temporal } + + begin { exponente } + case exp of + 0: exponente := ''; { si el exponente es nulo, mustra solo el coeficiente } + 1: exponente := 'X'; { si el exponente es 1, mustra el coeficiente y X } + 2: exponente := 'Xý'; { si el exponente es 2, mustra el coeficiente y Xý } + else begin + str(exp, s); { convierte al exponente en string } + exponente := 'X^' + s; { si el exponente es mayor que 1, mustra el coeficiente y X^exp } + end; { else } + end; { case } + end; { exponente } + + {########################################################} + + + var + i: integer; { indice para usar en el ciclo for } + + begin { muestraVector } + textcolor(lightcyan); { pone el color del texto en cian claro } + writeln; { separacion de una linea } + write(s); { mustra el mensaje } + textcolor(lightmagenta); { pone el color del texto en magenta claro } + for i := TAM_MAX - 1 downto 0 do { recorre el vector de atras para adelante } + if v[i] <> 0 then break; { si el coeficiente no es nulo, termina el for dejando a i en ese indice } + if (i = 0) and (v[i] = 0) then { si el primer exponente que encuentra es 0 y el coeficiente es 0, entonces } + begin { muestra el resultado como 0 y sale del procedimiento } + write('0'); { imprime que el resultado es cero } + writeln; { separacion de una linea } + writeln; { separacion de una linea } + exit; { sale de este procedimiento } + end; + if (abs(v[i]) <> 1) or (i = 0) { si el modulo del coeficiente es distinto de 1 o si el exp. es 0 } + then if abs(v[i]) - trunc(abs(v[i])) = 0 then write(trunc(v[i]):1, ' ') { imprime si es un numero entero } + else write(v[i]:1:2, ' ') { imprime si es un numero real } + else if v[i] = -1 then write('-'); { si es -1 entonces solo escribe el signo del termino } + write(exponente(i)); + for i := i - 1 downto 0 do { recorre el vector de atras para adelante } + if v[i] <> 0 then { si el coeficiente no es nulo, termina el for dejando a i en ese indice } + begin + if v[i] < 0 { si el coeficiente en negativo } + then write(' - ') { le agrega el signo - } + else write(' + '); { si no, le agrega el signo + } + if (abs(v[i]) <> 1) or (i = 0) then { si el modulo del coeficiente es distinto de 1 o si el exp. es 0 } + if abs(v[i]) - trunc(abs(v[i])) = 0 then write(trunc(abs(v[i])):1, ' ') { imprime si es un entero } + else write(abs(v[i]):1:2, ' '); { imprime si es un real } + write(exponente(i)); + end; { if } + writeln; { separacion de una linea } + writeln; { separacion de una linea } + end; { muestraVector } + + {########################################################} + + procedure inicializaVector(var v: Vector); + { procedimiento que inicializa un vector de tama¤o tam } + + var i: integer; { indice para usar en el ciclo for } + + begin { inicializaVector } + for i := 0 to TAM_MAX - 1 do { recorre el vector } + v[i] := 0; { inicializa la variable actual en 0 } + end; { inicializaVector } + + {########################################################} + + function ObtenerNombreArchivo: String; + { funcion que obtiene un nombre de archivo valido (es decir, el nombre + de un archivo que exista) } + + {########################################################} + + function fileExists(FileName: String): Boolean; + { funcion extraida de la ayuda del Turbo Pascal 7 + indica si el archivo existe } + + var + F: file; + + begin + {$I-} + Assign(F, FileName); + FileMode := 0; { Set file access to read only } + Reset(F); + Close(F); + {$I+} + FileExists := (IOResult = 0) and (FileName <> ''); + end; { FileExists } + + {########################################################} + + { Continuacion de la funcion ObtenerNombreArchivo } + const + DEFAUL_FILE_NAME = 'datos.txt'; { nombre del archivo por defecto } + + var + tmp: String; { cadena para almacenar el resultado temporal } + + begin { ObtenerNombreArchivo } + { mensaje para entrada del nombre de archivo } + clrscr; { borra la pantalla } + textcolor( Yellow ); { establece el color para el texto a amarillo } + gotoxy( 30, 3 ); { va a las coordenas de pantalla 25 horizontal, 3 verical } + writeln( 'PolinomiosEnVector' ); { titulo } + gotoxy( 30, 4 ); { va a las coordenas de pantalla 25 horizontal, 4 verical } + writeln( '~~~~~~~~~~~~~~~~~~' ); { subrayado del titulo } + textcolor( LightCyan ); { establece el color para el texto a cian claro } + gotoxy( 1, 7 ); { va a las coordenas de pantalla 1 horizontal, 7 verical } + writeln(' Ingrese el nombre del archivo con los datos (ENTER = ', DEFAUL_FILE_NAME, '):'); + readln(tmp); { entrada del nombre de archivo } + if tmp = '' then tmp := DEFAUL_FILE_NAME; { se fija si no se ingreso nada y reasigana el nombre } + while not fileExists(tmp) do { repite el proceso hasta que el archivo exista } + begin + clrscr; { borra la pantalla } + textcolor( Yellow ); { establece el color para el texto a amarillo } + gotoxy( 30, 3 ); { va a las coordenas de pantalla 25 horizontal, 3 verical } + writeln( 'PolinomiosEnVector' ); { titulo } + gotoxy( 30, 4 ); { va a las coordenas de pantalla 25 horizontal, 4 verical } + writeln( '~~~~~~~~~~~~~~~~~~' ); { subrayado del titulo } + textcolor( LightCyan ); { establece el color para el texto a cian claro } + gotoxy( 1, 7 ); { va a las coordenas de pantalla 1 horizontal, 7 verical } + write(' El archivo ', tmp, ' no existe. Ingrese un nombre correcto'); + if tmp = DEFAUL_FILE_NAME { si es el nombre de archivo predeterminado } + then { entonces, elije un mensaje apropiado } + write(': ') + else + begin { si no es el predeterminado, muestra otro mensaje } + writeln('.'); + write(' (ENTER = ', DEFAUL_FILE_NAME, '): '); + end; + readln(tmp); { vuelve a leer el nombre del archivo para ser verificado } + if tmp = '' then tmp := DEFAUL_FILE_NAME; { asigna como nombre de archivo al predeterminado + si no se escribio nada } + end; { fin del loop de verificacion } + ObtenerNombreArchivo := tmp; { asigna el nombre correcto al valor de salida de la funcion } + end; { ObtenerNombreArchivo } + + {########################################################} + + function trans(c: char; e: Estado): Estado; + { establece el estado en el que se encuentra la lectura } + { c es el caracter que se leyo, e es el estado actual de la lectura } + + begin { trans } + case e of { acciona segun es estado actual de la lectura } + INICIO: { estado de inicio de la lectura } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un numero (o negativo), empieza a leer el coeficiente } + SPACE, TAB, CR, LF: trans := COEF_BUSCA; { si es un caracter tipo "espacio", busca el prox. coef. } + else trans := ERROR; { si es otro, da ERROR } + end; + COEF_BUSCA: { estado de busqueda del primer ceoficiente del polinomio } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un numero (o negativo), empieza a leer el coeficiente } + SPACE, TAB, CR, LF: trans := COEF_BUSCA; { si es un caracter tupo "espacio", sigue buscando } + ENDF: trans := FIN; { si es el caracter de fin de archivo, pasa al estado de tarea finalizada } + else trans := ERROR; { si es otro, da ERROR } + end; + COEF: { estado de lectura del coeficiente del termino del polinomio (sin punto decimal) } + case c of { acciona segun el caracter leido } + '0'..'9': trans := COEF; { si es un numero sigue con el mismo estado } + '.': trans := COEF_PUNTO; { si es punto cambia al estado COEF_PUNTO } + SPACE, TAB: trans := COEF_FIN; { si es un espacio o un tabulador, finaliza la lectura del coeficiente } + else trans := ERROR; { si es otra cosa, pasa a estado de error } + end; + COEF_PUNTO: { estado de lectura del coeficiente del termino del polinomio (con punto decimal) } + case c of { acciona segun el caracter leido } + '0'..'9': trans := COEF_PUNTO; { si es un numero sigue con el mismo estado } + SPACE, TAB: trans := COEF_FIN; { si es un espacio o un tabulador, finaliza la lectura del coeficiente } + else trans := ERROR; { si es otra cosa, pasa a estado de error } + end; + COEF_FIN: { estado de fin de la lectura del coeficiente del termino del polinomio } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si el caracter es un numero establece el estado en EXP (exponente) } + SPACE, TAB: trans := EXP_BUSCA; { si es un espacio o tabulador, pasa a buscar el proximo exponente } + else trans := ERROR; { si no es ninguno de los anteriores, el estado pasa a ERROR } + end; + EXP_BUSCA: { estado de busqueda del proximo exponente } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si el caracter es un numero, empieza a leer el exponente } + SPACE, TAB: trans := EXP_BUSCA; { si es un espacio o tabulador, sigue buscando } + else trans := ERROR; { si no es ninguno de los anteriores, el estado pasa a ERROR } + end; + EXP: { estado de lectura del exponente del termino actual del polinomio } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si es un digito, sigue en el mismo estado } + CR: trans := EXP_FIN; { si es un ratorno de carro, finaliza el exponente + (quiere decir que hubo un ) } + ENDF: trans := FIN; { si es el final del archivo, se indica que termino su tarea } + else trans := ERROR; { si es otra cosa, devuelve ERROR } + end; + EXP_FIN: { estado de fin de la lectura del exponente del termino actual del polinomio } + if c = LF then trans := EXP_FIN_BUSCA { debe ser un caracter de nueva linea (para completar el ) } + else trans := ERROR; { si no lo es, devuelve ERROR } + EXP_FIN_BUSCA: { estado de fin de lectura de la nueva linea (luego de finalizar el exponente + ahora decide si termino el polinomio o si sigue leyendo el proximo coeficiente } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un digito (o negativo), pasa a leer en proximo coeficiente } + CR: trans := POLI_FIN; { si es un ratorno de carro o nueva linea, finaliza el polinomio } + else trans := ERROR; { si es otra cosa, devuelve ERROR } + end; + POLI_FIN: { estado de finalizacion del polinomio actual } + if c = LF then trans := COEF_BUSCA { debe ser un caracter de nueva linea (para completar el ), + entonces pasa a buscar el primer coeficiente del nuevo polinomio } + else trans := ERROR; { si no lo es, devuelve ERROR } + FIN: { estado que adquiere cuando se finalizo la tarea } + trans := FIN; { se queda en este estado avisando que termino su tarea } + else { otro estado, no deberia ocurrir, salvo que se le pase a la funcion un estado de ERROR } + trans := ERROR; { si es otro, da ERROR } + end; { case } + end; { trans } + + {########################################################} + + function cargarVectores(var v1, v2: Vector): boolean; + { Funcion que abre el archivo de texto con los datos, lo carga en el vector procesandolo debidamente a medida + que lo lee y, al finalizar, cierra el archivo de texto. + v1 es el primer vector a cargar + v2 es el segundo vector a cargar + devuelve true si la lectura fue hecha con exito, false si hubo un error } + + var + f: Text; { archivo de texto con los datos } + c: char; { caracter que se extrae del archivo de texto } + nombreArchivo: String; { nombre del archivo de datos } + est: Estado; { Indicador del estado actual de la lectura } + seguir: boolean; { indicador para saber si debe seguir con el proceso } + i, { indice del vector del polinomio para ser inicializado } + iExp, { valor temporal para almacenar al exponente } + code, { almacena el resultado de la funcion val (no se usa porque los + datos ya estan validados } + poliN: integer; { numero del polinomio que se esta leyendo } + rCoef: real; { valor temporal para almacenar al coeficiente } + exponente, { string que representa al exponente leido } + coeficiente: String; { string que representa al coeficiente leido } + + begin { cargarVectores } + rCoef := 0.0; { inicializacion de variable } + iExp := 0; { inicializacion de variable } + coeficiente := ''; { inicializacion de variable } + exponente := ''; { inicializacion de variable } + est := INICIO; { empieza con el estado de INICIO } + poliN := 1; { establece que se procesara el primer polinomio } + inicializaVector(v1); { inicializacion del vector 1 (primer polinomio) } + inicializaVector(v2); { inicializacion del vector 2 (segundo polinomio) } + nombreArchivo := ObtenerNombreArchivo; { obtiene el nombre del archivo } + assign(f, nombreArchivo); { asigna la variable al nombre del archivo } + reset(f); { abre el archivo para leerlo desde el principio } + seguir := true; { inicializa seguir e true para comenzar el bucle } + while seguir do begin { continua mientras seguir sea true } + read(f, c); { lee un caracter del archivo de texto } + est := trans(c, est); { establece el nuevo estado de lectura } + case est of { toma una desicion dependiendo del estado en que se encuentre } + INICIO: ; { No hace nada, nunca toma este valor. Solo incica que empezo el proceso } + COEF_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + COEF, COEF_PUNTO: { Si esta leyendo el coeficiente ... } + coeficiente := coeficiente + c; { concatena el caracter a la representacion + de texto del coeficiente } + COEF_FIN: ; { Si termino de leer el coeficiente, no hace nada, la asignacion + se realiza cuando termina de leer el exponente (es necesario + para establecer el indice del vector } + EXP_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + EXP: { Si esta leyendo el exponente ... } + exponente := exponente + c; { concatena el caracter a la representacion + de texto del exponente } + EXP_FIN: { Si termino de leer el exponente, hace las asignaciones correspondientes } + begin { convirtiendo las cadenas de texto en real e integer, segun el caso } + val(coeficiente, rCoef, code); { convierte el coeficiente en real } + val(exponente, iExp, code); { convierte el exponente en integer } + if iExp < TAM { si el exponente es menor que el tama¤o maximo permitido ... } + then if poliN = 1 then v1[iExp] := rCoef { asigna el valor correspondiente } + else v2[iExp] := rCoef { al polinomio correspondiente } + else est := ERROR; { si no es menor, pone el estado en ERROR } + coeficiente := ''; { una vez asignados, vacia los valores del coeficiente y el } + exponente := ''; { exponente para poder realizar las lecturas de los proximos } + end; + EXP_FIN_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + POLI_FIN: { Si termino la lectura de un polinomio ... } + if poliN = 1 then poliN := 2 { si se leyo el 1er polinomio, se indica que se leera el 2do } + else est := FIN; { si no (ya se leyo el segundo), pone el estado en FIN } + FIN: { Si se finalizaron las tareas ... } + begin + cargarVectores := true; { en principio se establece que la lectura se hizo con exito ) } + seguir := false; { poner seguir en false para que se termine el bucle } + { este codigo es similar al de EXP_FIN, se hacen las asignaciones por el caso en que el fin + del archivo esta pegado al fin del ultimo exponente, en cuyo caso no pasa por el estado + de EXP_FIN (y, por ende, no se pueden hacer las asignaciones correspondientes } + val(coeficiente, rCoef, code); { convierte el coeficiente en real } + val(exponente, iExp, code); { convierte el exponente en integer } + if iExp < TAM { si el exponente es menor que el tama¤o maximo permitido ... } + then if poliN = 2 + then v2[iExp] := rCoef { si es el 2do polinomio, asigna el valor correspondiente } + else cargarVectores := false { si es el primero, no se hizo bien la lectura } + else cargarVectores := false; { si no es menor, no se hizo bien la lectura } + end; + ERROR: { Si hubo un error ... } + begin + cargarVectores := false; { Se devuelve false (hubo un ERROR, no se leyeron bien los vectores) } + seguir := false; { seguir se pone en false para que termine el bucle } + end; + end; { case } + end; { while } + close(f); { se cierra el archivo de lectura de datos } + end; { cargarVectores } + + {########################################################} + + procedure suma(v1, v2: Vector; var vr: Vector); + { procedimiento que suma dos polinomios. + v1: vector que contiene el primer polinomio a sumar + v2: vector que contiene el segundo polinomio a sumar + vr: vector donde se almacenara el resultado de la suma } + + var + i: integer; { indice para usar en el ciclo for } + + begin { suma } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el vector (de tama¤o maximo TAM) } + vr[i] := v1[i] + v2[i]; { suma los coeficientes de los terminos con igual exponente } + end; { suma } + + {########################################################} + + procedure resta(v1, v2: Vector; var vr: Vector); + { procedimiento que resta dos polinomios. + v1: vector que contiene el primer polinomio + v2: vector que contiene el polinomio para restarle al primero + vr: vector donde se almacenara el resultado de la resta } + + var + i: integer; { indice para usar en el ciclo for } + + begin { resta } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el vector (de tama¤o maximo TAM) } + vr[i] := v1[i] - v2[i]; { resta los coeficientes de los terminos con igual exponente } + end; { resta } + + {########################################################} + + procedure producto(v1, v2: Vector; var vr: Vector); + { procedimiento que multiplica dos polinomios. + v1: vector que contiene el primer polinomio a multiplicar + v2: vector que contiene el segundo polinomio a multiplicar + vr: vector donde se almacenara el resultado de la multiplicacion } + + var + i, j: integer; { indices para usar en los ciclos for } + + begin { producto } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el 1er vector (de tama¤o maximo TAM) } + for j := 0 to TAM - 1 do { recorre el 2do vector (de tama¤o maximo TAM) } + vr[i+j] := vr[i+j] + (v1[i] * v2[j]); + { multiplica los coeficientes de los terminos y lo almacena en la posicion del exponente } + { igual a la suma de los exponentes de v1 y v2, sumando el valor previo de dicha posicion } + end; { producto } + + {########################################################} + + function division(v1, v2: Vector; var vr, vResto: Vector): boolean; + { procedimiento que divide dos polinomios. + v1: vector que contiene el polinomio denominador + v2: vector que contiene el polinomio divisor + vr: vector donde se almacenara el resultado de la division + vResto: vector donde se almacenara el resto de la division + devuelve true si el segundo polinomio no es 0 y se efectua la division y + devuelve false si segundo polinomio es 0 y no se puede efectuar la division } + + var + i, j: integer; { indices para usar en los ciclos for } + vRTmp, { vector auxuliares para almacenar el termino actual del resultado } + vTmp: Vector; { vector auxuliares para almacenar el polinomio que es la multiplicacion del + termino actual del resultado por el divisor } + + begin { division } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vResto); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vTmp); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vRTmp); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := TAM - 1 downto 0 do { recorre el 1er vector (de tama¤o maximo TAM) de atras para adelante } + if v1[i] <> 0 then break; + { busca empezando por el indice (exponete) mas alto el primer coeficiente no nulo } + { si lo encuentra sale del for dejando al valor de i como el de dicho inidice } + for j := TAM - 1 downto 0 do { recorre el 2do vector (de tama¤o maximo TAM) de atras para adelante } + if v2[j] <> 0 then break; + { busca empezando por el indice (exponete) mas alto el primer coeficiente no nulo } + { si lo encuentra sale del for dejando al valor de j como el de dicho inidice } + if (j = 0) and (v2[j] = 0) { si el no se encontro ningun coeficiente no nulo, entonces } + then { el polinomio 2 es nulo y no se puede efectuar la division } + begin { se devuelve false y se quedan los vectores resultado en 0 } + division := false; { devuelve false } + exit; { sale del procedimiento } + end; + while i >= j do { si el primer exponente es mayor o igual que el segundo empieza a dividir } + begin + vr[i-j] := v1[i] / v2[j]; { almacena el resultado de la division entre los coeficientes en + la posicion de la resta de ambos } + vRTmp[i-j] := vr[i-j]; { almacena ese resultado en un polinomio temporal cuyo unico termio + no nulo es el del exponente i-j, para luego multiplicarlo } + producto(vRTmp, v2, vTmp);{ multiplica este polinomio por el segundo almacenado el resultado + en otro temporal, para luego hacer la resta } + resta(v1, vTmp, v1); { resta al primer polinomio, v1, (en su estado actual, no el original) + el temporal vTmp y lo almacena en v1, para poder volver a operarlo de + la misma forma } + vRTmp[i-j] := 0; { resetea el termino del temporal vRTmp que se asigno para los calculos } + for i := i downto 0 do { recorre el vector v1 (de tama¤o maximo TAM) de atras para adelante } + if v1[i] <> 0 then break; + { busca empezando por el indice (exponete) i el primer coeficiente no nulo + si lo encuentra sale del for dejando al valor de i como el de dicho inidice } + end; { while } + vResto := v1; { asigna el vector v1 (que ya no se procesara mas al resto } + division := true; { devuelve true indicando que se finalizo con exito } + end; { division } + + {########################################################} + + procedure mensajeSalida; { muestra un mensaje en la salida del programa } + + begin + writeln; { linea en blanco } + NormVideo; { reestablece los colores a los valores por defecto } + clrscr; { borra la pantalla } + writeln; { linea en blanco } + textcolor(white); { cambia el color del texto } + writeln(' PolinomiosEnVector versi¢n ', VERSION); { mensaje con version del programa } + NormVideo; { reestablece los colores a los valores por defecto } + writeln(' Desarrollado por: Javier Grijalba'); { mensaje con los integrantes del grupo } + writeln(' Leandro Lucarella'); + writeln(' Erasmo Troncovich'); + writeln(' Diego Wojnicki'); + writeln(' para la Facultad de Ingenier¡a de la Universidad de Buenos Aires.'); + writeln(' Consultas y/o sugerencias a:'); + writeln; + textcolor(LightMagenta); { cambia el color del texto } + write(' lluca@cnba.uba.ar'); + NormVideo; { reestablece los colores a los valores por defecto } + write(' o '); + textcolor(LightMagenta); { cambia el color del texto } + writeln('grijalba@cvtci.com.ar'); + NormVideo; { reestablece los colores a los valores por defecto } + writeln; + writeln(' (c) 1999 - Todos los derechos reservados.'); + delay(750); + end; + + + {########################################################} + + +var + i: integer; { variable auxiliar } + v1, v2, vResult, vResto: Vector; { vectores para hacer las operaciones } + seguir, { indicador para saber si sigue corriendo el programa } + noNulo, { indicador para saber si en la division el divisor es nulo } + continua: boolean; { indicador para saber si se leyeron bien los polinomios } + tecla: char; { entrada de teclado del usuario para elegir una opcion } + +begin { programa principal } + textbackground( Blue ); { establece el color para el fondo a azul } + continua := cargarVectores(v1, v2); { carga los vectores del archivo de datos } + if continua then { si se leyeron bien ... } + begin + seguir := true; { inicializa la variable en true para que entre en el ciclo while } + while seguir do { mientras el usuario no salga del programa } + begin + clrscr; { borra la pantalla } + textcolor(Yellow); { establece el color para el texto a amarillo } + gotoxy( 30, 3 ); { va a las coordenas de pantalla 25 horizontal, 3 verical } + writeln( 'PolinomiosEnVector' ); { titulo } + gotoxy( 30, 4 ); { va a las coordenas de pantalla 25 horizontal, 4 verical } + writeln( '~~~~~~~~~~~~~~~~~~' ); { subrayado del titulo } + textcolor(LightCyan); { establece el color para el texto a cian claro } + gotoxy( 1, 7 ); { va a las coordenas de pantalla 1 horizontal, 7 verical } + writeln( ' Elija que desea hacer:' ); { mensaje } + writeln( ' ----- --- ----- ------' ); { mensaje } + textcolor(LightGray); { establece el color para el texto a gris claro } + writeln; { mensaje con las opciones ... } + writeln; + writeln( ' 1.- Ver el polinomio 1.' ); + writeln( ' 2.- Ver el polinomio 2.' ); + writeln( ' 3.- Sumar los polinomios.' ); + writeln( ' 4.- Restar el polinomio 2 al polinomio 1 (poli1 - poli2).' ); + writeln( ' 5.- Restar el polinomio 1 al polinomio 2 (poli2 - poli1).' ); + writeln( ' 6.- Multiplicar los polinomios.' ); + writeln( ' 7.- Polinomio 1 dividido polinomio 2 (poli1 / poli2).' ); + writeln( ' 8.- Polinomio 2 dividido polinomio 1 (poli2 / poli1).' ); + writeln( ' 0.- Salir.' ); + gotoxy(1, 23); { va a las coordenas de pantalla 1 horizontal, 23 verical } + textcolor(White ); { establece el color para el texto a blanco } + write(' Ingrese su opci¢n: '); + textcolor(Yellow); { establece el color para el texto a amarillo } + tecla := readkey; { lee una tecla del usuario indicando la opcion que elijio } + while ((tecla < '1') or (tecla > '8')) and (tecla <> '0') do { mientras sea una tecla no admitida } + begin + textcolor(White); { establece el color para el texto a blanco } + gotoxy( 1, 23 ); { va a las coordenas de pantalla 1 horizontal, 7 verical } + write(' Ingrese su opci¢n ("1" a "8" o "0"): ' ); + textcolor(Yellow); { establece el color para el texto a amarillo } + tecla := readkey; { lee una tecla del usuario indicando la opcion que elijio } + end; { while } + if tecla = '0' then { si la opcion fue salir del programa ... } + begin + mensajeSalida; { presenta un mensaje de salida } + exit; { sale del programa } + end; + clrscr; { borra la pantalla } + textcolor(Yellow); { establece el color para el texto a amarillo } + gotoxy( 30, 3 ); { va a las coordenas de pantalla 25 horizontal, 3 verical } + writeln( 'PolinomiosEnVector' ); { titulo } + gotoxy( 30, 4 ); { va a las coordenas de pantalla 25 horizontal, 4 verical } + writeln( '~~~~~~~~~~~~~~~~~~' ); { subrayado del titulo } + textcolor(LightCyan); { establece el color para el texto a cian claro } + gotoxy(1, 7); { va a las coordenas de pantalla 1 horizontal, 7 verical } + case tecla of + '1': muestraVector(v1, ' Polinomio 1 = '); + '2': muestraVector(v2, ' Polinomio 2 = '); + '3': begin + suma(v1, v2, vResult); + muestraVector(vResult, ' Polinomio 1 + Polinomio 2 = '); + end; { case 3 } + '4': begin + resta(v1, v2, vResult); + muestraVector(vResult, ' Polinomio 1 - Polinomio 2 = '); + end; { case 4 } + '5': begin + resta(v2, v1, vResult); + muestraVector(vResult, ' Polinomio 2 - Polinomio 1 = '); + end; { case 5 } + '6': begin + producto(v1, v2, vResult); + muestraVector(vResult, ' Polinomio 1 * Polinomio 2 = '); + end; { case 6 } + '7': begin + noNulo := division(v1, v2, vResult, vResto); + if noNulo + then + begin + muestraVector(vResult, ' Polinomio 1 / Polinomio 2 = '); + muestraVector(vResto, ' Resto = '); + end + else writeln(' El polinomio 2 es nulo, por lo tanto no se puede efectuar la division.'); + end; { case 7 } + '8': begin + noNulo := division(v2, v1, vResult, vResto); + if noNulo + then + begin + muestraVector(vResult, 'Polinomio 2 / Polinomio 1 = '); + muestraVector(vResto, 'Resto = '); + end + else writeln(' El polinomio 1 es nulo, por lo tanto no se puede efectuar la division.'); + end; { case 8 } + '0': ; { no hace nada, nunca deberia entrar en este case } + end; { case } + writeln; { los siguientes mensajes son para que el usuario pueda ver los datos y luego } + writeln; { presione una tecla para continuar } + textcolor(white); { pone el color del texto en blanco } + writeln(' Presione una tecla para continuar ...'); + tecla := readkey; + end; { while } + end + else { si los vectores no se leyeron bien ... } + begin { presenta un mensaje de error } + writeln('ERROR: No se pudieron cargar los datos. Revise que el formato del archivo'); + writeln(' sea correcto y que no este siendo usado por otro programa.'); + end; +end. { programa principal } \ No newline at end of file diff --git a/poli_10.pas b/poli_10.pas new file mode 100644 index 0000000..6047f9a --- /dev/null +++ b/poli_10.pas @@ -0,0 +1,501 @@ +program PolinomiosEnVector; +{ Programa que lee 2 polinomios desde un archivo de texto para luego + hacer operaciones basicas entre estos (suma, resta, multiplicacion + y division). + El formato del archivo de texto debe ser de la siguiente manera: + + * Se ingresan cada polinomio en lineas sucesivas. + * El primer polinomio puede comenzar a ingresarse en cualquier lugar + del archivo de texto. + * El fin del primer polinomio (y comienzo del segundo) se indica por + medio de 1 o mas lineas en blanco. + * El segundo polinomio puede comenzar a ingresarse en cualquier lugar + del archivo de texto a partir de dicha(s) linea(s) en blanco. + * Cada termino de un polinomio debe estar en la misma linea y comenzar + al principio de esta (excepto el primer termino). + * En cada linea se ingresa primero el coeficiente real (puede tener un + signo '-' al comenzar y/o un punto, y solamente uno) y luego el + exponente entero positivo. + * La separacion entre el coeficiente y el exponente debe estar dada por + uno o mas espacios o tabuladores. + * Cualquier caracter incluido en el texto que no sea un degito (0..9), + un punto ('.'), un signo menos ('-'), un espacio (' '), un tabulador + o alguno de los caracteres de nueva linea, dara un error en la + lectura. + * El archivo de texto debe tener formato DOS (es decir, el indicador de + nueva linea debe ser primero un caracter de retorno del carro + seguido inmediatamente por uno de avance de linea). +} + +uses + CRT, DOS; { Declaracion de funciones predefinidas + para crear la interfaz grafica } + +const + VERSION = '1.0.1r (POLI_10)'; { version del programa } + + TAM_MAX = 100; { Tama¤o maximo del vector que almacena + la multiplicacion de polinomios } + TAM = TAM_MAX div 2; { Tama¤o maximo (virtual) del vector que contiene + los vector con los que se va a operar } + CR = chr(13); { caracter de retorno del carro } + LF = chr(10); { caracter de nueva linea } + ENDF = chr(26); { caracter de fin del archivo } + TAB = chr(9); { caracter de tabulacion } + SPACE = chr(32); { caracter de espacio } + +type + { Tipo de dato para identificar el estado de la entrada de datos } + Estado = (INICIO, COEF_BUSCA, COEF, COEF_PUNTO, COEF_FIN, EXP_BUSCA, EXP, EXP_FIN, EXP_FIN_BUSCA, POLI_FIN, FIN, ERROR); + Vector = array [0..TAM_MAX-1] of real; { vector para almacenar los polinomios } + + + {########################################################} + + procedure muestraVector(var v: Vector; s: String); + { procedimiento que imprime el polinomio v en pantalla con un titulo s } + + {########################################################} + + function exponente(exp: integer): String; + + var + s: String; { variable temporal } + + begin { exponente } + case exp of + 0: exponente := ''; { si el exponente es nulo, mustra solo el coeficiente } + 1: exponente := 'X'; { si el exponente es 1, mustra el coeficiente y X } + 2: exponente := 'Xý'; { si el exponente es 2, mustra el coeficiente y Xý } + else begin + str(exp, s); { convierte al exponente en string } + exponente := 'X^' + s; { si el exponente es mayor que 1, mustra el coeficiente y X^exp } + end; { else } + end; { case } + end; { exponente } + + {########################################################} + + + var + i: integer; { indice para usar en el ciclo for } + + begin { muestraVector } + writeln; { separacion de una linea } + write(s); { mustra el mensaje } + for i := TAM_MAX - 1 downto 0 do { recorre el vector de atras para adelante } + if v[i] <> 0 then break; { si el coeficiente no es nulo, termina el for dejando a i en ese indice } + if (i = 0) and (v[i] = 0) then { si el primer exponente que encuentra es 0 y el coeficiente es 0, entonces } + begin { muestra el resultado como 0 y sale del procedimiento } + write('0'); { imprime que el resultado es cero } + writeln; { separacion de una linea } + writeln; { separacion de una linea } + exit; { sale de este procedimiento } + end; + if (abs(v[i]) <> 1) or (i = 0) { si el modulo del coeficiente es distinto de 1 o si el exp. es 0 } + then if abs(v[i]) - trunc(abs(v[i])) = 0 then write(trunc(v[i]):1, ' ') { imprime si es un numero entero } + else write(v[i]:1:2, ' ') { imprime si es un numero real } + else if v[i] = -1 then write('-'); { si es -1 entonces solo escribe el signo del termino } + write(exponente(i)); + for i := i - 1 downto 0 do { recorre el vector de atras para adelante } + if v[i] <> 0 then { si el coeficiente no es nulo, termina el for dejando a i en ese indice } + begin + if v[i] < 0 { si el coeficiente en negativo } + then write(' - ') { le agrega el signo - } + else write(' + '); { si no, le agrega el signo + } + if (abs(v[i]) <> 1) or (i = 0) then { si el modulo del coeficiente es distinto de 1 o si el exp. es 0 } + if abs(v[i]) - trunc(abs(v[i])) = 0 then write(trunc(abs(v[i])):1, ' ') { imprime si es un entero } + else write(abs(v[i]):1:2, ' '); { imprime si es un real } + write(exponente(i)); + end; { if } + writeln; { separacion de una linea } + writeln; { separacion de una linea } + end; { muestraVector } + + {########################################################} + + procedure inicializaVector(var v: Vector); + { procedimiento que inicializa un vector de tama¤o tam } + + var i: integer; { indice para usar en el ciclo for } + + begin { inicializaVector } + for i := 0 to TAM_MAX - 1 do { recorre el vector } + v[i] := 0; { inicializa la variable actual en 0 } + end; { inicializaVector } + + {########################################################} + + function ObtenerNombreArchivo: String; + { funcion que obtiene un nombre de archivo valido (es decir, el nombre + de un archivo que exista) } + + {########################################################} + + function fileExists(FileName: String): Boolean; + { funcion extraida de la ayuda del Turbo Pascal 7 + indica si el archivo existe } + + var + F: file; + + begin + {$I-} + Assign(F, FileName); + FileMode := 0; { Set file access to read only } + Reset(F); + Close(F); + {$I+} + FileExists := (IOResult = 0) and (FileName <> ''); + end; { FileExists } + + {########################################################} + + { Continuacion de la funcion ObtenerNombreArchivo } + const + DEFAUL_FILE_NAME = 'datos.txt'; { nombre del archivo por defecto } + + var + tmp: String; { cadena para almacenar el resultado temporal } + + begin { ObtenerNombreArchivo } + { mensaje para entrada del nombre de archivo } + writeln('Ingrese el nombre del archivo con los datos (ENTER = ', DEFAUL_FILE_NAME, '):'); + readln(tmp); { entrada del nombre de archivo } + if tmp = '' then tmp := DEFAUL_FILE_NAME; { se fija si no se ingreso nada y reasigana el nombre } + while not fileExists(tmp) do { repite el proceso hasta que el archivo exista } + begin + write('El archivo ', tmp, ' no existe. Ingrese un nombre correcto'); + if tmp = DEFAUL_FILE_NAME { si es el nombre de archivo predeterminado } + then { entonces, elije un mensaje apropiado } + write(': ') + else + begin { si no es el predeterminado, muestra otro mensaje } + writeln('.'); + write('(ENTER = ', DEFAUL_FILE_NAME, '): '); + end; + readln(tmp); { vuelve a leer el nombre del archivo para ser verificado } + if tmp = '' then tmp := DEFAUL_FILE_NAME; { asigna como nombre de archivo al predeterminado + si no se escribio nada } + end; { fin del loop de verificacion } + ObtenerNombreArchivo := tmp; { asigna el nombre correcto al valor de salida de la funcion } + end; { ObtenerNombreArchivo } + + {########################################################} + + function trans(c: char; e: Estado): Estado; + { establece el estado en el que se encuentra la lectura } + { c es el caracter que se leyo, e es el estado actual de la lectura } + + begin { trans } + case e of { acciona segun es estado actual de la lectura } + INICIO: { estado de inicio de la lectura } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un numero (o negativo), empieza a leer el coeficiente } + SPACE, TAB, CR, LF: trans := COEF_BUSCA; { si es un caracter tipo "espacio", busca el prox. coef. } + else trans := ERROR; { si es otro, da ERROR } + end; + COEF_BUSCA: { estado de busqueda del primer ceoficiente del polinomio } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un numero (o negativo), empieza a leer el coeficiente } + SPACE, TAB, CR, LF: trans := COEF_BUSCA; { si es un caracter tupo "espacio", sigue buscando } + ENDF: trans := FIN; { si es el caracter de fin de archivo, pasa al estado de tarea finalizada } + else trans := ERROR; { si es otro, da ERROR } + end; + COEF: { estado de lectura del coeficiente del termino del polinomio (sin punto decimal) } + case c of { acciona segun el caracter leido } + '0'..'9': trans := COEF; { si es un numero sigue con el mismo estado } + '.': trans := COEF_PUNTO; { si es punto cambia al estado COEF_PUNTO } + SPACE, TAB: trans := COEF_FIN; { si es un espacio o un tabulador, finaliza la lectura del coeficiente } + else trans := ERROR; { si es otra cosa, pasa a estado de error } + end; + COEF_PUNTO: { estado de lectura del coeficiente del termino del polinomio (con punto decimal) } + case c of { acciona segun el caracter leido } + '0'..'9': trans := COEF_PUNTO; { si es un numero sigue con el mismo estado } + SPACE, TAB: trans := COEF_FIN; { si es un espacio o un tabulador, finaliza la lectura del coeficiente } + else trans := ERROR; { si es otra cosa, pasa a estado de error } + end; + COEF_FIN: { estado de fin de la lectura del coeficiente del termino del polinomio } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si el caracter es un numero establece el estado en EXP (exponente) } + SPACE, TAB: trans := EXP_BUSCA; { si es un espacio o tabulador, pasa a buscar el proximo exponente } + else trans := ERROR; { si no es ninguno de los anteriores, el estado pasa a ERROR } + end; + EXP_BUSCA: { estado de busqueda del proximo exponente } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si el caracter es un numero, empieza a leer el exponente } + SPACE, TAB: trans := EXP_BUSCA; { si es un espacio o tabulador, sigue buscando } + else trans := ERROR; { si no es ninguno de los anteriores, el estado pasa a ERROR } + end; + EXP: { estado de lectura del exponente del termino actual del polinomio } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si es un digito, sigue en el mismo estado } + CR: trans := EXP_FIN; { si es un ratorno de carro, finaliza el exponente + (quiere decir que hubo un ) } + ENDF: trans := FIN; { si es el final del archivo, se indica que termino su tarea } + else trans := ERROR; { si es otra cosa, devuelve ERROR } + end; + EXP_FIN: { estado de fin de la lectura del exponente del termino actual del polinomio } + if c = LF then trans := EXP_FIN_BUSCA { debe ser un caracter de nueva linea (para completar el ) } + else trans := ERROR; { si no lo es, devuelve ERROR } + EXP_FIN_BUSCA: { estado de fin de lectura de la nueva linea (luego de finalizar el exponente + ahora decide si termino el polinomio o si sigue leyendo el proximo coeficiente } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un digito (o negativo), pasa a leer en proximo coeficiente } + CR: trans := POLI_FIN; { si es un ratorno de carro o nueva linea, finaliza el polinomio } + else trans := ERROR; { si es otra cosa, devuelve ERROR } + end; + POLI_FIN: { estado de finalizacion del polinomio actual } + if c = LF then trans := COEF_BUSCA { debe ser un caracter de nueva linea (para completar el ), + entonces pasa a buscar el primer coeficiente del nuevo polinomio } + else trans := ERROR; { si no lo es, devuelve ERROR } + FIN: { estado que adquiere cuando se finalizo la tarea } + trans := FIN; { se queda en este estado avisando que termino su tarea } + else { otro estado, no deberia ocurrir, salvo que se le pase a la funcion un estado de ERROR } + trans := ERROR; { si es otro, da ERROR } + end; { case } + end; { trans } + + {########################################################} + + function cargarVectores(var v1, v2: Vector): boolean; + { Funcion que abre el archivo de texto con los datos, lo carga en el vector procesandolo debidamente a medida + que lo lee y, al finalizar, cierra el archivo de texto. + v1 es el primer vector a cargar + v2 es el segundo vector a cargar + devuelve true si la lectura fue hecha con exito, false si hubo un error } + + var + f: Text; { archivo de texto con los datos } + c: char; { caracter que se extrae del archivo de texto } + nombreArchivo: String; { nombre del archivo de datos } + est: Estado; { Indicador del estado actual de la lectura } + seguir: boolean; { indicador para saber si debe seguir con el proceso } + i, { indice del vector del polinomio para ser inicializado } + iExp, { valor temporal para almacenar al exponente } + code, { almacena el resultado de la funcion val (no se usa porque los + datos ya estan validados } + poliN: integer; { numero del polinomio que se esta leyendo } + rCoef: real; { valor temporal para almacenar al coeficiente } + exponente, { string que representa al exponente leido } + coeficiente: String; { string que representa al coeficiente leido } + + begin { cargarVectores } + rCoef := 0.0; { inicializacion de variable } + iExp := 0; { inicializacion de variable } + coeficiente := ''; { inicializacion de variable } + exponente := ''; { inicializacion de variable } + est := INICIO; { empieza con el estado de INICIO } + poliN := 1; { establece que se procesara el primer polinomio } + inicializaVector(v1); { inicializacion del vector 1 (primer polinomio) } + inicializaVector(v2); { inicializacion del vector 2 (segundo polinomio) } + nombreArchivo := ObtenerNombreArchivo; { obtiene el nombre del archivo } + assign(f, nombreArchivo); { asigna la variable al nombre del archivo } + reset(f); { abre el archivo para leerlo desde el principio } + seguir := true; { inicializa seguir e true para comenzar el bucle } + while seguir do begin { continua mientras seguir sea true } + read(f, c); { lee un caracter del archivo de texto } + est := trans(c, est); { establece el nuevo estado de lectura } + case est of { toma una desicion dependiendo del estado en que se encuentre } + INICIO: ; { No hace nada, nunca toma este valor. Solo incica que empezo el proceso } + COEF_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + COEF, COEF_PUNTO: { Si esta leyendo el coeficiente ... } + coeficiente := coeficiente + c; { concatena el caracter a la representacion + de texto del coeficiente } + COEF_FIN: ; { Si termino de leer el coeficiente, no hace nada, la asignacion + se realiza cuando termina de leer el exponente (es necesario + para establecer el indice del vector } + EXP_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + EXP: { Si esta leyendo el exponente ... } + exponente := exponente + c; { concatena el caracter a la representacion + de texto del exponente } + EXP_FIN: { Si termino de leer el exponente, hace las asignaciones correspondientes } + begin { convirtiendo las cadenas de texto en real e integer, segun el caso } + val(coeficiente, rCoef, code); { convierte el coeficiente en real } + val(exponente, iExp, code); { convierte el exponente en integer } + if iExp < TAM { si el exponente es menor que el tama¤o maximo permitido ... } + then if poliN = 1 then v1[iExp] := rCoef { asigna el valor correspondiente } + else v2[iExp] := rCoef { al polinomio correspondiente } + else est := ERROR; { si no es menor, pone el estado en ERROR } + coeficiente := ''; { una vez asignados, vacia los valores del coeficiente y el } + exponente := ''; { exponente para poder realizar las lecturas de los proximos } + end; + EXP_FIN_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + POLI_FIN: { Si termino la lectura de un polinomio ... } + if poliN = 1 then poliN := 2 { si se leyo el 1er polinomio, se indica que se leera el 2do } + else est := FIN; { si no (ya se leyo el segundo), pone el estado en FIN } + FIN: { Si se finalizaron las tareas ... } + begin + { este codigo es el mismo que el de EXP_FIN, se repite aca solo por si el final del + archivo esta pegado al fin del ultimo exponente, en cuyo caso no pasa por el estado + de EXP_FIN (y, por ende, no se pueden hacer las asignaciones correspondientes } + val(coeficiente, rCoef, code); { convierte el coeficiente en real } + val(exponente, iExp, code); { convierte el exponente en integer } + if iExp < TAM { si el exponente es menor que el tama¤o maximo permitido ... } + then if poliN = 1 then v1[iExp] := rCoef { asigna el valor correspondiente } + else v2[iExp] := rCoef { al polinomio correspondiente } + else est := ERROR; { si no es menor, pone el estado en ERROR } + coeficiente := ''; { una vez asignados, vacia los valores del coeficiente y el } + exponente := ''; { exponente para poder realizar las lecturas de los proximos } + { fin del codigo identico a EXP_FIN } + if poliN = 2 then cargarVectores := true { si se leyeron los 2 polinomios, devuelve true } + else cargarVectores := false; { si no se leyeron los dos, devuelve false } + seguir := false; { poner seguir en false para que se termine el bucle } + end; + ERROR: { Si hubo un error ... } + begin + cargarVectores := false; { Se devuelve false (hubo un ERROR, no se leyeron bien los vectores) } + seguir := false; { seguir se pone en false para que termine el bucle } + end; + end; { case } + end; { while } + close(f); { se cierra el archivo de lectura de datos } + end; { cargarVectores } + + {########################################################} + + procedure suma(v1, v2: Vector; var vr: Vector); + { procedimiento que suma dos polinomios. + v1: vector que contiene el primer polinomio a sumar + v2: vector que contiene el segundo polinomio a sumar + vr: vector donde se almacenara el resultado de la suma } + + var + i: integer; { indice para usar en el ciclo for } + + begin { suma } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el vector (de tama¤o maximo TAM) } + vr[i] := v1[i] + v2[i]; { suma los coeficientes de los terminos con igual exponente } + end; { suma } + + {########################################################} + + procedure resta(v1, v2: Vector; var vr: Vector); + { procedimiento que resta dos polinomios. + v1: vector que contiene el primer polinomio + v2: vector que contiene el polinomio para restarle al primero + vr: vector donde se almacenara el resultado de la resta } + + var + i: integer; { indice para usar en el ciclo for } + + begin { resta } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el vector (de tama¤o maximo TAM) } + vr[i] := v1[i] - v2[i]; { resta los coeficientes de los terminos con igual exponente } + end; { resta } + + {########################################################} + + procedure producto(v1, v2: Vector; var vr: Vector); + { procedimiento que multiplica dos polinomios. + v1: vector que contiene el primer polinomio a multiplicar + v2: vector que contiene el segundo polinomio a multiplicar + vr: vector donde se almacenara el resultado de la multiplicacion } + + var + i, j: integer; { indices para usar en los ciclos for } + + begin { producto } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el 1er vector (de tama¤o maximo TAM) } + for j := 0 to TAM - 1 do { recorre el 2do vector (de tama¤o maximo TAM) } + vr[i+j] := vr[i+j] + (v1[i] * v2[j]); + { multiplica los coeficientes de los terminos y lo almacena en la posicion del exponente } + { igual a la suma de los exponentes de v1 y v2, sumando el valor previo de dicha posicion } + end; { producto } + + {########################################################} + + function division(v1, v2: Vector; var vr, vResto: Vector): boolean; + { procedimiento que divide dos polinomios. + v1: vector que contiene el polinomio denominador + v2: vector que contiene el polinomio divisor + vr: vector donde se almacenara el resultado de la division + vResto: vector donde se almacenara el resto de la division + devuelve true si el segundo polinomio no es 0 y se efectua la division y + devuelve false si segundo polinomio es 0 y no se puede efectuar la division } + + var + i, j: integer; { indices para usar en los ciclos for } + vRTmp, { vector auxuliares para almacenar el termino actual del resultado } + vTmp: Vector; { vector auxuliares para almacenar el polinomio que es la multiplicacion del + termino actual del resultado por el divisor } + + begin { division } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vResto); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vTmp); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vRTmp); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := TAM - 1 downto 0 do { recorre el 1er vector (de tama¤o maximo TAM) de atras para adelante } + if v1[i] <> 0 then break; + { busca empezando por el indice (exponete) mas alto el primer coeficiente no nulo } + { si lo encuentra sale del for dejando al valor de i como el de dicho inidice } + for j := TAM - 1 downto 0 do { recorre el 2do vector (de tama¤o maximo TAM) de atras para adelante } + if v2[j] <> 0 then break; + { busca empezando por el indice (exponete) mas alto el primer coeficiente no nulo } + { si lo encuentra sale del for dejando al valor de j como el de dicho inidice } + if (j = 0) and (v2[j] = 0) { si el no se encontro ningun coeficiente no nulo, entonces } + then { el polinomio 2 es nulo y no se puede efectuar la division } + begin { se devuelve false y se quedan los vectores resultado en 0 } + division := false; { devuelve false } + exit; { sale del procedimiento } + end; + while i >= j do { si el primer exponente es mayor o igual que el segundo empieza a dividir } + begin + vr[i-j] := v1[i] / v2[j]; { almacena el resultado de la division entre los coeficientes en + la posicion de la resta de ambos } + vRTmp[i-j] := vr[i-j]; { almacena ese resultado en un polinomio temporal cuyo unico termio + no nulo es el del exponente i-j, para luego multiplicarlo } + producto(vRTmp, v2, vTmp);{ multiplica este polinomio por el segundo almacenado el resultado + en otro temporal, para luego hacer la resta } + resta(v1, vTmp, v1); { resta al primer polinomio, v1, (en su estado actual, no el original) + el temporal vTmp y lo almacena en v1, para poder volver a operarlo de + la misma forma } + vRTmp[i-j] := 0; { resetea el termino del temporal vRTmp que se asigno para los calculos } + for i := i downto 0 do { recorre el vector v1 (de tama¤o maximo TAM) de atras para adelante } + if v1[i] <> 0 then break; + { busca empezando por el indice (exponete) i el primer coeficiente no nulo + si lo encuentra sale del for dejando al valor de i como el de dicho inidice } + end; { while } + vResto := v1; { asigna el vector v1 (que ya no se procesara mas al resto } + division := true; { devuelve true indicando que se finalizo con exito } + end; { division } + + {########################################################} + +{ Continuacion del programa principal } + +var + i: integer; { variable auxiliar } + v1, v2, vResult, vResto: Vector; { vectores para hacer las operaciones } + continua: boolean; { valor para obtener los resultados de algunas funciones } + +begin { Comienzo del programa principal } + continua := cargarVectores(v1, v2); + if continua then + begin + muestraVector(v1, 'Polinomio 1 = '); + muestraVector(v2, 'Polinomio 2 = '); + suma(v1, v2, vResult); + muestraVector(vResult, 'Polinomio 1 + Polinomio 2 = '); + resta(v1, v2, vResult); + muestraVector(vResult, 'Polinomio 1 - Polinomio 2 = '); + producto(v1, v2, vResult); + muestraVector(vResult, 'Polinomio 1 * Polinomio 2 = '); + continua := division(v1, v2, vResult, vResto); + if continua + then + begin + muestraVector(vResult, 'Polinomio 1 / Polinomio 2 = '); + muestraVector(vResto, 'Resto = '); + end + else writeln('El segundo polinomio es nulo, por lo tanto no se puede efectuar la division'); + end + else + begin + writeln('ERROR: No se pudieron cargar los datos. Revise que el formato del archivo'); + writeln(' sea correcto y que no este siendo usado por otro programa.'); + end; +end. \ No newline at end of file diff --git a/poli_11.pas b/poli_11.pas new file mode 100644 index 0000000..2e1986b --- /dev/null +++ b/poli_11.pas @@ -0,0 +1,498 @@ +program PolinomiosEnVector; +{ Programa que lee 2 polinomios desde un archivo de texto para luego + hacer operaciones basicas entre estos (suma, resta, multiplicacion + y division). + El formato del archivo de texto debe ser de la siguiente manera: + + * Se ingresan cada polinomio en lineas sucesivas. + * El primer polinomio puede comenzar a ingresarse en cualquier lugar + del archivo de texto. + * El fin del primer polinomio (y comienzo del segundo) se indica por + medio de 1 o mas lineas en blanco. + * El segundo polinomio puede comenzar a ingresarse en cualquier lugar + del archivo de texto a partir de dicha(s) linea(s) en blanco. + * Cada termino de un polinomio debe estar en la misma linea y comenzar + al principio de esta (excepto el primer termino). + * En cada linea se ingresa primero el coeficiente real (puede tener un + signo '-' al comenzar y/o un punto, y solamente uno) y luego el + exponente entero positivo. + * La separacion entre el coeficiente y el exponente debe estar dada por + uno o mas espacios o tabuladores. + * Cualquier caracter incluido en el texto que no sea un degito (0..9), + un punto ('.'), un signo menos ('-'), un espacio (' '), un tabulador + o alguno de los caracteres de nueva linea, dara un error en la + lectura. + * El archivo de texto debe tener formato DOS (es decir, el indicador de + nueva linea debe ser primero un caracter de retorno del carro + seguido inmediatamente por uno de avance de linea). +} + +uses + CRT, DOS; { Declaracion de funciones predefinidas + para crear la interfaz grafica } + +const + VERSION = '1.0.5r (POLI_11)'; { version del programa } + + TAM_MAX = 100; { Tama¤o maximo del vector que almacena + la multiplicacion de polinomios } + TAM = TAM_MAX div 2; { Tama¤o maximo (virtual) del vector que contiene + los vector con los que se va a operar } + CR = chr(13); { caracter de retorno del carro } + LF = chr(10); { caracter de nueva linea } + ENDF = chr(26); { caracter de fin del archivo } + TAB = chr(9); { caracter de tabulacion } + SPACE = chr(32); { caracter de espacio } + +type + { Tipo de dato para identificar el estado de la entrada de datos } + Estado = (INICIO, COEF_BUSCA, COEF, COEF_PUNTO, COEF_FIN, EXP_BUSCA, EXP, EXP_FIN, EXP_FIN_BUSCA, POLI_FIN, FIN, ERROR); + Vector = array [0..TAM_MAX-1] of real; { vector para almacenar los polinomios } + + + {########################################################} + + procedure muestraVector(var v: Vector; s: String); + { procedimiento que imprime el polinomio v en pantalla con un titulo s } + + {########################################################} + + function exponente(exp: integer): String; + + var + s: String; { variable temporal } + + begin { exponente } + case exp of + 0: exponente := ''; { si el exponente es nulo, mustra solo el coeficiente } + 1: exponente := 'X'; { si el exponente es 1, mustra el coeficiente y X } + 2: exponente := 'Xý'; { si el exponente es 2, mustra el coeficiente y Xý } + else begin + str(exp, s); { convierte al exponente en string } + exponente := 'X^' + s; { si el exponente es mayor que 1, mustra el coeficiente y X^exp } + end; { else } + end; { case } + end; { exponente } + + {########################################################} + + + var + i: integer; { indice para usar en el ciclo for } + + begin { muestraVector } + writeln; { separacion de una linea } + write(s); { mustra el mensaje } + for i := TAM_MAX - 1 downto 0 do { recorre el vector de atras para adelante } + if v[i] <> 0 then break; { si el coeficiente no es nulo, termina el for dejando a i en ese indice } + if (i = 0) and (v[i] = 0) then { si el primer exponente que encuentra es 0 y el coeficiente es 0, entonces } + begin { muestra el resultado como 0 y sale del procedimiento } + write('0'); { imprime que el resultado es cero } + writeln; { separacion de una linea } + writeln; { separacion de una linea } + exit; { sale de este procedimiento } + end; + if (abs(v[i]) <> 1) or (i = 0) { si el modulo del coeficiente es distinto de 1 o si el exp. es 0 } + then if abs(v[i]) - trunc(abs(v[i])) = 0 then write(trunc(v[i]):1, ' ') { imprime si es un numero entero } + else write(v[i]:1:2, ' ') { imprime si es un numero real } + else if v[i] = -1 then write('-'); { si es -1 entonces solo escribe el signo del termino } + write(exponente(i)); + for i := i - 1 downto 0 do { recorre el vector de atras para adelante } + if v[i] <> 0 then { si el coeficiente no es nulo, termina el for dejando a i en ese indice } + begin + if v[i] < 0 { si el coeficiente en negativo } + then write(' - ') { le agrega el signo - } + else write(' + '); { si no, le agrega el signo + } + if (abs(v[i]) <> 1) or (i = 0) then { si el modulo del coeficiente es distinto de 1 o si el exp. es 0 } + if abs(v[i]) - trunc(abs(v[i])) = 0 then write(trunc(abs(v[i])):1, ' ') { imprime si es un entero } + else write(abs(v[i]):1:2, ' '); { imprime si es un real } + write(exponente(i)); + end; { if } + writeln; { separacion de una linea } + writeln; { separacion de una linea } + end; { muestraVector } + + {########################################################} + + procedure inicializaVector(var v: Vector); + { procedimiento que inicializa un vector de tama¤o tam } + + var i: integer; { indice para usar en el ciclo for } + + begin { inicializaVector } + for i := 0 to TAM_MAX - 1 do { recorre el vector } + v[i] := 0; { inicializa la variable actual en 0 } + end; { inicializaVector } + + {########################################################} + + function ObtenerNombreArchivo: String; + { funcion que obtiene un nombre de archivo valido (es decir, el nombre + de un archivo que exista) } + + {########################################################} + + function fileExists(FileName: String): Boolean; + { funcion extraida de la ayuda del Turbo Pascal 7 + indica si el archivo existe } + + var + F: file; + + begin + {$I-} + Assign(F, FileName); + FileMode := 0; { Set file access to read only } + Reset(F); + Close(F); + {$I+} + FileExists := (IOResult = 0) and (FileName <> ''); + end; { FileExists } + + {########################################################} + + { Continuacion de la funcion ObtenerNombreArchivo } + const + DEFAUL_FILE_NAME = 'datos.txt'; { nombre del archivo por defecto } + + var + tmp: String; { cadena para almacenar el resultado temporal } + + begin { ObtenerNombreArchivo } + { mensaje para entrada del nombre de archivo } + writeln('Ingrese el nombre del archivo con los datos (ENTER = ', DEFAUL_FILE_NAME, '):'); + readln(tmp); { entrada del nombre de archivo } + if tmp = '' then tmp := DEFAUL_FILE_NAME; { se fija si no se ingreso nada y reasigana el nombre } + while not fileExists(tmp) do { repite el proceso hasta que el archivo exista } + begin + write('El archivo ', tmp, ' no existe. Ingrese un nombre correcto'); + if tmp = DEFAUL_FILE_NAME { si es el nombre de archivo predeterminado } + then { entonces, elije un mensaje apropiado } + write(': ') + else + begin { si no es el predeterminado, muestra otro mensaje } + writeln('.'); + write('(ENTER = ', DEFAUL_FILE_NAME, '): '); + end; + readln(tmp); { vuelve a leer el nombre del archivo para ser verificado } + if tmp = '' then tmp := DEFAUL_FILE_NAME; { asigna como nombre de archivo al predeterminado + si no se escribio nada } + end; { fin del loop de verificacion } + ObtenerNombreArchivo := tmp; { asigna el nombre correcto al valor de salida de la funcion } + end; { ObtenerNombreArchivo } + + {########################################################} + + function trans(c: char; e: Estado): Estado; + { establece el estado en el que se encuentra la lectura } + { c es el caracter que se leyo, e es el estado actual de la lectura } + + begin { trans } + case e of { acciona segun es estado actual de la lectura } + INICIO: { estado de inicio de la lectura } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un numero (o negativo), empieza a leer el coeficiente } + SPACE, TAB, CR, LF: trans := COEF_BUSCA; { si es un caracter tipo "espacio", busca el prox. coef. } + else trans := ERROR; { si es otro, da ERROR } + end; + COEF_BUSCA: { estado de busqueda del primer ceoficiente del polinomio } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un numero (o negativo), empieza a leer el coeficiente } + SPACE, TAB, CR, LF: trans := COEF_BUSCA; { si es un caracter tupo "espacio", sigue buscando } + ENDF: trans := FIN; { si es el caracter de fin de archivo, pasa al estado de tarea finalizada } + else trans := ERROR; { si es otro, da ERROR } + end; + COEF: { estado de lectura del coeficiente del termino del polinomio (sin punto decimal) } + case c of { acciona segun el caracter leido } + '0'..'9': trans := COEF; { si es un numero sigue con el mismo estado } + '.': trans := COEF_PUNTO; { si es punto cambia al estado COEF_PUNTO } + SPACE, TAB: trans := COEF_FIN; { si es un espacio o un tabulador, finaliza la lectura del coeficiente } + else trans := ERROR; { si es otra cosa, pasa a estado de error } + end; + COEF_PUNTO: { estado de lectura del coeficiente del termino del polinomio (con punto decimal) } + case c of { acciona segun el caracter leido } + '0'..'9': trans := COEF_PUNTO; { si es un numero sigue con el mismo estado } + SPACE, TAB: trans := COEF_FIN; { si es un espacio o un tabulador, finaliza la lectura del coeficiente } + else trans := ERROR; { si es otra cosa, pasa a estado de error } + end; + COEF_FIN: { estado de fin de la lectura del coeficiente del termino del polinomio } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si el caracter es un numero establece el estado en EXP (exponente) } + SPACE, TAB: trans := EXP_BUSCA; { si es un espacio o tabulador, pasa a buscar el proximo exponente } + else trans := ERROR; { si no es ninguno de los anteriores, el estado pasa a ERROR } + end; + EXP_BUSCA: { estado de busqueda del proximo exponente } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si el caracter es un numero, empieza a leer el exponente } + SPACE, TAB: trans := EXP_BUSCA; { si es un espacio o tabulador, sigue buscando } + else trans := ERROR; { si no es ninguno de los anteriores, el estado pasa a ERROR } + end; + EXP: { estado de lectura del exponente del termino actual del polinomio } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si es un digito, sigue en el mismo estado } + CR: trans := EXP_FIN; { si es un ratorno de carro, finaliza el exponente + (quiere decir que hubo un ) } + ENDF: trans := FIN; { si es el final del archivo, se indica que termino su tarea } + else trans := ERROR; { si es otra cosa, devuelve ERROR } + end; + EXP_FIN: { estado de fin de la lectura del exponente del termino actual del polinomio } + if c = LF then trans := EXP_FIN_BUSCA { debe ser un caracter de nueva linea (para completar el ) } + else trans := ERROR; { si no lo es, devuelve ERROR } + EXP_FIN_BUSCA: { estado de fin de lectura de la nueva linea (luego de finalizar el exponente + ahora decide si termino el polinomio o si sigue leyendo el proximo coeficiente } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un digito (o negativo), pasa a leer en proximo coeficiente } + CR: trans := POLI_FIN; { si es un ratorno de carro o nueva linea, finaliza el polinomio } + else trans := ERROR; { si es otra cosa, devuelve ERROR } + end; + POLI_FIN: { estado de finalizacion del polinomio actual } + if c = LF then trans := COEF_BUSCA { debe ser un caracter de nueva linea (para completar el ), + entonces pasa a buscar el primer coeficiente del nuevo polinomio } + else trans := ERROR; { si no lo es, devuelve ERROR } + FIN: { estado que adquiere cuando se finalizo la tarea } + trans := FIN; { se queda en este estado avisando que termino su tarea } + else { otro estado, no deberia ocurrir, salvo que se le pase a la funcion un estado de ERROR } + trans := ERROR; { si es otro, da ERROR } + end; { case } + end; { trans } + + {########################################################} + + function cargarVectores(var v1, v2: Vector): boolean; + { Funcion que abre el archivo de texto con los datos, lo carga en el vector procesandolo debidamente a medida + que lo lee y, al finalizar, cierra el archivo de texto. + v1 es el primer vector a cargar + v2 es el segundo vector a cargar + devuelve true si la lectura fue hecha con exito, false si hubo un error } + + var + f: Text; { archivo de texto con los datos } + c: char; { caracter que se extrae del archivo de texto } + nombreArchivo: String; { nombre del archivo de datos } + est: Estado; { Indicador del estado actual de la lectura } + seguir: boolean; { indicador para saber si debe seguir con el proceso } + i, { indice del vector del polinomio para ser inicializado } + iExp, { valor temporal para almacenar al exponente } + code, { almacena el resultado de la funcion val (no se usa porque los + datos ya estan validados } + poliN: integer; { numero del polinomio que se esta leyendo } + rCoef: real; { valor temporal para almacenar al coeficiente } + exponente, { string que representa al exponente leido } + coeficiente: String; { string que representa al coeficiente leido } + + begin { cargarVectores } + rCoef := 0.0; { inicializacion de variable } + iExp := 0; { inicializacion de variable } + coeficiente := ''; { inicializacion de variable } + exponente := ''; { inicializacion de variable } + est := INICIO; { empieza con el estado de INICIO } + poliN := 1; { establece que se procesara el primer polinomio } + inicializaVector(v1); { inicializacion del vector 1 (primer polinomio) } + inicializaVector(v2); { inicializacion del vector 2 (segundo polinomio) } + nombreArchivo := ObtenerNombreArchivo; { obtiene el nombre del archivo } + assign(f, nombreArchivo); { asigna la variable al nombre del archivo } + reset(f); { abre el archivo para leerlo desde el principio } + seguir := true; { inicializa seguir e true para comenzar el bucle } + while seguir do begin { continua mientras seguir sea true } + read(f, c); { lee un caracter del archivo de texto } + est := trans(c, est); { establece el nuevo estado de lectura } + case est of { toma una desicion dependiendo del estado en que se encuentre } + INICIO: ; { No hace nada, nunca toma este valor. Solo incica que empezo el proceso } + COEF_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + COEF, COEF_PUNTO: { Si esta leyendo el coeficiente ... } + coeficiente := coeficiente + c; { concatena el caracter a la representacion + de texto del coeficiente } + COEF_FIN: ; { Si termino de leer el coeficiente, no hace nada, la asignacion + se realiza cuando termina de leer el exponente (es necesario + para establecer el indice del vector } + EXP_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + EXP: { Si esta leyendo el exponente ... } + exponente := exponente + c; { concatena el caracter a la representacion + de texto del exponente } + EXP_FIN: { Si termino de leer el exponente, hace las asignaciones correspondientes } + begin { convirtiendo las cadenas de texto en real e integer, segun el caso } + val(coeficiente, rCoef, code); { convierte el coeficiente en real } + val(exponente, iExp, code); { convierte el exponente en integer } + if iExp < TAM { si el exponente es menor que el tama¤o maximo permitido ... } + then if poliN = 1 then v1[iExp] := rCoef { asigna el valor correspondiente } + else v2[iExp] := rCoef { al polinomio correspondiente } + else est := ERROR; { si no es menor, pone el estado en ERROR } + coeficiente := ''; { una vez asignados, vacia los valores del coeficiente y el } + exponente := ''; { exponente para poder realizar las lecturas de los proximos } + end; + EXP_FIN_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + POLI_FIN: { Si termino la lectura de un polinomio ... } + if poliN = 1 then poliN := 2 { si se leyo el 1er polinomio, se indica que se leera el 2do } + else est := FIN; { si no (ya se leyo el segundo), pone el estado en FIN } + FIN: { Si se finalizaron las tareas ... } + begin + cargarVectores := true; { en principio se establece que la lectura se hizo con exito ) } + seguir := false; { poner seguir en false para que se termine el bucle } + { este codigo es similar al de EXP_FIN, se hacen las asignaciones por el caso en que el fin + del archivo esta pegado al fin del ultimo exponente, en cuyo caso no pasa por el estado + de EXP_FIN (y, por ende, no se pueden hacer las asignaciones correspondientes } + val(coeficiente, rCoef, code); { convierte el coeficiente en real } + val(exponente, iExp, code); { convierte el exponente en integer } + if iExp < TAM { si el exponente es menor que el tama¤o maximo permitido ... } + then if poliN = 2 + then v2[iExp] := rCoef { si es el 2do polinomio, asigna el valor correspondiente } + else cargarVectores := false { si es el primero, no se hizo bien la lectura } + else cargarVectores := false; { si no es menor, no se hizo bien la lectura } + end; + ERROR: { Si hubo un error ... } + begin + cargarVectores := false; { Se devuelve false (hubo un ERROR, no se leyeron bien los vectores) } + seguir := false; { seguir se pone en false para que termine el bucle } + end; + end; { case } + end; { while } + close(f); { se cierra el archivo de lectura de datos } + end; { cargarVectores } + + {########################################################} + + procedure suma(v1, v2: Vector; var vr: Vector); + { procedimiento que suma dos polinomios. + v1: vector que contiene el primer polinomio a sumar + v2: vector que contiene el segundo polinomio a sumar + vr: vector donde se almacenara el resultado de la suma } + + var + i: integer; { indice para usar en el ciclo for } + + begin { suma } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el vector (de tama¤o maximo TAM) } + vr[i] := v1[i] + v2[i]; { suma los coeficientes de los terminos con igual exponente } + end; { suma } + + {########################################################} + + procedure resta(v1, v2: Vector; var vr: Vector); + { procedimiento que resta dos polinomios. + v1: vector que contiene el primer polinomio + v2: vector que contiene el polinomio para restarle al primero + vr: vector donde se almacenara el resultado de la resta } + + var + i: integer; { indice para usar en el ciclo for } + + begin { resta } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el vector (de tama¤o maximo TAM) } + vr[i] := v1[i] - v2[i]; { resta los coeficientes de los terminos con igual exponente } + end; { resta } + + {########################################################} + + procedure producto(v1, v2: Vector; var vr: Vector); + { procedimiento que multiplica dos polinomios. + v1: vector que contiene el primer polinomio a multiplicar + v2: vector que contiene el segundo polinomio a multiplicar + vr: vector donde se almacenara el resultado de la multiplicacion } + + var + i, j: integer; { indices para usar en los ciclos for } + + begin { producto } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el 1er vector (de tama¤o maximo TAM) } + for j := 0 to TAM - 1 do { recorre el 2do vector (de tama¤o maximo TAM) } + vr[i+j] := vr[i+j] + (v1[i] * v2[j]); + { multiplica los coeficientes de los terminos y lo almacena en la posicion del exponente } + { igual a la suma de los exponentes de v1 y v2, sumando el valor previo de dicha posicion } + end; { producto } + + {########################################################} + + function division(v1, v2: Vector; var vr, vResto: Vector): boolean; + { procedimiento que divide dos polinomios. + v1: vector que contiene el polinomio denominador + v2: vector que contiene el polinomio divisor + vr: vector donde se almacenara el resultado de la division + vResto: vector donde se almacenara el resto de la division + devuelve true si el segundo polinomio no es 0 y se efectua la division y + devuelve false si segundo polinomio es 0 y no se puede efectuar la division } + + var + i, j: integer; { indices para usar en los ciclos for } + vRTmp, { vector auxuliares para almacenar el termino actual del resultado } + vTmp: Vector; { vector auxuliares para almacenar el polinomio que es la multiplicacion del + termino actual del resultado por el divisor } + + begin { division } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vResto); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vTmp); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vRTmp); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := TAM - 1 downto 0 do { recorre el 1er vector (de tama¤o maximo TAM) de atras para adelante } + if v1[i] <> 0 then break; + { busca empezando por el indice (exponete) mas alto el primer coeficiente no nulo } + { si lo encuentra sale del for dejando al valor de i como el de dicho inidice } + for j := TAM - 1 downto 0 do { recorre el 2do vector (de tama¤o maximo TAM) de atras para adelante } + if v2[j] <> 0 then break; + { busca empezando por el indice (exponete) mas alto el primer coeficiente no nulo } + { si lo encuentra sale del for dejando al valor de j como el de dicho inidice } + if (j = 0) and (v2[j] = 0) { si el no se encontro ningun coeficiente no nulo, entonces } + then { el polinomio 2 es nulo y no se puede efectuar la division } + begin { se devuelve false y se quedan los vectores resultado en 0 } + division := false; { devuelve false } + exit; { sale del procedimiento } + end; + while i >= j do { si el primer exponente es mayor o igual que el segundo empieza a dividir } + begin + vr[i-j] := v1[i] / v2[j]; { almacena el resultado de la division entre los coeficientes en + la posicion de la resta de ambos } + vRTmp[i-j] := vr[i-j]; { almacena ese resultado en un polinomio temporal cuyo unico termio + no nulo es el del exponente i-j, para luego multiplicarlo } + producto(vRTmp, v2, vTmp);{ multiplica este polinomio por el segundo almacenado el resultado + en otro temporal, para luego hacer la resta } + resta(v1, vTmp, v1); { resta al primer polinomio, v1, (en su estado actual, no el original) + el temporal vTmp y lo almacena en v1, para poder volver a operarlo de + la misma forma } + vRTmp[i-j] := 0; { resetea el termino del temporal vRTmp que se asigno para los calculos } + for i := i downto 0 do { recorre el vector v1 (de tama¤o maximo TAM) de atras para adelante } + if v1[i] <> 0 then break; + { busca empezando por el indice (exponete) i el primer coeficiente no nulo + si lo encuentra sale del for dejando al valor de i como el de dicho inidice } + end; { while } + vResto := v1; { asigna el vector v1 (que ya no se procesara mas al resto } + division := true; { devuelve true indicando que se finalizo con exito } + end; { division } + + {########################################################} + +{ Continuacion del programa principal } + +var + i: integer; { variable auxiliar } + v1, v2, vResult, vResto: Vector; { vectores para hacer las operaciones } + continua: boolean; { valor para obtener los resultados de algunas funciones } + +begin { Comienzo del programa principal } + continua := cargarVectores(v1, v2); + if continua then + begin + muestraVector(v1, 'Polinomio 1 = '); + muestraVector(v2, 'Polinomio 2 = '); + suma(v1, v2, vResult); + muestraVector(vResult, 'Polinomio 1 + Polinomio 2 = '); + resta(v1, v2, vResult); + muestraVector(vResult, 'Polinomio 1 - Polinomio 2 = '); + producto(v1, v2, vResult); + muestraVector(vResult, 'Polinomio 1 * Polinomio 2 = '); + continua := division(v1, v2, vResult, vResto); + if continua + then + begin + muestraVector(vResult, 'Polinomio 1 / Polinomio 2 = '); + muestraVector(vResto, 'Resto = '); + end + else writeln('El segundo polinomio es nulo, por lo tanto no se puede efectuar la division'); + end + else + begin + writeln('ERROR: No se pudieron cargar los datos. Revise que el formato del archivo'); + writeln(' sea correcto y que no este siendo usado por otro programa.'); + end; +end. \ No newline at end of file diff --git a/poli_12.pas b/poli_12.pas new file mode 100644 index 0000000..26e33ea --- /dev/null +++ b/poli_12.pas @@ -0,0 +1,611 @@ +program PolinomiosEnVector; +{ Programa que lee 2 polinomios desde un archivo de texto para luego + hacer operaciones basicas entre estos (suma, resta, multiplicacion + y division). + El formato del archivo de texto debe ser de la siguiente manera: + + * Se ingresan cada polinomio en lineas sucesivas. + * El primer polinomio puede comenzar a ingresarse en cualquier lugar + del archivo de texto. + * El fin del primer polinomio (y comienzo del segundo) se indica por + medio de 1 o mas lineas en blanco. + * El segundo polinomio puede comenzar a ingresarse en cualquier lugar + del archivo de texto a partir de dicha(s) linea(s) en blanco. + * Cada termino de un polinomio debe estar en la misma linea y comenzar + al principio de esta (excepto el primer termino). + * En cada linea se ingresa primero el coeficiente real (puede tener un + signo '-' al comenzar y/o un punto, y solamente uno) y luego el + exponente entero positivo. + * La separacion entre el coeficiente y el exponente debe estar dada por + uno o mas espacios o tabuladores. + * Cualquier caracter incluido en el texto que no sea un digito (0..9), + un punto ('.'), un signo menos ('-'), un espacio (' '), un tabulador + o alguno de los caracteres de nueva linea, dara un error en la + lectura. + * El archivo de texto debe tener formato DOS (es decir, el indicador de + nueva linea debe ser primero un caracter de retorno del carro + seguido inmediatamente por uno de avance de linea). +} + +uses + CRT, DOS; { Declaracion de funciones predefinidas + para crear la interfaz grafica } + +const + VERSION = '1.1.3b (POLI_12)'; { version del programa } + + TAM_MAX = 100; { Tama¤o maximo del vector que almacena + la multiplicacion de polinomios } + TAM = TAM_MAX div 2; { Tama¤o maximo (virtual) del vector que contiene + los vector con los que se va a operar } + CR = chr(13); { caracter de retorno del carro } + LF = chr(10); { caracter de nueva linea } + ENDF = chr(26); { caracter de fin del archivo } + TAB = chr(9); { caracter de tabulacion } + SPACE = chr(32); { caracter de espacio } + +type + { Tipo de dato para identificar el estado de la entrada de datos } + Estado = (INICIO, COEF_BUSCA, COEF, COEF_PUNTO, COEF_FIN, EXP_BUSCA, EXP, EXP_FIN, EXP_FIN_BUSCA, POLI_FIN, FIN, ERROR); + Vector = array [0..TAM_MAX-1] of real; { vector para almacenar los polinomios } + + + {########################################################} + + procedure muestraVector(var v: Vector; s: String); + { procedimiento que imprime el polinomio 'v' en pantalla con un titulo 's' } + + {########################################################} + + function exponente(exp: integer): String; + + var + s: String; { variable temporal } + + begin { exponente } + case exp of + 0: exponente := ''; { si el exponente es nulo, mustra solo el coeficiente } + 1: exponente := 'X'; { si el exponente es 1, mustra el coeficiente y X } + 2: exponente := 'Xý'; { si el exponente es 2, mustra el coeficiente y Xý } + else begin + str(exp, s); { convierte al exponente en string } + exponente := 'X^' + s; { si el exponente es mayor que 1, mustra el coeficiente y X^exp } + end; { else } + end; { case } + end; { exponente } + + {########################################################} + + + var + i: integer; { indice para usar en el ciclo for } + + begin { muestraVector } + textcolor(lightcyan); { pone el color del texto en cian claro } + writeln; { separacion de una linea } + write(s); { mustra el mensaje } + textcolor(lightmagenta); { pone el color del texto en magenta claro } + for i := TAM_MAX - 1 downto 0 do { recorre el vector de atras para adelante } + if v[i] <> 0 then break; { si el coeficiente no es nulo, termina el for dejando a i en ese indice } + if (i = 0) and (v[i] = 0) then { si el primer exponente que encuentra es 0 y el coeficiente es 0, entonces } + begin { muestra el resultado como 0 y sale del procedimiento } + write('0'); { imprime que el resultado es cero } + writeln; { separacion de una linea } + writeln; { separacion de una linea } + exit; { sale de este procedimiento } + end; + if (abs(v[i]) <> 1) or (i = 0) { si el modulo del coeficiente es distinto de 1 o si el exp. es 0 } + then if abs(v[i]) - trunc(abs(v[i])) = 0 then write(trunc(v[i]):1, ' ') { imprime si es un numero entero } + else write(v[i]:1:2, ' ') { imprime si es un numero real } + else if v[i] = -1 then write('-'); { si es -1 entonces solo escribe el signo del termino } + write(exponente(i)); + for i := i - 1 downto 0 do { recorre el vector de atras para adelante } + if v[i] <> 0 then { si el coeficiente no es nulo, termina el for dejando a i en ese indice } + begin + if v[i] < 0 { si el coeficiente en negativo } + then write(' - ') { le agrega el signo - } + else write(' + '); { si no, le agrega el signo + } + if (abs(v[i]) <> 1) or (i = 0) then { si el modulo del coeficiente es distinto de 1 o si el exp. es 0 } + if abs(v[i]) - trunc(abs(v[i])) = 0 then write(trunc(abs(v[i])):1, ' ') { imprime si es un entero } + else write(abs(v[i]):1:2, ' '); { imprime si es un real } + write(exponente(i)); + end; { if } + writeln; { separacion de una linea } + writeln; { separacion de una linea } + end; { muestraVector } + + {########################################################} + + procedure inicializaVector(var v: Vector); + { procedimiento que inicializa un vector de tama¤o tam } + + var i: integer; { indice para usar en el ciclo for } + + begin { inicializaVector } + for i := 0 to TAM_MAX - 1 do { recorre el vector } + v[i] := 0; { inicializa la variable actual en 0 } + end; { inicializaVector } + + {########################################################} + + function ObtenerNombreArchivo: String; + { funcion que obtiene un nombre de archivo valido (es decir, el nombre + de un archivo que exista) } + + {########################################################} + + function fileExists(FileName: String): Boolean; + { funcion extraida de la ayuda del Turbo Pascal 7 + indica si el archivo existe } + + var + F: file; + + begin + {$I-} + Assign(F, FileName); + FileMode := 0; { Set file access to read only } + Reset(F); + Close(F); + {$I+} + FileExists := (IOResult = 0) and (FileName <> ''); + end; { FileExists } + + {########################################################} + + { Continuacion de la funcion ObtenerNombreArchivo } + const + DEFAUL_FILE_NAME = 'datos.txt'; { nombre del archivo por defecto } + + var + tmp: String; { cadena para almacenar el resultado temporal } + + begin { ObtenerNombreArchivo } + { mensaje para entrada del nombre de archivo } + clrscr; { borra la pantalla } + textcolor( Yellow ); { establece el color para el texto a amarillo } + gotoxy( 25, 3 ); { va a las coordenas de pantalla 25 horizontal, 3 verical } + writeln( 'OPERACIONES ENTRE POLINOMIOS' ); { titulo } + gotoxy( 25, 4 ); { va a las coordenas de pantalla 25 horizontal, 4 verical } + writeln( '~~~~~~~~~~~ ~~~~~ ~~~~~~~~~~' ); { subrayado del titulo } + textcolor( LightCyan ); { establece el color para el texto a cian claro } + gotoxy( 1, 7 ); { va a las coordenas de pantalla 1 horizontal, 7 verical } + writeln(' Ingrese el nombre del archivo con los datos (ENTER = ', DEFAUL_FILE_NAME, '):'); + gotoxy( 5, 8 ); { va a las coordenas de pantalla 5 horizontal, 8 verical } + readln(tmp); { entrada del nombre de archivo } + if tmp = '' then tmp := DEFAUL_FILE_NAME; { se fija si no se ingreso nada y reasigana el nombre } + while not fileExists(tmp) do { repite el proceso hasta que el archivo exista } + begin + clrscr; { borra la pantalla } + textcolor( Yellow ); { establece el color para el texto a amarillo } + gotoxy( 25, 3 ); { va a las coordenas de pantalla 19 horizontal, 3 verical } + writeln( 'OPERACIONES ENTRE POLINOMIOS' ); { titulo } + gotoxy( 25, 4 ); { va a las coordenas de pantalla 19 horizontal, 4 verical } + writeln( '~~~~~~~~~~~ ~~~~~ ~~~~~~~~~~' ); { subrayado del titulo } + textcolor( LightCyan ); { establece el color para el texto a cian claro } + gotoxy( 1, 7 ); { va a las coordenas de pantalla 1 horizontal, 7 verical } + write(' El archivo ', tmp, ' no existe. Ingrese un nombre correcto'); + if tmp = DEFAUL_FILE_NAME { si es el nombre de archivo predeterminado } + then { entonces, elije un mensaje apropiado } + write(': ') + else + begin { si no es el predeterminado, muestra otro mensaje } + writeln('.'); + write(' (ENTER = ', DEFAUL_FILE_NAME, '): '); + end; + gotoxy( 5, 9 ); { va a las coordenas de pantalla 5 horizontal, 9 verical } + readln(tmp); { vuelve a leer el nombre del archivo para ser verificado } + if tmp = '' then tmp := DEFAUL_FILE_NAME; { asigna como nombre de archivo al predeterminado + si no se escribio nada } + end; { fin del loop de verificacion } + ObtenerNombreArchivo := tmp; { asigna el nombre correcto al valor de salida de la funcion } + end; { ObtenerNombreArchivo } + + {########################################################} + + function trans(c: char; e: Estado): Estado; + { establece el estado en el que se encuentra la lectura } + { c es el caracter que se leyo, e es el estado actual de la lectura } + + begin { trans } + case e of { acciona segun es estado actual de la lectura } + INICIO: { estado de inicio de la lectura } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un numero (o negativo), empieza a leer el coeficiente } + SPACE, TAB, CR, LF: trans := COEF_BUSCA; { si es un caracter tipo "espacio", busca el prox. coef. } + else trans := ERROR; { si es otro, da ERROR } + end; + COEF_BUSCA: { estado de busqueda del primer ceoficiente del polinomio } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un numero (o negativo), empieza a leer el coeficiente } + SPACE, TAB, CR, LF: trans := COEF_BUSCA; { si es un caracter tupo "espacio", sigue buscando } + ENDF: trans := FIN; { si es el caracter de fin de archivo, pasa al estado de tarea finalizada } + else trans := ERROR; { si es otro, da ERROR } + end; + COEF: { estado de lectura del coeficiente del termino del polinomio (sin punto decimal) } + case c of { acciona segun el caracter leido } + '0'..'9': trans := COEF; { si es un numero sigue con el mismo estado } + '.': trans := COEF_PUNTO; { si es punto cambia al estado COEF_PUNTO } + SPACE, TAB: trans := COEF_FIN; { si es un espacio o un tabulador, finaliza la lectura del coeficiente } + else trans := ERROR; { si es otra cosa, pasa a estado de error } + end; + COEF_PUNTO: { estado de lectura del coeficiente del termino del polinomio (con punto decimal) } + case c of { acciona segun el caracter leido } + '0'..'9': trans := COEF_PUNTO; { si es un numero sigue con el mismo estado } + SPACE, TAB: trans := COEF_FIN; { si es un espacio o un tabulador, finaliza la lectura del coeficiente } + else trans := ERROR; { si es otra cosa, pasa a estado de error } + end; + COEF_FIN: { estado de fin de la lectura del coeficiente del termino del polinomio } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si el caracter es un numero establece el estado en EXP (exponente) } + SPACE, TAB: trans := EXP_BUSCA; { si es un espacio o tabulador, pasa a buscar el proximo exponente } + else trans := ERROR; { si no es ninguno de los anteriores, el estado pasa a ERROR } + end; + EXP_BUSCA: { estado de busqueda del proximo exponente } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si el caracter es un numero, empieza a leer el exponente } + SPACE, TAB: trans := EXP_BUSCA; { si es un espacio o tabulador, sigue buscando } + else trans := ERROR; { si no es ninguno de los anteriores, el estado pasa a ERROR } + end; + EXP: { estado de lectura del exponente del termino actual del polinomio } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si es un digito, sigue en el mismo estado } + CR: trans := EXP_FIN; { si es un ratorno de carro, finaliza el exponente + (quiere decir que hubo un ) } + ENDF: trans := FIN; { si es el final del archivo, se indica que termino su tarea } + else trans := ERROR; { si es otra cosa, devuelve ERROR } + end; + EXP_FIN: { estado de fin de la lectura del exponente del termino actual del polinomio } + if c = LF then trans := EXP_FIN_BUSCA { debe ser un caracter de nueva linea (para completar el ) } + else trans := ERROR; { si no lo es, devuelve ERROR } + EXP_FIN_BUSCA: { estado de fin de lectura de la nueva linea (luego de finalizar el exponente + ahora decide si termino el polinomio o si sigue leyendo el proximo coeficiente } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un digito (o negativo), pasa a leer en proximo coeficiente } + CR: trans := POLI_FIN; { si es un ratorno de carro o nueva linea, finaliza el polinomio } + else trans := ERROR; { si es otra cosa, devuelve ERROR } + end; + POLI_FIN: { estado de finalizacion del polinomio actual } + if c = LF then trans := COEF_BUSCA { debe ser un caracter de nueva linea (para completar el ), + entonces pasa a buscar el primer coeficiente del nuevo polinomio } + else trans := ERROR; { si no lo es, devuelve ERROR } + FIN: { estado que adquiere cuando se finalizo la tarea } + trans := FIN; { se queda en este estado avisando que termino su tarea } + else { otro estado, no deberia ocurrir, salvo que se le pase a la funcion un estado de ERROR } + trans := ERROR; { si es otro, da ERROR } + end; { case } + end; { trans } + + {########################################################} + + function cargarVectores(var v1, v2: Vector): boolean; + { Funcion que abre el archivo de texto con los datos, lo carga en el vector procesandolo debidamente a medida + que lo lee y, al finalizar, cierra el archivo de texto. + v1 es el primer vector a cargar + v2 es el segundo vector a cargar + devuelve true si la lectura fue hecha con exito, false si hubo un error } + + var + f: Text; { archivo de texto con los datos } + c: char; { caracter que se extrae del archivo de texto } + nombreArchivo: String; { nombre del archivo de datos } + est: Estado; { Indicador del estado actual de la lectura } + seguir: boolean; { indicador para saber si debe seguir con el proceso } + i, { indice del vector del polinomio para ser inicializado } + iExp, { valor temporal para almacenar al exponente } + code, { almacena el resultado de la funcion val (no se usa porque los + datos ya estan validados } + poliN: integer; { numero del polinomio que se esta leyendo } + rCoef: real; { valor temporal para almacenar al coeficiente } + exponente, { string que representa al exponente leido } + coeficiente: String; { string que representa al coeficiente leido } + + begin { cargarVectores } + rCoef := 0.0; { inicializacion de variable } + iExp := 0; { inicializacion de variable } + coeficiente := ''; { inicializacion de variable } + exponente := ''; { inicializacion de variable } + est := INICIO; { empieza con el estado de INICIO } + poliN := 1; { establece que se procesara el primer polinomio } + inicializaVector(v1); { inicializacion del vector 1 (primer polinomio) } + inicializaVector(v2); { inicializacion del vector 2 (segundo polinomio) } + nombreArchivo := ObtenerNombreArchivo; { obtiene el nombre del archivo } + assign(f, nombreArchivo); { asigna la variable al nombre del archivo } + reset(f); { abre el archivo para leerlo desde el principio } + seguir := true; { inicializa seguir e true para comenzar el bucle } + while seguir do begin { continua mientras seguir sea true } + read(f, c); { lee un caracter del archivo de texto } + est := trans(c, est); { establece el nuevo estado de lectura } + case est of { toma una desicion dependiendo del estado en que se encuentre } + INICIO: ; { No hace nada, nunca toma este valor. Solo incica que empezo el proceso } + COEF_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + COEF, COEF_PUNTO: { Si esta leyendo el coeficiente ... } + coeficiente := coeficiente + c; { concatena el caracter a la representacion + de texto del coeficiente } + COEF_FIN: ; { Si termino de leer el coeficiente, no hace nada, la asignacion + se realiza cuando termina de leer el exponente (es necesario + para establecer el indice del vector } + EXP_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + EXP: { Si esta leyendo el exponente ... } + exponente := exponente + c; { concatena el caracter a la representacion + de texto del exponente } + EXP_FIN: { Si termino de leer el exponente, hace las asignaciones correspondientes } + begin { convirtiendo las cadenas de texto en real e integer, segun el caso } + val(coeficiente, rCoef, code); { convierte el coeficiente en real } + val(exponente, iExp, code); { convierte el exponente en integer } + if iExp < TAM { si el exponente es menor que el tama¤o maximo permitido ... } + then if poliN = 1 then v1[iExp] := rCoef { asigna el valor correspondiente } + else v2[iExp] := rCoef { al polinomio correspondiente } + else est := ERROR; { si no es menor, pone el estado en ERROR } + coeficiente := ''; { una vez asignados, vacia los valores del coeficiente y el } + exponente := ''; { exponente para poder realizar las lecturas de los proximos } + end; + EXP_FIN_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + POLI_FIN: { Si termino la lectura de un polinomio ... } + if poliN = 1 then poliN := 2 { si se leyo el 1er polinomio, se indica que se leera el 2do } + else est := FIN; { si no (ya se leyo el segundo), pone el estado en FIN } + FIN: { Si se finalizaron las tareas ... } + begin + cargarVectores := true; { en principio se establece que la lectura se hizo con exito ) } + seguir := false; { poner seguir en false para que se termine el bucle } + { este codigo es similar al de EXP_FIN, se hacen las asignaciones por el caso en que el fin + del archivo esta pegado al fin del ultimo exponente, en cuyo caso no pasa por el estado + de EXP_FIN (y, por ende, no se pueden hacer las asignaciones correspondientes } + val(coeficiente, rCoef, code); { convierte el coeficiente en real } + val(exponente, iExp, code); { convierte el exponente en integer } + if iExp < TAM { si el exponente es menor que el tama¤o maximo permitido ... } + then if poliN = 2 + then v2[iExp] := rCoef { si es el 2do polinomio, asigna el valor correspondiente } + else cargarVectores := false { si es el primero, no se hizo bien la lectura } + else cargarVectores := false; { si no es menor, no se hizo bien la lectura } + end; + ERROR: { Si hubo un error ... } + begin + cargarVectores := false; { Se devuelve false (hubo un ERROR, no se leyeron bien los vectores) } + seguir := false; { seguir se pone en false para que termine el bucle } + end; + end; { case } + end; { while } + close(f); { se cierra el archivo de lectura de datos } + end; { cargarVectores } + + {########################################################} + + procedure suma(v1, v2: Vector; var vr: Vector); + { procedimiento que suma dos polinomios. + v1: vector que contiene el primer polinomio a sumar + v2: vector que contiene el segundo polinomio a sumar + vr: vector donde se almacenara el resultado de la suma } + + var + i: integer; { indice para usar en el ciclo for } + + begin { suma } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el vector (de tama¤o maximo TAM) } + vr[i] := v1[i] + v2[i]; { suma los coeficientes de los terminos con igual exponente } + end; { suma } + + {########################################################} + + procedure resta(v1, v2: Vector; var vr: Vector); + { procedimiento que resta dos polinomios. + v1: vector que contiene el primer polinomio + v2: vector que contiene el polinomio para restarle al primero + vr: vector donde se almacenara el resultado de la resta } + + var + i: integer; { indice para usar en el ciclo for } + + begin { resta } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el vector (de tama¤o maximo TAM) } + vr[i] := v1[i] - v2[i]; { resta los coeficientes de los terminos con igual exponente } + end; { resta } + + {########################################################} + + procedure producto(v1, v2: Vector; var vr: Vector); + { procedimiento que multiplica dos polinomios. + v1: vector que contiene el primer polinomio a multiplicar + v2: vector que contiene el segundo polinomio a multiplicar + vr: vector donde se almacenara el resultado de la multiplicacion } + + var + i, j: integer; { indices para usar en los ciclos for } + + begin { producto } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el 1er vector (de tama¤o maximo TAM) } + for j := 0 to TAM - 1 do { recorre el 2do vector (de tama¤o maximo TAM) } + vr[i+j] := vr[i+j] + (v1[i] * v2[j]); + { multiplica los coeficientes de los terminos y lo almacena en la posicion del exponente } + { igual a la suma de los exponentes de v1 y v2, sumando el valor previo de dicha posicion } + end; { producto } + + {########################################################} + + function division(v1, v2: Vector; var vr, vResto: Vector): boolean; + { procedimiento que divide dos polinomios. + v1: vector que contiene el polinomio denominador + v2: vector que contiene el polinomio divisor + vr: vector donde se almacenara el resultado de la division + vResto: vector donde se almacenara el resto de la division + devuelve true si el segundo polinomio no es 0 y se efectua la division y + devuelve false si segundo polinomio es 0 y no se puede efectuar la division } + + var + i, j: integer; { indices para usar en los ciclos for } + vRTmp, { vector auxuliares para almacenar el termino actual del resultado } + vTmp: Vector; { vector auxuliares para almacenar el polinomio que es la multiplicacion del + termino actual del resultado por el divisor } + + begin { division } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vResto); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vTmp); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vRTmp); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := TAM - 1 downto 0 do { recorre el 1er vector (de tama¤o maximo TAM) de atras para adelante } + if v1[i] <> 0 then break; + { busca empezando por el indice (exponete) mas alto el primer coeficiente no nulo } + { si lo encuentra sale del for dejando al valor de i como el de dicho inidice } + for j := TAM - 1 downto 0 do { recorre el 2do vector (de tama¤o maximo TAM) de atras para adelante } + if v2[j] <> 0 then break; + { busca empezando por el indice (exponete) mas alto el primer coeficiente no nulo } + { si lo encuentra sale del for dejando al valor de j como el de dicho inidice } + if (j = 0) and (v2[j] = 0) { si el no se encontro ningun coeficiente no nulo, entonces } + then { el polinomio 2 es nulo y no se puede efectuar la division } + begin { se devuelve false y se quedan los vectores resultado en 0 } + division := false; { devuelve false } + exit; { sale del procedimiento } + end; + while i >= j do { si el primer exponente es mayor o igual que el segundo empieza a dividir } + begin + vr[i-j] := v1[i] / v2[j]; { almacena el resultado de la division entre los coeficientes en + la posicion de la resta de ambos } + vRTmp[i-j] := vr[i-j]; { almacena ese resultado en un polinomio temporal cuyo unico termio + no nulo es el del exponente i-j, para luego multiplicarlo } + producto(vRTmp, v2, vTmp);{ multiplica este polinomio por el segundo almacenado el resultado + en otro temporal, para luego hacer la resta } + resta(v1, vTmp, v1); { resta al primer polinomio, v1, (en su estado actual, no el original) + el temporal vTmp y lo almacena en v1, para poder volver a operarlo de + la misma forma } + vRTmp[i-j] := 0; { resetea el termino del temporal vRTmp que se asigno para los calculos } + for i := i downto 0 do { recorre el vector v1 (de tama¤o maximo TAM) de atras para adelante } + if v1[i] <> 0 then break; + { busca empezando por el indice (exponete) i el primer coeficiente no nulo + si lo encuentra sale del for dejando al valor de i como el de dicho inidice } + end; { while } + vResto := v1; { asigna el vector v1 (que ya no se procesara mas al resto } + division := true; { devuelve true indicando que se finalizo con exito } + end; { division } + + {########################################################} + + procedure mensajeSalida; { muestra un mensaje en la salida del programa } + + begin + end; + + + {########################################################} + + +var + i: integer; { variable auxiliar } + v1, v2, vResult, vResto: Vector; { vectores para hacer las operaciones } + seguir, { indicador para saber si sigue corriendo el programa } + noNulo, { indicador para saber si en la division el divisor es nulo } + continua: boolean; { indicador para saber si se leyeron bien los polinomios } + tecla: char; { entrada de teclado del usuario para elegir una opcion } + +begin { programa principal } + textbackground( Blue ); { establece el color para el fondo a azul } + continua := cargarVectores(v1, v2); { carga los vectores del archivo de datos } + if continua then { si se leyeron bien ... } + begin + seguir := true; { inicializa la variable en true para que entre en el ciclo while } + while seguir do { mientras el usuario no salga del programa } + begin + clrscr; { borra la pantalla } + textcolor(Yellow); { establece el color para el texto a amarillo } + gotoxy( 25, 3 ); { va a las coordenas de pantalla 19 horizontal, 3 verical } + writeln( 'OPERACIONES ENTRE POLINOMIOS' ); { titulo } + gotoxy( 25, 4 ); { va a las coordenas de pantalla 19 horizontal, 4 verical } + writeln( '~~~~~~~~~~~ ~~~~~ ~~~~~~~~~~' ); { subrayado del titulo } + textcolor(LightCyan); { establece el color para el texto a cian claro } + gotoxy( 1, 7 ); { va a las coordenas de pantalla 1 horizontal, 7 verical } + writeln( ' Elija que desea hacer:' ); { mensaje } + writeln( ' ----- --- ----- ------' ); { mensaje } + textcolor(LightGray); { establece el color para el texto a gris claro } + writeln; { mensaje con las opciones ... } + writeln; + writeln( ' 1.- Ver el polinomio 1.' ); + writeln( ' 2.- Ver el polinomio 2.' ); + writeln( ' 3.- Sumar los polinomios.' ); + writeln( ' 4.- Restar el polinomio 2 al polinomio 1 (poli1 - poli2).' ); + writeln( ' 5.- Restar el polinomio 1 al polinomio 2 (poli2 - poli1).' ); + writeln( ' 6.- Multiplicar los polinomios.' ); + writeln( ' 7.- Polinomio 1 dividido polinomio 2 (poli1 / poli2).' ); + writeln( ' 8.- Polinomio 2 dividido polinomio 1 (poli2 / poli1).' ); + writeln( ' 0.- Salir.' ); + gotoxy(1, 23); { va a las coordenas de pantalla 1 horizontal, 23 verical } + textcolor(White ); { establece el color para el texto a blanco } + write(' Ingrese su opci¢n: '); + textcolor(Yellow); { establece el color para el texto a amarillo } + tecla := readkey; { lee una tecla del usuario indicando la opcion que elijio } + if tecla = '0' then { si la opcion fue salir del programa ... } + begin + mensajeSalida; { presenta un mensaje de salida } + exit; { sale del programa } + end; + while (tecla < '1') or (tecla > '8') do { mientras sea una tecla no admitida } + begin + textcolor(White); { establece el color para el texto a blanco } + gotoxy( 1, 23 ); { va a las coordenas de pantalla 1 horizontal, 7 verical } + write(' Ingrese su opci¢n ("1" a "8" o "0"): ' ); + textcolor(Yellow); { establece el color para el texto a amarillo } + tecla := readkey; { lee una tecla del usuario indicando la opcion que elijio } + end; { while } + clrscr; { borra la pantalla } + textcolor(Yellow); { establece el color para el texto a amarillo } + gotoxy(19, 3); { va a las coordenas de pantalla 19 horizontal, 3 verical } + writeln( 'OPERACIONES ENTRE POLINOMIOS'); { titulo } + gotoxy(19, 4); { va a las coordenas de pantalla 19 horizontal, 4 verical } + writeln('~~~~~~~~~~~ ~~~~~ ~~~~~~~~~~'); { subrayado del titulo } + textcolor(LightCyan); { establece el color para el texto a cian claro } + gotoxy(1, 7); { va a las coordenas de pantalla 1 horizontal, 7 verical } + case tecla of + '1': muestraVector(v1, ' Polinomio 1 = '); + '2': muestraVector(v2, ' Polinomio 2 = '); + '3': begin + suma(v1, v2, vResult); + muestraVector(vResult, ' Polinomio 1 + Polinomio 2 = '); + end; { case 3 } + '4': begin + resta(v1, v2, vResult); + muestraVector(vResult, ' Polinomio 1 - Polinomio 2 = '); + end; { case 4 } + '5': begin + resta(v2, v1, vResult); + muestraVector(vResult, ' Polinomio 2 - Polinomio 1 = '); + end; { case 5 } + '6': begin + producto(v1, v2, vResult); + muestraVector(vResult, ' Polinomio 1 * Polinomio 2 = '); + end; { case 6 } + '7': begin + noNulo := division(v1, v2, vResult, vResto); + if noNulo + then + begin + muestraVector(vResult, ' Polinomio 1 / Polinomio 2 = '); + muestraVector(vResto, ' Resto = '); + end + else writeln('El polinomio 2 es nulo, por lo tanto no se puede efectuar la division'); + end; { case 7 } + '8': begin + noNulo := division(v2, v1, vResult, vResto); + if noNulo + then + begin + muestraVector(vResult, 'Polinomio 2 / Polinomio 1 = '); + muestraVector(vResto, 'Resto = '); + end + else writeln('El polinomio 1 es nulo, por lo tanto no se puede efectuar la division'); + end; { case 8 } + '0': ; { no hace nada, nunca deberia entrar en este case } + end; { case } + writeln; { los siguientes mensajes son para que el usuario pueda ver los datos y luego } + writeln; { presione una tecla para continuar } + textcolor(white); { pone el color del texto en blanco } + writeln(' Presione una tecla para continuar ...'); + tecla := readkey; + end; { while } + end + else { si los vectores no se leyeron bien ... } + begin { presenta un mensaje de error } + writeln('ERROR: No se pudieron cargar los datos. Revise que el formato del archivo'); + writeln(' sea correcto y que no este siendo usado por otro programa.'); + end; +end. { procedure menuGenerar } \ No newline at end of file diff --git a/poli_13.pas b/poli_13.pas new file mode 100644 index 0000000..7386f0c --- /dev/null +++ b/poli_13.pas @@ -0,0 +1,633 @@ +program PolinomiosEnVector; +{ Programa que lee 2 polinomios desde un archivo de texto para luego + hacer operaciones basicas entre estos (suma, resta, multiplicacion + y division). + El formato del archivo de texto debe ser de la siguiente manera: + + * Se ingresan cada polinomio en lineas sucesivas. + * El primer polinomio puede comenzar a ingresarse en cualquier lugar + del archivo de texto. + * El fin del primer polinomio (y comienzo del segundo) se indica por + medio de 1 o mas lineas en blanco. + * El segundo polinomio puede comenzar a ingresarse en cualquier lugar + del archivo de texto a partir de dicha(s) linea(s) en blanco. + * Cada termino de un polinomio debe estar en la misma linea y comenzar + al principio de esta (excepto el primer termino). + * En cada linea se ingresa primero el coeficiente real (puede tener un + signo '-' al comenzar y/o un punto, y solamente uno) y luego el + exponente entero positivo. + * La separacion entre el coeficiente y el exponente debe estar dada por + uno o mas espacios o tabuladores. + * Cualquier caracter incluido en el texto que no sea un digito (0..9), + un punto ('.'), un signo menos ('-'), un espacio (' '), un tabulador + o alguno de los caracteres de nueva linea, dara un error en la + lectura. + * El archivo de texto debe tener formato DOS (es decir, el indicador de + nueva linea debe ser primero un caracter de retorno del carro + seguido inmediatamente por uno de avance de linea). +} + +uses + CRT, DOS; { Declaracion de funciones predefinidas + para crear la interfaz grafica } + +const + VERSION = '1.2.3r (POLI_13)'; { version del programa } + + TAM_MAX = 100; { Tama¤o maximo del vector que almacena + la multiplicacion de polinomios } + TAM = TAM_MAX div 2; { Tama¤o maximo (virtual) del vector que contiene + los vector con los que se va a operar } + CR = chr(13); { caracter de retorno del carro } + LF = chr(10); { caracter de nueva linea } + ENDF = chr(26); { caracter de fin del archivo } + TAB = chr(9); { caracter de tabulacion } + SPACE = chr(32); { caracter de espacio } + +type + { Tipo de dato para identificar el estado de la entrada de datos } + Estado = (INICIO, COEF_BUSCA, COEF, COEF_PUNTO, COEF_FIN, EXP_BUSCA, EXP, EXP_FIN, EXP_FIN_BUSCA, POLI_FIN, FIN, ERROR); + Vector = array [0..TAM_MAX-1] of real; { vector para almacenar los polinomios } + + + {########################################################} + + procedure muestraVector(var v: Vector; s: String); + { procedimiento que imprime el polinomio 'v' en pantalla con un titulo 's' } + + {########################################################} + + function exponente(exp: integer): String; + + var + s: String; { variable temporal } + + begin { exponente } + case exp of + 0: exponente := ''; { si el exponente es nulo, mustra solo el coeficiente } + 1: exponente := 'X'; { si el exponente es 1, mustra el coeficiente y X } + 2: exponente := 'Xý'; { si el exponente es 2, mustra el coeficiente y Xý } + else begin + str(exp, s); { convierte al exponente en string } + exponente := 'X^' + s; { si el exponente es mayor que 1, mustra el coeficiente y X^exp } + end; { else } + end; { case } + end; { exponente } + + {########################################################} + + + var + i: integer; { indice para usar en el ciclo for } + + begin { muestraVector } + textcolor(lightcyan); { pone el color del texto en cian claro } + writeln; { separacion de una linea } + write(s); { mustra el mensaje } + textcolor(lightmagenta); { pone el color del texto en magenta claro } + for i := TAM_MAX - 1 downto 0 do { recorre el vector de atras para adelante } + if v[i] <> 0 then break; { si el coeficiente no es nulo, termina el for dejando a i en ese indice } + if (i = 0) and (v[i] = 0) then { si el primer exponente que encuentra es 0 y el coeficiente es 0, entonces } + begin { muestra el resultado como 0 y sale del procedimiento } + write('0'); { imprime que el resultado es cero } + writeln; { separacion de una linea } + writeln; { separacion de una linea } + exit; { sale de este procedimiento } + end; + if (abs(v[i]) <> 1) or (i = 0) { si el modulo del coeficiente es distinto de 1 o si el exp. es 0 } + then if abs(v[i]) - trunc(abs(v[i])) = 0 then write(trunc(v[i]):1, ' ') { imprime si es un numero entero } + else write(v[i]:1:2, ' ') { imprime si es un numero real } + else if v[i] = -1 then write('-'); { si es -1 entonces solo escribe el signo del termino } + write(exponente(i)); + for i := i - 1 downto 0 do { recorre el vector de atras para adelante } + if v[i] <> 0 then { si el coeficiente no es nulo, termina el for dejando a i en ese indice } + begin + if v[i] < 0 { si el coeficiente en negativo } + then write(' - ') { le agrega el signo - } + else write(' + '); { si no, le agrega el signo + } + if (abs(v[i]) <> 1) or (i = 0) then { si el modulo del coeficiente es distinto de 1 o si el exp. es 0 } + if abs(v[i]) - trunc(abs(v[i])) = 0 then write(trunc(abs(v[i])):1, ' ') { imprime si es un entero } + else write(abs(v[i]):1:2, ' '); { imprime si es un real } + write(exponente(i)); + end; { if } + writeln; { separacion de una linea } + writeln; { separacion de una linea } + end; { muestraVector } + + {########################################################} + + procedure inicializaVector(var v: Vector); + { procedimiento que inicializa un vector de tama¤o tam } + + var i: integer; { indice para usar en el ciclo for } + + begin { inicializaVector } + for i := 0 to TAM_MAX - 1 do { recorre el vector } + v[i] := 0; { inicializa la variable actual en 0 } + end; { inicializaVector } + + {########################################################} + + function ObtenerNombreArchivo: String; + { funcion que obtiene un nombre de archivo valido (es decir, el nombre + de un archivo que exista) } + + {########################################################} + + function fileExists(FileName: String): Boolean; + { funcion extraida de la ayuda del Turbo Pascal 7 + indica si el archivo existe } + + var + F: file; + + begin + {$I-} + Assign(F, FileName); + FileMode := 0; { Set file access to read only } + Reset(F); + Close(F); + {$I+} + FileExists := (IOResult = 0) and (FileName <> ''); + end; { FileExists } + + {########################################################} + + { Continuacion de la funcion ObtenerNombreArchivo } + const + DEFAUL_FILE_NAME = 'datos.txt'; { nombre del archivo por defecto } + + var + tmp: String; { cadena para almacenar el resultado temporal } + + begin { ObtenerNombreArchivo } + { mensaje para entrada del nombre de archivo } + clrscr; { borra la pantalla } + textcolor( Yellow ); { establece el color para el texto a amarillo } + gotoxy( 25, 3 ); { va a las coordenas de pantalla 25 horizontal, 3 verical } + writeln( 'OPERACIONES ENTRE POLINOMIOS' ); { titulo } + gotoxy( 25, 4 ); { va a las coordenas de pantalla 25 horizontal, 4 verical } + writeln( '~~~~~~~~~~~ ~~~~~ ~~~~~~~~~~' ); { subrayado del titulo } + textcolor( LightCyan ); { establece el color para el texto a cian claro } + gotoxy( 1, 7 ); { va a las coordenas de pantalla 1 horizontal, 7 verical } + writeln(' Ingrese el nombre del archivo con los datos (ENTER = ', DEFAUL_FILE_NAME, '):'); + readln(tmp); { entrada del nombre de archivo } + if tmp = '' then tmp := DEFAUL_FILE_NAME; { se fija si no se ingreso nada y reasigana el nombre } + while not fileExists(tmp) do { repite el proceso hasta que el archivo exista } + begin + clrscr; { borra la pantalla } + textcolor( Yellow ); { establece el color para el texto a amarillo } + gotoxy( 25, 3 ); { va a las coordenas de pantalla 19 horizontal, 3 verical } + writeln( 'OPERACIONES ENTRE POLINOMIOS' ); { titulo } + gotoxy( 25, 4 ); { va a las coordenas de pantalla 19 horizontal, 4 verical } + writeln( '~~~~~~~~~~~ ~~~~~ ~~~~~~~~~~' ); { subrayado del titulo } + textcolor( LightCyan ); { establece el color para el texto a cian claro } + gotoxy( 1, 7 ); { va a las coordenas de pantalla 1 horizontal, 7 verical } + write(' El archivo ', tmp, ' no existe. Ingrese un nombre correcto'); + if tmp = DEFAUL_FILE_NAME { si es el nombre de archivo predeterminado } + then { entonces, elije un mensaje apropiado } + write(': ') + else + begin { si no es el predeterminado, muestra otro mensaje } + writeln('.'); + write(' (ENTER = ', DEFAUL_FILE_NAME, '): '); + end; + readln(tmp); { vuelve a leer el nombre del archivo para ser verificado } + if tmp = '' then tmp := DEFAUL_FILE_NAME; { asigna como nombre de archivo al predeterminado + si no se escribio nada } + end; { fin del loop de verificacion } + ObtenerNombreArchivo := tmp; { asigna el nombre correcto al valor de salida de la funcion } + end; { ObtenerNombreArchivo } + + {########################################################} + + function trans(c: char; e: Estado): Estado; + { establece el estado en el que se encuentra la lectura } + { c es el caracter que se leyo, e es el estado actual de la lectura } + + begin { trans } + case e of { acciona segun es estado actual de la lectura } + INICIO: { estado de inicio de la lectura } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un numero (o negativo), empieza a leer el coeficiente } + SPACE, TAB, CR, LF: trans := COEF_BUSCA; { si es un caracter tipo "espacio", busca el prox. coef. } + else trans := ERROR; { si es otro, da ERROR } + end; + COEF_BUSCA: { estado de busqueda del primer ceoficiente del polinomio } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un numero (o negativo), empieza a leer el coeficiente } + SPACE, TAB, CR, LF: trans := COEF_BUSCA; { si es un caracter tupo "espacio", sigue buscando } + ENDF: trans := FIN; { si es el caracter de fin de archivo, pasa al estado de tarea finalizada } + else trans := ERROR; { si es otro, da ERROR } + end; + COEF: { estado de lectura del coeficiente del termino del polinomio (sin punto decimal) } + case c of { acciona segun el caracter leido } + '0'..'9': trans := COEF; { si es un numero sigue con el mismo estado } + '.': trans := COEF_PUNTO; { si es punto cambia al estado COEF_PUNTO } + SPACE, TAB: trans := COEF_FIN; { si es un espacio o un tabulador, finaliza la lectura del coeficiente } + else trans := ERROR; { si es otra cosa, pasa a estado de error } + end; + COEF_PUNTO: { estado de lectura del coeficiente del termino del polinomio (con punto decimal) } + case c of { acciona segun el caracter leido } + '0'..'9': trans := COEF_PUNTO; { si es un numero sigue con el mismo estado } + SPACE, TAB: trans := COEF_FIN; { si es un espacio o un tabulador, finaliza la lectura del coeficiente } + else trans := ERROR; { si es otra cosa, pasa a estado de error } + end; + COEF_FIN: { estado de fin de la lectura del coeficiente del termino del polinomio } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si el caracter es un numero establece el estado en EXP (exponente) } + SPACE, TAB: trans := EXP_BUSCA; { si es un espacio o tabulador, pasa a buscar el proximo exponente } + else trans := ERROR; { si no es ninguno de los anteriores, el estado pasa a ERROR } + end; + EXP_BUSCA: { estado de busqueda del proximo exponente } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si el caracter es un numero, empieza a leer el exponente } + SPACE, TAB: trans := EXP_BUSCA; { si es un espacio o tabulador, sigue buscando } + else trans := ERROR; { si no es ninguno de los anteriores, el estado pasa a ERROR } + end; + EXP: { estado de lectura del exponente del termino actual del polinomio } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si es un digito, sigue en el mismo estado } + CR: trans := EXP_FIN; { si es un ratorno de carro, finaliza el exponente + (quiere decir que hubo un ) } + ENDF: trans := FIN; { si es el final del archivo, se indica que termino su tarea } + else trans := ERROR; { si es otra cosa, devuelve ERROR } + end; + EXP_FIN: { estado de fin de la lectura del exponente del termino actual del polinomio } + if c = LF then trans := EXP_FIN_BUSCA { debe ser un caracter de nueva linea (para completar el ) } + else trans := ERROR; { si no lo es, devuelve ERROR } + EXP_FIN_BUSCA: { estado de fin de lectura de la nueva linea (luego de finalizar el exponente + ahora decide si termino el polinomio o si sigue leyendo el proximo coeficiente } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un digito (o negativo), pasa a leer en proximo coeficiente } + CR: trans := POLI_FIN; { si es un ratorno de carro o nueva linea, finaliza el polinomio } + else trans := ERROR; { si es otra cosa, devuelve ERROR } + end; + POLI_FIN: { estado de finalizacion del polinomio actual } + if c = LF then trans := COEF_BUSCA { debe ser un caracter de nueva linea (para completar el ), + entonces pasa a buscar el primer coeficiente del nuevo polinomio } + else trans := ERROR; { si no lo es, devuelve ERROR } + FIN: { estado que adquiere cuando se finalizo la tarea } + trans := FIN; { se queda en este estado avisando que termino su tarea } + else { otro estado, no deberia ocurrir, salvo que se le pase a la funcion un estado de ERROR } + trans := ERROR; { si es otro, da ERROR } + end; { case } + end; { trans } + + {########################################################} + + function cargarVectores(var v1, v2: Vector): boolean; + { Funcion que abre el archivo de texto con los datos, lo carga en el vector procesandolo debidamente a medida + que lo lee y, al finalizar, cierra el archivo de texto. + v1 es el primer vector a cargar + v2 es el segundo vector a cargar + devuelve true si la lectura fue hecha con exito, false si hubo un error } + + var + f: Text; { archivo de texto con los datos } + c: char; { caracter que se extrae del archivo de texto } + nombreArchivo: String; { nombre del archivo de datos } + est: Estado; { Indicador del estado actual de la lectura } + seguir: boolean; { indicador para saber si debe seguir con el proceso } + i, { indice del vector del polinomio para ser inicializado } + iExp, { valor temporal para almacenar al exponente } + code, { almacena el resultado de la funcion val (no se usa porque los + datos ya estan validados } + poliN: integer; { numero del polinomio que se esta leyendo } + rCoef: real; { valor temporal para almacenar al coeficiente } + exponente, { string que representa al exponente leido } + coeficiente: String; { string que representa al coeficiente leido } + + begin { cargarVectores } + rCoef := 0.0; { inicializacion de variable } + iExp := 0; { inicializacion de variable } + coeficiente := ''; { inicializacion de variable } + exponente := ''; { inicializacion de variable } + est := INICIO; { empieza con el estado de INICIO } + poliN := 1; { establece que se procesara el primer polinomio } + inicializaVector(v1); { inicializacion del vector 1 (primer polinomio) } + inicializaVector(v2); { inicializacion del vector 2 (segundo polinomio) } + nombreArchivo := ObtenerNombreArchivo; { obtiene el nombre del archivo } + assign(f, nombreArchivo); { asigna la variable al nombre del archivo } + reset(f); { abre el archivo para leerlo desde el principio } + seguir := true; { inicializa seguir e true para comenzar el bucle } + while seguir do begin { continua mientras seguir sea true } + read(f, c); { lee un caracter del archivo de texto } + est := trans(c, est); { establece el nuevo estado de lectura } + case est of { toma una desicion dependiendo del estado en que se encuentre } + INICIO: ; { No hace nada, nunca toma este valor. Solo incica que empezo el proceso } + COEF_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + COEF, COEF_PUNTO: { Si esta leyendo el coeficiente ... } + coeficiente := coeficiente + c; { concatena el caracter a la representacion + de texto del coeficiente } + COEF_FIN: ; { Si termino de leer el coeficiente, no hace nada, la asignacion + se realiza cuando termina de leer el exponente (es necesario + para establecer el indice del vector } + EXP_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + EXP: { Si esta leyendo el exponente ... } + exponente := exponente + c; { concatena el caracter a la representacion + de texto del exponente } + EXP_FIN: { Si termino de leer el exponente, hace las asignaciones correspondientes } + begin { convirtiendo las cadenas de texto en real e integer, segun el caso } + val(coeficiente, rCoef, code); { convierte el coeficiente en real } + val(exponente, iExp, code); { convierte el exponente en integer } + if iExp < TAM { si el exponente es menor que el tama¤o maximo permitido ... } + then if poliN = 1 then v1[iExp] := rCoef { asigna el valor correspondiente } + else v2[iExp] := rCoef { al polinomio correspondiente } + else est := ERROR; { si no es menor, pone el estado en ERROR } + coeficiente := ''; { una vez asignados, vacia los valores del coeficiente y el } + exponente := ''; { exponente para poder realizar las lecturas de los proximos } + end; + EXP_FIN_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + POLI_FIN: { Si termino la lectura de un polinomio ... } + if poliN = 1 then poliN := 2 { si se leyo el 1er polinomio, se indica que se leera el 2do } + else est := FIN; { si no (ya se leyo el segundo), pone el estado en FIN } + FIN: { Si se finalizaron las tareas ... } + begin + cargarVectores := true; { en principio se establece que la lectura se hizo con exito ) } + seguir := false; { poner seguir en false para que se termine el bucle } + { este codigo es similar al de EXP_FIN, se hacen las asignaciones por el caso en que el fin + del archivo esta pegado al fin del ultimo exponente, en cuyo caso no pasa por el estado + de EXP_FIN (y, por ende, no se pueden hacer las asignaciones correspondientes } + val(coeficiente, rCoef, code); { convierte el coeficiente en real } + val(exponente, iExp, code); { convierte el exponente en integer } + if iExp < TAM { si el exponente es menor que el tama¤o maximo permitido ... } + then if poliN = 2 + then v2[iExp] := rCoef { si es el 2do polinomio, asigna el valor correspondiente } + else cargarVectores := false { si es el primero, no se hizo bien la lectura } + else cargarVectores := false; { si no es menor, no se hizo bien la lectura } + end; + ERROR: { Si hubo un error ... } + begin + cargarVectores := false; { Se devuelve false (hubo un ERROR, no se leyeron bien los vectores) } + seguir := false; { seguir se pone en false para que termine el bucle } + end; + end; { case } + end; { while } + close(f); { se cierra el archivo de lectura de datos } + end; { cargarVectores } + + {########################################################} + + procedure suma(v1, v2: Vector; var vr: Vector); + { procedimiento que suma dos polinomios. + v1: vector que contiene el primer polinomio a sumar + v2: vector que contiene el segundo polinomio a sumar + vr: vector donde se almacenara el resultado de la suma } + + var + i: integer; { indice para usar en el ciclo for } + + begin { suma } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el vector (de tama¤o maximo TAM) } + vr[i] := v1[i] + v2[i]; { suma los coeficientes de los terminos con igual exponente } + end; { suma } + + {########################################################} + + procedure resta(v1, v2: Vector; var vr: Vector); + { procedimiento que resta dos polinomios. + v1: vector que contiene el primer polinomio + v2: vector que contiene el polinomio para restarle al primero + vr: vector donde se almacenara el resultado de la resta } + + var + i: integer; { indice para usar en el ciclo for } + + begin { resta } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el vector (de tama¤o maximo TAM) } + vr[i] := v1[i] - v2[i]; { resta los coeficientes de los terminos con igual exponente } + end; { resta } + + {########################################################} + + procedure producto(v1, v2: Vector; var vr: Vector); + { procedimiento que multiplica dos polinomios. + v1: vector que contiene el primer polinomio a multiplicar + v2: vector que contiene el segundo polinomio a multiplicar + vr: vector donde se almacenara el resultado de la multiplicacion } + + var + i, j: integer; { indices para usar en los ciclos for } + + begin { producto } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el 1er vector (de tama¤o maximo TAM) } + for j := 0 to TAM - 1 do { recorre el 2do vector (de tama¤o maximo TAM) } + vr[i+j] := vr[i+j] + (v1[i] * v2[j]); + { multiplica los coeficientes de los terminos y lo almacena en la posicion del exponente } + { igual a la suma de los exponentes de v1 y v2, sumando el valor previo de dicha posicion } + end; { producto } + + {########################################################} + + function division(v1, v2: Vector; var vr, vResto: Vector): boolean; + { procedimiento que divide dos polinomios. + v1: vector que contiene el polinomio denominador + v2: vector que contiene el polinomio divisor + vr: vector donde se almacenara el resultado de la division + vResto: vector donde se almacenara el resto de la division + devuelve true si el segundo polinomio no es 0 y se efectua la division y + devuelve false si segundo polinomio es 0 y no se puede efectuar la division } + + var + i, j: integer; { indices para usar en los ciclos for } + vRTmp, { vector auxuliares para almacenar el termino actual del resultado } + vTmp: Vector; { vector auxuliares para almacenar el polinomio que es la multiplicacion del + termino actual del resultado por el divisor } + + begin { division } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vResto); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vTmp); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vRTmp); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := TAM - 1 downto 0 do { recorre el 1er vector (de tama¤o maximo TAM) de atras para adelante } + if v1[i] <> 0 then break; + { busca empezando por el indice (exponete) mas alto el primer coeficiente no nulo } + { si lo encuentra sale del for dejando al valor de i como el de dicho inidice } + for j := TAM - 1 downto 0 do { recorre el 2do vector (de tama¤o maximo TAM) de atras para adelante } + if v2[j] <> 0 then break; + { busca empezando por el indice (exponete) mas alto el primer coeficiente no nulo } + { si lo encuentra sale del for dejando al valor de j como el de dicho inidice } + if (j = 0) and (v2[j] = 0) { si el no se encontro ningun coeficiente no nulo, entonces } + then { el polinomio 2 es nulo y no se puede efectuar la division } + begin { se devuelve false y se quedan los vectores resultado en 0 } + division := false; { devuelve false } + exit; { sale del procedimiento } + end; + while i >= j do { si el primer exponente es mayor o igual que el segundo empieza a dividir } + begin + vr[i-j] := v1[i] / v2[j]; { almacena el resultado de la division entre los coeficientes en + la posicion de la resta de ambos } + vRTmp[i-j] := vr[i-j]; { almacena ese resultado en un polinomio temporal cuyo unico termio + no nulo es el del exponente i-j, para luego multiplicarlo } + producto(vRTmp, v2, vTmp);{ multiplica este polinomio por el segundo almacenado el resultado + en otro temporal, para luego hacer la resta } + resta(v1, vTmp, v1); { resta al primer polinomio, v1, (en su estado actual, no el original) + el temporal vTmp y lo almacena en v1, para poder volver a operarlo de + la misma forma } + vRTmp[i-j] := 0; { resetea el termino del temporal vRTmp que se asigno para los calculos } + for i := i downto 0 do { recorre el vector v1 (de tama¤o maximo TAM) de atras para adelante } + if v1[i] <> 0 then break; + { busca empezando por el indice (exponete) i el primer coeficiente no nulo + si lo encuentra sale del for dejando al valor de i como el de dicho inidice } + end; { while } + vResto := v1; { asigna el vector v1 (que ya no se procesara mas al resto } + division := true; { devuelve true indicando que se finalizo con exito } + end; { division } + + {########################################################} + + procedure mensajeSalida; { muestra un mensaje en la salida del programa } + + begin + writeln; { linea en blanco } + NormVideo; { reestablece los colores a los valores por defecto } + clrscr; { borra la pantalla } + writeln; { linea en blanco } + textcolor(white); { cambia el color del texto } + writeln(' OPERACIONES ENTRE POLINOMIOS versi¢n ', VERSION); { mensaje con version del programa } + NormVideo; { reestablece los colores a los valores por defecto } + writeln(' Desarrollado por: JavierGrijalba'); { mensaje con los integrantes del grupo } + writeln(' Leandro Lucarella'); + writeln(' Erasmo Troncovich'); + writeln(' Diego Wojmicki'); + writeln(' para la Facultad de Ingenier¡a de la Universidad de Buenos Aires.'); + writeln(' Consultas y/o sugerencias a:'); + writeln; + textcolor(LightMagenta); { cambia el color del texto } + write(' lluca@cnba.uba.ar'); + NormVideo; { reestablece los colores a los valores por defecto } + write(' o '); + textcolor(LightMagenta); { cambia el color del texto } + writeln('grijalba@cvtci.com.ar'); + NormVideo; { reestablece los colores a los valores por defecto } + writeln; + writeln(' (c) 1999 - Todos los derechos reservados.'); + delay(750); + end; + + + {########################################################} + + +var + i: integer; { variable auxiliar } + v1, v2, vResult, vResto: Vector; { vectores para hacer las operaciones } + seguir, { indicador para saber si sigue corriendo el programa } + noNulo, { indicador para saber si en la division el divisor es nulo } + continua: boolean; { indicador para saber si se leyeron bien los polinomios } + tecla: char; { entrada de teclado del usuario para elegir una opcion } + +begin { programa principal } + textbackground( Blue ); { establece el color para el fondo a azul } + continua := cargarVectores(v1, v2); { carga los vectores del archivo de datos } + if continua then { si se leyeron bien ... } + begin + seguir := true; { inicializa la variable en true para que entre en el ciclo while } + while seguir do { mientras el usuario no salga del programa } + begin + clrscr; { borra la pantalla } + textcolor(Yellow); { establece el color para el texto a amarillo } + gotoxy( 25, 3 ); { va a las coordenas de pantalla 19 horizontal, 3 verical } + writeln( 'OPERACIONES ENTRE POLINOMIOS' ); { titulo } + gotoxy( 25, 4 ); { va a las coordenas de pantalla 19 horizontal, 4 verical } + writeln( '~~~~~~~~~~~ ~~~~~ ~~~~~~~~~~' ); { subrayado del titulo } + textcolor(LightCyan); { establece el color para el texto a cian claro } + gotoxy( 1, 7 ); { va a las coordenas de pantalla 1 horizontal, 7 verical } + writeln( ' Elija que desea hacer:' ); { mensaje } + writeln( ' ----- --- ----- ------' ); { mensaje } + textcolor(LightGray); { establece el color para el texto a gris claro } + writeln; { mensaje con las opciones ... } + writeln; + writeln( ' 1.- Ver el polinomio 1.' ); + writeln( ' 2.- Ver el polinomio 2.' ); + writeln( ' 3.- Sumar los polinomios.' ); + writeln( ' 4.- Restar el polinomio 2 al polinomio 1 (poli1 - poli2).' ); + writeln( ' 5.- Restar el polinomio 1 al polinomio 2 (poli2 - poli1).' ); + writeln( ' 6.- Multiplicar los polinomios.' ); + writeln( ' 7.- Polinomio 1 dividido polinomio 2 (poli1 / poli2).' ); + writeln( ' 8.- Polinomio 2 dividido polinomio 1 (poli2 / poli1).' ); + writeln( ' 0.- Salir.' ); + gotoxy(1, 23); { va a las coordenas de pantalla 1 horizontal, 23 verical } + textcolor(White ); { establece el color para el texto a blanco } + write(' Ingrese su opci¢n: '); + textcolor(Yellow); { establece el color para el texto a amarillo } + tecla := readkey; { lee una tecla del usuario indicando la opcion que elijio } + while ((tecla < '1') or (tecla > '8')) and (tecla <> '0') do { mientras sea una tecla no admitida } + begin + textcolor(White); { establece el color para el texto a blanco } + gotoxy( 1, 23 ); { va a las coordenas de pantalla 1 horizontal, 7 verical } + write(' Ingrese su opci¢n ("1" a "8" o "0"): ' ); + textcolor(Yellow); { establece el color para el texto a amarillo } + tecla := readkey; { lee una tecla del usuario indicando la opcion que elijio } + end; { while } + if tecla = '0' then { si la opcion fue salir del programa ... } + begin + mensajeSalida; { presenta un mensaje de salida } + exit; { sale del programa } + end; + clrscr; { borra la pantalla } + textcolor(Yellow); { establece el color para el texto a amarillo } + gotoxy(19, 3); { va a las coordenas de pantalla 19 horizontal, 3 verical } + writeln( 'OPERACIONES ENTRE POLINOMIOS'); { titulo } + gotoxy(19, 4); { va a las coordenas de pantalla 19 horizontal, 4 verical } + writeln('~~~~~~~~~~~ ~~~~~ ~~~~~~~~~~'); { subrayado del titulo } + textcolor(LightCyan); { establece el color para el texto a cian claro } + gotoxy(1, 7); { va a las coordenas de pantalla 1 horizontal, 7 verical } + case tecla of + '1': muestraVector(v1, ' Polinomio 1 = '); + '2': muestraVector(v2, ' Polinomio 2 = '); + '3': begin + suma(v1, v2, vResult); + muestraVector(vResult, ' Polinomio 1 + Polinomio 2 = '); + end; { case 3 } + '4': begin + resta(v1, v2, vResult); + muestraVector(vResult, ' Polinomio 1 - Polinomio 2 = '); + end; { case 4 } + '5': begin + resta(v2, v1, vResult); + muestraVector(vResult, ' Polinomio 2 - Polinomio 1 = '); + end; { case 5 } + '6': begin + producto(v1, v2, vResult); + muestraVector(vResult, ' Polinomio 1 * Polinomio 2 = '); + end; { case 6 } + '7': begin + noNulo := division(v1, v2, vResult, vResto); + if noNulo + then + begin + muestraVector(vResult, ' Polinomio 1 / Polinomio 2 = '); + muestraVector(vResto, ' Resto = '); + end + else writeln(' El polinomio 2 es nulo, por lo tanto no se puede efectuar la division.'); + end; { case 7 } + '8': begin + noNulo := division(v2, v1, vResult, vResto); + if noNulo + then + begin + muestraVector(vResult, 'Polinomio 2 / Polinomio 1 = '); + muestraVector(vResto, 'Resto = '); + end + else writeln(' El polinomio 1 es nulo, por lo tanto no se puede efectuar la division.'); + end; { case 8 } + '0': ; { no hace nada, nunca deberia entrar en este case } + end; { case } + writeln; { los siguientes mensajes son para que el usuario pueda ver los datos y luego } + writeln; { presione una tecla para continuar } + textcolor(white); { pone el color del texto en blanco } + writeln(' Presione una tecla para continuar ...'); + tecla := readkey; + end; { while } + end + else { si los vectores no se leyeron bien ... } + begin { presenta un mensaje de error } + writeln('ERROR: No se pudieron cargar los datos. Revise que el formato del archivo'); + writeln(' sea correcto y que no este siendo usado por otro programa.'); + end; +end. { procedure menuGenerar } \ No newline at end of file diff --git a/poli_14.pas b/poli_14.pas new file mode 100644 index 0000000..8f470b7 --- /dev/null +++ b/poli_14.pas @@ -0,0 +1,633 @@ +program PolinomiosEnVector; +{ Programa que lee 2 polinomios desde un archivo de texto para luego + hacer operaciones basicas entre estos (suma, resta, multiplicacion + y division). + El formato del archivo de texto debe ser de la siguiente manera: + + * Se ingresan cada polinomio en lineas sucesivas. + * El primer polinomio puede comenzar a ingresarse en cualquier lugar + del archivo de texto. + * El fin del primer polinomio (y comienzo del segundo) se indica por + medio de 1 o mas lineas en blanco. + * El segundo polinomio puede comenzar a ingresarse en cualquier lugar + del archivo de texto a partir de dicha(s) linea(s) en blanco. + * Cada termino de un polinomio debe estar en la misma linea y comenzar + al principio de esta (excepto el primer termino). + * En cada linea se ingresa primero el coeficiente real (puede tener un + signo '-' al comenzar y/o un punto, y solamente uno) y luego el + exponente entero positivo. + * La separacion entre el coeficiente y el exponente debe estar dada por + uno o mas espacios o tabuladores. + * Cualquier caracter incluido en el texto que no sea un digito (0..9), + un punto ('.'), un signo menos ('-'), un espacio (' '), un tabulador + o alguno de los caracteres de nueva linea, dara un error en la + lectura. + * El archivo de texto debe tener formato DOS (es decir, el indicador de + nueva linea debe ser primero un caracter de retorno del carro + seguido inmediatamente por uno de avance de linea). +} + +uses + CRT, DOS; { Declaracion de funciones predefinidas + para crear la interfaz grafica } + +const + VERSION = '1.2.5r (POLI_14)'; { version del programa } + + TAM_MAX = 100; { Tama¤o maximo del vector que almacena + la multiplicacion de polinomios } + TAM = TAM_MAX div 2; { Tama¤o maximo (virtual) del vector que contiene + los vector con los que se va a operar } + CR = chr(13); { caracter de retorno del carro } + LF = chr(10); { caracter de nueva linea } + ENDF = chr(26); { caracter de fin del archivo } + TAB = chr(9); { caracter de tabulacion } + SPACE = chr(32); { caracter de espacio } + +type + { Tipo de dato para identificar el estado de la entrada de datos } + Estado = (INICIO, COEF_BUSCA, COEF, COEF_PUNTO, COEF_FIN, EXP_BUSCA, EXP, EXP_FIN, EXP_FIN_BUSCA, POLI_FIN, FIN, ERROR); + Vector = array [0..TAM_MAX-1] of real; { vector para almacenar los polinomios } + + + {########################################################} + + procedure muestraVector(var v: Vector; s: String); + { procedimiento que imprime el polinomio 'v' en pantalla con un titulo 's' } + + {########################################################} + + function exponente(exp: integer): String; + + var + s: String; { variable temporal } + + begin { exponente } + case exp of + 0: exponente := ''; { si el exponente es nulo, mustra solo el coeficiente } + 1: exponente := 'X'; { si el exponente es 1, mustra el coeficiente y X } + 2: exponente := 'Xý'; { si el exponente es 2, mustra el coeficiente y Xý } + else begin + str(exp, s); { convierte al exponente en string } + exponente := 'X^' + s; { si el exponente es mayor que 1, mustra el coeficiente y X^exp } + end; { else } + end; { case } + end; { exponente } + + {########################################################} + + + var + i: integer; { indice para usar en el ciclo for } + + begin { muestraVector } + textcolor(lightcyan); { pone el color del texto en cian claro } + writeln; { separacion de una linea } + write(s); { mustra el mensaje } + textcolor(lightmagenta); { pone el color del texto en magenta claro } + for i := TAM_MAX - 1 downto 0 do { recorre el vector de atras para adelante } + if v[i] <> 0 then break; { si el coeficiente no es nulo, termina el for dejando a i en ese indice } + if (i = 0) and (v[i] = 0) then { si el primer exponente que encuentra es 0 y el coeficiente es 0, entonces } + begin { muestra el resultado como 0 y sale del procedimiento } + write('0'); { imprime que el resultado es cero } + writeln; { separacion de una linea } + writeln; { separacion de una linea } + exit; { sale de este procedimiento } + end; + if (abs(v[i]) <> 1) or (i = 0) { si el modulo del coeficiente es distinto de 1 o si el exp. es 0 } + then if abs(v[i]) - trunc(abs(v[i])) = 0 then write(trunc(v[i]):1, ' ') { imprime si es un numero entero } + else write(v[i]:1:2, ' ') { imprime si es un numero real } + else if v[i] = -1 then write('-'); { si es -1 entonces solo escribe el signo del termino } + write(exponente(i)); + for i := i - 1 downto 0 do { recorre el vector de atras para adelante } + if v[i] <> 0 then { si el coeficiente no es nulo, termina el for dejando a i en ese indice } + begin + if v[i] < 0 { si el coeficiente en negativo } + then write(' - ') { le agrega el signo - } + else write(' + '); { si no, le agrega el signo + } + if (abs(v[i]) <> 1) or (i = 0) then { si el modulo del coeficiente es distinto de 1 o si el exp. es 0 } + if abs(v[i]) - trunc(abs(v[i])) = 0 then write(trunc(abs(v[i])):1, ' ') { imprime si es un entero } + else write(abs(v[i]):1:2, ' '); { imprime si es un real } + write(exponente(i)); + end; { if } + writeln; { separacion de una linea } + writeln; { separacion de una linea } + end; { muestraVector } + + {########################################################} + + procedure inicializaVector(var v: Vector); + { procedimiento que inicializa un vector de tama¤o tam } + + var i: integer; { indice para usar en el ciclo for } + + begin { inicializaVector } + for i := 0 to TAM_MAX - 1 do { recorre el vector } + v[i] := 0; { inicializa la variable actual en 0 } + end; { inicializaVector } + + {########################################################} + + function ObtenerNombreArchivo: String; + { funcion que obtiene un nombre de archivo valido (es decir, el nombre + de un archivo que exista) } + + {########################################################} + + function fileExists(FileName: String): Boolean; + { funcion extraida de la ayuda del Turbo Pascal 7 + indica si el archivo existe } + + var + F: file; + + begin + {$I-} + Assign(F, FileName); + FileMode := 0; { Set file access to read only } + Reset(F); + Close(F); + {$I+} + FileExists := (IOResult = 0) and (FileName <> ''); + end; { FileExists } + + {########################################################} + + { Continuacion de la funcion ObtenerNombreArchivo } + const + DEFAUL_FILE_NAME = 'datos.txt'; { nombre del archivo por defecto } + + var + tmp: String; { cadena para almacenar el resultado temporal } + + begin { ObtenerNombreArchivo } + { mensaje para entrada del nombre de archivo } + clrscr; { borra la pantalla } + textcolor( Yellow ); { establece el color para el texto a amarillo } + gotoxy( 30, 3 ); { va a las coordenas de pantalla 25 horizontal, 3 verical } + writeln( 'PolinomiosEnVector' ); { titulo } + gotoxy( 30, 4 ); { va a las coordenas de pantalla 25 horizontal, 4 verical } + writeln( '~~~~~~~~~~~~~~~~~~' ); { subrayado del titulo } + textcolor( LightCyan ); { establece el color para el texto a cian claro } + gotoxy( 1, 7 ); { va a las coordenas de pantalla 1 horizontal, 7 verical } + writeln(' Ingrese el nombre del archivo con los datos (ENTER = ', DEFAUL_FILE_NAME, '):'); + readln(tmp); { entrada del nombre de archivo } + if tmp = '' then tmp := DEFAUL_FILE_NAME; { se fija si no se ingreso nada y reasigana el nombre } + while not fileExists(tmp) do { repite el proceso hasta que el archivo exista } + begin + clrscr; { borra la pantalla } + textcolor( Yellow ); { establece el color para el texto a amarillo } + gotoxy( 30, 3 ); { va a las coordenas de pantalla 25 horizontal, 3 verical } + writeln( 'PolinomiosEnVector' ); { titulo } + gotoxy( 30, 4 ); { va a las coordenas de pantalla 25 horizontal, 4 verical } + writeln( '~~~~~~~~~~~~~~~~~~' ); { subrayado del titulo } + textcolor( LightCyan ); { establece el color para el texto a cian claro } + gotoxy( 1, 7 ); { va a las coordenas de pantalla 1 horizontal, 7 verical } + write(' El archivo ', tmp, ' no existe. Ingrese un nombre correcto'); + if tmp = DEFAUL_FILE_NAME { si es el nombre de archivo predeterminado } + then { entonces, elije un mensaje apropiado } + write(': ') + else + begin { si no es el predeterminado, muestra otro mensaje } + writeln('.'); + write(' (ENTER = ', DEFAUL_FILE_NAME, '): '); + end; + readln(tmp); { vuelve a leer el nombre del archivo para ser verificado } + if tmp = '' then tmp := DEFAUL_FILE_NAME; { asigna como nombre de archivo al predeterminado + si no se escribio nada } + end; { fin del loop de verificacion } + ObtenerNombreArchivo := tmp; { asigna el nombre correcto al valor de salida de la funcion } + end; { ObtenerNombreArchivo } + + {########################################################} + + function trans(c: char; e: Estado): Estado; + { establece el estado en el que se encuentra la lectura } + { c es el caracter que se leyo, e es el estado actual de la lectura } + + begin { trans } + case e of { acciona segun es estado actual de la lectura } + INICIO: { estado de inicio de la lectura } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un numero (o negativo), empieza a leer el coeficiente } + SPACE, TAB, CR, LF: trans := COEF_BUSCA; { si es un caracter tipo "espacio", busca el prox. coef. } + else trans := ERROR; { si es otro, da ERROR } + end; + COEF_BUSCA: { estado de busqueda del primer ceoficiente del polinomio } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un numero (o negativo), empieza a leer el coeficiente } + SPACE, TAB, CR, LF: trans := COEF_BUSCA; { si es un caracter tupo "espacio", sigue buscando } + ENDF: trans := FIN; { si es el caracter de fin de archivo, pasa al estado de tarea finalizada } + else trans := ERROR; { si es otro, da ERROR } + end; + COEF: { estado de lectura del coeficiente del termino del polinomio (sin punto decimal) } + case c of { acciona segun el caracter leido } + '0'..'9': trans := COEF; { si es un numero sigue con el mismo estado } + '.': trans := COEF_PUNTO; { si es punto cambia al estado COEF_PUNTO } + SPACE, TAB: trans := COEF_FIN; { si es un espacio o un tabulador, finaliza la lectura del coeficiente } + else trans := ERROR; { si es otra cosa, pasa a estado de error } + end; + COEF_PUNTO: { estado de lectura del coeficiente del termino del polinomio (con punto decimal) } + case c of { acciona segun el caracter leido } + '0'..'9': trans := COEF_PUNTO; { si es un numero sigue con el mismo estado } + SPACE, TAB: trans := COEF_FIN; { si es un espacio o un tabulador, finaliza la lectura del coeficiente } + else trans := ERROR; { si es otra cosa, pasa a estado de error } + end; + COEF_FIN: { estado de fin de la lectura del coeficiente del termino del polinomio } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si el caracter es un numero establece el estado en EXP (exponente) } + SPACE, TAB: trans := EXP_BUSCA; { si es un espacio o tabulador, pasa a buscar el proximo exponente } + else trans := ERROR; { si no es ninguno de los anteriores, el estado pasa a ERROR } + end; + EXP_BUSCA: { estado de busqueda del proximo exponente } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si el caracter es un numero, empieza a leer el exponente } + SPACE, TAB: trans := EXP_BUSCA; { si es un espacio o tabulador, sigue buscando } + else trans := ERROR; { si no es ninguno de los anteriores, el estado pasa a ERROR } + end; + EXP: { estado de lectura del exponente del termino actual del polinomio } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si es un digito, sigue en el mismo estado } + CR: trans := EXP_FIN; { si es un ratorno de carro, finaliza el exponente + (quiere decir que hubo un ) } + ENDF: trans := FIN; { si es el final del archivo, se indica que termino su tarea } + else trans := ERROR; { si es otra cosa, devuelve ERROR } + end; + EXP_FIN: { estado de fin de la lectura del exponente del termino actual del polinomio } + if c = LF then trans := EXP_FIN_BUSCA { debe ser un caracter de nueva linea (para completar el ) } + else trans := ERROR; { si no lo es, devuelve ERROR } + EXP_FIN_BUSCA: { estado de fin de lectura de la nueva linea (luego de finalizar el exponente + ahora decide si termino el polinomio o si sigue leyendo el proximo coeficiente } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un digito (o negativo), pasa a leer en proximo coeficiente } + CR: trans := POLI_FIN; { si es un ratorno de carro o nueva linea, finaliza el polinomio } + else trans := ERROR; { si es otra cosa, devuelve ERROR } + end; + POLI_FIN: { estado de finalizacion del polinomio actual } + if c = LF then trans := COEF_BUSCA { debe ser un caracter de nueva linea (para completar el ), + entonces pasa a buscar el primer coeficiente del nuevo polinomio } + else trans := ERROR; { si no lo es, devuelve ERROR } + FIN: { estado que adquiere cuando se finalizo la tarea } + trans := FIN; { se queda en este estado avisando que termino su tarea } + else { otro estado, no deberia ocurrir, salvo que se le pase a la funcion un estado de ERROR } + trans := ERROR; { si es otro, da ERROR } + end; { case } + end; { trans } + + {########################################################} + + function cargarVectores(var v1, v2: Vector): boolean; + { Funcion que abre el archivo de texto con los datos, lo carga en el vector procesandolo debidamente a medida + que lo lee y, al finalizar, cierra el archivo de texto. + v1 es el primer vector a cargar + v2 es el segundo vector a cargar + devuelve true si la lectura fue hecha con exito, false si hubo un error } + + var + f: Text; { archivo de texto con los datos } + c: char; { caracter que se extrae del archivo de texto } + nombreArchivo: String; { nombre del archivo de datos } + est: Estado; { Indicador del estado actual de la lectura } + seguir: boolean; { indicador para saber si debe seguir con el proceso } + i, { indice del vector del polinomio para ser inicializado } + iExp, { valor temporal para almacenar al exponente } + code, { almacena el resultado de la funcion val (no se usa porque los + datos ya estan validados } + poliN: integer; { numero del polinomio que se esta leyendo } + rCoef: real; { valor temporal para almacenar al coeficiente } + exponente, { string que representa al exponente leido } + coeficiente: String; { string que representa al coeficiente leido } + + begin { cargarVectores } + rCoef := 0.0; { inicializacion de variable } + iExp := 0; { inicializacion de variable } + coeficiente := ''; { inicializacion de variable } + exponente := ''; { inicializacion de variable } + est := INICIO; { empieza con el estado de INICIO } + poliN := 1; { establece que se procesara el primer polinomio } + inicializaVector(v1); { inicializacion del vector 1 (primer polinomio) } + inicializaVector(v2); { inicializacion del vector 2 (segundo polinomio) } + nombreArchivo := ObtenerNombreArchivo; { obtiene el nombre del archivo } + assign(f, nombreArchivo); { asigna la variable al nombre del archivo } + reset(f); { abre el archivo para leerlo desde el principio } + seguir := true; { inicializa seguir e true para comenzar el bucle } + while seguir do begin { continua mientras seguir sea true } + read(f, c); { lee un caracter del archivo de texto } + est := trans(c, est); { establece el nuevo estado de lectura } + case est of { toma una desicion dependiendo del estado en que se encuentre } + INICIO: ; { No hace nada, nunca toma este valor. Solo incica que empezo el proceso } + COEF_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + COEF, COEF_PUNTO: { Si esta leyendo el coeficiente ... } + coeficiente := coeficiente + c; { concatena el caracter a la representacion + de texto del coeficiente } + COEF_FIN: ; { Si termino de leer el coeficiente, no hace nada, la asignacion + se realiza cuando termina de leer el exponente (es necesario + para establecer el indice del vector } + EXP_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + EXP: { Si esta leyendo el exponente ... } + exponente := exponente + c; { concatena el caracter a la representacion + de texto del exponente } + EXP_FIN: { Si termino de leer el exponente, hace las asignaciones correspondientes } + begin { convirtiendo las cadenas de texto en real e integer, segun el caso } + val(coeficiente, rCoef, code); { convierte el coeficiente en real } + val(exponente, iExp, code); { convierte el exponente en integer } + if iExp < TAM { si el exponente es menor que el tama¤o maximo permitido ... } + then if poliN = 1 then v1[iExp] := rCoef { asigna el valor correspondiente } + else v2[iExp] := rCoef { al polinomio correspondiente } + else est := ERROR; { si no es menor, pone el estado en ERROR } + coeficiente := ''; { una vez asignados, vacia los valores del coeficiente y el } + exponente := ''; { exponente para poder realizar las lecturas de los proximos } + end; + EXP_FIN_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + POLI_FIN: { Si termino la lectura de un polinomio ... } + if poliN = 1 then poliN := 2 { si se leyo el 1er polinomio, se indica que se leera el 2do } + else est := FIN; { si no (ya se leyo el segundo), pone el estado en FIN } + FIN: { Si se finalizaron las tareas ... } + begin + cargarVectores := true; { en principio se establece que la lectura se hizo con exito ) } + seguir := false; { poner seguir en false para que se termine el bucle } + { este codigo es similar al de EXP_FIN, se hacen las asignaciones por el caso en que el fin + del archivo esta pegado al fin del ultimo exponente, en cuyo caso no pasa por el estado + de EXP_FIN (y, por ende, no se pueden hacer las asignaciones correspondientes } + val(coeficiente, rCoef, code); { convierte el coeficiente en real } + val(exponente, iExp, code); { convierte el exponente en integer } + if iExp < TAM { si el exponente es menor que el tama¤o maximo permitido ... } + then if poliN = 2 + then v2[iExp] := rCoef { si es el 2do polinomio, asigna el valor correspondiente } + else cargarVectores := false { si es el primero, no se hizo bien la lectura } + else cargarVectores := false; { si no es menor, no se hizo bien la lectura } + end; + ERROR: { Si hubo un error ... } + begin + cargarVectores := false; { Se devuelve false (hubo un ERROR, no se leyeron bien los vectores) } + seguir := false; { seguir se pone en false para que termine el bucle } + end; + end; { case } + end; { while } + close(f); { se cierra el archivo de lectura de datos } + end; { cargarVectores } + + {########################################################} + + procedure suma(v1, v2: Vector; var vr: Vector); + { procedimiento que suma dos polinomios. + v1: vector que contiene el primer polinomio a sumar + v2: vector que contiene el segundo polinomio a sumar + vr: vector donde se almacenara el resultado de la suma } + + var + i: integer; { indice para usar en el ciclo for } + + begin { suma } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el vector (de tama¤o maximo TAM) } + vr[i] := v1[i] + v2[i]; { suma los coeficientes de los terminos con igual exponente } + end; { suma } + + {########################################################} + + procedure resta(v1, v2: Vector; var vr: Vector); + { procedimiento que resta dos polinomios. + v1: vector que contiene el primer polinomio + v2: vector que contiene el polinomio para restarle al primero + vr: vector donde se almacenara el resultado de la resta } + + var + i: integer; { indice para usar en el ciclo for } + + begin { resta } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el vector (de tama¤o maximo TAM) } + vr[i] := v1[i] - v2[i]; { resta los coeficientes de los terminos con igual exponente } + end; { resta } + + {########################################################} + + procedure producto(v1, v2: Vector; var vr: Vector); + { procedimiento que multiplica dos polinomios. + v1: vector que contiene el primer polinomio a multiplicar + v2: vector que contiene el segundo polinomio a multiplicar + vr: vector donde se almacenara el resultado de la multiplicacion } + + var + i, j: integer; { indices para usar en los ciclos for } + + begin { producto } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el 1er vector (de tama¤o maximo TAM) } + for j := 0 to TAM - 1 do { recorre el 2do vector (de tama¤o maximo TAM) } + vr[i+j] := vr[i+j] + (v1[i] * v2[j]); + { multiplica los coeficientes de los terminos y lo almacena en la posicion del exponente } + { igual a la suma de los exponentes de v1 y v2, sumando el valor previo de dicha posicion } + end; { producto } + + {########################################################} + + function division(v1, v2: Vector; var vr, vResto: Vector): boolean; + { procedimiento que divide dos polinomios. + v1: vector que contiene el polinomio denominador + v2: vector que contiene el polinomio divisor + vr: vector donde se almacenara el resultado de la division + vResto: vector donde se almacenara el resto de la division + devuelve true si el segundo polinomio no es 0 y se efectua la division y + devuelve false si segundo polinomio es 0 y no se puede efectuar la division } + + var + i, j: integer; { indices para usar en los ciclos for } + vRTmp, { vector auxuliares para almacenar el termino actual del resultado } + vTmp: Vector; { vector auxuliares para almacenar el polinomio que es la multiplicacion del + termino actual del resultado por el divisor } + + begin { division } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vResto); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vTmp); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vRTmp); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := TAM - 1 downto 0 do { recorre el 1er vector (de tama¤o maximo TAM) de atras para adelante } + if v1[i] <> 0 then break; + { busca empezando por el indice (exponete) mas alto el primer coeficiente no nulo } + { si lo encuentra sale del for dejando al valor de i como el de dicho inidice } + for j := TAM - 1 downto 0 do { recorre el 2do vector (de tama¤o maximo TAM) de atras para adelante } + if v2[j] <> 0 then break; + { busca empezando por el indice (exponete) mas alto el primer coeficiente no nulo } + { si lo encuentra sale del for dejando al valor de j como el de dicho inidice } + if (j = 0) and (v2[j] = 0) { si el no se encontro ningun coeficiente no nulo, entonces } + then { el polinomio 2 es nulo y no se puede efectuar la division } + begin { se devuelve false y se quedan los vectores resultado en 0 } + division := false; { devuelve false } + exit; { sale del procedimiento } + end; + while i >= j do { si el primer exponente es mayor o igual que el segundo empieza a dividir } + begin + vr[i-j] := v1[i] / v2[j]; { almacena el resultado de la division entre los coeficientes en + la posicion de la resta de ambos } + vRTmp[i-j] := vr[i-j]; { almacena ese resultado en un polinomio temporal cuyo unico termio + no nulo es el del exponente i-j, para luego multiplicarlo } + producto(vRTmp, v2, vTmp);{ multiplica este polinomio por el segundo almacenado el resultado + en otro temporal, para luego hacer la resta } + resta(v1, vTmp, v1); { resta al primer polinomio, v1, (en su estado actual, no el original) + el temporal vTmp y lo almacena en v1, para poder volver a operarlo de + la misma forma } + vRTmp[i-j] := 0; { resetea el termino del temporal vRTmp que se asigno para los calculos } + for i := i downto 0 do { recorre el vector v1 (de tama¤o maximo TAM) de atras para adelante } + if v1[i] <> 0 then break; + { busca empezando por el indice (exponete) i el primer coeficiente no nulo + si lo encuentra sale del for dejando al valor de i como el de dicho inidice } + end; { while } + vResto := v1; { asigna el vector v1 (que ya no se procesara mas al resto } + division := true; { devuelve true indicando que se finalizo con exito } + end; { division } + + {########################################################} + + procedure mensajeSalida; { muestra un mensaje en la salida del programa } + + begin + writeln; { linea en blanco } + NormVideo; { reestablece los colores a los valores por defecto } + clrscr; { borra la pantalla } + writeln; { linea en blanco } + textcolor(white); { cambia el color del texto } + writeln(' PolinomiosEnVector versi¢n ', VERSION); { mensaje con version del programa } + NormVideo; { reestablece los colores a los valores por defecto } + writeln(' Desarrollado por: JavierGrijalba'); { mensaje con los integrantes del grupo } + writeln(' Leandro Lucarella'); + writeln(' Erasmo Troncovich'); + writeln(' Diego Wojmicki'); + writeln(' para la Facultad de Ingenier¡a de la Universidad de Buenos Aires.'); + writeln(' Consultas y/o sugerencias a:'); + writeln; + textcolor(LightMagenta); { cambia el color del texto } + write(' lluca@cnba.uba.ar'); + NormVideo; { reestablece los colores a los valores por defecto } + write(' o '); + textcolor(LightMagenta); { cambia el color del texto } + writeln('grijalba@cvtci.com.ar'); + NormVideo; { reestablece los colores a los valores por defecto } + writeln; + writeln(' (c) 1999 - Todos los derechos reservados.'); + delay(750); + end; + + + {########################################################} + + +var + i: integer; { variable auxiliar } + v1, v2, vResult, vResto: Vector; { vectores para hacer las operaciones } + seguir, { indicador para saber si sigue corriendo el programa } + noNulo, { indicador para saber si en la division el divisor es nulo } + continua: boolean; { indicador para saber si se leyeron bien los polinomios } + tecla: char; { entrada de teclado del usuario para elegir una opcion } + +begin { programa principal } + textbackground( Blue ); { establece el color para el fondo a azul } + continua := cargarVectores(v1, v2); { carga los vectores del archivo de datos } + if continua then { si se leyeron bien ... } + begin + seguir := true; { inicializa la variable en true para que entre en el ciclo while } + while seguir do { mientras el usuario no salga del programa } + begin + clrscr; { borra la pantalla } + textcolor(Yellow); { establece el color para el texto a amarillo } + gotoxy( 30, 3 ); { va a las coordenas de pantalla 25 horizontal, 3 verical } + writeln( 'PolinomiosEnVector' ); { titulo } + gotoxy( 30, 4 ); { va a las coordenas de pantalla 25 horizontal, 4 verical } + writeln( '~~~~~~~~~~~~~~~~~~' ); { subrayado del titulo } + textcolor(LightCyan); { establece el color para el texto a cian claro } + gotoxy( 1, 7 ); { va a las coordenas de pantalla 1 horizontal, 7 verical } + writeln( ' Elija que desea hacer:' ); { mensaje } + writeln( ' ----- --- ----- ------' ); { mensaje } + textcolor(LightGray); { establece el color para el texto a gris claro } + writeln; { mensaje con las opciones ... } + writeln; + writeln( ' 1.- Ver el polinomio 1.' ); + writeln( ' 2.- Ver el polinomio 2.' ); + writeln( ' 3.- Sumar los polinomios.' ); + writeln( ' 4.- Restar el polinomio 2 al polinomio 1 (poli1 - poli2).' ); + writeln( ' 5.- Restar el polinomio 1 al polinomio 2 (poli2 - poli1).' ); + writeln( ' 6.- Multiplicar los polinomios.' ); + writeln( ' 7.- Polinomio 1 dividido polinomio 2 (poli1 / poli2).' ); + writeln( ' 8.- Polinomio 2 dividido polinomio 1 (poli2 / poli1).' ); + writeln( ' 0.- Salir.' ); + gotoxy(1, 23); { va a las coordenas de pantalla 1 horizontal, 23 verical } + textcolor(White ); { establece el color para el texto a blanco } + write(' Ingrese su opci¢n: '); + textcolor(Yellow); { establece el color para el texto a amarillo } + tecla := readkey; { lee una tecla del usuario indicando la opcion que elijio } + while ((tecla < '1') or (tecla > '8')) and (tecla <> '0') do { mientras sea una tecla no admitida } + begin + textcolor(White); { establece el color para el texto a blanco } + gotoxy( 1, 23 ); { va a las coordenas de pantalla 1 horizontal, 7 verical } + write(' Ingrese su opci¢n ("1" a "8" o "0"): ' ); + textcolor(Yellow); { establece el color para el texto a amarillo } + tecla := readkey; { lee una tecla del usuario indicando la opcion que elijio } + end; { while } + if tecla = '0' then { si la opcion fue salir del programa ... } + begin + mensajeSalida; { presenta un mensaje de salida } + exit; { sale del programa } + end; + clrscr; { borra la pantalla } + textcolor(Yellow); { establece el color para el texto a amarillo } + gotoxy( 30, 3 ); { va a las coordenas de pantalla 25 horizontal, 3 verical } + writeln( 'PolinomiosEnVector' ); { titulo } + gotoxy( 30, 4 ); { va a las coordenas de pantalla 25 horizontal, 4 verical } + writeln( '~~~~~~~~~~~~~~~~~~' ); { subrayado del titulo } + textcolor(LightCyan); { establece el color para el texto a cian claro } + gotoxy(1, 7); { va a las coordenas de pantalla 1 horizontal, 7 verical } + case tecla of + '1': muestraVector(v1, ' Polinomio 1 = '); + '2': muestraVector(v2, ' Polinomio 2 = '); + '3': begin + suma(v1, v2, vResult); + muestraVector(vResult, ' Polinomio 1 + Polinomio 2 = '); + end; { case 3 } + '4': begin + resta(v1, v2, vResult); + muestraVector(vResult, ' Polinomio 1 - Polinomio 2 = '); + end; { case 4 } + '5': begin + resta(v2, v1, vResult); + muestraVector(vResult, ' Polinomio 2 - Polinomio 1 = '); + end; { case 5 } + '6': begin + producto(v1, v2, vResult); + muestraVector(vResult, ' Polinomio 1 * Polinomio 2 = '); + end; { case 6 } + '7': begin + noNulo := division(v1, v2, vResult, vResto); + if noNulo + then + begin + muestraVector(vResult, ' Polinomio 1 / Polinomio 2 = '); + muestraVector(vResto, ' Resto = '); + end + else writeln(' El polinomio 2 es nulo, por lo tanto no se puede efectuar la division.'); + end; { case 7 } + '8': begin + noNulo := division(v2, v1, vResult, vResto); + if noNulo + then + begin + muestraVector(vResult, 'Polinomio 2 / Polinomio 1 = '); + muestraVector(vResto, 'Resto = '); + end + else writeln(' El polinomio 1 es nulo, por lo tanto no se puede efectuar la division.'); + end; { case 8 } + '0': ; { no hace nada, nunca deberia entrar en este case } + end; { case } + writeln; { los siguientes mensajes son para que el usuario pueda ver los datos y luego } + writeln; { presione una tecla para continuar } + textcolor(white); { pone el color del texto en blanco } + writeln(' Presione una tecla para continuar ...'); + tecla := readkey; + end; { while } + end + else { si los vectores no se leyeron bien ... } + begin { presenta un mensaje de error } + writeln('ERROR: No se pudieron cargar los datos. Revise que el formato del archivo'); + writeln(' sea correcto y que no este siendo usado por otro programa.'); + end; +end. { procedure menuGenerar } \ No newline at end of file diff --git a/poli_2.pas b/poli_2.pas new file mode 100644 index 0000000..9ff537c --- /dev/null +++ b/poli_2.pas @@ -0,0 +1,338 @@ +program Polinomios; + +uses + CRT, DOS; { Declaracion de funciones predefinidas + para crear la interfaz grafica } + +const + VERSION = '0.6.0a (POLI_2)'; { version del programa } + + TAM_MAX = 100; { Tama¤o maximo del vector que almacena + la multiplicacion de polinomios } + TAM = TAM_MAX div 2; { Tama¤o maximo del vector que contiene + los vector con los que se va a operar } + CR = chr(13); { caracter de retorno del carro } + LF = chr(10); { caracter de nueva linea } + ENDF = chr(26); { caracter de fin del archivo } + TAB = chr(9); { caracter de tabulacion } + SPACE = chr(32); { caracter de espacio } + +type + Estado = (INICIO, COEF_BUSCA, COEF, COEF_PUNTO, COEF_FIN, EXP_BUSCA, EXP, EXP_FIN, EXP_FIN_BUSCA, POLI_FIN, FIN, ERROR); + { Tipo de dato para identificar el estado de la entrada + de datos } + VectorResultado = array [0..TAM_MAX-1] of real; { vector para almacenar + el polinomio resultado } + Vector = array [0..TAM-1] of real; { vector para almacenar los polinomios } + Termino = record { tipo de dato que representa un termino de un poinomio } + coef: real; { coeficiente del termino } + exp: integer; { exponente de lavariable del polinomio } + end; { fin del tipo de dato } + + + {########################################################} + + function ObtenerNombreArchivo: String; + { funcion que obtiene un nombre de archivo valido (es decir, el nombre + de un archivo que exista) } + + {########################################################} + + function fileExists(FileName: String): Boolean; + { funcion extraida de la ayuda del Turbo Pascal 7 + indica si el archivo existe } + + var + F: file; + + begin + {$I-} + Assign(F, FileName); + FileMode := 0; { Set file access to read only } + Reset(F); + Close(F); + {$I+} + FileExists := (IOResult = 0) and (FileName <> ''); + end; { FileExists } + + {########################################################} + + { Continuacion de la funcion ObtenerNombreArchivo } + const + DEFAUL_FILE_NAME = 'datos.txt'; { nombre del archivo por defecto } + + var + tmp: String; { cadena para almacenar el resultado temporal } + + begin + { mensaje para entrada del nombre de archivo } + writeln('Ingrese el nombre del archivo con los datos (ENTER = ', DEFAUL_FILE_NAME, '):'); + readln(tmp); { entrada del nombre de archivo } + if tmp = '' then tmp := DEFAUL_FILE_NAME; { se fija si no se ingreso nada y reasigana el nombre } + while not fileExists(tmp) do { repite el proceso hasta que el archivo exista } + begin + write('El archivo ', tmp, ' no existe. Ingrese un nombre correcto'); + if tmp = DEFAUL_FILE_NAME { si es el nombre de archivo predeterminado } + then { entonces, elije un mensaje apropiado } + write(': ') + else + begin { si no es el predeterminado, muestra otro mensaje } + writeln('.'); + write('(ENTER = ', DEFAUL_FILE_NAME, '): '); + end; + readln(tmp); { vuelve a leer el nombre del archivo para ser verificado } + if tmp = '' then tmp := DEFAUL_FILE_NAME; { asigna como nombre de archivo al predeterminado + si no se escribio nada } + end; { fin del loop de verificacion } + ObtenerNombreArchivo := tmp; { asigna el nombre correcto al valor de salida de la funcion } + end; { ObtenerNombreArchivo } + + {########################################################} + + function trans(c: char; e: Estado): Estado; + { establece el estado en el que se encuentra la lectura } + { c es el caracter que se leyo, e es el estado actual de la lectura } + +{DEBUG var l: Text; {} + + begin +{DEBUG assign(l, 'log.txt'); {} +{DEBUG append(l); {} + case e of { acciona segun es estado actual de la lectura } + INICIO: { estado de inicio de la lectura } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un numero (o negativo), empieza a leer el coeficiente } + SPACE, TAB, CR, LF: trans := COEF_BUSCA; { si es un caracter tipo "espacio", busca el prox. coef. } + else trans := ERROR; { si es otro, da ERROR } + end; + COEF_BUSCA: { estado de busqueda del primer ceoficiente del polinomio } +{DEBUG begin {} + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un numero (o negativo), empieza a leer el coeficiente } + SPACE, TAB, CR, LF: trans := COEF_BUSCA; { si es un caracter tupo "espacio", sigue buscando } + ENDF: trans := FIN; { si es el caracter de fin de archivo, pasa al estado de tarea finalizada } + else trans := ERROR; { si es otro, da ERROR } + end; +{DEBUG writeln(l, ' --> trans: COEF_BUSCA: c: ', ord(c)); {} +{DEBUG end; {} + COEF: { estado de lectura del coeficiente del termino del polinomio (sin punto decimal) } +{DEBUG begin {} + case c of { acciona segun el caracter leido } + '0'..'9': trans := COEF; { si es un numero sigue con el mismo estado } + '.': trans := COEF_PUNTO; { si es punto cambia al estado COEF_PUNTO } + SPACE, TAB: trans := COEF_FIN; { si es un espacio o un tabulador, finaliza la lectura del coeficiente } + else trans := ERROR; { si es otra cosa, pasa a estado de error } + end; +{DEBUG writeln(l, ' --> trans: COEF: c: ', ord(c)); {} +{DEBUG end; {} + COEF_PUNTO: { estado de lectura del coeficiente del termino del polinomio (con punto decimal) } +{DEBUG begin {} + case c of { acciona segun el caracter leido } + '0'..'9': trans := COEF_PUNTO; { si es un numero sigue con el mismo estado } + SPACE, TAB: trans := COEF_FIN; { si es un espacio o un tabulador, finaliza la lectura del coeficiente } + else trans := ERROR; { si es otra cosa, pasa a estado de error } + end; +{DEBUG writeln(l, ' --> trans: COEF_PUNTO: c: ', ord(c)); {} +{DEBUG end; {} + COEF_FIN: { estado de fin de la lectura del coeficiente del termino del polinomio } +{DEBUG begin {} + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si el caracter es un numero establece el estado en EXP (exponente) } + SPACE, TAB: trans := EXP_BUSCA; { si es un espacio o tabulador, pasa a buscar el proximo exponente } + else trans := ERROR; { si no es ninguno de los anteriores, el estado pasa a ERROR } + end; +{DEBUG writeln(l, ' --> trans: COEF_FIN: c: ', ord(c)); {} +{DEBUG end; {} + EXP_BUSCA: { estado de busqueda del proximo exponente } +{DEBUG begin {} + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si el caracter es un numero, empieza a leer el exponente } + SPACE, TAB: trans := EXP_BUSCA; { si es un espacio o tabulador, sigue buscando } + else trans := ERROR; { si no es ninguno de los anteriores, el estado pasa a ERROR } + end; +{DEBUG writeln(l, ' --> trans: EXP_BUSCA: c: ', ord(c)); {} +{DEBUG end; {} + EXP: { estado de lectura del exponente del termino actual del polinomio } +{DEBUG begin {} + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si es un digito, sigue en el mismo estado } + CR: trans := EXP_FIN; { si es un ratorno de carro, finaliza el exponente + (quiere decir que hubo un ) } + ENDF: trans := FIN; { si es el final del archivo, se indica que termino su tarea } + else trans := ERROR; { si es otra cosa, devuelve ERROR } + end; +{DEBUG writeln(l, ' --> trans: EXP: c: ', ord(c)); {} +{DEBUG end; {} + EXP_FIN: { estado de fin de la lectura del exponente del termino actual del polinomio } +{DEBUG begin {} + if c = LF then trans := EXP_FIN_BUSCA { debe ser un caracter de nueva linea (para completar el ) } + else trans := ERROR; { si no lo es, devuelve ERROR } +{DEBUG writeln(l, ' --> trans: EXP_FIN: c: ', ord(c)); {} +{DEBUG end; {} + EXP_FIN_BUSCA: { estado de fin de lectura de la nueva linea (luego de finalizar el exponente + ahora decide si termino el polinomio o si sigue leyendo el proximo coeficiente } +{DEBUG begin {} + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un digito (o negativo), pasa a leer en proximo coeficiente } + CR: trans := POLI_FIN; { si es un ratorno de carro o nueva linea, finaliza el polinomio } + else trans := ERROR; { si es otra cosa, devuelve ERROR } + end; +{DEBUG writeln(l, ' --> trans: EXP_FIN_BUSCA: c: ', ord(c)); {} +{DEBUG end; {} + POLI_FIN: { estado de finalizacion del polinomio actual } +{DEBUG begin {} + if c = LF then trans := COEF_BUSCA { debe ser un caracter de nueva linea (para completar el ), + entonces pasa a buscar el primer coeficiente del nuevo polinomio } + else trans := ERROR; { si no lo es, devuelve ERROR } +{DEBUG writeln(l, ' --> trans: POLI_FIN: c: ', ord(c)); {} +{DEBUG end; {} + FIN: { estado que adquiere cuando se finalizo la tarea } + trans := FIN; { se queda en este estado avisando que termino su tarea } + else { otro estado, no deberia ocurrir, salvo que se le pase a la funcion un estado de ERROR } + trans := ERROR; { si es otro, da ERROR } + end; { case } +{DEBUG close(l); {} + end; { trans } + + {########################################################} + + function cargarVectores(var v1, v2: Vector): boolean; + { Funcion que abre el archivo de texto con los datos, lo carga en el vector procesandolo debidamente a medida + que lo lee y, al finalizar, cierra el archivo de texto. + v1 es el primer vector a cargar + v2 es el segundo vector a cargar + devuelve true si la lectura fue hecha con exito, false si hubo un error } + + var + f: Text; { archivo de texto con los datos } + c: char; { caracter que se extrae del archivo de texto } + nombreArchivo: String; { nombre del archivo de datos } + est: Estado; { Indicador del estado actual de la lectura } + seguir: boolean; { indicador para saber si debe seguir con el proceso } + i, { indice del vector del polinomio para ser inicializado } + iExp, { valor temporal para almacenar al exponente } + code, { almacena el resultado de la funcion val (no se usa porque los + datos ya estan validados } + poliN: integer; { numero del polinomio que se esta leyendo } + rCoef: real; { valor temporal para almacenar al coeficiente } + exponente, { string que representa al exponente leido } + coeficiente: String; { string que representa al coeficiente leido } + + begin + rCoef := 0.0; { inicializacion de variable } + iExp := 0; { inicializacion de variable } + coeficiente := ''; { inicializacion de variable } + exponente := ''; { inicializacion de variable } + est := INICIO; { empieza con el estado de INICIO } + poliN := 1; { establece que se procesara el primer polinomio } + for i := 0 to TAM - 1 do { iteracion para inicializar los vectores a cero } + begin { para que los valores que no son especificados no contengan "basura" } + v1[i] := 0; { inicializacion del vector 1 (primer polinomio) } + v2[i] := 0; { inicializacion del vector 2 (segundo polinomio) } + end; + nombreArchivo := ObtenerNombreArchivo; { obtiene el nombre del archivo } +{DEBUG nombreArchivo := 'datos.txt'; {} + assign(f, nombreArchivo); { asigna la variable al nombre del archivo } + reset(f); { abre el archivo para leerlo desde el principio } + seguir := true; { inicializa seguir e true para comenzar el bucle } + while seguir do begin { continua mientras seguir sea true } + read(f, c); { lee un caracter del archivo de texto } + est := trans(c, est); { establece el nuevo estado de lectura } + case est of { toma una desicion dependiendo del estado en que se encuentre } + INICIO: ; { No hace nada, nunca toma este valor. Solo incica que empezo el proceso } + COEF_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + COEF, COEF_PUNTO: { Si esta leyendo el coeficiente ... } + coeficiente := coeficiente + c; { concatena el caracter a la representacion + de texto del coeficiente } + COEF_FIN: ; { Si termino de leer el coeficiente, no hace nada, la asignacion + se realiza cuando termina de leer el exponente (es necesario + para establecer el indice del vector } + EXP_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + EXP: { Si esta leyendo el exponente ... } + exponente := exponente + c; { concatena el caracter a la representacion + de texto del exponente } + EXP_FIN: { Si termino de leer el exponente, hace las asignaciones correspondientes } + begin { convirtiendo las cadenas de texto en real e integer, segun el caso } + val(coeficiente, rCoef, code); { convierte el coeficiente en real } + val(exponente, iExp, code); { convierte el exponente en integer } + if iExp < TAM { si el exponente es menor que el tama¤o maximo permitido ... } + then if poliN = 1 then v1[iExp] := rCoef { asigna el valor correspondiente } + else v2[iExp] := rCoef { al polinomio correspondiente } + else est := ERROR; { si no es menor, pone el estado en ERROR } +{DEBUG writeln(' --> cargarVectores: EXP_FIN'); {} +{DEBUG writeln(' v[', iExp,'] = ', rCoef:1:1); {} + coeficiente := ''; { una vez asignados, vacia los valores del coeficiente y el } + exponente := ''; { exponente para poder realizar las lecturas de los proximos } + end; + EXP_FIN_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + POLI_FIN: { Si termino la lectura de un polinomio ... } + if poliN = 1 then poliN := 2 { si se leyo el 1er polinomio, se indica que se leera el 2do } + else est := FIN; { si no (ya se leyo el segundo), pone el estado en FIN } + FIN: { Si se finalizaron las tareas ... } + begin + { este codigo es el mismo que el de EXP_FIN, se repite aca solo por si el final del + archivo esta pegado al fin del ultimo exponente, en cuyo caso no pasa por el estado + de EXP_FIN (y, por ende, no se pueden hacer las asignaciones correspondientes } + val(coeficiente, rCoef, code); { convierte el coeficiente en real } + val(exponente, iExp, code); { convierte el exponente en integer } + if iExp < TAM { si el exponente es menor que el tama¤o maximo permitido ... } + then if poliN = 1 then v1[iExp] := rCoef { asigna el valor correspondiente } + else v2[iExp] := rCoef { al polinomio correspondiente } + else est := ERROR; { si no es menor, pone el estado en ERROR } +{DEBUG writeln(' --> cargarVectores: FIN'); {} +{DEBUG writeln(' v[', iExp,'] = ', rCoef:1:1);} + coeficiente := ''; { una vez asignados, vacia los valores del coeficiente y el } + exponente := ''; { exponente para poder realizar las lecturas de los proximos } + { fin del codigo identico a EXP_FIN } + if poliN = 2 then cargarVectores := true { si se leyeron los 2 polinomios, devuelve true } + else cargarVectores := false; { si no se leyeron los dos, devuelve false } + seguir := false; { poner seguir en false para que se termine el bucle } + end; + ERROR: { Si hubo un error ... } + begin + cargarVectores := false; { Se devuelve false (hubo un ERROR, no se leyeron bien los vectores) } + seguir := false; { seguir se pone en false para que termine el bucle } + end; + end; { case } +{DEBUG writeln(' --> cargarVectores: EN CICLO WHILE PRINCIPAL'); {} +{DEBUG writeln(' c: ',ord(c),' | est: ',ord(est),' | poliN: ',poliN,' | coeficiente: ', {} +{DEBUG coeficiente,' | exponente: ',exponente); {} + end; { while } +{DEBUG writeln(' --> cargarVectores: SALIDA'); {} +{DEBUG writeln(' c: ',ord(c),' | est: ',ord(est),' | poliN: ',poliN,' | coeficiente: ', {} +{DEBUG coeficiente,' | exponente: ',exponente); {} + close(f); { se cierra el archivo de lectura de datos } + end; { cargarVectores } + + {########################################################} + +{ Continuacion del programa principal } + +var + i: integer; { variable auxiliar } + v1, v2: vector; + resultado: boolean; + +begin { Comienzo del programa principal } + resultado := cargarVectores(v1, v2); + {if not resultado then exit;} + writeln('Polinomio 1:'); + for i := TAM - 1 downto 0 do + if v1[i] <> 0 then + begin + if v1[i] < 0 then write(' - ', abs(v1[i]):1:2) + else write(' + ', v1[i]:1:2); + if i <> 0 then write('*X^', i); + end; + writeln; + writeln('Polinomio 2:'); + for i := TAM - 1 downto 0 do + if v2[i] <> 0 then + begin + if v2[i] < 0 then write(' - ', abs(v2[i]):1:2) + else write(' + ', v2[i]:1:2); + if i <> 0 then write('*X^', i); + end; + writeln; + writeln(ord(resultado)); +end. \ No newline at end of file diff --git a/poli_3.pas b/poli_3.pas new file mode 100644 index 0000000..4c264ea --- /dev/null +++ b/poli_3.pas @@ -0,0 +1,396 @@ +program Polinomios; + +uses + CRT, DOS; { Declaracion de funciones predefinidas + para crear la interfaz grafica } + +const + VERSION = '0.7.0a (POLI_3)'; { version del programa } + + TAM_MAX = 100; { Tama¤o maximo del vector que almacena + la multiplicacion de polinomios } + TAM = TAM_MAX div 2; { Tama¤o maximo (virtual) del vector que contiene + los vector con los que se va a operar } + CR = chr(13); { caracter de retorno del carro } + LF = chr(10); { caracter de nueva linea } + ENDF = chr(26); { caracter de fin del archivo } + TAB = chr(9); { caracter de tabulacion } + SPACE = chr(32); { caracter de espacio } + +type + { Tipo de dato para identificar el estado de la entrada de datos } + Estado = (INICIO, COEF_BUSCA, COEF, COEF_PUNTO, COEF_FIN, EXP_BUSCA, EXP, EXP_FIN, EXP_FIN_BUSCA, POLI_FIN, FIN, ERROR); + Vector = array [0..TAM_MAX-1] of real; { vector para almacenar los polinomios } + + + {########################################################} + + procedure inicializaVector(var v: Vector; t: integer); + { procedimiento que inicializa un vector de tama¤o tam } + + var i: integer; { indice para usar en el ciclo for } + + begin { inicializaVector } + for i := 0 to t - 1 do { recorre el vector } + v[i] := 0; { inicializa la variable actual en 0 } + end; { inicializaVector } + + {########################################################} + + function ObtenerNombreArchivo: String; + { funcion que obtiene un nombre de archivo valido (es decir, el nombre + de un archivo que exista) } + + {########################################################} + + function fileExists(FileName: String): Boolean; + { funcion extraida de la ayuda del Turbo Pascal 7 + indica si el archivo existe } + + var + F: file; + + begin + {$I-} + Assign(F, FileName); + FileMode := 0; { Set file access to read only } + Reset(F); + Close(F); + {$I+} + FileExists := (IOResult = 0) and (FileName <> ''); + end; { FileExists } + + {########################################################} + + { Continuacion de la funcion ObtenerNombreArchivo } + const + DEFAUL_FILE_NAME = 'datos.txt'; { nombre del archivo por defecto } + + var + tmp: String; { cadena para almacenar el resultado temporal } + + begin { ObtenerNombreArchivo } + { mensaje para entrada del nombre de archivo } + writeln('Ingrese el nombre del archivo con los datos (ENTER = ', DEFAUL_FILE_NAME, '):'); + readln(tmp); { entrada del nombre de archivo } + if tmp = '' then tmp := DEFAUL_FILE_NAME; { se fija si no se ingreso nada y reasigana el nombre } + while not fileExists(tmp) do { repite el proceso hasta que el archivo exista } + begin + write('El archivo ', tmp, ' no existe. Ingrese un nombre correcto'); + if tmp = DEFAUL_FILE_NAME { si es el nombre de archivo predeterminado } + then { entonces, elije un mensaje apropiado } + write(': ') + else + begin { si no es el predeterminado, muestra otro mensaje } + writeln('.'); + write('(ENTER = ', DEFAUL_FILE_NAME, '): '); + end; + readln(tmp); { vuelve a leer el nombre del archivo para ser verificado } + if tmp = '' then tmp := DEFAUL_FILE_NAME; { asigna como nombre de archivo al predeterminado + si no se escribio nada } + end; { fin del loop de verificacion } + ObtenerNombreArchivo := tmp; { asigna el nombre correcto al valor de salida de la funcion } + end; { ObtenerNombreArchivo } + + {########################################################} + + function trans(c: char; e: Estado): Estado; + { establece el estado en el que se encuentra la lectura } + { c es el caracter que se leyo, e es el estado actual de la lectura } + + begin { trans } + case e of { acciona segun es estado actual de la lectura } + INICIO: { estado de inicio de la lectura } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un numero (o negativo), empieza a leer el coeficiente } + SPACE, TAB, CR, LF: trans := COEF_BUSCA; { si es un caracter tipo "espacio", busca el prox. coef. } + else trans := ERROR; { si es otro, da ERROR } + end; + COEF_BUSCA: { estado de busqueda del primer ceoficiente del polinomio } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un numero (o negativo), empieza a leer el coeficiente } + SPACE, TAB, CR, LF: trans := COEF_BUSCA; { si es un caracter tupo "espacio", sigue buscando } + ENDF: trans := FIN; { si es el caracter de fin de archivo, pasa al estado de tarea finalizada } + else trans := ERROR; { si es otro, da ERROR } + end; + COEF: { estado de lectura del coeficiente del termino del polinomio (sin punto decimal) } + case c of { acciona segun el caracter leido } + '0'..'9': trans := COEF; { si es un numero sigue con el mismo estado } + '.': trans := COEF_PUNTO; { si es punto cambia al estado COEF_PUNTO } + SPACE, TAB: trans := COEF_FIN; { si es un espacio o un tabulador, finaliza la lectura del coeficiente } + else trans := ERROR; { si es otra cosa, pasa a estado de error } + end; + COEF_PUNTO: { estado de lectura del coeficiente del termino del polinomio (con punto decimal) } + case c of { acciona segun el caracter leido } + '0'..'9': trans := COEF_PUNTO; { si es un numero sigue con el mismo estado } + SPACE, TAB: trans := COEF_FIN; { si es un espacio o un tabulador, finaliza la lectura del coeficiente } + else trans := ERROR; { si es otra cosa, pasa a estado de error } + end; + COEF_FIN: { estado de fin de la lectura del coeficiente del termino del polinomio } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si el caracter es un numero establece el estado en EXP (exponente) } + SPACE, TAB: trans := EXP_BUSCA; { si es un espacio o tabulador, pasa a buscar el proximo exponente } + else trans := ERROR; { si no es ninguno de los anteriores, el estado pasa a ERROR } + end; + EXP_BUSCA: { estado de busqueda del proximo exponente } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si el caracter es un numero, empieza a leer el exponente } + SPACE, TAB: trans := EXP_BUSCA; { si es un espacio o tabulador, sigue buscando } + else trans := ERROR; { si no es ninguno de los anteriores, el estado pasa a ERROR } + end; + EXP: { estado de lectura del exponente del termino actual del polinomio } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si es un digito, sigue en el mismo estado } + CR: trans := EXP_FIN; { si es un ratorno de carro, finaliza el exponente + (quiere decir que hubo un ) } + ENDF: trans := FIN; { si es el final del archivo, se indica que termino su tarea } + else trans := ERROR; { si es otra cosa, devuelve ERROR } + end; + EXP_FIN: { estado de fin de la lectura del exponente del termino actual del polinomio } + if c = LF then trans := EXP_FIN_BUSCA { debe ser un caracter de nueva linea (para completar el ) } + else trans := ERROR; { si no lo es, devuelve ERROR } + EXP_FIN_BUSCA: { estado de fin de lectura de la nueva linea (luego de finalizar el exponente + ahora decide si termino el polinomio o si sigue leyendo el proximo coeficiente } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un digito (o negativo), pasa a leer en proximo coeficiente } + CR: trans := POLI_FIN; { si es un ratorno de carro o nueva linea, finaliza el polinomio } + else trans := ERROR; { si es otra cosa, devuelve ERROR } + end; + POLI_FIN: { estado de finalizacion del polinomio actual } + if c = LF then trans := COEF_BUSCA { debe ser un caracter de nueva linea (para completar el ), + entonces pasa a buscar el primer coeficiente del nuevo polinomio } + else trans := ERROR; { si no lo es, devuelve ERROR } + FIN: { estado que adquiere cuando se finalizo la tarea } + trans := FIN; { se queda en este estado avisando que termino su tarea } + else { otro estado, no deberia ocurrir, salvo que se le pase a la funcion un estado de ERROR } + trans := ERROR; { si es otro, da ERROR } + end; { case } + end; { trans } + + {########################################################} + + function cargarVectores(var v1, v2: Vector): boolean; + { Funcion que abre el archivo de texto con los datos, lo carga en el vector procesandolo debidamente a medida + que lo lee y, al finalizar, cierra el archivo de texto. + v1 es el primer vector a cargar + v2 es el segundo vector a cargar + devuelve true si la lectura fue hecha con exito, false si hubo un error } + + var + f: Text; { archivo de texto con los datos } + c: char; { caracter que se extrae del archivo de texto } + nombreArchivo: String; { nombre del archivo de datos } + est: Estado; { Indicador del estado actual de la lectura } + seguir: boolean; { indicador para saber si debe seguir con el proceso } + i, { indice del vector del polinomio para ser inicializado } + iExp, { valor temporal para almacenar al exponente } + code, { almacena el resultado de la funcion val (no se usa porque los + datos ya estan validados } + poliN: integer; { numero del polinomio que se esta leyendo } + rCoef: real; { valor temporal para almacenar al coeficiente } + exponente, { string que representa al exponente leido } + coeficiente: String; { string que representa al coeficiente leido } + + begin { cargarVectores } + rCoef := 0.0; { inicializacion de variable } + iExp := 0; { inicializacion de variable } + coeficiente := ''; { inicializacion de variable } + exponente := ''; { inicializacion de variable } + est := INICIO; { empieza con el estado de INICIO } + poliN := 1; { establece que se procesara el primer polinomio } + for i := 0 to TAM - 1 do { iteracion para inicializar los vectores a cero } + begin { para que los valores que no son especificados no contengan "basura" } + v1[i] := 0; { inicializacion del vector 1 (primer polinomio) } + v2[i] := 0; { inicializacion del vector 2 (segundo polinomio) } + end; + nombreArchivo := ObtenerNombreArchivo; { obtiene el nombre del archivo } + assign(f, nombreArchivo); { asigna la variable al nombre del archivo } + reset(f); { abre el archivo para leerlo desde el principio } + seguir := true; { inicializa seguir e true para comenzar el bucle } + while seguir do begin { continua mientras seguir sea true } + read(f, c); { lee un caracter del archivo de texto } + est := trans(c, est); { establece el nuevo estado de lectura } + case est of { toma una desicion dependiendo del estado en que se encuentre } + INICIO: ; { No hace nada, nunca toma este valor. Solo incica que empezo el proceso } + COEF_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + COEF, COEF_PUNTO: { Si esta leyendo el coeficiente ... } + coeficiente := coeficiente + c; { concatena el caracter a la representacion + de texto del coeficiente } + COEF_FIN: ; { Si termino de leer el coeficiente, no hace nada, la asignacion + se realiza cuando termina de leer el exponente (es necesario + para establecer el indice del vector } + EXP_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + EXP: { Si esta leyendo el exponente ... } + exponente := exponente + c; { concatena el caracter a la representacion + de texto del exponente } + EXP_FIN: { Si termino de leer el exponente, hace las asignaciones correspondientes } + begin { convirtiendo las cadenas de texto en real e integer, segun el caso } + val(coeficiente, rCoef, code); { convierte el coeficiente en real } + val(exponente, iExp, code); { convierte el exponente en integer } + if iExp < TAM { si el exponente es menor que el tama¤o maximo permitido ... } + then if poliN = 1 then v1[iExp] := rCoef { asigna el valor correspondiente } + else v2[iExp] := rCoef { al polinomio correspondiente } + else est := ERROR; { si no es menor, pone el estado en ERROR } + coeficiente := ''; { una vez asignados, vacia los valores del coeficiente y el } + exponente := ''; { exponente para poder realizar las lecturas de los proximos } + end; + EXP_FIN_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + POLI_FIN: { Si termino la lectura de un polinomio ... } + if poliN = 1 then poliN := 2 { si se leyo el 1er polinomio, se indica que se leera el 2do } + else est := FIN; { si no (ya se leyo el segundo), pone el estado en FIN } + FIN: { Si se finalizaron las tareas ... } + begin + { este codigo es el mismo que el de EXP_FIN, se repite aca solo por si el final del + archivo esta pegado al fin del ultimo exponente, en cuyo caso no pasa por el estado + de EXP_FIN (y, por ende, no se pueden hacer las asignaciones correspondientes } + val(coeficiente, rCoef, code); { convierte el coeficiente en real } + val(exponente, iExp, code); { convierte el exponente en integer } + if iExp < TAM { si el exponente es menor que el tama¤o maximo permitido ... } + then if poliN = 1 then v1[iExp] := rCoef { asigna el valor correspondiente } + else v2[iExp] := rCoef { al polinomio correspondiente } + else est := ERROR; { si no es menor, pone el estado en ERROR } + coeficiente := ''; { una vez asignados, vacia los valores del coeficiente y el } + exponente := ''; { exponente para poder realizar las lecturas de los proximos } + { fin del codigo identico a EXP_FIN } + if poliN = 2 then cargarVectores := true { si se leyeron los 2 polinomios, devuelve true } + else cargarVectores := false; { si no se leyeron los dos, devuelve false } + seguir := false; { poner seguir en false para que se termine el bucle } + end; + ERROR: { Si hubo un error ... } + begin + cargarVectores := false; { Se devuelve false (hubo un ERROR, no se leyeron bien los vectores) } + seguir := false; { seguir se pone en false para que termine el bucle } + end; + end; { case } + end; { while } + close(f); { se cierra el archivo de lectura de datos } + end; { cargarVectores } + + {########################################################} + + procedure suma(v1, v2: Vector; var vr: Vector); + { procedimiento que suma dos polinomios. + v1: vector que contiene el primer polinomio a sumar + v2: vector que contiene el segundo polinomio a sumar + vr: vector donde se almacenara el resultado de la suma } + + var + i: integer; { indice para usar en el ciclo for } + + begin { suma } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el vector (de tama¤o maximo TAM) } + vr[i] := v1[i] + v2[i]; { suma los coeficientes de los terminos con igual exponente } + end; { suma } + + {########################################################} + + procedure resta(v1, v2: Vector; var vr: Vector); + { procedimiento que resta dos polinomios. + v1: vector que contiene el primer polinomio + v2: vector que contiene el polinomio para restarle al primero + vr: vector donde se almacenara el resultado de la resta } + + var + i: integer; { indice para usar en el ciclo for } + + begin { resta } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el vector (de tama¤o maximo TAM) } + vr[i] := v1[i] + v2[i]; { resta los coeficientes de los terminos con igual exponente } + end; { resta } + + {########################################################} + + procedure producto(v1, v2: Vector; var vr: Vector); + { procedimiento que multiplica dos polinomios. + v1: vector que contiene el primer polinomio a multiplicar + v2: vector que contiene el segundo polinomio a multiplicar + vr: vector donde se almacenara el resultado de la multiplicacion } + + var + i, j: integer; { indices para usar en los ciclos for } + + begin { producto } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el 1er vector (de tama¤o maximo TAM) } + for i := 0 to TAM - 1 do { recorre el 2do vector (de tama¤o maximo TAM) } + vr[i+j] := vr[i+j] + (v1[i] * v2[j]); + { multiplica los coeficientes de los terminos y lo almacena en la posicion del exponente } + { igual a la suma de los exponentes de v1 y v2, sumando el valor previo de dicha posicion } + end; { producto } + + {########################################################} + + procedure division(v1, v2: Vector; var vr, vResto: Vector); + { procedimiento que divide dos polinomios. + v1: vector que contiene el polinomio denominador + v2: vector que contiene el polinomio divisor + vr: vector donde se almacenara el resultado de la division + vResto: vector donde se almacenara el resto de la division } + var + i, j: integer; { indices para usar en los ciclos for } + vRTmp, { vector auxuliares para almacenar el termino actual del resultado } + vTmp: Vector; { vector auxuliares para almacenar el polinomio que es la multiplicacion del + termino actual del resultado por el divisor } + + begin { division } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vResto); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vTmp); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vRTmp); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := TAM - 1 donwto 0 do { recorre el 1er vector (de tama¤o maximo TAM) de atras para adelante } + if v1[i] <> 0 then break; + { busca empezando por el indice (exponete) mas alto el primer coeficiente no nulo } + { si lo encuentra sale del for dejando al valor de i como el de dicho inidice } + for j := TAM - 1 donwto 0 do { recorre el 2do vector (de tama¤o maximo TAM) de atras para adelante } + if v2[j] <> 0 then break; + { busca empezando por el indice (exponete) mas alto el primer coeficiente no nulo } + { si lo encuentra sale del for dejando al valor de j como el de dicho inidice } + while i >= j do + begin + vr[i-j] := v1[i] / v2[j]; + vRTmp[i-j] := vr[i-j]; + producto(vRTmp, v2, vTmp); + resta(v1, vTmp, v1); + vRTmp[i-j] := 0; + for i := i downto 0 do + if v1[i] <> 0 then break; + { busca empezando por el indice (exponete) mas alto el primer coeficiente no nulo } + { si lo encuentra sale del for dejando al valor de i como el de dicho inidice } + end; { while } + vResto := v1; + end; { division } + + {########################################################} + +{ Continuacion del programa principal } + +var + i: integer; { variable auxiliar } + v1, v2, vResult, vResto: Vector; + resultado: boolean; + +begin { Comienzo del programa principal } + resultado := cargarVectores(v1, v2); + {if not resultado then exit;} + writeln('Polinomio 1:'); + for i := TAM - 1 downto 0 do + if v1[i] <> 0 then + begin + if v1[i] < 0 then write(' - ', abs(v1[i]):1:2) + else write(' + ', v1[i]:1:2); + if i <> 0 then write('*X^', i); + end; + writeln; + writeln('Polinomio 2:'); + for i := TAM - 1 downto 0 do + if v2[i] <> 0 then + begin + if v2[i] < 0 then write(' - ', abs(v2[i]):1:2) + else write(' + ', v2[i]:1:2); + if i <> 0 then write('*X^', i); + end; + writeln; + writeln(ord(resultado)); +end. \ No newline at end of file diff --git a/poli_4.pas b/poli_4.pas new file mode 100644 index 0000000..4dc3460 --- /dev/null +++ b/poli_4.pas @@ -0,0 +1,393 @@ +program Polinomios; + +uses + CRT, DOS; { Declaracion de funciones predefinidas + para crear la interfaz grafica } + +const + VERSION = '0.8.0a (POLI_4)'; { version del programa } + + TAM_MAX = 100; { Tama¤o maximo del vector que almacena + la multiplicacion de polinomios } + TAM = TAM_MAX div 2; { Tama¤o maximo (virtual) del vector que contiene + los vector con los que se va a operar } + CR = chr(13); { caracter de retorno del carro } + LF = chr(10); { caracter de nueva linea } + ENDF = chr(26); { caracter de fin del archivo } + TAB = chr(9); { caracter de tabulacion } + SPACE = chr(32); { caracter de espacio } + +type + { Tipo de dato para identificar el estado de la entrada de datos } + Estado = (INICIO, COEF_BUSCA, COEF, COEF_PUNTO, COEF_FIN, EXP_BUSCA, EXP, EXP_FIN, EXP_FIN_BUSCA, POLI_FIN, FIN, ERROR); + Vector = array [0..TAM_MAX-1] of real; { vector para almacenar los polinomios } + + + {########################################################} + + procedure inicializaVector(var v: Vector); + { procedimiento que inicializa un vector de tama¤o tam } + + var i: integer; { indice para usar en el ciclo for } + + begin { inicializaVector } + for i := 0 to TAM_MAX - 1 do { recorre el vector } + v[i] := 0; { inicializa la variable actual en 0 } + end; { inicializaVector } + + {########################################################} + + function ObtenerNombreArchivo: String; + { funcion que obtiene un nombre de archivo valido (es decir, el nombre + de un archivo que exista) } + + {########################################################} + + function fileExists(FileName: String): Boolean; + { funcion extraida de la ayuda del Turbo Pascal 7 + indica si el archivo existe } + + var + F: file; + + begin + {$I-} + Assign(F, FileName); + FileMode := 0; { Set file access to read only } + Reset(F); + Close(F); + {$I+} + FileExists := (IOResult = 0) and (FileName <> ''); + end; { FileExists } + + {########################################################} + + { Continuacion de la funcion ObtenerNombreArchivo } + const + DEFAUL_FILE_NAME = 'datos.txt'; { nombre del archivo por defecto } + + var + tmp: String; { cadena para almacenar el resultado temporal } + + begin { ObtenerNombreArchivo } + { mensaje para entrada del nombre de archivo } + writeln('Ingrese el nombre del archivo con los datos (ENTER = ', DEFAUL_FILE_NAME, '):'); + readln(tmp); { entrada del nombre de archivo } + if tmp = '' then tmp := DEFAUL_FILE_NAME; { se fija si no se ingreso nada y reasigana el nombre } + while not fileExists(tmp) do { repite el proceso hasta que el archivo exista } + begin + write('El archivo ', tmp, ' no existe. Ingrese un nombre correcto'); + if tmp = DEFAUL_FILE_NAME { si es el nombre de archivo predeterminado } + then { entonces, elije un mensaje apropiado } + write(': ') + else + begin { si no es el predeterminado, muestra otro mensaje } + writeln('.'); + write('(ENTER = ', DEFAUL_FILE_NAME, '): '); + end; + readln(tmp); { vuelve a leer el nombre del archivo para ser verificado } + if tmp = '' then tmp := DEFAUL_FILE_NAME; { asigna como nombre de archivo al predeterminado + si no se escribio nada } + end; { fin del loop de verificacion } + ObtenerNombreArchivo := tmp; { asigna el nombre correcto al valor de salida de la funcion } + end; { ObtenerNombreArchivo } + + {########################################################} + + function trans(c: char; e: Estado): Estado; + { establece el estado en el que se encuentra la lectura } + { c es el caracter que se leyo, e es el estado actual de la lectura } + + begin { trans } + case e of { acciona segun es estado actual de la lectura } + INICIO: { estado de inicio de la lectura } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un numero (o negativo), empieza a leer el coeficiente } + SPACE, TAB, CR, LF: trans := COEF_BUSCA; { si es un caracter tipo "espacio", busca el prox. coef. } + else trans := ERROR; { si es otro, da ERROR } + end; + COEF_BUSCA: { estado de busqueda del primer ceoficiente del polinomio } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un numero (o negativo), empieza a leer el coeficiente } + SPACE, TAB, CR, LF: trans := COEF_BUSCA; { si es un caracter tupo "espacio", sigue buscando } + ENDF: trans := FIN; { si es el caracter de fin de archivo, pasa al estado de tarea finalizada } + else trans := ERROR; { si es otro, da ERROR } + end; + COEF: { estado de lectura del coeficiente del termino del polinomio (sin punto decimal) } + case c of { acciona segun el caracter leido } + '0'..'9': trans := COEF; { si es un numero sigue con el mismo estado } + '.': trans := COEF_PUNTO; { si es punto cambia al estado COEF_PUNTO } + SPACE, TAB: trans := COEF_FIN; { si es un espacio o un tabulador, finaliza la lectura del coeficiente } + else trans := ERROR; { si es otra cosa, pasa a estado de error } + end; + COEF_PUNTO: { estado de lectura del coeficiente del termino del polinomio (con punto decimal) } + case c of { acciona segun el caracter leido } + '0'..'9': trans := COEF_PUNTO; { si es un numero sigue con el mismo estado } + SPACE, TAB: trans := COEF_FIN; { si es un espacio o un tabulador, finaliza la lectura del coeficiente } + else trans := ERROR; { si es otra cosa, pasa a estado de error } + end; + COEF_FIN: { estado de fin de la lectura del coeficiente del termino del polinomio } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si el caracter es un numero establece el estado en EXP (exponente) } + SPACE, TAB: trans := EXP_BUSCA; { si es un espacio o tabulador, pasa a buscar el proximo exponente } + else trans := ERROR; { si no es ninguno de los anteriores, el estado pasa a ERROR } + end; + EXP_BUSCA: { estado de busqueda del proximo exponente } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si el caracter es un numero, empieza a leer el exponente } + SPACE, TAB: trans := EXP_BUSCA; { si es un espacio o tabulador, sigue buscando } + else trans := ERROR; { si no es ninguno de los anteriores, el estado pasa a ERROR } + end; + EXP: { estado de lectura del exponente del termino actual del polinomio } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si es un digito, sigue en el mismo estado } + CR: trans := EXP_FIN; { si es un ratorno de carro, finaliza el exponente + (quiere decir que hubo un ) } + ENDF: trans := FIN; { si es el final del archivo, se indica que termino su tarea } + else trans := ERROR; { si es otra cosa, devuelve ERROR } + end; + EXP_FIN: { estado de fin de la lectura del exponente del termino actual del polinomio } + if c = LF then trans := EXP_FIN_BUSCA { debe ser un caracter de nueva linea (para completar el ) } + else trans := ERROR; { si no lo es, devuelve ERROR } + EXP_FIN_BUSCA: { estado de fin de lectura de la nueva linea (luego de finalizar el exponente + ahora decide si termino el polinomio o si sigue leyendo el proximo coeficiente } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un digito (o negativo), pasa a leer en proximo coeficiente } + CR: trans := POLI_FIN; { si es un ratorno de carro o nueva linea, finaliza el polinomio } + else trans := ERROR; { si es otra cosa, devuelve ERROR } + end; + POLI_FIN: { estado de finalizacion del polinomio actual } + if c = LF then trans := COEF_BUSCA { debe ser un caracter de nueva linea (para completar el ), + entonces pasa a buscar el primer coeficiente del nuevo polinomio } + else trans := ERROR; { si no lo es, devuelve ERROR } + FIN: { estado que adquiere cuando se finalizo la tarea } + trans := FIN; { se queda en este estado avisando que termino su tarea } + else { otro estado, no deberia ocurrir, salvo que se le pase a la funcion un estado de ERROR } + trans := ERROR; { si es otro, da ERROR } + end; { case } + end; { trans } + + {########################################################} + + function cargarVectores(var v1, v2: Vector): boolean; + { Funcion que abre el archivo de texto con los datos, lo carga en el vector procesandolo debidamente a medida + que lo lee y, al finalizar, cierra el archivo de texto. + v1 es el primer vector a cargar + v2 es el segundo vector a cargar + devuelve true si la lectura fue hecha con exito, false si hubo un error } + + var + f: Text; { archivo de texto con los datos } + c: char; { caracter que se extrae del archivo de texto } + nombreArchivo: String; { nombre del archivo de datos } + est: Estado; { Indicador del estado actual de la lectura } + seguir: boolean; { indicador para saber si debe seguir con el proceso } + i, { indice del vector del polinomio para ser inicializado } + iExp, { valor temporal para almacenar al exponente } + code, { almacena el resultado de la funcion val (no se usa porque los + datos ya estan validados } + poliN: integer; { numero del polinomio que se esta leyendo } + rCoef: real; { valor temporal para almacenar al coeficiente } + exponente, { string que representa al exponente leido } + coeficiente: String; { string que representa al coeficiente leido } + + begin { cargarVectores } + rCoef := 0.0; { inicializacion de variable } + iExp := 0; { inicializacion de variable } + coeficiente := ''; { inicializacion de variable } + exponente := ''; { inicializacion de variable } + est := INICIO; { empieza con el estado de INICIO } + poliN := 1; { establece que se procesara el primer polinomio } + inicializaVector(v1); { inicializacion del vector 1 (primer polinomio) } + inicializaVector(v2); { inicializacion del vector 2 (segundo polinomio) } + nombreArchivo := ObtenerNombreArchivo; { obtiene el nombre del archivo } + assign(f, nombreArchivo); { asigna la variable al nombre del archivo } + reset(f); { abre el archivo para leerlo desde el principio } + seguir := true; { inicializa seguir e true para comenzar el bucle } + while seguir do begin { continua mientras seguir sea true } + read(f, c); { lee un caracter del archivo de texto } + est := trans(c, est); { establece el nuevo estado de lectura } + case est of { toma una desicion dependiendo del estado en que se encuentre } + INICIO: ; { No hace nada, nunca toma este valor. Solo incica que empezo el proceso } + COEF_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + COEF, COEF_PUNTO: { Si esta leyendo el coeficiente ... } + coeficiente := coeficiente + c; { concatena el caracter a la representacion + de texto del coeficiente } + COEF_FIN: ; { Si termino de leer el coeficiente, no hace nada, la asignacion + se realiza cuando termina de leer el exponente (es necesario + para establecer el indice del vector } + EXP_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + EXP: { Si esta leyendo el exponente ... } + exponente := exponente + c; { concatena el caracter a la representacion + de texto del exponente } + EXP_FIN: { Si termino de leer el exponente, hace las asignaciones correspondientes } + begin { convirtiendo las cadenas de texto en real e integer, segun el caso } + val(coeficiente, rCoef, code); { convierte el coeficiente en real } + val(exponente, iExp, code); { convierte el exponente en integer } + if iExp < TAM { si el exponente es menor que el tama¤o maximo permitido ... } + then if poliN = 1 then v1[iExp] := rCoef { asigna el valor correspondiente } + else v2[iExp] := rCoef { al polinomio correspondiente } + else est := ERROR; { si no es menor, pone el estado en ERROR } + coeficiente := ''; { una vez asignados, vacia los valores del coeficiente y el } + exponente := ''; { exponente para poder realizar las lecturas de los proximos } + end; + EXP_FIN_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + POLI_FIN: { Si termino la lectura de un polinomio ... } + if poliN = 1 then poliN := 2 { si se leyo el 1er polinomio, se indica que se leera el 2do } + else est := FIN; { si no (ya se leyo el segundo), pone el estado en FIN } + FIN: { Si se finalizaron las tareas ... } + begin + { este codigo es el mismo que el de EXP_FIN, se repite aca solo por si el final del + archivo esta pegado al fin del ultimo exponente, en cuyo caso no pasa por el estado + de EXP_FIN (y, por ende, no se pueden hacer las asignaciones correspondientes } + val(coeficiente, rCoef, code); { convierte el coeficiente en real } + val(exponente, iExp, code); { convierte el exponente en integer } + if iExp < TAM { si el exponente es menor que el tama¤o maximo permitido ... } + then if poliN = 1 then v1[iExp] := rCoef { asigna el valor correspondiente } + else v2[iExp] := rCoef { al polinomio correspondiente } + else est := ERROR; { si no es menor, pone el estado en ERROR } + coeficiente := ''; { una vez asignados, vacia los valores del coeficiente y el } + exponente := ''; { exponente para poder realizar las lecturas de los proximos } + { fin del codigo identico a EXP_FIN } + if poliN = 2 then cargarVectores := true { si se leyeron los 2 polinomios, devuelve true } + else cargarVectores := false; { si no se leyeron los dos, devuelve false } + seguir := false; { poner seguir en false para que se termine el bucle } + end; + ERROR: { Si hubo un error ... } + begin + cargarVectores := false; { Se devuelve false (hubo un ERROR, no se leyeron bien los vectores) } + seguir := false; { seguir se pone en false para que termine el bucle } + end; + end; { case } + end; { while } + close(f); { se cierra el archivo de lectura de datos } + end; { cargarVectores } + + {########################################################} + + procedure suma(v1, v2: Vector; var vr: Vector); + { procedimiento que suma dos polinomios. + v1: vector que contiene el primer polinomio a sumar + v2: vector que contiene el segundo polinomio a sumar + vr: vector donde se almacenara el resultado de la suma } + + var + i: integer; { indice para usar en el ciclo for } + + begin { suma } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el vector (de tama¤o maximo TAM) } + vr[i] := v1[i] + v2[i]; { suma los coeficientes de los terminos con igual exponente } + end; { suma } + + {########################################################} + + procedure resta(v1, v2: Vector; var vr: Vector); + { procedimiento que resta dos polinomios. + v1: vector que contiene el primer polinomio + v2: vector que contiene el polinomio para restarle al primero + vr: vector donde se almacenara el resultado de la resta } + + var + i: integer; { indice para usar en el ciclo for } + + begin { resta } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el vector (de tama¤o maximo TAM) } + vr[i] := v1[i] + v2[i]; { resta los coeficientes de los terminos con igual exponente } + end; { resta } + + {########################################################} + + procedure producto(v1, v2: Vector; var vr: Vector); + { procedimiento que multiplica dos polinomios. + v1: vector que contiene el primer polinomio a multiplicar + v2: vector que contiene el segundo polinomio a multiplicar + vr: vector donde se almacenara el resultado de la multiplicacion } + + var + i, j: integer; { indices para usar en los ciclos for } + + begin { producto } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el 1er vector (de tama¤o maximo TAM) } + for i := 0 to TAM - 1 do { recorre el 2do vector (de tama¤o maximo TAM) } + vr[i+j] := vr[i+j] + (v1[i] * v2[j]); + { multiplica los coeficientes de los terminos y lo almacena en la posicion del exponente } + { igual a la suma de los exponentes de v1 y v2, sumando el valor previo de dicha posicion } + end; { producto } + + {########################################################} + + procedure division(v1, v2: Vector; var vr, vResto: Vector); + { procedimiento que divide dos polinomios. + v1: vector que contiene el polinomio denominador + v2: vector que contiene el polinomio divisor + vr: vector donde se almacenara el resultado de la division + vResto: vector donde se almacenara el resto de la division } + var + i, j: integer; { indices para usar en los ciclos for } + vRTmp, { vector auxuliares para almacenar el termino actual del resultado } + vTmp: Vector; { vector auxuliares para almacenar el polinomio que es la multiplicacion del + termino actual del resultado por el divisor } + + begin { division } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vResto); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vTmp); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vRTmp); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := TAM - 1 downto 0 do { recorre el 1er vector (de tama¤o maximo TAM) de atras para adelante } + if v1[i] <> 0 then break; + { busca empezando por el indice (exponete) mas alto el primer coeficiente no nulo } + { si lo encuentra sale del for dejando al valor de i como el de dicho inidice } + for j := TAM - 1 downto 0 do { recorre el 2do vector (de tama¤o maximo TAM) de atras para adelante } + if v2[j] <> 0 then break; + { busca empezando por el indice (exponete) mas alto el primer coeficiente no nulo } + { si lo encuentra sale del for dejando al valor de j como el de dicho inidice } + while i >= j do + begin + vr[i-j] := v1[i] / v2[j]; + vRTmp[i-j] := vr[i-j]; + producto(vRTmp, v2, vTmp); + resta(v1, vTmp, v1); + vRTmp[i-j] := 0; + for i := i downto 0 do + if v1[i] <> 0 then break; + { busca empezando por el indice (exponete) mas alto el primer coeficiente no nulo } + { si lo encuentra sale del for dejando al valor de i como el de dicho inidice } + end; { while } + vResto := v1; + end; { division } + + {########################################################} + +{ Continuacion del programa principal } + +var + i: integer; { variable auxiliar } + v1, v2, vResult, vResto: Vector; + resultado: boolean; + +begin { Comienzo del programa principal } + resultado := cargarVectores(v1, v2); + {if not resultado then exit;} + writeln('Polinomio 1:'); + for i := TAM - 1 downto 0 do + if v1[i] <> 0 then + begin + if v1[i] < 0 then write(' - ', abs(v1[i]):1:2) + else write(' + ', v1[i]:1:2); + if i <> 0 then write('*X^', i); + end; + writeln; + writeln('Polinomio 2:'); + for i := TAM - 1 downto 0 do + if v2[i] <> 0 then + begin + if v2[i] < 0 then write(' - ', abs(v2[i]):1:2) + else write(' + ', v2[i]:1:2); + if i <> 0 then write('*X^', i); + end; + writeln; + writeln(ord(resultado)); +end. \ No newline at end of file diff --git a/poli_5.pas b/poli_5.pas new file mode 100644 index 0000000..e392da1 --- /dev/null +++ b/poli_5.pas @@ -0,0 +1,401 @@ +program Polinomios; + +uses + CRT, DOS; { Declaracion de funciones predefinidas + para crear la interfaz grafica } + +const + VERSION = '0.8.2a (POLI_5)'; { version del programa } + + TAM_MAX = 100; { Tama¤o maximo del vector que almacena + la multiplicacion de polinomios } + TAM = TAM_MAX div 2; { Tama¤o maximo (virtual) del vector que contiene + los vector con los que se va a operar } + CR = chr(13); { caracter de retorno del carro } + LF = chr(10); { caracter de nueva linea } + ENDF = chr(26); { caracter de fin del archivo } + TAB = chr(9); { caracter de tabulacion } + SPACE = chr(32); { caracter de espacio } + +type + { Tipo de dato para identificar el estado de la entrada de datos } + Estado = (INICIO, COEF_BUSCA, COEF, COEF_PUNTO, COEF_FIN, EXP_BUSCA, EXP, EXP_FIN, EXP_FIN_BUSCA, POLI_FIN, FIN, ERROR); + Vector = array [0..TAM_MAX-1] of real; { vector para almacenar los polinomios } + + + {########################################################} + + procedure muestraVector(var v: Vector; s: String); + { procedimiento que imprime el polinomio v en pantalla con un titulo s } + + var i: integer; { indice para usar en el ciclo for } + + begin { muestraVector } + writeln(s); { mustra el mensaje } + for i := TAM_MAX - 1 downto 0 do { recorre el vector de atras para adelante } + if v[i] <> 0 then { si el coeficiente no es nulo, muestra ... } + begin + if v[i] < 0 then write(' - ', abs(v[i]):1:2) { si el coeficiente en negativo } + else write(' + ', v[i]:1:2); { si el coeficiente en positivo } + case i of + 0: ; { si el exponente es nulo, mustra solo el coeficiente } + 1: write(' X'); { si el exponente es 1, mustra el coeficiente y X } + else write(' X^', i); { si el exponente es mayor que 1, mustra el coeficiente y X^exp } + end; { case } + end; { if } + writeln; + end; { muestraVector } + + {########################################################} + + procedure inicializaVector(var v: Vector); + { procedimiento que inicializa un vector de tama¤o tam } + + var i: integer; { indice para usar en el ciclo for } + + begin { inicializaVector } + for i := 0 to TAM_MAX - 1 do { recorre el vector } + v[i] := 0; { inicializa la variable actual en 0 } + end; { inicializaVector } + + {########################################################} + + function ObtenerNombreArchivo: String; + { funcion que obtiene un nombre de archivo valido (es decir, el nombre + de un archivo que exista) } + + {########################################################} + + function fileExists(FileName: String): Boolean; + { funcion extraida de la ayuda del Turbo Pascal 7 + indica si el archivo existe } + + var + F: file; + + begin + {$I-} + Assign(F, FileName); + FileMode := 0; { Set file access to read only } + Reset(F); + Close(F); + {$I+} + FileExists := (IOResult = 0) and (FileName <> ''); + end; { FileExists } + + {########################################################} + + { Continuacion de la funcion ObtenerNombreArchivo } + const + DEFAUL_FILE_NAME = 'datos.txt'; { nombre del archivo por defecto } + + var + tmp: String; { cadena para almacenar el resultado temporal } + + begin { ObtenerNombreArchivo } + { mensaje para entrada del nombre de archivo } + writeln('Ingrese el nombre del archivo con los datos (ENTER = ', DEFAUL_FILE_NAME, '):'); + readln(tmp); { entrada del nombre de archivo } + if tmp = '' then tmp := DEFAUL_FILE_NAME; { se fija si no se ingreso nada y reasigana el nombre } + while not fileExists(tmp) do { repite el proceso hasta que el archivo exista } + begin + write('El archivo ', tmp, ' no existe. Ingrese un nombre correcto'); + if tmp = DEFAUL_FILE_NAME { si es el nombre de archivo predeterminado } + then { entonces, elije un mensaje apropiado } + write(': ') + else + begin { si no es el predeterminado, muestra otro mensaje } + writeln('.'); + write('(ENTER = ', DEFAUL_FILE_NAME, '): '); + end; + readln(tmp); { vuelve a leer el nombre del archivo para ser verificado } + if tmp = '' then tmp := DEFAUL_FILE_NAME; { asigna como nombre de archivo al predeterminado + si no se escribio nada } + end; { fin del loop de verificacion } + ObtenerNombreArchivo := tmp; { asigna el nombre correcto al valor de salida de la funcion } + end; { ObtenerNombreArchivo } + + {########################################################} + + function trans(c: char; e: Estado): Estado; + { establece el estado en el que se encuentra la lectura } + { c es el caracter que se leyo, e es el estado actual de la lectura } + + begin { trans } + case e of { acciona segun es estado actual de la lectura } + INICIO: { estado de inicio de la lectura } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un numero (o negativo), empieza a leer el coeficiente } + SPACE, TAB, CR, LF: trans := COEF_BUSCA; { si es un caracter tipo "espacio", busca el prox. coef. } + else trans := ERROR; { si es otro, da ERROR } + end; + COEF_BUSCA: { estado de busqueda del primer ceoficiente del polinomio } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un numero (o negativo), empieza a leer el coeficiente } + SPACE, TAB, CR, LF: trans := COEF_BUSCA; { si es un caracter tupo "espacio", sigue buscando } + ENDF: trans := FIN; { si es el caracter de fin de archivo, pasa al estado de tarea finalizada } + else trans := ERROR; { si es otro, da ERROR } + end; + COEF: { estado de lectura del coeficiente del termino del polinomio (sin punto decimal) } + case c of { acciona segun el caracter leido } + '0'..'9': trans := COEF; { si es un numero sigue con el mismo estado } + '.': trans := COEF_PUNTO; { si es punto cambia al estado COEF_PUNTO } + SPACE, TAB: trans := COEF_FIN; { si es un espacio o un tabulador, finaliza la lectura del coeficiente } + else trans := ERROR; { si es otra cosa, pasa a estado de error } + end; + COEF_PUNTO: { estado de lectura del coeficiente del termino del polinomio (con punto decimal) } + case c of { acciona segun el caracter leido } + '0'..'9': trans := COEF_PUNTO; { si es un numero sigue con el mismo estado } + SPACE, TAB: trans := COEF_FIN; { si es un espacio o un tabulador, finaliza la lectura del coeficiente } + else trans := ERROR; { si es otra cosa, pasa a estado de error } + end; + COEF_FIN: { estado de fin de la lectura del coeficiente del termino del polinomio } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si el caracter es un numero establece el estado en EXP (exponente) } + SPACE, TAB: trans := EXP_BUSCA; { si es un espacio o tabulador, pasa a buscar el proximo exponente } + else trans := ERROR; { si no es ninguno de los anteriores, el estado pasa a ERROR } + end; + EXP_BUSCA: { estado de busqueda del proximo exponente } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si el caracter es un numero, empieza a leer el exponente } + SPACE, TAB: trans := EXP_BUSCA; { si es un espacio o tabulador, sigue buscando } + else trans := ERROR; { si no es ninguno de los anteriores, el estado pasa a ERROR } + end; + EXP: { estado de lectura del exponente del termino actual del polinomio } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si es un digito, sigue en el mismo estado } + CR: trans := EXP_FIN; { si es un ratorno de carro, finaliza el exponente + (quiere decir que hubo un ) } + ENDF: trans := FIN; { si es el final del archivo, se indica que termino su tarea } + else trans := ERROR; { si es otra cosa, devuelve ERROR } + end; + EXP_FIN: { estado de fin de la lectura del exponente del termino actual del polinomio } + if c = LF then trans := EXP_FIN_BUSCA { debe ser un caracter de nueva linea (para completar el ) } + else trans := ERROR; { si no lo es, devuelve ERROR } + EXP_FIN_BUSCA: { estado de fin de lectura de la nueva linea (luego de finalizar el exponente + ahora decide si termino el polinomio o si sigue leyendo el proximo coeficiente } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un digito (o negativo), pasa a leer en proximo coeficiente } + CR: trans := POLI_FIN; { si es un ratorno de carro o nueva linea, finaliza el polinomio } + else trans := ERROR; { si es otra cosa, devuelve ERROR } + end; + POLI_FIN: { estado de finalizacion del polinomio actual } + if c = LF then trans := COEF_BUSCA { debe ser un caracter de nueva linea (para completar el ), + entonces pasa a buscar el primer coeficiente del nuevo polinomio } + else trans := ERROR; { si no lo es, devuelve ERROR } + FIN: { estado que adquiere cuando se finalizo la tarea } + trans := FIN; { se queda en este estado avisando que termino su tarea } + else { otro estado, no deberia ocurrir, salvo que se le pase a la funcion un estado de ERROR } + trans := ERROR; { si es otro, da ERROR } + end; { case } + end; { trans } + + {########################################################} + + function cargarVectores(var v1, v2: Vector): boolean; + { Funcion que abre el archivo de texto con los datos, lo carga en el vector procesandolo debidamente a medida + que lo lee y, al finalizar, cierra el archivo de texto. + v1 es el primer vector a cargar + v2 es el segundo vector a cargar + devuelve true si la lectura fue hecha con exito, false si hubo un error } + + var + f: Text; { archivo de texto con los datos } + c: char; { caracter que se extrae del archivo de texto } + nombreArchivo: String; { nombre del archivo de datos } + est: Estado; { Indicador del estado actual de la lectura } + seguir: boolean; { indicador para saber si debe seguir con el proceso } + i, { indice del vector del polinomio para ser inicializado } + iExp, { valor temporal para almacenar al exponente } + code, { almacena el resultado de la funcion val (no se usa porque los + datos ya estan validados } + poliN: integer; { numero del polinomio que se esta leyendo } + rCoef: real; { valor temporal para almacenar al coeficiente } + exponente, { string que representa al exponente leido } + coeficiente: String; { string que representa al coeficiente leido } + + begin { cargarVectores } + rCoef := 0.0; { inicializacion de variable } + iExp := 0; { inicializacion de variable } + coeficiente := ''; { inicializacion de variable } + exponente := ''; { inicializacion de variable } + est := INICIO; { empieza con el estado de INICIO } + poliN := 1; { establece que se procesara el primer polinomio } + inicializaVector(v1); { inicializacion del vector 1 (primer polinomio) } + inicializaVector(v2); { inicializacion del vector 2 (segundo polinomio) } + nombreArchivo := ObtenerNombreArchivo; { obtiene el nombre del archivo } + assign(f, nombreArchivo); { asigna la variable al nombre del archivo } + reset(f); { abre el archivo para leerlo desde el principio } + seguir := true; { inicializa seguir e true para comenzar el bucle } + while seguir do begin { continua mientras seguir sea true } + read(f, c); { lee un caracter del archivo de texto } + est := trans(c, est); { establece el nuevo estado de lectura } + case est of { toma una desicion dependiendo del estado en que se encuentre } + INICIO: ; { No hace nada, nunca toma este valor. Solo incica que empezo el proceso } + COEF_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + COEF, COEF_PUNTO: { Si esta leyendo el coeficiente ... } + coeficiente := coeficiente + c; { concatena el caracter a la representacion + de texto del coeficiente } + COEF_FIN: ; { Si termino de leer el coeficiente, no hace nada, la asignacion + se realiza cuando termina de leer el exponente (es necesario + para establecer el indice del vector } + EXP_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + EXP: { Si esta leyendo el exponente ... } + exponente := exponente + c; { concatena el caracter a la representacion + de texto del exponente } + EXP_FIN: { Si termino de leer el exponente, hace las asignaciones correspondientes } + begin { convirtiendo las cadenas de texto en real e integer, segun el caso } + val(coeficiente, rCoef, code); { convierte el coeficiente en real } + val(exponente, iExp, code); { convierte el exponente en integer } + if iExp < TAM { si el exponente es menor que el tama¤o maximo permitido ... } + then if poliN = 1 then v1[iExp] := rCoef { asigna el valor correspondiente } + else v2[iExp] := rCoef { al polinomio correspondiente } + else est := ERROR; { si no es menor, pone el estado en ERROR } + coeficiente := ''; { una vez asignados, vacia los valores del coeficiente y el } + exponente := ''; { exponente para poder realizar las lecturas de los proximos } + end; + EXP_FIN_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + POLI_FIN: { Si termino la lectura de un polinomio ... } + if poliN = 1 then poliN := 2 { si se leyo el 1er polinomio, se indica que se leera el 2do } + else est := FIN; { si no (ya se leyo el segundo), pone el estado en FIN } + FIN: { Si se finalizaron las tareas ... } + begin + { este codigo es el mismo que el de EXP_FIN, se repite aca solo por si el final del + archivo esta pegado al fin del ultimo exponente, en cuyo caso no pasa por el estado + de EXP_FIN (y, por ende, no se pueden hacer las asignaciones correspondientes } + val(coeficiente, rCoef, code); { convierte el coeficiente en real } + val(exponente, iExp, code); { convierte el exponente en integer } + if iExp < TAM { si el exponente es menor que el tama¤o maximo permitido ... } + then if poliN = 1 then v1[iExp] := rCoef { asigna el valor correspondiente } + else v2[iExp] := rCoef { al polinomio correspondiente } + else est := ERROR; { si no es menor, pone el estado en ERROR } + coeficiente := ''; { una vez asignados, vacia los valores del coeficiente y el } + exponente := ''; { exponente para poder realizar las lecturas de los proximos } + { fin del codigo identico a EXP_FIN } + if poliN = 2 then cargarVectores := true { si se leyeron los 2 polinomios, devuelve true } + else cargarVectores := false; { si no se leyeron los dos, devuelve false } + seguir := false; { poner seguir en false para que se termine el bucle } + end; + ERROR: { Si hubo un error ... } + begin + cargarVectores := false; { Se devuelve false (hubo un ERROR, no se leyeron bien los vectores) } + seguir := false; { seguir se pone en false para que termine el bucle } + end; + end; { case } + end; { while } + close(f); { se cierra el archivo de lectura de datos } + end; { cargarVectores } + + {########################################################} + + procedure suma(v1, v2: Vector; var vr: Vector); + { procedimiento que suma dos polinomios. + v1: vector que contiene el primer polinomio a sumar + v2: vector que contiene el segundo polinomio a sumar + vr: vector donde se almacenara el resultado de la suma } + + var + i: integer; { indice para usar en el ciclo for } + + begin { suma } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el vector (de tama¤o maximo TAM) } + vr[i] := v1[i] + v2[i]; { suma los coeficientes de los terminos con igual exponente } + end; { suma } + + {########################################################} + + procedure resta(v1, v2: Vector; var vr: Vector); + { procedimiento que resta dos polinomios. + v1: vector que contiene el primer polinomio + v2: vector que contiene el polinomio para restarle al primero + vr: vector donde se almacenara el resultado de la resta } + + var + i: integer; { indice para usar en el ciclo for } + + begin { resta } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el vector (de tama¤o maximo TAM) } + vr[i] := v1[i] + v2[i]; { resta los coeficientes de los terminos con igual exponente } + end; { resta } + + {########################################################} + + procedure producto(v1, v2: Vector; var vr: Vector); + { procedimiento que multiplica dos polinomios. + v1: vector que contiene el primer polinomio a multiplicar + v2: vector que contiene el segundo polinomio a multiplicar + vr: vector donde se almacenara el resultado de la multiplicacion } + + var + i, j: integer; { indices para usar en los ciclos for } + + begin { producto } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el 1er vector (de tama¤o maximo TAM) } + for i := 0 to TAM - 1 do { recorre el 2do vector (de tama¤o maximo TAM) } + vr[i+j] := vr[i+j] + (v1[i] * v2[j]); + { multiplica los coeficientes de los terminos y lo almacena en la posicion del exponente } + { igual a la suma de los exponentes de v1 y v2, sumando el valor previo de dicha posicion } + end; { producto } + + {########################################################} + + procedure division(v1, v2: Vector; var vr, vResto: Vector); + { procedimiento que divide dos polinomios. + v1: vector que contiene el polinomio denominador + v2: vector que contiene el polinomio divisor + vr: vector donde se almacenara el resultado de la division + vResto: vector donde se almacenara el resto de la division } + var + i, j: integer; { indices para usar en los ciclos for } + vRTmp, { vector auxuliares para almacenar el termino actual del resultado } + vTmp: Vector; { vector auxuliares para almacenar el polinomio que es la multiplicacion del + termino actual del resultado por el divisor } + + begin { division } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vResto); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vTmp); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vRTmp); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := TAM - 1 downto 0 do { recorre el 1er vector (de tama¤o maximo TAM) de atras para adelante } + if v1[i] <> 0 then break; + { busca empezando por el indice (exponete) mas alto el primer coeficiente no nulo } + { si lo encuentra sale del for dejando al valor de i como el de dicho inidice } + for j := TAM - 1 downto 0 do { recorre el 2do vector (de tama¤o maximo TAM) de atras para adelante } + if v2[j] <> 0 then break; + { busca empezando por el indice (exponete) mas alto el primer coeficiente no nulo } + { si lo encuentra sale del for dejando al valor de j como el de dicho inidice } + while i >= j do + begin + vr[i-j] := v1[i] / v2[j]; + vRTmp[i-j] := vr[i-j]; + producto(vRTmp, v2, vTmp); + resta(v1, vTmp, v1); + vRTmp[i-j] := 0; + for i := i downto 0 do + if v1[i] <> 0 then break; + { busca empezando por el indice (exponete) mas alto el primer coeficiente no nulo } + { si lo encuentra sale del for dejando al valor de i como el de dicho inidice } + end; { while } + vResto := v1; + end; { division } + + {########################################################} + +{ Continuacion del programa principal } + +var + i: integer; { variable auxiliar } + v1, v2, vResult, vResto: Vector; + resultado: boolean; + +begin { Comienzo del programa principal } + resultado := cargarVectores(v1, v2); + if not resultado then exit; + muestraVector(v1, 'Polinomio 1 ='); + muestraVector(v2, 'Polinomio 2 ='); + suma(v1, v2, vResult); + muestraVector(vResult, 'Polinomio 1 + Polinomio 2 ='); +end. \ No newline at end of file diff --git a/poli_6.pas b/poli_6.pas new file mode 100644 index 0000000..2e5294a --- /dev/null +++ b/poli_6.pas @@ -0,0 +1,432 @@ +program Polinomios; + +uses + CRT, DOS; { Declaracion de funciones predefinidas + para crear la interfaz grafica } + +const + VERSION = '0.8.4a (POLI_6)'; { version del programa } + + TAM_MAX = 100; { Tama¤o maximo del vector que almacena + la multiplicacion de polinomios } + TAM = TAM_MAX div 2; { Tama¤o maximo (virtual) del vector que contiene + los vector con los que se va a operar } + CR = chr(13); { caracter de retorno del carro } + LF = chr(10); { caracter de nueva linea } + ENDF = chr(26); { caracter de fin del archivo } + TAB = chr(9); { caracter de tabulacion } + SPACE = chr(32); { caracter de espacio } + +type + { Tipo de dato para identificar el estado de la entrada de datos } + Estado = (INICIO, COEF_BUSCA, COEF, COEF_PUNTO, COEF_FIN, EXP_BUSCA, EXP, EXP_FIN, EXP_FIN_BUSCA, POLI_FIN, FIN, ERROR); + Vector = array [0..TAM_MAX-1] of real; { vector para almacenar los polinomios } + + + {########################################################} + + procedure muestraVector(var v: Vector; s: String); + { procedimiento que imprime el polinomio v en pantalla con un titulo s } + + {########################################################} + + function exponente(exp: integer): String; + + var + s: String; { variable temporal } + + begin { exponente } + case exp of + 0: exponente := ''; { si el exponente es nulo, mustra solo el coeficiente } + 1: exponente := 'X'; { si el exponente es 1, mustra el coeficiente y X } + 2: exponente := 'Xý'; { si el exponente es 2, mustra el coeficiente y Xý } + else begin + str(exp, s); { convierte al exponente en string } + exponente := 'X^' + s; { si el exponente es mayor que 1, mustra el coeficiente y X^exp } + end; { else } + end; { case } + end; { exponente } + + {########################################################} + + + var + i: integer; { indice para usar en el ciclo for } + + begin { muestraVector } + writeln(s); { mustra el mensaje } + write(' '); { deja un espacio antes de empezar a mostrar el polinomio } + for i := TAM_MAX - 1 downto 0 do { recorre el vector de atras para adelante } + if v[i] <> 0 then break; { si el coeficiente no es nulo, termina el for dejando a i en ese indice } + if (abs(v[i]) <> 1) or (i = 0) { si el modulo del coeficiente es distinto de 1 o si el exp. es 0 } + then if abs(v[i]) - trunc(abs(v[i])) = 0 then write(trunc(v[i]):1, ' ') { imprime si es un numero entero } + else write(v[i]:1:2, ' ') { imprime si es un numero real } + else if v[i] = -1 then write('-'); { si es -1 entonces solo escribe el signo del termino } + write(exponente(i)); + for i := i - 1 downto 0 do { recorre el vector de atras para adelante } + if v[i] <> 0 then { si el coeficiente no es nulo, termina el for dejando a i en ese indice } + begin + if v[i] < 0 { si el coeficiente en negativo } + then write(' - ') { le agrega el signo - } + else write(' + '); { si no, le agrega el signo + } + if (abs(v[i]) <> 1) or (i = 0) then { si el modulo del coeficiente es distinto de 1 o si el exp. es 0 } + if abs(v[i]) - trunc(abs(v[i])) = 0 then write(trunc(abs(v[i])):1, ' ') { imprime si es un entero } + else write(abs(v[i]):1:2, ' '); { imprime si es un real } + write(exponente(i)); + end; { if } + writeln; + end; { muestraVector } + + {########################################################} + + procedure inicializaVector(var v: Vector); + { procedimiento que inicializa un vector de tama¤o tam } + + var i: integer; { indice para usar en el ciclo for } + + begin { inicializaVector } + for i := 0 to TAM_MAX - 1 do { recorre el vector } + v[i] := 0; { inicializa la variable actual en 0 } + end; { inicializaVector } + + {########################################################} + + function ObtenerNombreArchivo: String; + { funcion que obtiene un nombre de archivo valido (es decir, el nombre + de un archivo que exista) } + + {########################################################} + + function fileExists(FileName: String): Boolean; + { funcion extraida de la ayuda del Turbo Pascal 7 + indica si el archivo existe } + + var + F: file; + + begin + {$I-} + Assign(F, FileName); + FileMode := 0; { Set file access to read only } + Reset(F); + Close(F); + {$I+} + FileExists := (IOResult = 0) and (FileName <> ''); + end; { FileExists } + + {########################################################} + + { Continuacion de la funcion ObtenerNombreArchivo } + const + DEFAUL_FILE_NAME = 'datos.txt'; { nombre del archivo por defecto } + + var + tmp: String; { cadena para almacenar el resultado temporal } + + begin { ObtenerNombreArchivo } + { mensaje para entrada del nombre de archivo } + writeln('Ingrese el nombre del archivo con los datos (ENTER = ', DEFAUL_FILE_NAME, '):'); + readln(tmp); { entrada del nombre de archivo } + if tmp = '' then tmp := DEFAUL_FILE_NAME; { se fija si no se ingreso nada y reasigana el nombre } + while not fileExists(tmp) do { repite el proceso hasta que el archivo exista } + begin + write('El archivo ', tmp, ' no existe. Ingrese un nombre correcto'); + if tmp = DEFAUL_FILE_NAME { si es el nombre de archivo predeterminado } + then { entonces, elije un mensaje apropiado } + write(': ') + else + begin { si no es el predeterminado, muestra otro mensaje } + writeln('.'); + write('(ENTER = ', DEFAUL_FILE_NAME, '): '); + end; + readln(tmp); { vuelve a leer el nombre del archivo para ser verificado } + if tmp = '' then tmp := DEFAUL_FILE_NAME; { asigna como nombre de archivo al predeterminado + si no se escribio nada } + end; { fin del loop de verificacion } + ObtenerNombreArchivo := tmp; { asigna el nombre correcto al valor de salida de la funcion } + end; { ObtenerNombreArchivo } + + {########################################################} + + function trans(c: char; e: Estado): Estado; + { establece el estado en el que se encuentra la lectura } + { c es el caracter que se leyo, e es el estado actual de la lectura } + + begin { trans } + case e of { acciona segun es estado actual de la lectura } + INICIO: { estado de inicio de la lectura } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un numero (o negativo), empieza a leer el coeficiente } + SPACE, TAB, CR, LF: trans := COEF_BUSCA; { si es un caracter tipo "espacio", busca el prox. coef. } + else trans := ERROR; { si es otro, da ERROR } + end; + COEF_BUSCA: { estado de busqueda del primer ceoficiente del polinomio } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un numero (o negativo), empieza a leer el coeficiente } + SPACE, TAB, CR, LF: trans := COEF_BUSCA; { si es un caracter tupo "espacio", sigue buscando } + ENDF: trans := FIN; { si es el caracter de fin de archivo, pasa al estado de tarea finalizada } + else trans := ERROR; { si es otro, da ERROR } + end; + COEF: { estado de lectura del coeficiente del termino del polinomio (sin punto decimal) } + case c of { acciona segun el caracter leido } + '0'..'9': trans := COEF; { si es un numero sigue con el mismo estado } + '.': trans := COEF_PUNTO; { si es punto cambia al estado COEF_PUNTO } + SPACE, TAB: trans := COEF_FIN; { si es un espacio o un tabulador, finaliza la lectura del coeficiente } + else trans := ERROR; { si es otra cosa, pasa a estado de error } + end; + COEF_PUNTO: { estado de lectura del coeficiente del termino del polinomio (con punto decimal) } + case c of { acciona segun el caracter leido } + '0'..'9': trans := COEF_PUNTO; { si es un numero sigue con el mismo estado } + SPACE, TAB: trans := COEF_FIN; { si es un espacio o un tabulador, finaliza la lectura del coeficiente } + else trans := ERROR; { si es otra cosa, pasa a estado de error } + end; + COEF_FIN: { estado de fin de la lectura del coeficiente del termino del polinomio } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si el caracter es un numero establece el estado en EXP (exponente) } + SPACE, TAB: trans := EXP_BUSCA; { si es un espacio o tabulador, pasa a buscar el proximo exponente } + else trans := ERROR; { si no es ninguno de los anteriores, el estado pasa a ERROR } + end; + EXP_BUSCA: { estado de busqueda del proximo exponente } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si el caracter es un numero, empieza a leer el exponente } + SPACE, TAB: trans := EXP_BUSCA; { si es un espacio o tabulador, sigue buscando } + else trans := ERROR; { si no es ninguno de los anteriores, el estado pasa a ERROR } + end; + EXP: { estado de lectura del exponente del termino actual del polinomio } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si es un digito, sigue en el mismo estado } + CR: trans := EXP_FIN; { si es un ratorno de carro, finaliza el exponente + (quiere decir que hubo un ) } + ENDF: trans := FIN; { si es el final del archivo, se indica que termino su tarea } + else trans := ERROR; { si es otra cosa, devuelve ERROR } + end; + EXP_FIN: { estado de fin de la lectura del exponente del termino actual del polinomio } + if c = LF then trans := EXP_FIN_BUSCA { debe ser un caracter de nueva linea (para completar el ) } + else trans := ERROR; { si no lo es, devuelve ERROR } + EXP_FIN_BUSCA: { estado de fin de lectura de la nueva linea (luego de finalizar el exponente + ahora decide si termino el polinomio o si sigue leyendo el proximo coeficiente } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un digito (o negativo), pasa a leer en proximo coeficiente } + CR: trans := POLI_FIN; { si es un ratorno de carro o nueva linea, finaliza el polinomio } + else trans := ERROR; { si es otra cosa, devuelve ERROR } + end; + POLI_FIN: { estado de finalizacion del polinomio actual } + if c = LF then trans := COEF_BUSCA { debe ser un caracter de nueva linea (para completar el ), + entonces pasa a buscar el primer coeficiente del nuevo polinomio } + else trans := ERROR; { si no lo es, devuelve ERROR } + FIN: { estado que adquiere cuando se finalizo la tarea } + trans := FIN; { se queda en este estado avisando que termino su tarea } + else { otro estado, no deberia ocurrir, salvo que se le pase a la funcion un estado de ERROR } + trans := ERROR; { si es otro, da ERROR } + end; { case } + end; { trans } + + {########################################################} + + function cargarVectores(var v1, v2: Vector): boolean; + { Funcion que abre el archivo de texto con los datos, lo carga en el vector procesandolo debidamente a medida + que lo lee y, al finalizar, cierra el archivo de texto. + v1 es el primer vector a cargar + v2 es el segundo vector a cargar + devuelve true si la lectura fue hecha con exito, false si hubo un error } + + var + f: Text; { archivo de texto con los datos } + c: char; { caracter que se extrae del archivo de texto } + nombreArchivo: String; { nombre del archivo de datos } + est: Estado; { Indicador del estado actual de la lectura } + seguir: boolean; { indicador para saber si debe seguir con el proceso } + i, { indice del vector del polinomio para ser inicializado } + iExp, { valor temporal para almacenar al exponente } + code, { almacena el resultado de la funcion val (no se usa porque los + datos ya estan validados } + poliN: integer; { numero del polinomio que se esta leyendo } + rCoef: real; { valor temporal para almacenar al coeficiente } + exponente, { string que representa al exponente leido } + coeficiente: String; { string que representa al coeficiente leido } + + begin { cargarVectores } + rCoef := 0.0; { inicializacion de variable } + iExp := 0; { inicializacion de variable } + coeficiente := ''; { inicializacion de variable } + exponente := ''; { inicializacion de variable } + est := INICIO; { empieza con el estado de INICIO } + poliN := 1; { establece que se procesara el primer polinomio } + inicializaVector(v1); { inicializacion del vector 1 (primer polinomio) } + inicializaVector(v2); { inicializacion del vector 2 (segundo polinomio) } + nombreArchivo := ObtenerNombreArchivo; { obtiene el nombre del archivo } + assign(f, nombreArchivo); { asigna la variable al nombre del archivo } + reset(f); { abre el archivo para leerlo desde el principio } + seguir := true; { inicializa seguir e true para comenzar el bucle } + while seguir do begin { continua mientras seguir sea true } + read(f, c); { lee un caracter del archivo de texto } + est := trans(c, est); { establece el nuevo estado de lectura } + case est of { toma una desicion dependiendo del estado en que se encuentre } + INICIO: ; { No hace nada, nunca toma este valor. Solo incica que empezo el proceso } + COEF_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + COEF, COEF_PUNTO: { Si esta leyendo el coeficiente ... } + coeficiente := coeficiente + c; { concatena el caracter a la representacion + de texto del coeficiente } + COEF_FIN: ; { Si termino de leer el coeficiente, no hace nada, la asignacion + se realiza cuando termina de leer el exponente (es necesario + para establecer el indice del vector } + EXP_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + EXP: { Si esta leyendo el exponente ... } + exponente := exponente + c; { concatena el caracter a la representacion + de texto del exponente } + EXP_FIN: { Si termino de leer el exponente, hace las asignaciones correspondientes } + begin { convirtiendo las cadenas de texto en real e integer, segun el caso } + val(coeficiente, rCoef, code); { convierte el coeficiente en real } + val(exponente, iExp, code); { convierte el exponente en integer } + if iExp < TAM { si el exponente es menor que el tama¤o maximo permitido ... } + then if poliN = 1 then v1[iExp] := rCoef { asigna el valor correspondiente } + else v2[iExp] := rCoef { al polinomio correspondiente } + else est := ERROR; { si no es menor, pone el estado en ERROR } + coeficiente := ''; { una vez asignados, vacia los valores del coeficiente y el } + exponente := ''; { exponente para poder realizar las lecturas de los proximos } + end; + EXP_FIN_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + POLI_FIN: { Si termino la lectura de un polinomio ... } + if poliN = 1 then poliN := 2 { si se leyo el 1er polinomio, se indica que se leera el 2do } + else est := FIN; { si no (ya se leyo el segundo), pone el estado en FIN } + FIN: { Si se finalizaron las tareas ... } + begin + { este codigo es el mismo que el de EXP_FIN, se repite aca solo por si el final del + archivo esta pegado al fin del ultimo exponente, en cuyo caso no pasa por el estado + de EXP_FIN (y, por ende, no se pueden hacer las asignaciones correspondientes } + val(coeficiente, rCoef, code); { convierte el coeficiente en real } + val(exponente, iExp, code); { convierte el exponente en integer } + if iExp < TAM { si el exponente es menor que el tama¤o maximo permitido ... } + then if poliN = 1 then v1[iExp] := rCoef { asigna el valor correspondiente } + else v2[iExp] := rCoef { al polinomio correspondiente } + else est := ERROR; { si no es menor, pone el estado en ERROR } + coeficiente := ''; { una vez asignados, vacia los valores del coeficiente y el } + exponente := ''; { exponente para poder realizar las lecturas de los proximos } + { fin del codigo identico a EXP_FIN } + if poliN = 2 then cargarVectores := true { si se leyeron los 2 polinomios, devuelve true } + else cargarVectores := false; { si no se leyeron los dos, devuelve false } + seguir := false; { poner seguir en false para que se termine el bucle } + end; + ERROR: { Si hubo un error ... } + begin + cargarVectores := false; { Se devuelve false (hubo un ERROR, no se leyeron bien los vectores) } + seguir := false; { seguir se pone en false para que termine el bucle } + end; + end; { case } + end; { while } + close(f); { se cierra el archivo de lectura de datos } + end; { cargarVectores } + + {########################################################} + + procedure suma(v1, v2: Vector; var vr: Vector); + { procedimiento que suma dos polinomios. + v1: vector que contiene el primer polinomio a sumar + v2: vector que contiene el segundo polinomio a sumar + vr: vector donde se almacenara el resultado de la suma } + + var + i: integer; { indice para usar en el ciclo for } + + begin { suma } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el vector (de tama¤o maximo TAM) } + vr[i] := v1[i] + v2[i]; { suma los coeficientes de los terminos con igual exponente } + end; { suma } + + {########################################################} + + procedure resta(v1, v2: Vector; var vr: Vector); + { procedimiento que resta dos polinomios. + v1: vector que contiene el primer polinomio + v2: vector que contiene el polinomio para restarle al primero + vr: vector donde se almacenara el resultado de la resta } + + var + i: integer; { indice para usar en el ciclo for } + + begin { resta } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el vector (de tama¤o maximo TAM) } + vr[i] := v1[i] + v2[i]; { resta los coeficientes de los terminos con igual exponente } + end; { resta } + + {########################################################} + + procedure producto(v1, v2: Vector; var vr: Vector); + { procedimiento que multiplica dos polinomios. + v1: vector que contiene el primer polinomio a multiplicar + v2: vector que contiene el segundo polinomio a multiplicar + vr: vector donde se almacenara el resultado de la multiplicacion } + + var + i, j: integer; { indices para usar en los ciclos for } + + begin { producto } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el 1er vector (de tama¤o maximo TAM) } + for i := 0 to TAM - 1 do { recorre el 2do vector (de tama¤o maximo TAM) } + vr[i+j] := vr[i+j] + (v1[i] * v2[j]); + { multiplica los coeficientes de los terminos y lo almacena en la posicion del exponente } + { igual a la suma de los exponentes de v1 y v2, sumando el valor previo de dicha posicion } + end; { producto } + + {########################################################} + + procedure division(v1, v2: Vector; var vr, vResto: Vector); + { procedimiento que divide dos polinomios. + v1: vector que contiene el polinomio denominador + v2: vector que contiene el polinomio divisor + vr: vector donde se almacenara el resultado de la division + vResto: vector donde se almacenara el resto de la division } + var + i, j: integer; { indices para usar en los ciclos for } + vRTmp, { vector auxuliares para almacenar el termino actual del resultado } + vTmp: Vector; { vector auxuliares para almacenar el polinomio que es la multiplicacion del + termino actual del resultado por el divisor } + + begin { division } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vResto); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vTmp); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vRTmp); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := TAM - 1 downto 0 do { recorre el 1er vector (de tama¤o maximo TAM) de atras para adelante } + if v1[i] <> 0 then break; + { busca empezando por el indice (exponete) mas alto el primer coeficiente no nulo } + { si lo encuentra sale del for dejando al valor de i como el de dicho inidice } + for j := TAM - 1 downto 0 do { recorre el 2do vector (de tama¤o maximo TAM) de atras para adelante } + if v2[j] <> 0 then break; + { busca empezando por el indice (exponete) mas alto el primer coeficiente no nulo } + { si lo encuentra sale del for dejando al valor de j como el de dicho inidice } + while i >= j do + begin + vr[i-j] := v1[i] / v2[j]; + vRTmp[i-j] := vr[i-j]; + producto(vRTmp, v2, vTmp); + resta(v1, vTmp, v1); + vRTmp[i-j] := 0; + for i := i downto 0 do + if v1[i] <> 0 then break; + { busca empezando por el indice (exponete) mas alto el primer coeficiente no nulo } + { si lo encuentra sale del for dejando al valor de i como el de dicho inidice } + end; { while } + vResto := v1; + end; { division } + + {########################################################} + +{ Continuacion del programa principal } + +var + i: integer; { variable auxiliar } + v1, v2, vResult, vResto: Vector; + resultado: boolean; + +begin { Comienzo del programa principal } + resultado := cargarVectores(v1, v2); + if not resultado then exit; + muestraVector(v1, 'Polinomio 1 ='); + muestraVector(v2, 'Polinomio 2 ='); + suma(v1, v2, vResult); + muestraVector(vResult, 'Polinomio 1 + Polinomio 2 ='); +end. \ No newline at end of file diff --git a/poli_7.pas b/poli_7.pas new file mode 100644 index 0000000..d3731a9 --- /dev/null +++ b/poli_7.pas @@ -0,0 +1,441 @@ +program Polinomios; + +uses + CRT, DOS; { Declaracion de funciones predefinidas + para crear la interfaz grafica } + +const + VERSION = '0.8.5a (POLI_7)'; { version del programa } + + TAM_MAX = 100; { Tama¤o maximo del vector que almacena + la multiplicacion de polinomios } + TAM = TAM_MAX div 2; { Tama¤o maximo (virtual) del vector que contiene + los vector con los que se va a operar } + CR = chr(13); { caracter de retorno del carro } + LF = chr(10); { caracter de nueva linea } + ENDF = chr(26); { caracter de fin del archivo } + TAB = chr(9); { caracter de tabulacion } + SPACE = chr(32); { caracter de espacio } + +type + { Tipo de dato para identificar el estado de la entrada de datos } + Estado = (INICIO, COEF_BUSCA, COEF, COEF_PUNTO, COEF_FIN, EXP_BUSCA, EXP, EXP_FIN, EXP_FIN_BUSCA, POLI_FIN, FIN, ERROR); + Vector = array [0..TAM_MAX-1] of real; { vector para almacenar los polinomios } + + + {########################################################} + + procedure muestraVector(var v: Vector; s: String); + { procedimiento que imprime el polinomio v en pantalla con un titulo s } + + {########################################################} + + function exponente(exp: integer): String; + + var + s: String; { variable temporal } + + begin { exponente } + case exp of + 0: exponente := ''; { si el exponente es nulo, mustra solo el coeficiente } + 1: exponente := 'X'; { si el exponente es 1, mustra el coeficiente y X } + 2: exponente := 'Xý'; { si el exponente es 2, mustra el coeficiente y Xý } + else begin + str(exp, s); { convierte al exponente en string } + exponente := 'X^' + s; { si el exponente es mayor que 1, mustra el coeficiente y X^exp } + end; { else } + end; { case } + end; { exponente } + + {########################################################} + + + var + i: integer; { indice para usar en el ciclo for } + + begin { muestraVector } + writeln(s); { mustra el mensaje } + write(' '); { deja un espacio antes de empezar a mostrar el polinomio } + for i := TAM_MAX - 1 downto 0 do { recorre el vector de atras para adelante } + if v[i] <> 0 then break; { si el coeficiente no es nulo, termina el for dejando a i en ese indice } + if (abs(v[i]) <> 1) or (i = 0) { si el modulo del coeficiente es distinto de 1 o si el exp. es 0 } + then if abs(v[i]) - trunc(abs(v[i])) = 0 then write(trunc(v[i]):1, ' ') { imprime si es un numero entero } + else write(v[i]:1:2, ' ') { imprime si es un numero real } + else if v[i] = -1 then write('-'); { si es -1 entonces solo escribe el signo del termino } + write(exponente(i)); + for i := i - 1 downto 0 do { recorre el vector de atras para adelante } + if v[i] <> 0 then { si el coeficiente no es nulo, termina el for dejando a i en ese indice } + begin + if v[i] < 0 { si el coeficiente en negativo } + then write(' - ') { le agrega el signo - } + else write(' + '); { si no, le agrega el signo + } + if (abs(v[i]) <> 1) or (i = 0) then { si el modulo del coeficiente es distinto de 1 o si el exp. es 0 } + if abs(v[i]) - trunc(abs(v[i])) = 0 then write(trunc(abs(v[i])):1, ' ') { imprime si es un entero } + else write(abs(v[i]):1:2, ' '); { imprime si es un real } + write(exponente(i)); + end; { if } + writeln; + end; { muestraVector } + + {########################################################} + + procedure inicializaVector(var v: Vector); + { procedimiento que inicializa un vector de tama¤o tam } + + var i: integer; { indice para usar en el ciclo for } + + begin { inicializaVector } + for i := 0 to TAM_MAX - 1 do { recorre el vector } + v[i] := 0; { inicializa la variable actual en 0 } + end; { inicializaVector } + + {########################################################} + + function ObtenerNombreArchivo: String; + { funcion que obtiene un nombre de archivo valido (es decir, el nombre + de un archivo que exista) } + + {########################################################} + + function fileExists(FileName: String): Boolean; + { funcion extraida de la ayuda del Turbo Pascal 7 + indica si el archivo existe } + + var + F: file; + + begin + {$I-} + Assign(F, FileName); + FileMode := 0; { Set file access to read only } + Reset(F); + Close(F); + {$I+} + FileExists := (IOResult = 0) and (FileName <> ''); + end; { FileExists } + + {########################################################} + + { Continuacion de la funcion ObtenerNombreArchivo } + const + DEFAUL_FILE_NAME = 'datos.txt'; { nombre del archivo por defecto } + + var + tmp: String; { cadena para almacenar el resultado temporal } + + begin { ObtenerNombreArchivo } + { mensaje para entrada del nombre de archivo } + writeln('Ingrese el nombre del archivo con los datos (ENTER = ', DEFAUL_FILE_NAME, '):'); + readln(tmp); { entrada del nombre de archivo } + if tmp = '' then tmp := DEFAUL_FILE_NAME; { se fija si no se ingreso nada y reasigana el nombre } + while not fileExists(tmp) do { repite el proceso hasta que el archivo exista } + begin + write('El archivo ', tmp, ' no existe. Ingrese un nombre correcto'); + if tmp = DEFAUL_FILE_NAME { si es el nombre de archivo predeterminado } + then { entonces, elije un mensaje apropiado } + write(': ') + else + begin { si no es el predeterminado, muestra otro mensaje } + writeln('.'); + write('(ENTER = ', DEFAUL_FILE_NAME, '): '); + end; + readln(tmp); { vuelve a leer el nombre del archivo para ser verificado } + if tmp = '' then tmp := DEFAUL_FILE_NAME; { asigna como nombre de archivo al predeterminado + si no se escribio nada } + end; { fin del loop de verificacion } + ObtenerNombreArchivo := tmp; { asigna el nombre correcto al valor de salida de la funcion } + end; { ObtenerNombreArchivo } + + {########################################################} + + function trans(c: char; e: Estado): Estado; + { establece el estado en el que se encuentra la lectura } + { c es el caracter que se leyo, e es el estado actual de la lectura } + + begin { trans } + case e of { acciona segun es estado actual de la lectura } + INICIO: { estado de inicio de la lectura } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un numero (o negativo), empieza a leer el coeficiente } + SPACE, TAB, CR, LF: trans := COEF_BUSCA; { si es un caracter tipo "espacio", busca el prox. coef. } + else trans := ERROR; { si es otro, da ERROR } + end; + COEF_BUSCA: { estado de busqueda del primer ceoficiente del polinomio } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un numero (o negativo), empieza a leer el coeficiente } + SPACE, TAB, CR, LF: trans := COEF_BUSCA; { si es un caracter tupo "espacio", sigue buscando } + ENDF: trans := FIN; { si es el caracter de fin de archivo, pasa al estado de tarea finalizada } + else trans := ERROR; { si es otro, da ERROR } + end; + COEF: { estado de lectura del coeficiente del termino del polinomio (sin punto decimal) } + case c of { acciona segun el caracter leido } + '0'..'9': trans := COEF; { si es un numero sigue con el mismo estado } + '.': trans := COEF_PUNTO; { si es punto cambia al estado COEF_PUNTO } + SPACE, TAB: trans := COEF_FIN; { si es un espacio o un tabulador, finaliza la lectura del coeficiente } + else trans := ERROR; { si es otra cosa, pasa a estado de error } + end; + COEF_PUNTO: { estado de lectura del coeficiente del termino del polinomio (con punto decimal) } + case c of { acciona segun el caracter leido } + '0'..'9': trans := COEF_PUNTO; { si es un numero sigue con el mismo estado } + SPACE, TAB: trans := COEF_FIN; { si es un espacio o un tabulador, finaliza la lectura del coeficiente } + else trans := ERROR; { si es otra cosa, pasa a estado de error } + end; + COEF_FIN: { estado de fin de la lectura del coeficiente del termino del polinomio } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si el caracter es un numero establece el estado en EXP (exponente) } + SPACE, TAB: trans := EXP_BUSCA; { si es un espacio o tabulador, pasa a buscar el proximo exponente } + else trans := ERROR; { si no es ninguno de los anteriores, el estado pasa a ERROR } + end; + EXP_BUSCA: { estado de busqueda del proximo exponente } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si el caracter es un numero, empieza a leer el exponente } + SPACE, TAB: trans := EXP_BUSCA; { si es un espacio o tabulador, sigue buscando } + else trans := ERROR; { si no es ninguno de los anteriores, el estado pasa a ERROR } + end; + EXP: { estado de lectura del exponente del termino actual del polinomio } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si es un digito, sigue en el mismo estado } + CR: trans := EXP_FIN; { si es un ratorno de carro, finaliza el exponente + (quiere decir que hubo un ) } + ENDF: trans := FIN; { si es el final del archivo, se indica que termino su tarea } + else trans := ERROR; { si es otra cosa, devuelve ERROR } + end; + EXP_FIN: { estado de fin de la lectura del exponente del termino actual del polinomio } + if c = LF then trans := EXP_FIN_BUSCA { debe ser un caracter de nueva linea (para completar el ) } + else trans := ERROR; { si no lo es, devuelve ERROR } + EXP_FIN_BUSCA: { estado de fin de lectura de la nueva linea (luego de finalizar el exponente + ahora decide si termino el polinomio o si sigue leyendo el proximo coeficiente } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un digito (o negativo), pasa a leer en proximo coeficiente } + CR: trans := POLI_FIN; { si es un ratorno de carro o nueva linea, finaliza el polinomio } + else trans := ERROR; { si es otra cosa, devuelve ERROR } + end; + POLI_FIN: { estado de finalizacion del polinomio actual } + if c = LF then trans := COEF_BUSCA { debe ser un caracter de nueva linea (para completar el ), + entonces pasa a buscar el primer coeficiente del nuevo polinomio } + else trans := ERROR; { si no lo es, devuelve ERROR } + FIN: { estado que adquiere cuando se finalizo la tarea } + trans := FIN; { se queda en este estado avisando que termino su tarea } + else { otro estado, no deberia ocurrir, salvo que se le pase a la funcion un estado de ERROR } + trans := ERROR; { si es otro, da ERROR } + end; { case } + end; { trans } + + {########################################################} + + function cargarVectores(var v1, v2: Vector): boolean; + { Funcion que abre el archivo de texto con los datos, lo carga en el vector procesandolo debidamente a medida + que lo lee y, al finalizar, cierra el archivo de texto. + v1 es el primer vector a cargar + v2 es el segundo vector a cargar + devuelve true si la lectura fue hecha con exito, false si hubo un error } + + var + f: Text; { archivo de texto con los datos } + c: char; { caracter que se extrae del archivo de texto } + nombreArchivo: String; { nombre del archivo de datos } + est: Estado; { Indicador del estado actual de la lectura } + seguir: boolean; { indicador para saber si debe seguir con el proceso } + i, { indice del vector del polinomio para ser inicializado } + iExp, { valor temporal para almacenar al exponente } + code, { almacena el resultado de la funcion val (no se usa porque los + datos ya estan validados } + poliN: integer; { numero del polinomio que se esta leyendo } + rCoef: real; { valor temporal para almacenar al coeficiente } + exponente, { string que representa al exponente leido } + coeficiente: String; { string que representa al coeficiente leido } + + begin { cargarVectores } + rCoef := 0.0; { inicializacion de variable } + iExp := 0; { inicializacion de variable } + coeficiente := ''; { inicializacion de variable } + exponente := ''; { inicializacion de variable } + est := INICIO; { empieza con el estado de INICIO } + poliN := 1; { establece que se procesara el primer polinomio } + inicializaVector(v1); { inicializacion del vector 1 (primer polinomio) } + inicializaVector(v2); { inicializacion del vector 2 (segundo polinomio) } + nombreArchivo := ObtenerNombreArchivo; { obtiene el nombre del archivo } + assign(f, nombreArchivo); { asigna la variable al nombre del archivo } + reset(f); { abre el archivo para leerlo desde el principio } + seguir := true; { inicializa seguir e true para comenzar el bucle } + while seguir do begin { continua mientras seguir sea true } + read(f, c); { lee un caracter del archivo de texto } + est := trans(c, est); { establece el nuevo estado de lectura } + case est of { toma una desicion dependiendo del estado en que se encuentre } + INICIO: ; { No hace nada, nunca toma este valor. Solo incica que empezo el proceso } + COEF_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + COEF, COEF_PUNTO: { Si esta leyendo el coeficiente ... } + coeficiente := coeficiente + c; { concatena el caracter a la representacion + de texto del coeficiente } + COEF_FIN: ; { Si termino de leer el coeficiente, no hace nada, la asignacion + se realiza cuando termina de leer el exponente (es necesario + para establecer el indice del vector } + EXP_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + EXP: { Si esta leyendo el exponente ... } + exponente := exponente + c; { concatena el caracter a la representacion + de texto del exponente } + EXP_FIN: { Si termino de leer el exponente, hace las asignaciones correspondientes } + begin { convirtiendo las cadenas de texto en real e integer, segun el caso } + val(coeficiente, rCoef, code); { convierte el coeficiente en real } + val(exponente, iExp, code); { convierte el exponente en integer } + if iExp < TAM { si el exponente es menor que el tama¤o maximo permitido ... } + then if poliN = 1 then v1[iExp] := rCoef { asigna el valor correspondiente } + else v2[iExp] := rCoef { al polinomio correspondiente } + else est := ERROR; { si no es menor, pone el estado en ERROR } + coeficiente := ''; { una vez asignados, vacia los valores del coeficiente y el } + exponente := ''; { exponente para poder realizar las lecturas de los proximos } + end; + EXP_FIN_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + POLI_FIN: { Si termino la lectura de un polinomio ... } + if poliN = 1 then poliN := 2 { si se leyo el 1er polinomio, se indica que se leera el 2do } + else est := FIN; { si no (ya se leyo el segundo), pone el estado en FIN } + FIN: { Si se finalizaron las tareas ... } + begin + { este codigo es el mismo que el de EXP_FIN, se repite aca solo por si el final del + archivo esta pegado al fin del ultimo exponente, en cuyo caso no pasa por el estado + de EXP_FIN (y, por ende, no se pueden hacer las asignaciones correspondientes } + val(coeficiente, rCoef, code); { convierte el coeficiente en real } + val(exponente, iExp, code); { convierte el exponente en integer } + if iExp < TAM { si el exponente es menor que el tama¤o maximo permitido ... } + then if poliN = 1 then v1[iExp] := rCoef { asigna el valor correspondiente } + else v2[iExp] := rCoef { al polinomio correspondiente } + else est := ERROR; { si no es menor, pone el estado en ERROR } + coeficiente := ''; { una vez asignados, vacia los valores del coeficiente y el } + exponente := ''; { exponente para poder realizar las lecturas de los proximos } + { fin del codigo identico a EXP_FIN } + if poliN = 2 then cargarVectores := true { si se leyeron los 2 polinomios, devuelve true } + else cargarVectores := false; { si no se leyeron los dos, devuelve false } + seguir := false; { poner seguir en false para que se termine el bucle } + end; + ERROR: { Si hubo un error ... } + begin + cargarVectores := false; { Se devuelve false (hubo un ERROR, no se leyeron bien los vectores) } + seguir := false; { seguir se pone en false para que termine el bucle } + end; + end; { case } + end; { while } + close(f); { se cierra el archivo de lectura de datos } + end; { cargarVectores } + + {########################################################} + + procedure suma(v1, v2: Vector; var vr: Vector); + { procedimiento que suma dos polinomios. + v1: vector que contiene el primer polinomio a sumar + v2: vector que contiene el segundo polinomio a sumar + vr: vector donde se almacenara el resultado de la suma } + + var + i: integer; { indice para usar en el ciclo for } + + begin { suma } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el vector (de tama¤o maximo TAM) } + vr[i] := v1[i] + v2[i]; { suma los coeficientes de los terminos con igual exponente } + end; { suma } + + {########################################################} + + procedure resta(v1, v2: Vector; var vr: Vector); + { procedimiento que resta dos polinomios. + v1: vector que contiene el primer polinomio + v2: vector que contiene el polinomio para restarle al primero + vr: vector donde se almacenara el resultado de la resta } + + var + i: integer; { indice para usar en el ciclo for } + + begin { resta } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el vector (de tama¤o maximo TAM) } + vr[i] := v1[i] - v2[i]; { resta los coeficientes de los terminos con igual exponente } + end; { resta } + + {########################################################} + + procedure producto(v1, v2: Vector; var vr: Vector); + { procedimiento que multiplica dos polinomios. + v1: vector que contiene el primer polinomio a multiplicar + v2: vector que contiene el segundo polinomio a multiplicar + vr: vector donde se almacenara el resultado de la multiplicacion } + + var + i, j: integer; { indices para usar en los ciclos for } + + begin { producto } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el 1er vector (de tama¤o maximo TAM) } + for i := 0 to TAM - 1 do { recorre el 2do vector (de tama¤o maximo TAM) } + vr[i+j] := vr[i+j] + (v1[i] * v2[j]); + { multiplica los coeficientes de los terminos y lo almacena en la posicion del exponente } + { igual a la suma de los exponentes de v1 y v2, sumando el valor previo de dicha posicion } + end; { producto } + + {########################################################} + + procedure division(v1, v2: Vector; var vr, vResto: Vector); + { procedimiento que divide dos polinomios. + v1: vector que contiene el polinomio denominador + v2: vector que contiene el polinomio divisor + vr: vector donde se almacenara el resultado de la division + vResto: vector donde se almacenara el resto de la division } + var + i, j: integer; { indices para usar en los ciclos for } + vRTmp, { vector auxuliares para almacenar el termino actual del resultado } + vTmp: Vector; { vector auxuliares para almacenar el polinomio que es la multiplicacion del + termino actual del resultado por el divisor } + + begin { division } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vResto); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vTmp); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vRTmp); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := TAM - 1 downto 0 do { recorre el 1er vector (de tama¤o maximo TAM) de atras para adelante } + if v1[i] <> 0 then break; + { busca empezando por el indice (exponete) mas alto el primer coeficiente no nulo } + { si lo encuentra sale del for dejando al valor de i como el de dicho inidice } + for j := TAM - 1 downto 0 do { recorre el 2do vector (de tama¤o maximo TAM) de atras para adelante } + if v2[j] <> 0 then break; + { busca empezando por el indice (exponete) mas alto el primer coeficiente no nulo } + { si lo encuentra sale del for dejando al valor de j como el de dicho inidice } + while i >= j do + begin + vr[i-j] := v1[i] / v2[j]; + vRTmp[i-j] := vr[i-j]; + producto(vRTmp, v2, vTmp); + resta(v1, vTmp, v1); + vRTmp[i-j] := 0; + for i := i downto 0 do + if v1[i] <> 0 then break; + { busca empezando por el indice (exponete) mas alto el primer coeficiente no nulo } + { si lo encuentra sale del for dejando al valor de i como el de dicho inidice } + end; { while } + vResto := v1; + end; { division } + + {########################################################} + +{ Continuacion del programa principal } + +var + i: integer; { variable auxiliar } + v1, v2, vResult, vResto: Vector; + resultado: boolean; + +begin { Comienzo del programa principal } + resultado := cargarVectores(v1, v2); + if resultado then + begin + muestraVector(v1, 'Polinomio 1 ='); + muestraVector(v2, 'Polinomio 2 ='); + suma(v1, v2, vResult); + muestraVector(vResult, 'Polinomio 1 + Polinomio 2 ='); + resta(v1, v2, vResult); + muestraVector(vResult, 'Polinomio 1 - Polinomio 2 ='); + end + else + begin + writeln('ERROR: No se pudieron cargar los datos. Revise que el formato del archivo'); + writeln(' sea correcto y que no este siendo usado por otro programa.'); + end; +end. \ No newline at end of file diff --git a/poli_8.pas b/poli_8.pas new file mode 100644 index 0000000..e6f2605 --- /dev/null +++ b/poli_8.pas @@ -0,0 +1,444 @@ +program Polinomios; + +uses + CRT, DOS; { Declaracion de funciones predefinidas + para crear la interfaz grafica } + +const + VERSION = '0.9.0a (POLI_8)'; { version del programa } + + TAM_MAX = 100; { Tama¤o maximo del vector que almacena + la multiplicacion de polinomios } + TAM = TAM_MAX div 2; { Tama¤o maximo (virtual) del vector que contiene + los vector con los que se va a operar } + CR = chr(13); { caracter de retorno del carro } + LF = chr(10); { caracter de nueva linea } + ENDF = chr(26); { caracter de fin del archivo } + TAB = chr(9); { caracter de tabulacion } + SPACE = chr(32); { caracter de espacio } + +type + { Tipo de dato para identificar el estado de la entrada de datos } + Estado = (INICIO, COEF_BUSCA, COEF, COEF_PUNTO, COEF_FIN, EXP_BUSCA, EXP, EXP_FIN, EXP_FIN_BUSCA, POLI_FIN, FIN, ERROR); + Vector = array [0..TAM_MAX-1] of real; { vector para almacenar los polinomios } + + + {########################################################} + + procedure muestraVector(var v: Vector; s: String); + { procedimiento que imprime el polinomio v en pantalla con un titulo s } + + {########################################################} + + function exponente(exp: integer): String; + + var + s: String; { variable temporal } + + begin { exponente } + case exp of + 0: exponente := ''; { si el exponente es nulo, mustra solo el coeficiente } + 1: exponente := 'X'; { si el exponente es 1, mustra el coeficiente y X } + 2: exponente := 'Xý'; { si el exponente es 2, mustra el coeficiente y Xý } + else begin + str(exp, s); { convierte al exponente en string } + exponente := 'X^' + s; { si el exponente es mayor que 1, mustra el coeficiente y X^exp } + end; { else } + end; { case } + end; { exponente } + + {########################################################} + + + var + i: integer; { indice para usar en el ciclo for } + + begin { muestraVector } + writeln; { separacion de una linea } + write(s); { mustra el mensaje } + for i := TAM_MAX - 1 downto 0 do { recorre el vector de atras para adelante } + if v[i] <> 0 then break; { si el coeficiente no es nulo, termina el for dejando a i en ese indice } + if (abs(v[i]) <> 1) or (i = 0) { si el modulo del coeficiente es distinto de 1 o si el exp. es 0 } + then if abs(v[i]) - trunc(abs(v[i])) = 0 then write(trunc(v[i]):1, ' ') { imprime si es un numero entero } + else write(v[i]:1:2, ' ') { imprime si es un numero real } + else if v[i] = -1 then write('-'); { si es -1 entonces solo escribe el signo del termino } + write(exponente(i)); + for i := i - 1 downto 0 do { recorre el vector de atras para adelante } + if v[i] <> 0 then { si el coeficiente no es nulo, termina el for dejando a i en ese indice } + begin + if v[i] < 0 { si el coeficiente en negativo } + then write(' - ') { le agrega el signo - } + else write(' + '); { si no, le agrega el signo + } + if (abs(v[i]) <> 1) or (i = 0) then { si el modulo del coeficiente es distinto de 1 o si el exp. es 0 } + if abs(v[i]) - trunc(abs(v[i])) = 0 then write(trunc(abs(v[i])):1, ' ') { imprime si es un entero } + else write(abs(v[i]):1:2, ' '); { imprime si es un real } + write(exponente(i)); + end; { if } + writeln; { separacion de una linea } + writeln; { separacion de una linea } + end; { muestraVector } + + {########################################################} + + procedure inicializaVector(var v: Vector); + { procedimiento que inicializa un vector de tama¤o tam } + + var i: integer; { indice para usar en el ciclo for } + + begin { inicializaVector } + for i := 0 to TAM_MAX - 1 do { recorre el vector } + v[i] := 0; { inicializa la variable actual en 0 } + end; { inicializaVector } + + {########################################################} + + function ObtenerNombreArchivo: String; + { funcion que obtiene un nombre de archivo valido (es decir, el nombre + de un archivo que exista) } + + {########################################################} + + function fileExists(FileName: String): Boolean; + { funcion extraida de la ayuda del Turbo Pascal 7 + indica si el archivo existe } + + var + F: file; + + begin + {$I-} + Assign(F, FileName); + FileMode := 0; { Set file access to read only } + Reset(F); + Close(F); + {$I+} + FileExists := (IOResult = 0) and (FileName <> ''); + end; { FileExists } + + {########################################################} + + { Continuacion de la funcion ObtenerNombreArchivo } + const + DEFAUL_FILE_NAME = 'datos.txt'; { nombre del archivo por defecto } + + var + tmp: String; { cadena para almacenar el resultado temporal } + + begin { ObtenerNombreArchivo } + { mensaje para entrada del nombre de archivo } + writeln('Ingrese el nombre del archivo con los datos (ENTER = ', DEFAUL_FILE_NAME, '):'); + readln(tmp); { entrada del nombre de archivo } + if tmp = '' then tmp := DEFAUL_FILE_NAME; { se fija si no se ingreso nada y reasigana el nombre } + while not fileExists(tmp) do { repite el proceso hasta que el archivo exista } + begin + write('El archivo ', tmp, ' no existe. Ingrese un nombre correcto'); + if tmp = DEFAUL_FILE_NAME { si es el nombre de archivo predeterminado } + then { entonces, elije un mensaje apropiado } + write(': ') + else + begin { si no es el predeterminado, muestra otro mensaje } + writeln('.'); + write('(ENTER = ', DEFAUL_FILE_NAME, '): '); + end; + readln(tmp); { vuelve a leer el nombre del archivo para ser verificado } + if tmp = '' then tmp := DEFAUL_FILE_NAME; { asigna como nombre de archivo al predeterminado + si no se escribio nada } + end; { fin del loop de verificacion } + ObtenerNombreArchivo := tmp; { asigna el nombre correcto al valor de salida de la funcion } + end; { ObtenerNombreArchivo } + + {########################################################} + + function trans(c: char; e: Estado): Estado; + { establece el estado en el que se encuentra la lectura } + { c es el caracter que se leyo, e es el estado actual de la lectura } + + begin { trans } + case e of { acciona segun es estado actual de la lectura } + INICIO: { estado de inicio de la lectura } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un numero (o negativo), empieza a leer el coeficiente } + SPACE, TAB, CR, LF: trans := COEF_BUSCA; { si es un caracter tipo "espacio", busca el prox. coef. } + else trans := ERROR; { si es otro, da ERROR } + end; + COEF_BUSCA: { estado de busqueda del primer ceoficiente del polinomio } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un numero (o negativo), empieza a leer el coeficiente } + SPACE, TAB, CR, LF: trans := COEF_BUSCA; { si es un caracter tupo "espacio", sigue buscando } + ENDF: trans := FIN; { si es el caracter de fin de archivo, pasa al estado de tarea finalizada } + else trans := ERROR; { si es otro, da ERROR } + end; + COEF: { estado de lectura del coeficiente del termino del polinomio (sin punto decimal) } + case c of { acciona segun el caracter leido } + '0'..'9': trans := COEF; { si es un numero sigue con el mismo estado } + '.': trans := COEF_PUNTO; { si es punto cambia al estado COEF_PUNTO } + SPACE, TAB: trans := COEF_FIN; { si es un espacio o un tabulador, finaliza la lectura del coeficiente } + else trans := ERROR; { si es otra cosa, pasa a estado de error } + end; + COEF_PUNTO: { estado de lectura del coeficiente del termino del polinomio (con punto decimal) } + case c of { acciona segun el caracter leido } + '0'..'9': trans := COEF_PUNTO; { si es un numero sigue con el mismo estado } + SPACE, TAB: trans := COEF_FIN; { si es un espacio o un tabulador, finaliza la lectura del coeficiente } + else trans := ERROR; { si es otra cosa, pasa a estado de error } + end; + COEF_FIN: { estado de fin de la lectura del coeficiente del termino del polinomio } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si el caracter es un numero establece el estado en EXP (exponente) } + SPACE, TAB: trans := EXP_BUSCA; { si es un espacio o tabulador, pasa a buscar el proximo exponente } + else trans := ERROR; { si no es ninguno de los anteriores, el estado pasa a ERROR } + end; + EXP_BUSCA: { estado de busqueda del proximo exponente } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si el caracter es un numero, empieza a leer el exponente } + SPACE, TAB: trans := EXP_BUSCA; { si es un espacio o tabulador, sigue buscando } + else trans := ERROR; { si no es ninguno de los anteriores, el estado pasa a ERROR } + end; + EXP: { estado de lectura del exponente del termino actual del polinomio } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si es un digito, sigue en el mismo estado } + CR: trans := EXP_FIN; { si es un ratorno de carro, finaliza el exponente + (quiere decir que hubo un ) } + ENDF: trans := FIN; { si es el final del archivo, se indica que termino su tarea } + else trans := ERROR; { si es otra cosa, devuelve ERROR } + end; + EXP_FIN: { estado de fin de la lectura del exponente del termino actual del polinomio } + if c = LF then trans := EXP_FIN_BUSCA { debe ser un caracter de nueva linea (para completar el ) } + else trans := ERROR; { si no lo es, devuelve ERROR } + EXP_FIN_BUSCA: { estado de fin de lectura de la nueva linea (luego de finalizar el exponente + ahora decide si termino el polinomio o si sigue leyendo el proximo coeficiente } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un digito (o negativo), pasa a leer en proximo coeficiente } + CR: trans := POLI_FIN; { si es un ratorno de carro o nueva linea, finaliza el polinomio } + else trans := ERROR; { si es otra cosa, devuelve ERROR } + end; + POLI_FIN: { estado de finalizacion del polinomio actual } + if c = LF then trans := COEF_BUSCA { debe ser un caracter de nueva linea (para completar el ), + entonces pasa a buscar el primer coeficiente del nuevo polinomio } + else trans := ERROR; { si no lo es, devuelve ERROR } + FIN: { estado que adquiere cuando se finalizo la tarea } + trans := FIN; { se queda en este estado avisando que termino su tarea } + else { otro estado, no deberia ocurrir, salvo que se le pase a la funcion un estado de ERROR } + trans := ERROR; { si es otro, da ERROR } + end; { case } + end; { trans } + + {########################################################} + + function cargarVectores(var v1, v2: Vector): boolean; + { Funcion que abre el archivo de texto con los datos, lo carga en el vector procesandolo debidamente a medida + que lo lee y, al finalizar, cierra el archivo de texto. + v1 es el primer vector a cargar + v2 es el segundo vector a cargar + devuelve true si la lectura fue hecha con exito, false si hubo un error } + + var + f: Text; { archivo de texto con los datos } + c: char; { caracter que se extrae del archivo de texto } + nombreArchivo: String; { nombre del archivo de datos } + est: Estado; { Indicador del estado actual de la lectura } + seguir: boolean; { indicador para saber si debe seguir con el proceso } + i, { indice del vector del polinomio para ser inicializado } + iExp, { valor temporal para almacenar al exponente } + code, { almacena el resultado de la funcion val (no se usa porque los + datos ya estan validados } + poliN: integer; { numero del polinomio que se esta leyendo } + rCoef: real; { valor temporal para almacenar al coeficiente } + exponente, { string que representa al exponente leido } + coeficiente: String; { string que representa al coeficiente leido } + + begin { cargarVectores } + rCoef := 0.0; { inicializacion de variable } + iExp := 0; { inicializacion de variable } + coeficiente := ''; { inicializacion de variable } + exponente := ''; { inicializacion de variable } + est := INICIO; { empieza con el estado de INICIO } + poliN := 1; { establece que se procesara el primer polinomio } + inicializaVector(v1); { inicializacion del vector 1 (primer polinomio) } + inicializaVector(v2); { inicializacion del vector 2 (segundo polinomio) } + nombreArchivo := ObtenerNombreArchivo; { obtiene el nombre del archivo } + assign(f, nombreArchivo); { asigna la variable al nombre del archivo } + reset(f); { abre el archivo para leerlo desde el principio } + seguir := true; { inicializa seguir e true para comenzar el bucle } + while seguir do begin { continua mientras seguir sea true } + read(f, c); { lee un caracter del archivo de texto } + est := trans(c, est); { establece el nuevo estado de lectura } + case est of { toma una desicion dependiendo del estado en que se encuentre } + INICIO: ; { No hace nada, nunca toma este valor. Solo incica que empezo el proceso } + COEF_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + COEF, COEF_PUNTO: { Si esta leyendo el coeficiente ... } + coeficiente := coeficiente + c; { concatena el caracter a la representacion + de texto del coeficiente } + COEF_FIN: ; { Si termino de leer el coeficiente, no hace nada, la asignacion + se realiza cuando termina de leer el exponente (es necesario + para establecer el indice del vector } + EXP_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + EXP: { Si esta leyendo el exponente ... } + exponente := exponente + c; { concatena el caracter a la representacion + de texto del exponente } + EXP_FIN: { Si termino de leer el exponente, hace las asignaciones correspondientes } + begin { convirtiendo las cadenas de texto en real e integer, segun el caso } + val(coeficiente, rCoef, code); { convierte el coeficiente en real } + val(exponente, iExp, code); { convierte el exponente en integer } + if iExp < TAM { si el exponente es menor que el tama¤o maximo permitido ... } + then if poliN = 1 then v1[iExp] := rCoef { asigna el valor correspondiente } + else v2[iExp] := rCoef { al polinomio correspondiente } + else est := ERROR; { si no es menor, pone el estado en ERROR } + coeficiente := ''; { una vez asignados, vacia los valores del coeficiente y el } + exponente := ''; { exponente para poder realizar las lecturas de los proximos } + end; + EXP_FIN_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + POLI_FIN: { Si termino la lectura de un polinomio ... } + if poliN = 1 then poliN := 2 { si se leyo el 1er polinomio, se indica que se leera el 2do } + else est := FIN; { si no (ya se leyo el segundo), pone el estado en FIN } + FIN: { Si se finalizaron las tareas ... } + begin + { este codigo es el mismo que el de EXP_FIN, se repite aca solo por si el final del + archivo esta pegado al fin del ultimo exponente, en cuyo caso no pasa por el estado + de EXP_FIN (y, por ende, no se pueden hacer las asignaciones correspondientes } + val(coeficiente, rCoef, code); { convierte el coeficiente en real } + val(exponente, iExp, code); { convierte el exponente en integer } + if iExp < TAM { si el exponente es menor que el tama¤o maximo permitido ... } + then if poliN = 1 then v1[iExp] := rCoef { asigna el valor correspondiente } + else v2[iExp] := rCoef { al polinomio correspondiente } + else est := ERROR; { si no es menor, pone el estado en ERROR } + coeficiente := ''; { una vez asignados, vacia los valores del coeficiente y el } + exponente := ''; { exponente para poder realizar las lecturas de los proximos } + { fin del codigo identico a EXP_FIN } + if poliN = 2 then cargarVectores := true { si se leyeron los 2 polinomios, devuelve true } + else cargarVectores := false; { si no se leyeron los dos, devuelve false } + seguir := false; { poner seguir en false para que se termine el bucle } + end; + ERROR: { Si hubo un error ... } + begin + cargarVectores := false; { Se devuelve false (hubo un ERROR, no se leyeron bien los vectores) } + seguir := false; { seguir se pone en false para que termine el bucle } + end; + end; { case } + end; { while } + close(f); { se cierra el archivo de lectura de datos } + end; { cargarVectores } + + {########################################################} + + procedure suma(v1, v2: Vector; var vr: Vector); + { procedimiento que suma dos polinomios. + v1: vector que contiene el primer polinomio a sumar + v2: vector que contiene el segundo polinomio a sumar + vr: vector donde se almacenara el resultado de la suma } + + var + i: integer; { indice para usar en el ciclo for } + + begin { suma } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el vector (de tama¤o maximo TAM) } + vr[i] := v1[i] + v2[i]; { suma los coeficientes de los terminos con igual exponente } + end; { suma } + + {########################################################} + + procedure resta(v1, v2: Vector; var vr: Vector); + { procedimiento que resta dos polinomios. + v1: vector que contiene el primer polinomio + v2: vector que contiene el polinomio para restarle al primero + vr: vector donde se almacenara el resultado de la resta } + + var + i: integer; { indice para usar en el ciclo for } + + begin { resta } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el vector (de tama¤o maximo TAM) } + vr[i] := v1[i] - v2[i]; { resta los coeficientes de los terminos con igual exponente } + end; { resta } + + {########################################################} + + procedure producto(v1, v2: Vector; var vr: Vector); + { procedimiento que multiplica dos polinomios. + v1: vector que contiene el primer polinomio a multiplicar + v2: vector que contiene el segundo polinomio a multiplicar + vr: vector donde se almacenara el resultado de la multiplicacion } + + var + i, j: integer; { indices para usar en los ciclos for } + + begin { producto } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el 1er vector (de tama¤o maximo TAM) } + for j := 0 to TAM - 1 do { recorre el 2do vector (de tama¤o maximo TAM) } + vr[i+j] := vr[i+j] + (v1[i] * v2[j]); + { multiplica los coeficientes de los terminos y lo almacena en la posicion del exponente } + { igual a la suma de los exponentes de v1 y v2, sumando el valor previo de dicha posicion } + end; { producto } + + {########################################################} + + procedure division(v1, v2: Vector; var vr, vResto: Vector); + { procedimiento que divide dos polinomios. + v1: vector que contiene el polinomio denominador + v2: vector que contiene el polinomio divisor + vr: vector donde se almacenara el resultado de la division + vResto: vector donde se almacenara el resto de la division } + var + i, j: integer; { indices para usar en los ciclos for } + vRTmp, { vector auxuliares para almacenar el termino actual del resultado } + vTmp: Vector; { vector auxuliares para almacenar el polinomio que es la multiplicacion del + termino actual del resultado por el divisor } + + begin { division } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vResto); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vTmp); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vRTmp); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := TAM - 1 downto 0 do { recorre el 1er vector (de tama¤o maximo TAM) de atras para adelante } + if v1[i] <> 0 then break; + { busca empezando por el indice (exponete) mas alto el primer coeficiente no nulo } + { si lo encuentra sale del for dejando al valor de i como el de dicho inidice } + for j := TAM - 1 downto 0 do { recorre el 2do vector (de tama¤o maximo TAM) de atras para adelante } + if v2[j] <> 0 then break; + { busca empezando por el indice (exponete) mas alto el primer coeficiente no nulo } + { si lo encuentra sale del for dejando al valor de j como el de dicho inidice } + while i >= j do + begin + vr[i-j] := v1[i] / v2[j]; + vRTmp[i-j] := vr[i-j]; + producto(vRTmp, v2, vTmp); + resta(v1, vTmp, v1); + vRTmp[i-j] := 0; + for i := i downto 0 do + if v1[i] <> 0 then break; + { busca empezando por el indice (exponete) mas alto el primer coeficiente no nulo } + { si lo encuentra sale del for dejando al valor de i como el de dicho inidice } + end; { while } + vResto := v1; + end; { division } + + {########################################################} + +{ Continuacion del programa principal } + +var + i: integer; { variable auxiliar } + v1, v2, vResult, vResto: Vector; + resultado: boolean; + +begin { Comienzo del programa principal } + resultado := cargarVectores(v1, v2); + if resultado then + begin + muestraVector(v1, 'Polinomio 1 = '); + muestraVector(v2, 'Polinomio 2 = '); + suma(v1, v2, vResult); + muestraVector(vResult, 'Polinomio 1 + Polinomio 2 = '); + resta(v1, v2, vResult); + muestraVector(vResult, 'Polinomio 1 - Polinomio 2 = '); + producto(v1, v2, vResult); + muestraVector(vResult, 'Polinomio 1 * Polinomio 2 = '); + end + else + begin + writeln('ERROR: No se pudieron cargar los datos. Revise que el formato del archivo'); + writeln(' sea correcto y que no este siendo usado por otro programa.'); + end; +end. \ No newline at end of file diff --git a/poli_9.pas b/poli_9.pas new file mode 100644 index 0000000..95accba --- /dev/null +++ b/poli_9.pas @@ -0,0 +1,474 @@ +program Polinomios; + +uses + CRT, DOS; { Declaracion de funciones predefinidas + para crear la interfaz grafica } + +const + VERSION = '0.9.8b (POLI_9)'; { version del programa } + + TAM_MAX = 100; { Tama¤o maximo del vector que almacena + la multiplicacion de polinomios } + TAM = TAM_MAX div 2; { Tama¤o maximo (virtual) del vector que contiene + los vector con los que se va a operar } + CR = chr(13); { caracter de retorno del carro } + LF = chr(10); { caracter de nueva linea } + ENDF = chr(26); { caracter de fin del archivo } + TAB = chr(9); { caracter de tabulacion } + SPACE = chr(32); { caracter de espacio } + +type + { Tipo de dato para identificar el estado de la entrada de datos } + Estado = (INICIO, COEF_BUSCA, COEF, COEF_PUNTO, COEF_FIN, EXP_BUSCA, EXP, EXP_FIN, EXP_FIN_BUSCA, POLI_FIN, FIN, ERROR); + Vector = array [0..TAM_MAX-1] of real; { vector para almacenar los polinomios } + + + {########################################################} + + procedure muestraVector(var v: Vector; s: String); + { procedimiento que imprime el polinomio v en pantalla con un titulo s } + + {########################################################} + + function exponente(exp: integer): String; + + var + s: String; { variable temporal } + + begin { exponente } + case exp of + 0: exponente := ''; { si el exponente es nulo, mustra solo el coeficiente } + 1: exponente := 'X'; { si el exponente es 1, mustra el coeficiente y X } + 2: exponente := 'Xý'; { si el exponente es 2, mustra el coeficiente y Xý } + else begin + str(exp, s); { convierte al exponente en string } + exponente := 'X^' + s; { si el exponente es mayor que 1, mustra el coeficiente y X^exp } + end; { else } + end; { case } + end; { exponente } + + {########################################################} + + + var + i: integer; { indice para usar en el ciclo for } + + begin { muestraVector } + writeln; { separacion de una linea } + write(s); { mustra el mensaje } + for i := TAM_MAX - 1 downto 0 do { recorre el vector de atras para adelante } + if v[i] <> 0 then break; { si el coeficiente no es nulo, termina el for dejando a i en ese indice } + if (i = 0) and (v[i] = 0) then { si el primer exponente que encuentra es 0 y el coeficiente es 0, entonces } + begin { muestra el resultado como 0 y sale del procedimiento } + write('0'); { imprime que el resultado es cero } + writeln; { separacion de una linea } + writeln; { separacion de una linea } + exit; { sale de este procedimiento } + end; + if (abs(v[i]) <> 1) or (i = 0) { si el modulo del coeficiente es distinto de 1 o si el exp. es 0 } + then if abs(v[i]) - trunc(abs(v[i])) = 0 then write(trunc(v[i]):1, ' ') { imprime si es un numero entero } + else write(v[i]:1:2, ' ') { imprime si es un numero real } + else if v[i] = -1 then write('-'); { si es -1 entonces solo escribe el signo del termino } + write(exponente(i)); + for i := i - 1 downto 0 do { recorre el vector de atras para adelante } + if v[i] <> 0 then { si el coeficiente no es nulo, termina el for dejando a i en ese indice } + begin + if v[i] < 0 { si el coeficiente en negativo } + then write(' - ') { le agrega el signo - } + else write(' + '); { si no, le agrega el signo + } + if (abs(v[i]) <> 1) or (i = 0) then { si el modulo del coeficiente es distinto de 1 o si el exp. es 0 } + if abs(v[i]) - trunc(abs(v[i])) = 0 then write(trunc(abs(v[i])):1, ' ') { imprime si es un entero } + else write(abs(v[i]):1:2, ' '); { imprime si es un real } + write(exponente(i)); + end; { if } + writeln; { separacion de una linea } + writeln; { separacion de una linea } + end; { muestraVector } + + {########################################################} + + procedure inicializaVector(var v: Vector); + { procedimiento que inicializa un vector de tama¤o tam } + + var i: integer; { indice para usar en el ciclo for } + + begin { inicializaVector } + for i := 0 to TAM_MAX - 1 do { recorre el vector } + v[i] := 0; { inicializa la variable actual en 0 } + end; { inicializaVector } + + {########################################################} + + function ObtenerNombreArchivo: String; + { funcion que obtiene un nombre de archivo valido (es decir, el nombre + de un archivo que exista) } + + {########################################################} + + function fileExists(FileName: String): Boolean; + { funcion extraida de la ayuda del Turbo Pascal 7 + indica si el archivo existe } + + var + F: file; + + begin + {$I-} + Assign(F, FileName); + FileMode := 0; { Set file access to read only } + Reset(F); + Close(F); + {$I+} + FileExists := (IOResult = 0) and (FileName <> ''); + end; { FileExists } + + {########################################################} + + { Continuacion de la funcion ObtenerNombreArchivo } + const + DEFAUL_FILE_NAME = 'datos.txt'; { nombre del archivo por defecto } + + var + tmp: String; { cadena para almacenar el resultado temporal } + + begin { ObtenerNombreArchivo } + { mensaje para entrada del nombre de archivo } + writeln('Ingrese el nombre del archivo con los datos (ENTER = ', DEFAUL_FILE_NAME, '):'); + readln(tmp); { entrada del nombre de archivo } + if tmp = '' then tmp := DEFAUL_FILE_NAME; { se fija si no se ingreso nada y reasigana el nombre } + while not fileExists(tmp) do { repite el proceso hasta que el archivo exista } + begin + write('El archivo ', tmp, ' no existe. Ingrese un nombre correcto'); + if tmp = DEFAUL_FILE_NAME { si es el nombre de archivo predeterminado } + then { entonces, elije un mensaje apropiado } + write(': ') + else + begin { si no es el predeterminado, muestra otro mensaje } + writeln('.'); + write('(ENTER = ', DEFAUL_FILE_NAME, '): '); + end; + readln(tmp); { vuelve a leer el nombre del archivo para ser verificado } + if tmp = '' then tmp := DEFAUL_FILE_NAME; { asigna como nombre de archivo al predeterminado + si no se escribio nada } + end; { fin del loop de verificacion } + ObtenerNombreArchivo := tmp; { asigna el nombre correcto al valor de salida de la funcion } + end; { ObtenerNombreArchivo } + + {########################################################} + + function trans(c: char; e: Estado): Estado; + { establece el estado en el que se encuentra la lectura } + { c es el caracter que se leyo, e es el estado actual de la lectura } + + begin { trans } + case e of { acciona segun es estado actual de la lectura } + INICIO: { estado de inicio de la lectura } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un numero (o negativo), empieza a leer el coeficiente } + SPACE, TAB, CR, LF: trans := COEF_BUSCA; { si es un caracter tipo "espacio", busca el prox. coef. } + else trans := ERROR; { si es otro, da ERROR } + end; + COEF_BUSCA: { estado de busqueda del primer ceoficiente del polinomio } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un numero (o negativo), empieza a leer el coeficiente } + SPACE, TAB, CR, LF: trans := COEF_BUSCA; { si es un caracter tupo "espacio", sigue buscando } + ENDF: trans := FIN; { si es el caracter de fin de archivo, pasa al estado de tarea finalizada } + else trans := ERROR; { si es otro, da ERROR } + end; + COEF: { estado de lectura del coeficiente del termino del polinomio (sin punto decimal) } + case c of { acciona segun el caracter leido } + '0'..'9': trans := COEF; { si es un numero sigue con el mismo estado } + '.': trans := COEF_PUNTO; { si es punto cambia al estado COEF_PUNTO } + SPACE, TAB: trans := COEF_FIN; { si es un espacio o un tabulador, finaliza la lectura del coeficiente } + else trans := ERROR; { si es otra cosa, pasa a estado de error } + end; + COEF_PUNTO: { estado de lectura del coeficiente del termino del polinomio (con punto decimal) } + case c of { acciona segun el caracter leido } + '0'..'9': trans := COEF_PUNTO; { si es un numero sigue con el mismo estado } + SPACE, TAB: trans := COEF_FIN; { si es un espacio o un tabulador, finaliza la lectura del coeficiente } + else trans := ERROR; { si es otra cosa, pasa a estado de error } + end; + COEF_FIN: { estado de fin de la lectura del coeficiente del termino del polinomio } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si el caracter es un numero establece el estado en EXP (exponente) } + SPACE, TAB: trans := EXP_BUSCA; { si es un espacio o tabulador, pasa a buscar el proximo exponente } + else trans := ERROR; { si no es ninguno de los anteriores, el estado pasa a ERROR } + end; + EXP_BUSCA: { estado de busqueda del proximo exponente } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si el caracter es un numero, empieza a leer el exponente } + SPACE, TAB: trans := EXP_BUSCA; { si es un espacio o tabulador, sigue buscando } + else trans := ERROR; { si no es ninguno de los anteriores, el estado pasa a ERROR } + end; + EXP: { estado de lectura del exponente del termino actual del polinomio } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si es un digito, sigue en el mismo estado } + CR: trans := EXP_FIN; { si es un ratorno de carro, finaliza el exponente + (quiere decir que hubo un ) } + ENDF: trans := FIN; { si es el final del archivo, se indica que termino su tarea } + else trans := ERROR; { si es otra cosa, devuelve ERROR } + end; + EXP_FIN: { estado de fin de la lectura del exponente del termino actual del polinomio } + if c = LF then trans := EXP_FIN_BUSCA { debe ser un caracter de nueva linea (para completar el ) } + else trans := ERROR; { si no lo es, devuelve ERROR } + EXP_FIN_BUSCA: { estado de fin de lectura de la nueva linea (luego de finalizar el exponente + ahora decide si termino el polinomio o si sigue leyendo el proximo coeficiente } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un digito (o negativo), pasa a leer en proximo coeficiente } + CR: trans := POLI_FIN; { si es un ratorno de carro o nueva linea, finaliza el polinomio } + else trans := ERROR; { si es otra cosa, devuelve ERROR } + end; + POLI_FIN: { estado de finalizacion del polinomio actual } + if c = LF then trans := COEF_BUSCA { debe ser un caracter de nueva linea (para completar el ), + entonces pasa a buscar el primer coeficiente del nuevo polinomio } + else trans := ERROR; { si no lo es, devuelve ERROR } + FIN: { estado que adquiere cuando se finalizo la tarea } + trans := FIN; { se queda en este estado avisando que termino su tarea } + else { otro estado, no deberia ocurrir, salvo que se le pase a la funcion un estado de ERROR } + trans := ERROR; { si es otro, da ERROR } + end; { case } + end; { trans } + + {########################################################} + + function cargarVectores(var v1, v2: Vector): boolean; + { Funcion que abre el archivo de texto con los datos, lo carga en el vector procesandolo debidamente a medida + que lo lee y, al finalizar, cierra el archivo de texto. + v1 es el primer vector a cargar + v2 es el segundo vector a cargar + devuelve true si la lectura fue hecha con exito, false si hubo un error } + + var + f: Text; { archivo de texto con los datos } + c: char; { caracter que se extrae del archivo de texto } + nombreArchivo: String; { nombre del archivo de datos } + est: Estado; { Indicador del estado actual de la lectura } + seguir: boolean; { indicador para saber si debe seguir con el proceso } + i, { indice del vector del polinomio para ser inicializado } + iExp, { valor temporal para almacenar al exponente } + code, { almacena el resultado de la funcion val (no se usa porque los + datos ya estan validados } + poliN: integer; { numero del polinomio que se esta leyendo } + rCoef: real; { valor temporal para almacenar al coeficiente } + exponente, { string que representa al exponente leido } + coeficiente: String; { string que representa al coeficiente leido } + + begin { cargarVectores } + rCoef := 0.0; { inicializacion de variable } + iExp := 0; { inicializacion de variable } + coeficiente := ''; { inicializacion de variable } + exponente := ''; { inicializacion de variable } + est := INICIO; { empieza con el estado de INICIO } + poliN := 1; { establece que se procesara el primer polinomio } + inicializaVector(v1); { inicializacion del vector 1 (primer polinomio) } + inicializaVector(v2); { inicializacion del vector 2 (segundo polinomio) } + nombreArchivo := ObtenerNombreArchivo; { obtiene el nombre del archivo } + assign(f, nombreArchivo); { asigna la variable al nombre del archivo } + reset(f); { abre el archivo para leerlo desde el principio } + seguir := true; { inicializa seguir e true para comenzar el bucle } + while seguir do begin { continua mientras seguir sea true } + read(f, c); { lee un caracter del archivo de texto } + est := trans(c, est); { establece el nuevo estado de lectura } + case est of { toma una desicion dependiendo del estado en que se encuentre } + INICIO: ; { No hace nada, nunca toma este valor. Solo incica que empezo el proceso } + COEF_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + COEF, COEF_PUNTO: { Si esta leyendo el coeficiente ... } + coeficiente := coeficiente + c; { concatena el caracter a la representacion + de texto del coeficiente } + COEF_FIN: ; { Si termino de leer el coeficiente, no hace nada, la asignacion + se realiza cuando termina de leer el exponente (es necesario + para establecer el indice del vector } + EXP_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + EXP: { Si esta leyendo el exponente ... } + exponente := exponente + c; { concatena el caracter a la representacion + de texto del exponente } + EXP_FIN: { Si termino de leer el exponente, hace las asignaciones correspondientes } + begin { convirtiendo las cadenas de texto en real e integer, segun el caso } + val(coeficiente, rCoef, code); { convierte el coeficiente en real } + val(exponente, iExp, code); { convierte el exponente en integer } + if iExp < TAM { si el exponente es menor que el tama¤o maximo permitido ... } + then if poliN = 1 then v1[iExp] := rCoef { asigna el valor correspondiente } + else v2[iExp] := rCoef { al polinomio correspondiente } + else est := ERROR; { si no es menor, pone el estado en ERROR } + coeficiente := ''; { una vez asignados, vacia los valores del coeficiente y el } + exponente := ''; { exponente para poder realizar las lecturas de los proximos } + end; + EXP_FIN_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + POLI_FIN: { Si termino la lectura de un polinomio ... } + if poliN = 1 then poliN := 2 { si se leyo el 1er polinomio, se indica que se leera el 2do } + else est := FIN; { si no (ya se leyo el segundo), pone el estado en FIN } + FIN: { Si se finalizaron las tareas ... } + begin + { este codigo es el mismo que el de EXP_FIN, se repite aca solo por si el final del + archivo esta pegado al fin del ultimo exponente, en cuyo caso no pasa por el estado + de EXP_FIN (y, por ende, no se pueden hacer las asignaciones correspondientes } + val(coeficiente, rCoef, code); { convierte el coeficiente en real } + val(exponente, iExp, code); { convierte el exponente en integer } + if iExp < TAM { si el exponente es menor que el tama¤o maximo permitido ... } + then if poliN = 1 then v1[iExp] := rCoef { asigna el valor correspondiente } + else v2[iExp] := rCoef { al polinomio correspondiente } + else est := ERROR; { si no es menor, pone el estado en ERROR } + coeficiente := ''; { una vez asignados, vacia los valores del coeficiente y el } + exponente := ''; { exponente para poder realizar las lecturas de los proximos } + { fin del codigo identico a EXP_FIN } + if poliN = 2 then cargarVectores := true { si se leyeron los 2 polinomios, devuelve true } + else cargarVectores := false; { si no se leyeron los dos, devuelve false } + seguir := false; { poner seguir en false para que se termine el bucle } + end; + ERROR: { Si hubo un error ... } + begin + cargarVectores := false; { Se devuelve false (hubo un ERROR, no se leyeron bien los vectores) } + seguir := false; { seguir se pone en false para que termine el bucle } + end; + end; { case } + end; { while } + close(f); { se cierra el archivo de lectura de datos } + end; { cargarVectores } + + {########################################################} + + procedure suma(v1, v2: Vector; var vr: Vector); + { procedimiento que suma dos polinomios. + v1: vector que contiene el primer polinomio a sumar + v2: vector que contiene el segundo polinomio a sumar + vr: vector donde se almacenara el resultado de la suma } + + var + i: integer; { indice para usar en el ciclo for } + + begin { suma } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el vector (de tama¤o maximo TAM) } + vr[i] := v1[i] + v2[i]; { suma los coeficientes de los terminos con igual exponente } + end; { suma } + + {########################################################} + + procedure resta(v1, v2: Vector; var vr: Vector); + { procedimiento que resta dos polinomios. + v1: vector que contiene el primer polinomio + v2: vector que contiene el polinomio para restarle al primero + vr: vector donde se almacenara el resultado de la resta } + + var + i: integer; { indice para usar en el ciclo for } + + begin { resta } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el vector (de tama¤o maximo TAM) } + vr[i] := v1[i] - v2[i]; { resta los coeficientes de los terminos con igual exponente } + end; { resta } + + {########################################################} + + procedure producto(v1, v2: Vector; var vr: Vector); + { procedimiento que multiplica dos polinomios. + v1: vector que contiene el primer polinomio a multiplicar + v2: vector que contiene el segundo polinomio a multiplicar + vr: vector donde se almacenara el resultado de la multiplicacion } + + var + i, j: integer; { indices para usar en los ciclos for } + + begin { producto } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el 1er vector (de tama¤o maximo TAM) } + for j := 0 to TAM - 1 do { recorre el 2do vector (de tama¤o maximo TAM) } + vr[i+j] := vr[i+j] + (v1[i] * v2[j]); + { multiplica los coeficientes de los terminos y lo almacena en la posicion del exponente } + { igual a la suma de los exponentes de v1 y v2, sumando el valor previo de dicha posicion } + end; { producto } + + {########################################################} + + function division(v1, v2: Vector; var vr, vResto: Vector): boolean; + { procedimiento que divide dos polinomios. + v1: vector que contiene el polinomio denominador + v2: vector que contiene el polinomio divisor + vr: vector donde se almacenara el resultado de la division + vResto: vector donde se almacenara el resto de la division + devuelve true si el segundo polinomio no es 0 y se efectua la division y + devuelve false si segundo polinomio es 0 y no se puede efectuar la division } + + var + i, j: integer; { indices para usar en los ciclos for } + vRTmp, { vector auxuliares para almacenar el termino actual del resultado } + vTmp: Vector; { vector auxuliares para almacenar el polinomio que es la multiplicacion del + termino actual del resultado por el divisor } + + begin { division } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vResto); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vTmp); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vRTmp); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := TAM - 1 downto 0 do { recorre el 1er vector (de tama¤o maximo TAM) de atras para adelante } + if v1[i] <> 0 then break; + { busca empezando por el indice (exponete) mas alto el primer coeficiente no nulo } + { si lo encuentra sale del for dejando al valor de i como el de dicho inidice } + for j := TAM - 1 downto 0 do { recorre el 2do vector (de tama¤o maximo TAM) de atras para adelante } + if v2[j] <> 0 then break; + { busca empezando por el indice (exponete) mas alto el primer coeficiente no nulo } + { si lo encuentra sale del for dejando al valor de j como el de dicho inidice } + if (j = 0) and (v2[j] = 0) { si el no se encontro ningun coeficiente no nulo, entonces } + then { el polinomio 2 es nulo y no se puede efectuar la division } + begin { se devuelve false y se quedan los vectores resultado en 0 } + division := false; { devuelve false } + exit; { sale del procedimiento } + end; + while i >= j do { si el primer exponente es mayor o igual que el segundo empieza a dividir } + begin + vr[i-j] := v1[i] / v2[j]; { almacena el resultado de la division entre los coeficientes en + la posicion de la resta de ambos } + vRTmp[i-j] := vr[i-j]; { almacena ese resultado en un polinomio temporal cuyo unico termio + no nulo es el del exponente i-j, para luego multiplicarlo } + producto(vRTmp, v2, vTmp);{ multiplica este polinomio por el segundo almacenado el resultado + en otro temporal, para luego hacer la resta } + resta(v1, vTmp, v1); { resta al primer polinomio, v1, (en su estado actual, no el original) + el temporal vTmp y lo almacena en v1, para poder volver a operarlo de + la misma forma } + vRTmp[i-j] := 0; { resetea el termino del temporal vRTmp que se asigno para los calculos } + for i := i downto 0 do { recorre el vector v1 (de tama¤o maximo TAM) de atras para adelante } + if v1[i] <> 0 then break; + { busca empezando por el indice (exponete) i el primer coeficiente no nulo + si lo encuentra sale del for dejando al valor de i como el de dicho inidice } + end; { while } + vResto := v1; { asigna el vector v1 (que ya no se procesara mas al resto } + division := true; { devuelve true indicando que se finalizo con exito } + end; { division } + + {########################################################} + +{ Continuacion del programa principal } + +var + i: integer; { variable auxiliar } + v1, v2, vResult, vResto: Vector; { vectores para hacer las operaciones } + continua: boolean; { valor para obtener los resultados de algunas funciones } + +begin { Comienzo del programa principal } + continua := cargarVectores(v1, v2); + if continua then + begin + muestraVector(v1, 'Polinomio 1 = '); + muestraVector(v2, 'Polinomio 2 = '); + suma(v1, v2, vResult); + muestraVector(vResult, 'Polinomio 1 + Polinomio 2 = '); + resta(v1, v2, vResult); + muestraVector(vResult, 'Polinomio 1 - Polinomio 2 = '); + producto(v1, v2, vResult); + muestraVector(vResult, 'Polinomio 1 * Polinomio 2 = '); + continua := division(v1, v2, vResult, vResto); + if continua + then + begin + muestraVector(vResult, 'Polinomio 1 / Polinomio 2 = '); + muestraVector(vResto, 'Resto = '); + end + else writeln('El segundo polinomio es nulo, por lo tanto no se puede efectuar la division'); + end + else + begin + writeln('ERROR: No se pudieron cargar los datos. Revise que el formato del archivo'); + writeln(' sea correcto y que no este siendo usado por otro programa.'); + end; +end. \ No newline at end of file diff --git a/term.pas b/term.pas new file mode 100644 index 0000000..36f072a --- /dev/null +++ b/term.pas @@ -0,0 +1,665 @@ +program PolinomiosEnTermino; +{ Programa que lee 2 polinomios desde un archivo de texto para luego + hacer operaciones basicas entre estos (suma, resta, multiplicacion + y division). + El formato del archivo de texto debe ser de la siguiente manera: + + * Se ingresan cada polinomio en lineas sucesivas. + * El primer polinomio puede comenzar a ingresarse en cualquier lugar + del archivo de texto. + * El fin del primer polinomio (y comienzo del segundo) se indica por + medio de 1 o mas lineas en blanco. + * El segundo polinomio puede comenzar a ingresarse en cualquier lugar + del archivo de texto a partir de dicha(s) linea(s) en blanco. + * Cada termino de un polinomio debe estar en la misma linea y comenzar + al principio de esta (excepto el primer termino). + * Los terminos debes estar ordenados de menor a mayor segun el exponente. + * En cada linea se ingresa primero el coeficiente real (puede tener un + signo '-' al comenzar y/o un punto, y solamente uno) y luego el + exponente entero positivo. + * La separacion entre el coeficiente y el exponente debe estar dada por + uno o mas espacios o tabuladores. + * Cualquier caracter incluido en el texto que no sea un degito (0..9), + un punto ('.'), un signo menos ('-'), un espacio (' '), un tabulador + o alguno de los caracteres de nueva linea, dara un error en la + lectura. + * El archivo de texto debe tener formato DOS (es decir, el indicador de + nueva linea debe ser primero un caracter de retorno del carro + seguido inmediatamente por uno de avance de linea). +} + +uses + CRT, DOS; { Declaracion de funciones predefinidas + para crear la interfaz grafica } + +const + VERSION = '1.2.2r (TERM_5)'; { version del programa } + + TAM_MAX = 100; { Tama¤o maximo del vector que almacena + la multiplicacion de polinomios } + TAM = TAM_MAX div 2; { Tama¤o maximo (virtual) del vector que contiene + los vector con los que se va a operar } + CR = chr(13); { caracter de retorno del carro } + LF = chr(10); { caracter de nueva linea } + ENDF = chr(26); { caracter de fin del archivo } + TAB = chr(9); { caracter de tabulacion } + SPACE = chr(32); { caracter de espacio } + +type + { Tipo de dato para identificar el estado de la entrada de datos } + Estado = (INICIO, COEF_BUSCA, COEF, COEF_PUNTO, COEF_FIN, EXP_BUSCA, EXP, EXP_FIN, EXP_FIN_BUSCA, POLI_FIN, FIN, ERROR); + Termino = record { tipo de dato que representa un termino de un polinomio } + coef: real; { parte del coeficiente del termino } + exp: integer; { parte del exponente del termino } + end; { Termino } + Vector = array [0..TAM_MAX-1] of Termino; { vector para almacenar los polinomios } + + + {########################################################} + + procedure muestraVector(var v: Vector; s: String); + { procedimiento que imprime el polinomio v en pantalla con un titulo s } + + {########################################################} + + function exponente(exp: integer): String; + + var + s: String; { variable temporal } + + begin { exponente } + case exp of + 0: exponente := ''; { si el exponente es nulo, mustra solo el coeficiente } + 1: exponente := 'X'; { si el exponente es 1, mustra el coeficiente y X } + 2: exponente := 'Xý'; { si el exponente es 2, mustra el coeficiente y Xý } + else begin + str(exp, s); { convierte al exponente en string } + exponente := 'X^' + s; { si el exponente es mayor que 1, mustra el coeficiente y X^exp } + end; { else } + end; { case } + end; { exponente } + + {########################################################} + + + var + i: integer; { indice para usar en el ciclo for } + + begin { muestraVector } + textcolor(lightcyan); { pone el color del texto en cian claro } + writeln; { separacion de una linea } + write(s); { mustra el mensaje } + textcolor(lightmagenta); { pone el color del texto en magenta claro } + for i := TAM_MAX - 1 downto 0 do { recorre el vector de atras para adelante } + if v[i].coef <> 0 then break; { si el coeficiente no es nulo, termina el for dejando a i en ese indice } + if (v[i].exp = 0) and (v[i].coef = 0) then { si el primer exponente que encuentra es 0 y el coeficiente es 0, entonces } + begin { muestra el resultado como 0 y sale del procedimiento } + write('0'); { imprime que el resultado es cero } + writeln; { separacion de una linea } + writeln; { separacion de una linea } + exit; { sale de este procedimiento } + end; + if (abs(v[i].coef) <> 1) or (v[i].exp = 0) { si el modulo del coeficiente es distinto de 1 o si el exp. es 0 } + then if abs(v[i].coef) - trunc(abs(v[i].coef)) = 0 then write(trunc(v[i].coef):1, ' ') {imprime si es un numero entero} + else write(v[i].coef:1:2, ' ') { imprime si es un numero real } + else if v[i].coef = -1 then write('-'); { si es -1 entonces solo escribe el signo del termino } + write(exponente(v[i].exp)); + for i := i - 1 downto 0 do { recorre el vector de atras para adelante } + if v[i].coef <> 0 then { si el coeficiente no es nulo, termina el for dejando a i en ese indice } + begin + if v[i].coef < 0 { si el coeficiente en negativo } + then write(' - ') { le agrega el signo - } + else write(' + '); { si no, le agrega el signo + } + if (abs(v[i].coef) <> 1) or (i = 0) then { si el modulo del coeficiente es distinto de 1 o si el exp. es 0 } + if abs(v[i].coef) - trunc(abs(v[i].coef)) = 0 + then write(trunc(abs(v[i].coef)):1, ' ') { imprime si es entero } + else write(abs(v[i].coef):1:2, ' '); { imprime si es un real } + write(exponente(v[i].exp)); + end; { if } + writeln; { separacion de una linea } + writeln; { separacion de una linea } + end; { muestraVector } + + {########################################################} + + procedure inicializaVector(var v: Vector); + { procedimiento que inicializa un vector de tama¤o tam } + + var i: integer; { indice para usar en el ciclo for } + + begin { inicializaVector } + for i := 0 to TAM_MAX - 1 do { recorre el vector } + begin + v[i].coef := 0.0; { inicializa la variable actual en 0 } + v[i].exp := 0; { inicializa la variable actual en 0 } + end; + end; { inicializaVector } + + {########################################################} + + function ObtenerNombreArchivo: String; + { funcion que obtiene un nombre de archivo valido (es decir, el nombre + de un archivo que exista) } + + {########################################################} + + function fileExists(FileName: String): Boolean; + { funcion extraida de la ayuda del Turbo Pascal 7 + indica si el archivo existe } + + var + F: file; + + begin + {$I-} + Assign(F, FileName); + FileMode := 0; { Set file access to read only } + Reset(F); + Close(F); + {$I+} + FileExists := (IOResult = 0) and (FileName <> ''); + end; { FileExists } + + {########################################################} + + { Continuacion de la funcion ObtenerNombreArchivo } + const + DEFAUL_FILE_NAME = 'datos.txt'; { nombre del archivo por defecto } + + var + tmp: String; { cadena para almacenar el resultado temporal } + + begin { ObtenerNombreArchivo } + { mensaje para entrada del nombre de archivo } + clrscr; { borra la pantalla } + textcolor( Yellow ); { establece el color para el texto a amarillo } + gotoxy( 30, 3 ); { va a las coordenas de pantalla 25 horizontal, 3 verical } + writeln( 'PolinomiosEnTermino' ); { titulo } + gotoxy( 30, 4 ); { va a las coordenas de pantalla 25 horizontal, 4 verical } + writeln( '~~~~~~~~~~~~~~~~~~~' ); { subrayado del titulo } + textcolor( LightCyan ); { establece el color para el texto a cian claro } + gotoxy( 1, 7 ); { va a las coordenas de pantalla 1 horizontal, 7 verical } + writeln(' Ingrese el nombre del archivo con los datos (ENTER = ', DEFAUL_FILE_NAME, '):'); + readln(tmp); { entrada del nombre de archivo } + if tmp = '' then tmp := DEFAUL_FILE_NAME; { se fija si no se ingreso nada y reasigana el nombre } + while not fileExists(tmp) do { repite el proceso hasta que el archivo exista } + begin + clrscr; { borra la pantalla } + textcolor( Yellow ); { establece el color para el texto a amarillo } + gotoxy( 30, 3 ); { va a las coordenas de pantalla 25 horizontal, 3 verical } + writeln( 'PolinomiosEnTermino' ); { titulo } + gotoxy( 30, 4 ); { va a las coordenas de pantalla 25 horizontal, 4 verical } + writeln( '~~~~~~~~~~~~~~~~~~~' ); { subrayado del titulo } + textcolor( LightCyan ); { establece el color para el texto a cian claro } + gotoxy( 1, 7 ); { va a las coordenas de pantalla 1 horizontal, 7 verical } + write(' El archivo ', tmp, ' no existe. Ingrese un nombre correcto'); + if tmp = DEFAUL_FILE_NAME { si es el nombre de archivo predeterminado } + then { entonces, elije un mensaje apropiado } + write(': ') + else + begin { si no es el predeterminado, muestra otro mensaje } + writeln('.'); + write(' (ENTER = ', DEFAUL_FILE_NAME, '): '); + end; + readln(tmp); { vuelve a leer el nombre del archivo para ser verificado } + if tmp = '' then tmp := DEFAUL_FILE_NAME; { asigna como nombre de archivo al predeterminado + si no se escribio nada } + end; { fin del loop de verificacion } + ObtenerNombreArchivo := tmp; { asigna el nombre correcto al valor de salida de la funcion } + end; { ObtenerNombreArchivo } + + {########################################################} + + function trans(c: char; e: Estado): Estado; + { establece el estado en el que se encuentra la lectura } + { c es el caracter que se leyo, e es el estado actual de la lectura } + + begin { trans } + case e of { acciona segun es estado actual de la lectura } + INICIO: { estado de inicio de la lectura } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un numero (o negativo), empieza a leer el coeficiente } + SPACE, TAB, CR, LF: trans := COEF_BUSCA; { si es un caracter tipo "espacio", busca el prox. coef. } + else trans := ERROR; { si es otro, da ERROR } + end; + COEF_BUSCA: { estado de busqueda del primer ceoficiente del polinomio } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un numero (o negativo), empieza a leer el coeficiente } + SPACE, TAB, CR, LF: trans := COEF_BUSCA; { si es un caracter tupo "espacio", sigue buscando } + ENDF: trans := FIN; { si es el caracter de fin de archivo, pasa al estado de tarea finalizada } + else trans := ERROR; { si es otro, da ERROR } + end; + COEF: { estado de lectura del coeficiente del termino del polinomio (sin punto decimal) } + case c of { acciona segun el caracter leido } + '0'..'9': trans := COEF; { si es un numero sigue con el mismo estado } + '.': trans := COEF_PUNTO; { si es punto cambia al estado COEF_PUNTO } + SPACE, TAB: trans := COEF_FIN; { si es un espacio o un tabulador, finaliza la lectura del coeficiente } + else trans := ERROR; { si es otra cosa, pasa a estado de error } + end; + COEF_PUNTO: { estado de lectura del coeficiente del termino del polinomio (con punto decimal) } + case c of { acciona segun el caracter leido } + '0'..'9': trans := COEF_PUNTO; { si es un numero sigue con el mismo estado } + SPACE, TAB: trans := COEF_FIN; { si es un espacio o un tabulador, finaliza la lectura del coeficiente } + else trans := ERROR; { si es otra cosa, pasa a estado de error } + end; + COEF_FIN: { estado de fin de la lectura del coeficiente del termino del polinomio } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si el caracter es un numero establece el estado en EXP (exponente) } + SPACE, TAB: trans := EXP_BUSCA; { si es un espacio o tabulador, pasa a buscar el proximo exponente } + else trans := ERROR; { si no es ninguno de los anteriores, el estado pasa a ERROR } + end; + EXP_BUSCA: { estado de busqueda del proximo exponente } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si el caracter es un numero, empieza a leer el exponente } + SPACE, TAB: trans := EXP_BUSCA; { si es un espacio o tabulador, sigue buscando } + else trans := ERROR; { si no es ninguno de los anteriores, el estado pasa a ERROR } + end; + EXP: { estado de lectura del exponente del termino actual del polinomio } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si es un digito, sigue en el mismo estado } + CR: trans := EXP_FIN; { si es un ratorno de carro, finaliza el exponente + (quiere decir que hubo un ) } + ENDF: trans := FIN; { si es el final del archivo, se indica que termino su tarea } + else trans := ERROR; { si es otra cosa, devuelve ERROR } + end; + EXP_FIN: { estado de fin de la lectura del exponente del termino actual del polinomio } + if c = LF then trans := EXP_FIN_BUSCA { debe ser un caracter de nueva linea (para completar el ) } + else trans := ERROR; { si no lo es, devuelve ERROR } + EXP_FIN_BUSCA: { estado de fin de lectura de la nueva linea (luego de finalizar el exponente + ahora decide si termino el polinomio o si sigue leyendo el proximo coeficiente } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un digito (o negativo), pasa a leer en proximo coeficiente } + CR: trans := POLI_FIN; { si es un ratorno de carro o nueva linea, finaliza el polinomio } + else trans := ERROR; { si es otra cosa, devuelve ERROR } + end; + POLI_FIN: { estado de finalizacion del polinomio actual } + if c = LF then trans := COEF_BUSCA { debe ser un caracter de nueva linea (para completar el ), + entonces pasa a buscar el primer coeficiente del nuevo polinomio } + else trans := ERROR; { si no lo es, devuelve ERROR } + FIN: { estado que adquiere cuando se finalizo la tarea } + trans := FIN; { se queda en este estado avisando que termino su tarea } + else { otro estado, no deberia ocurrir, salvo que se le pase a la funcion un estado de ERROR } + trans := ERROR; { si es otro, da ERROR } + end; { case } + end; { trans } + + {########################################################} + + function cargarVectores(var v1, v2: Vector): boolean; + { Funcion que abre el archivo de texto con los datos, lo carga en el vector procesandolo debidamente a medida + que lo lee y, al finalizar, cierra el archivo de texto. + v1 es el primer vector a cargar + v2 es el segundo vector a cargar + devuelve true si la lectura fue hecha con exito, false si hubo un error } + + var + f: Text; { archivo de texto con los datos } + c: char; { caracter que se extrae del archivo de texto } + nombreArchivo: String; { nombre del archivo de datos } + est: Estado; { Indicador del estado actual de la lectura } + seguir: boolean; { indicador para saber si debe seguir con el proceso } + i, { indice del vector del polinomio para ser inicializado } + iExp, { valor temporal para almacenar al exponente } + code, { almacena el resultado de la funcion val (no se usa porque los + datos ya estan validados } + poliN: integer; { numero del polinomio que se esta leyendo } + rCoef: real; { valor temporal para almacenar al coeficiente } + exponente, { string que representa al exponente leido } + coeficiente: String; { string que representa al coeficiente leido } + + begin { cargarVectores } + rCoef := 0.0; { inicializacion de variable } + iExp := 0; { inicializacion de variable } + coeficiente := ''; { inicializacion de variable } + exponente := ''; { inicializacion de variable } + est := INICIO; { empieza con el estado de INICIO } + poliN := 1; { establece que se procesara el primer polinomio } + inicializaVector(v1); { inicializacion del vector 1 (primer polinomio) } + inicializaVector(v2); { inicializacion del vector 2 (segundo polinomio) } + nombreArchivo := ObtenerNombreArchivo; { obtiene el nombre del archivo } + assign(f, nombreArchivo); { asigna la variable al nombre del archivo } + reset(f); { abre el archivo para leerlo desde el principio } + seguir := true; { inicializa seguir e true para comenzar el bucle } + while seguir do begin { continua mientras seguir sea true } + read(f, c); { lee un caracter del archivo de texto } + est := trans(c, est); { establece el nuevo estado de lectura } + case est of { toma una desicion dependiendo del estado en que se encuentre } + INICIO: ; { No hace nada, nunca toma este valor. Solo incica que empezo el proceso } + COEF_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + COEF, COEF_PUNTO: { Si esta leyendo el coeficiente ... } + coeficiente := coeficiente + c; { concatena el caracter a la representacion + de texto del coeficiente } + COEF_FIN: ; { Si termino de leer el coeficiente, no hace nada, la asignacion + se realiza cuando termina de leer el exponente (es necesario + para establecer el indice del vector } + EXP_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + EXP: { Si esta leyendo el exponente ... } + exponente := exponente + c; { concatena el caracter a la representacion + de texto del exponente } + EXP_FIN: { Si termino de leer el exponente, hace las asignaciones correspondientes } + begin { convirtiendo las cadenas de texto en real e integer, segun el caso } + val(coeficiente, rCoef, code); { convierte el coeficiente en real } + val(exponente, iExp, code); { convierte el exponente en integer } + if iExp < TAM { si el exponente es menor que el tama¤o maximo permitido ... } + then if poliN = 1 + then { si es el polinomio 1 } + begin + v1[iExp].coef := rCoef; { asigna el valor correspondiente } + v1[iExp].exp := iExp; { asigna el valor correspondiente } + end + else { si es el polinomio 2 } + begin + v2[iExp].coef := rCoef; { asigna el valor correspondiente } + v2[iExp].exp := iExp; { asigna el valor correspondiente } + end + else est := ERROR; { si no es menor, pone el estado en ERROR } + coeficiente := ''; { una vez asignados, vacia los valores del coeficiente y el } + exponente := ''; { exponente para poder realizar las lecturas de los proximos } + end; + EXP_FIN_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + POLI_FIN: { Si termino la lectura de un polinomio ... } + if poliN = 1 then poliN := 2 { si se leyo el 1er polinomio, se indica que se leera el 2do } + else est := FIN; { si no (ya se leyo el segundo), pone el estado en FIN } + FIN: { Si se finalizaron las tareas ... } + begin + cargarVectores := true; { en principio se establece que la lectura se hizo con exito ) } + seguir := false; { poner seguir en false para que se termine el bucle } + { este codigo es similar al de EXP_FIN, se hacen las asignaciones por el caso en que el fin + del archivo esta pegado al fin del ultimo exponente, en cuyo caso no pasa por el estado + de EXP_FIN (y, por ende, no se pueden hacer las asignaciones correspondientes } + val(coeficiente, rCoef, code); { convierte el coeficiente en real } + val(exponente, iExp, code); { convierte el exponente en integer } + if iExp < TAM { si el exponente es menor que el tama¤o maximo permitido ... } + then if poliN = 2 + then { si es el polinomio 2 } + begin + v2[iExp].coef := rCoef; { asigna el valor correspondiente } + v2[iExp].exp := iExp; { asigna el valor correspondiente } + end + else cargarVectores := false { si es el primero, no se hizo bien la lectura } + else cargarVectores := false; { si no es menor, no se hizo bien la lectura } + end; + ERROR: { Si hubo un error ... } + begin + cargarVectores := false; { Se devuelve false (hubo un ERROR, no se leyeron bien los vectores) } + seguir := false; { seguir se pone en false para que termine el bucle } + end; + end; { case } + end; { while } + close(f); { se cierra el archivo de lectura de datos } + end; { cargarVectores } + + {########################################################} + + procedure suma(v1, v2: Vector; var vr: Vector); + { procedimiento que suma dos polinomios. + v1: vector que contiene el primer polinomio a sumar + v2: vector que contiene el segundo polinomio a sumar + vr: vector donde se almacenara el resultado de la suma } + + var + i: integer; { indice para usar en el ciclo for } + + begin { suma } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el vector (de tama¤o maximo TAM) } + begin + vr[i].coef := v1[i].coef + v2[i].coef; { suma los coeficientes de los terminos con igual exponente } + vr[i].exp := i; { establece como valor del exponente al indice } + end; + end; { suma } + + {########################################################} + + procedure resta(v1, v2: Vector; var vr: Vector); + { procedimiento que resta dos polinomios. + v1: vector que contiene el primer polinomio + v2: vector que contiene el polinomio para restarle al primero + vr: vector donde se almacenara el resultado de la resta } + + var + i: integer; { indice para usar en el ciclo for } + + begin { resta } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el vector (de tama¤o maximo TAM) } + begin + vr[i].coef := v1[i].coef - v2[i].coef; { resta los coeficientes de los terminos con igual exponente } + vr[i].exp := i; { establece como valor del exponente al indice } + end; + end; { resta } + + {########################################################} + + procedure producto(v1, v2: Vector; var vr: Vector); + { procedimiento que multiplica dos polinomios. + v1: vector que contiene el primer polinomio a multiplicar + v2: vector que contiene el segundo polinomio a multiplicar + vr: vector donde se almacenara el resultado de la multiplicacion } + + var + i, j: integer; { indices para usar en los ciclos for } + + begin { producto } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el 1er vector (de tama¤o maximo TAM) } + for j := 0 to TAM - 1 do { recorre el 2do vector (de tama¤o maximo TAM) } + begin + vr[i+j].coef := vr[i+j].coef + (v1[i].coef * v2[j].coef); + { multiplica los coeficientes de los terminos y lo almacena en la posicion del exponente } + { igual a la suma de los exponentes de v1 y v2, sumando el valor previo de dicha posicion } + vr[i+j].exp := i+j; { establece como exponente a la suma de los otros dos } + end; + end; { producto } + + {########################################################} + + function division(v1, v2: Vector; var vr, vResto: Vector): boolean; + { procedimiento que divide dos polinomios. + v1: vector que contiene el polinomio denominador + v2: vector que contiene el polinomio divisor + vr: vector donde se almacenara el resultado de la division + vResto: vector donde se almacenara el resto de la division + devuelve true si el segundo polinomio no es 0 y se efectua la division y + devuelve false si segundo polinomio es 0 y no se puede efectuar la division } + + var + i, j: integer; { indices para usar en los ciclos for } + vRTmp, { vector auxuliares para almacenar el termino actual del resultado } + vTmp: Vector; { vector auxuliares para almacenar el polinomio que es la multiplicacion del + termino actual del resultado por el divisor } + + begin { division } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vResto); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vTmp); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vRTmp); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := TAM - 1 downto 0 do { recorre el 1er vector (de tama¤o maximo TAM) de atras para adelante } + if v1[i].coef <> 0 then break; + { busca empezando por el indice (exponete) mas alto el primer coeficiente no nulo } + { si lo encuentra sale del for dejando al valor de i como el de dicho inidice } + for j := TAM - 1 downto 0 do { recorre el 2do vector (de tama¤o maximo TAM) de atras para adelante } + if v2[j].coef <> 0 then break; + { busca empezando por el indice (exponete) mas alto el primer coeficiente no nulo } + { si lo encuentra sale del for dejando al valor de j como el de dicho inidice } + if (j = 0) and (v2[j].coef = 0) { si el no se encontro ningun coeficiente no nulo, entonces } + then { el polinomio 2 es nulo y no se puede efectuar la division } + begin { se devuelve false y se quedan los vectores resultado en 0 } + division := false; { devuelve false } + exit; { sale del procedimiento } + end; + while i >= j do { si el primer exponente es mayor o igual que el segundo empieza a dividir } + begin + vr[i-j].coef := v1[i].coef / v2[j].coef; { almacena el resultado de la division entre los coeficientes en } + vr[i-j].exp := v1[i].exp - v2[j].exp; { coeficientes en la posicion de la resta de ambos } + vRTmp[i-j].coef := vr[i-j].coef; { almacena ese resultado en un polinomio temporal cuyo unico termio } + vRTmp[i-j].exp := vr[i-j].exp; { no nulo es el del exponente i-j, para luego multiplicarlo } + producto(vRTmp, v2, vTmp);{ multiplica este polinomio por el segundo almacenado el resultado + en otro temporal, para luego hacer la resta } + resta(v1, vTmp, v1); { resta al primer polinomio, v1, (en su estado actual, no el original) + el temporal vTmp y lo almacena en v1, para poder volver a operarlo de + la misma forma } + vRTmp[i-j].coef := 0.0; {resetea el coeficiente del termino del temporal vRTmp que se asigno para los calculos} + vRTmp[i-j].exp := 0; { resetea el exponente del termino del temporal vRTmp que se asigno para los calculos } + for i := i downto 0 do { recorre el vector v1 (de tama¤o maximo TAM) de atras para adelante } + if v1[i].coef <> 0 then break; + { busca empezando por el indice (exponete) i el primer coeficiente no nulo + si lo encuentra sale del for dejando al valor de i como el de dicho inidice } + end; { while } + vResto := v1; { asigna el vector v1 (que ya no se procesara mas al resto } + division := true; { devuelve true indicando que se finalizo con exito } + end; { division } + + {########################################################} + + procedure mensajeSalida; { muestra un mensaje en la salida del programa } + + begin + writeln; { linea en blanco } + NormVideo; { reestablece los colores a los valores por defecto } + clrscr; { borra la pantalla } + writeln; { linea en blanco } + textcolor(white); { cambia el color del texto } + writeln(' PolinomiosEnTermino versi¢n ', VERSION); { mensaje con version del programa } + NormVideo; { reestablece los colores a los valores por defecto } + writeln(' Desarrollado por: Javier Grijalba'); { mensaje con los integrantes del grupo } + writeln(' Leandro Lucarella'); + writeln(' Erasmo Troncovich'); + writeln(' Diego Wojnicki'); + writeln(' para la Facultad de Ingenier¡a de la Universidad de Buenos Aires.'); + writeln(' Consultas y/o sugerencias a:'); + writeln; + textcolor(LightMagenta); { cambia el color del texto } + write(' lluca@cnba.uba.ar'); + NormVideo; { reestablece los colores a los valores por defecto } + write(' o '); + textcolor(LightMagenta); { cambia el color del texto } + writeln('grijalba@cvtci.com.ar'); + NormVideo; { reestablece los colores a los valores por defecto } + writeln; + writeln(' (c) 1999 - Todos los derechos reservados.'); + delay(750); + end; + + + {########################################################} + + +var + i: integer; { variable auxiliar } + v1, v2, vResult, vResto: Vector; { vectores para hacer las operaciones } + seguir, { indicador para saber si sigue corriendo el programa } + noNulo, { indicador para saber si en la division el divisor es nulo } + continua: boolean; { indicador para saber si se leyeron bien los polinomios } + tecla: char; { entrada de teclado del usuario para elegir una opcion } + +begin { programa principal } + textbackground( Blue ); { establece el color para el fondo a azul } + continua := cargarVectores(v1, v2); { carga los vectores del archivo de datos } + if continua then { si se leyeron bien ... } + begin + seguir := true; { inicializa la variable en true para que entre en el ciclo while } + while seguir do { mientras el usuario no salga del programa } + begin + clrscr; { borra la pantalla } + textcolor(Yellow); { establece el color para el texto a amarillo } + gotoxy( 30, 3 ); { va a las coordenas de pantalla 25 horizontal, 3 verical } + writeln( 'PolinomiosEnTermino' ); { titulo } + gotoxy( 30, 4 ); { va a las coordenas de pantalla 25 horizontal, 4 verical } + writeln( '~~~~~~~~~~~~~~~~~~~' ); { subrayado del titulo } + textcolor(LightCyan); { establece el color para el texto a cian claro } + gotoxy( 1, 7 ); { va a las coordenas de pantalla 1 horizontal, 7 verical } + writeln( ' Elija que desea hacer:' ); { mensaje } + writeln( ' ----- --- ----- ------' ); { mensaje } + textcolor(LightGray); { establece el color para el texto a gris claro } + writeln; { mensaje con las opciones ... } + writeln; + writeln( ' 1.- Ver el polinomio 1.' ); + writeln( ' 2.- Ver el polinomio 2.' ); + writeln( ' 3.- Sumar los polinomios.' ); + writeln( ' 4.- Restar el polinomio 2 al polinomio 1 (poli1 - poli2).' ); + writeln( ' 5.- Restar el polinomio 1 al polinomio 2 (poli2 - poli1).' ); + writeln( ' 6.- Multiplicar los polinomios.' ); + writeln( ' 7.- Polinomio 1 dividido polinomio 2 (poli1 / poli2).' ); + writeln( ' 8.- Polinomio 2 dividido polinomio 1 (poli2 / poli1).' ); + writeln( ' 0.- Salir.' ); + gotoxy(1, 23); { va a las coordenas de pantalla 1 horizontal, 23 verical } + textcolor(White ); { establece el color para el texto a blanco } + write(' Ingrese su opci¢n: '); + textcolor(Yellow); { establece el color para el texto a amarillo } + tecla := readkey; { lee una tecla del usuario indicando la opcion que elijio } + while ((tecla < '1') or (tecla > '8')) and (tecla <> '0') do { mientras sea una tecla no admitida } + begin + textcolor(White); { establece el color para el texto a blanco } + gotoxy( 1, 23 ); { va a las coordenas de pantalla 1 horizontal, 7 verical } + write(' Ingrese su opci¢n ("1" a "8" o "0"): ' ); + textcolor(Yellow); { establece el color para el texto a amarillo } + tecla := readkey; { lee una tecla del usuario indicando la opcion que elijio } + end; { while } + if tecla = '0' then { si la opcion fue salir del programa ... } + begin + mensajeSalida; { presenta un mensaje de salida } + exit; { sale del programa } + end; + clrscr; { borra la pantalla } + textcolor(Yellow); { establece el color para el texto a amarillo } + gotoxy( 30, 3 ); { va a las coordenas de pantalla 25 horizontal, 3 verical } + writeln( 'PolinomiosEnTermino' ); { titulo } + gotoxy( 30, 4 ); { va a las coordenas de pantalla 25 horizontal, 4 verical } + writeln( '~~~~~~~~~~~~~~~~~~~' ); { subrayado del titulo } + textcolor(LightCyan); { establece el color para el texto a cian claro } + gotoxy(1, 7); { va a las coordenas de pantalla 1 horizontal, 7 verical } + case tecla of + '1': muestraVector(v1, ' Polinomio 1 = '); + '2': muestraVector(v2, ' Polinomio 2 = '); + '3': begin + suma(v1, v2, vResult); + muestraVector(vResult, ' Polinomio 1 + Polinomio 2 = '); + end; { case 3 } + '4': begin + resta(v1, v2, vResult); + muestraVector(vResult, ' Polinomio 1 - Polinomio 2 = '); + end; { case 4 } + '5': begin + resta(v2, v1, vResult); + muestraVector(vResult, ' Polinomio 2 - Polinomio 1 = '); + end; { case 5 } + '6': begin + producto(v1, v2, vResult); + muestraVector(vResult, ' Polinomio 1 * Polinomio 2 = '); + end; { case 6 } + '7': begin + noNulo := division(v1, v2, vResult, vResto); + if noNulo + then + begin + muestraVector(vResult, ' Polinomio 1 / Polinomio 2 = '); + muestraVector(vResto, ' Resto = '); + end + else writeln(' El polinomio 2 es nulo, por lo tanto no se puede efectuar la division.'); + end; { case 7 } + '8': begin + noNulo := division(v2, v1, vResult, vResto); + if noNulo + then + begin + muestraVector(vResult, 'Polinomio 2 / Polinomio 1 = '); + muestraVector(vResto, 'Resto = '); + end + else writeln(' El polinomio 1 es nulo, por lo tanto no se puede efectuar la division.'); + end; { case 8 } + '0': ; { no hace nada, nunca deberia entrar en este case } + end; { case } + writeln; { los siguientes mensajes son para que el usuario pueda ver los datos y luego } + writeln; { presione una tecla para continuar } + textcolor(white); { pone el color del texto en blanco } + writeln(' Presione una tecla para continuar ...'); + tecla := readkey; + end; { while } + end + else { si los vectores no se leyeron bien ... } + begin { presenta un mensaje de error } + writeln('ERROR: No se pudieron cargar los datos. Revise que el formato del archivo'); + writeln(' sea correcto y que no este siendo usado por otro programa.'); + end; +end. { programa principal } \ No newline at end of file diff --git a/term_0.pas b/term_0.pas new file mode 100644 index 0000000..a15d4a3 --- /dev/null +++ b/term_0.pas @@ -0,0 +1,525 @@ +program PolinomiosEnTermino; +{ Programa que lee 2 polinomios desde un archivo de texto para luego + hacer operaciones basicas entre estos (suma, resta, multiplicacion + y division). + El formato del archivo de texto debe ser de la siguiente manera: + + * Se ingresan cada polinomio en lineas sucesivas. + * El primer polinomio puede comenzar a ingresarse en cualquier lugar + del archivo de texto. + * El fin del primer polinomio (y comienzo del segundo) se indica por + medio de 1 o mas lineas en blanco. + * El segundo polinomio puede comenzar a ingresarse en cualquier lugar + del archivo de texto a partir de dicha(s) linea(s) en blanco. + * Cada termino de un polinomio debe estar en la misma linea y comenzar + al principio de esta (excepto el primer termino). + * En cada linea se ingresa primero el coeficiente real (puede tener un + signo '-' al comenzar y/o un punto, y solamente uno) y luego el + exponente entero positivo. + * La separacion entre el coeficiente y el exponente debe estar dada por + uno o mas espacios o tabuladores. + * Cualquier caracter incluido en el texto que no sea un degito (0..9), + un punto ('.'), un signo menos ('-'), un espacio (' '), un tabulador + o alguno de los caracteres de nueva linea, dara un error en la + lectura. + * El archivo de texto debe tener formato DOS (es decir, el indicador de + nueva linea debe ser primero un caracter de retorno del carro + seguido inmediatamente por uno de avance de linea). +} + +uses + CRT, DOS; { Declaracion de funciones predefinidas + para crear la interfaz grafica } + +const + VERSION = '0.0.1a (TERM_0)'; { version del programa } + + TAM_MAX = 100; { Tama¤o maximo del vector que almacena + la multiplicacion de polinomios } + TAM = TAM_MAX div 2; { Tama¤o maximo (virtual) del vector que contiene + los vector con los que se va a operar } + CR = chr(13); { caracter de retorno del carro } + LF = chr(10); { caracter de nueva linea } + ENDF = chr(26); { caracter de fin del archivo } + TAB = chr(9); { caracter de tabulacion } + SPACE = chr(32); { caracter de espacio } + +type + { Tipo de dato para identificar el estado de la entrada de datos } + Estado = (INICIO, COEF_BUSCA, COEF, COEF_PUNTO, COEF_FIN, EXP_BUSCA, EXP, EXP_FIN, EXP_FIN_BUSCA, POLI_FIN, FIN, ERROR); + Termino = record + coef: real; + exp: integer; + end; + Vector = array [0..TAM_MAX-1] of Termino; { vector para almacenar los polinomios } + + + {########################################################} + + procedure muestraVector(var v: Vector; s: String); + { procedimiento que imprime el polinomio v en pantalla con un titulo s } + + {########################################################} + + function exponente(exp: integer): String; + + var + s: String; { variable temporal } + + begin { exponente } + case exp of + 0: exponente := ''; { si el exponente es nulo, mustra solo el coeficiente } + 1: exponente := 'X'; { si el exponente es 1, mustra el coeficiente y X } + 2: exponente := 'Xý'; { si el exponente es 2, mustra el coeficiente y Xý } + else begin + str(exp, s); { convierte al exponente en string } + exponente := 'X^' + s; { si el exponente es mayor que 1, mustra el coeficiente y X^exp } + end; { else } + end; { case } + end; { exponente } + + {########################################################} + + + var + i: integer; { indice para usar en el ciclo for } + + begin { muestraVector } + writeln; { separacion de una linea } + write(s); { mustra el mensaje } + for i := TAM_MAX - 1 downto 0 do { recorre el vector de atras para adelante } + if v[i].coef <> 0 then break; { si el coeficiente no es nulo, termina el for dejando a i en ese indice } + if (v[i].exp = 0) and (v[i].coef = 0) then { si el primer exponente que encuentra es 0 y el coeficiente es 0, entonces } + begin { muestra el resultado como 0 y sale del procedimiento } + write('0'); { imprime que el resultado es cero } + writeln; { separacion de una linea } + writeln; { separacion de una linea } + exit; { sale de este procedimiento } + end; + if (abs(v[i].coef) <> 1) or (v[i].exp = 0) { si el modulo del coeficiente es distinto de 1 o si el exp. es 0 } + then if abs(v[i].coef) - trunc(abs(v[i].coef)) = 0 then write(trunc(v[i].coef):1, ' ') {imprime si es un numero entero} + else write(v[i].coef:1:2, ' ') { imprime si es un numero real } + else if v[i].coef = -1 then write('-'); { si es -1 entonces solo escribe el signo del termino } + write(exponente(v[i].exp)); + for i := i - 1 downto 0 do { recorre el vector de atras para adelante } + if v[i].coef <> 0 then { si el coeficiente no es nulo, termina el for dejando a i en ese indice } + begin + if v[i].coef < 0 { si el coeficiente en negativo } + then write(' - ') { le agrega el signo - } + else write(' + '); { si no, le agrega el signo + } + if (abs(v[i].coef) <> 1) or (i = 0) then { si el modulo del coeficiente es distinto de 1 o si el exp. es 0 } + if abs(v[i].coef) - trunc(abs(v[i].coef)) = 0 + then write(trunc(abs(v[i].coef)):1, ' ') { imprime si es entero } + else write(abs(v[i].coef):1:2, ' '); { imprime si es un real } + write(exponente(v[i].exp)); + end; { if } + writeln; { separacion de una linea } + writeln; { separacion de una linea } + end; { muestraVector } + + {########################################################} + + procedure inicializaVector(var v: Vector); + { procedimiento que inicializa un vector de tama¤o tam } + + var i: integer; { indice para usar en el ciclo for } + + begin { inicializaVector } + for i := 0 to TAM_MAX - 1 do { recorre el vector } + begin + v[i].coef := 0.0; { inicializa la variable actual en 0 } + v[i].exp := 0; { inicializa la variable actual en 0 } + end; + end; { inicializaVector } + + {########################################################} + + function ObtenerNombreArchivo: String; + { funcion que obtiene un nombre de archivo valido (es decir, el nombre + de un archivo que exista) } + + {########################################################} + + function fileExists(FileName: String): Boolean; + { funcion extraida de la ayuda del Turbo Pascal 7 + indica si el archivo existe } + + var + F: file; + + begin + {$I-} + Assign(F, FileName); + FileMode := 0; { Set file access to read only } + Reset(F); + Close(F); + {$I+} + FileExists := (IOResult = 0) and (FileName <> ''); + end; { FileExists } + + {########################################################} + + { Continuacion de la funcion ObtenerNombreArchivo } + const + DEFAUL_FILE_NAME = 'datos.txt'; { nombre del archivo por defecto } + + var + tmp: String; { cadena para almacenar el resultado temporal } + + begin { ObtenerNombreArchivo } + { mensaje para entrada del nombre de archivo } + writeln('Ingrese el nombre del archivo con los datos (ENTER = ', DEFAUL_FILE_NAME, '):'); + readln(tmp); { entrada del nombre de archivo } + if tmp = '' then tmp := DEFAUL_FILE_NAME; { se fija si no se ingreso nada y reasigana el nombre } + while not fileExists(tmp) do { repite el proceso hasta que el archivo exista } + begin + write('El archivo ', tmp, ' no existe. Ingrese un nombre correcto'); + if tmp = DEFAUL_FILE_NAME { si es el nombre de archivo predeterminado } + then { entonces, elije un mensaje apropiado } + write(': ') + else + begin { si no es el predeterminado, muestra otro mensaje } + writeln('.'); + write('(ENTER = ', DEFAUL_FILE_NAME, '): '); + end; + readln(tmp); { vuelve a leer el nombre del archivo para ser verificado } + if tmp = '' then tmp := DEFAUL_FILE_NAME; { asigna como nombre de archivo al predeterminado + si no se escribio nada } + end; { fin del loop de verificacion } + ObtenerNombreArchivo := tmp; { asigna el nombre correcto al valor de salida de la funcion } + end; { ObtenerNombreArchivo } + + {########################################################} + + function trans(c: char; e: Estado): Estado; + { establece el estado en el que se encuentra la lectura } + { c es el caracter que se leyo, e es el estado actual de la lectura } + + begin { trans } + case e of { acciona segun es estado actual de la lectura } + INICIO: { estado de inicio de la lectura } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un numero (o negativo), empieza a leer el coeficiente } + SPACE, TAB, CR, LF: trans := COEF_BUSCA; { si es un caracter tipo "espacio", busca el prox. coef. } + else trans := ERROR; { si es otro, da ERROR } + end; + COEF_BUSCA: { estado de busqueda del primer ceoficiente del polinomio } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un numero (o negativo), empieza a leer el coeficiente } + SPACE, TAB, CR, LF: trans := COEF_BUSCA; { si es un caracter tupo "espacio", sigue buscando } + ENDF: trans := FIN; { si es el caracter de fin de archivo, pasa al estado de tarea finalizada } + else trans := ERROR; { si es otro, da ERROR } + end; + COEF: { estado de lectura del coeficiente del termino del polinomio (sin punto decimal) } + case c of { acciona segun el caracter leido } + '0'..'9': trans := COEF; { si es un numero sigue con el mismo estado } + '.': trans := COEF_PUNTO; { si es punto cambia al estado COEF_PUNTO } + SPACE, TAB: trans := COEF_FIN; { si es un espacio o un tabulador, finaliza la lectura del coeficiente } + else trans := ERROR; { si es otra cosa, pasa a estado de error } + end; + COEF_PUNTO: { estado de lectura del coeficiente del termino del polinomio (con punto decimal) } + case c of { acciona segun el caracter leido } + '0'..'9': trans := COEF_PUNTO; { si es un numero sigue con el mismo estado } + SPACE, TAB: trans := COEF_FIN; { si es un espacio o un tabulador, finaliza la lectura del coeficiente } + else trans := ERROR; { si es otra cosa, pasa a estado de error } + end; + COEF_FIN: { estado de fin de la lectura del coeficiente del termino del polinomio } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si el caracter es un numero establece el estado en EXP (exponente) } + SPACE, TAB: trans := EXP_BUSCA; { si es un espacio o tabulador, pasa a buscar el proximo exponente } + else trans := ERROR; { si no es ninguno de los anteriores, el estado pasa a ERROR } + end; + EXP_BUSCA: { estado de busqueda del proximo exponente } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si el caracter es un numero, empieza a leer el exponente } + SPACE, TAB: trans := EXP_BUSCA; { si es un espacio o tabulador, sigue buscando } + else trans := ERROR; { si no es ninguno de los anteriores, el estado pasa a ERROR } + end; + EXP: { estado de lectura del exponente del termino actual del polinomio } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si es un digito, sigue en el mismo estado } + CR: trans := EXP_FIN; { si es un ratorno de carro, finaliza el exponente + (quiere decir que hubo un ) } + ENDF: trans := FIN; { si es el final del archivo, se indica que termino su tarea } + else trans := ERROR; { si es otra cosa, devuelve ERROR } + end; + EXP_FIN: { estado de fin de la lectura del exponente del termino actual del polinomio } + if c = LF then trans := EXP_FIN_BUSCA { debe ser un caracter de nueva linea (para completar el ) } + else trans := ERROR; { si no lo es, devuelve ERROR } + EXP_FIN_BUSCA: { estado de fin de lectura de la nueva linea (luego de finalizar el exponente + ahora decide si termino el polinomio o si sigue leyendo el proximo coeficiente } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un digito (o negativo), pasa a leer en proximo coeficiente } + CR: trans := POLI_FIN; { si es un ratorno de carro o nueva linea, finaliza el polinomio } + else trans := ERROR; { si es otra cosa, devuelve ERROR } + end; + POLI_FIN: { estado de finalizacion del polinomio actual } + if c = LF then trans := COEF_BUSCA { debe ser un caracter de nueva linea (para completar el ), + entonces pasa a buscar el primer coeficiente del nuevo polinomio } + else trans := ERROR; { si no lo es, devuelve ERROR } + FIN: { estado que adquiere cuando se finalizo la tarea } + trans := FIN; { se queda en este estado avisando que termino su tarea } + else { otro estado, no deberia ocurrir, salvo que se le pase a la funcion un estado de ERROR } + trans := ERROR; { si es otro, da ERROR } + end; { case } + end; { trans } + + {########################################################} + + function cargarVectores(var v1, v2: Vector): boolean; + { Funcion que abre el archivo de texto con los datos, lo carga en el vector procesandolo debidamente a medida + que lo lee y, al finalizar, cierra el archivo de texto. + v1 es el primer vector a cargar + v2 es el segundo vector a cargar + devuelve true si la lectura fue hecha con exito, false si hubo un error } + + var + f: Text; { archivo de texto con los datos } + c: char; { caracter que se extrae del archivo de texto } + nombreArchivo: String; { nombre del archivo de datos } + est: Estado; { Indicador del estado actual de la lectura } + seguir: boolean; { indicador para saber si debe seguir con el proceso } + i, { indice del vector del polinomio para ser inicializado } + iExp, { valor temporal para almacenar al exponente } + code, { almacena el resultado de la funcion val (no se usa porque los + datos ya estan validados } + poliN: integer; { numero del polinomio que se esta leyendo } + rCoef: real; { valor temporal para almacenar al coeficiente } + exponente, { string que representa al exponente leido } + coeficiente: String; { string que representa al coeficiente leido } + + begin { cargarVectores } + rCoef := 0.0; { inicializacion de variable } + iExp := 0; { inicializacion de variable } + coeficiente := ''; { inicializacion de variable } + exponente := ''; { inicializacion de variable } + est := INICIO; { empieza con el estado de INICIO } + poliN := 1; { establece que se procesara el primer polinomio } + inicializaVector(v1); { inicializacion del vector 1 (primer polinomio) } + inicializaVector(v2); { inicializacion del vector 2 (segundo polinomio) } + nombreArchivo := ObtenerNombreArchivo; { obtiene el nombre del archivo } + assign(f, nombreArchivo); { asigna la variable al nombre del archivo } + reset(f); { abre el archivo para leerlo desde el principio } + seguir := true; { inicializa seguir e true para comenzar el bucle } + while seguir do begin { continua mientras seguir sea true } + read(f, c); { lee un caracter del archivo de texto } + est := trans(c, est); { establece el nuevo estado de lectura } + case est of { toma una desicion dependiendo del estado en que se encuentre } + INICIO: ; { No hace nada, nunca toma este valor. Solo incica que empezo el proceso } + COEF_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + COEF, COEF_PUNTO: { Si esta leyendo el coeficiente ... } + coeficiente := coeficiente + c; { concatena el caracter a la representacion + de texto del coeficiente } + COEF_FIN: ; { Si termino de leer el coeficiente, no hace nada, la asignacion + se realiza cuando termina de leer el exponente (es necesario + para establecer el indice del vector } + EXP_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + EXP: { Si esta leyendo el exponente ... } + exponente := exponente + c; { concatena el caracter a la representacion + de texto del exponente } + EXP_FIN: { Si termino de leer el exponente, hace las asignaciones correspondientes } + begin { convirtiendo las cadenas de texto en real e integer, segun el caso } + val(coeficiente, rCoef, code); { convierte el coeficiente en real } + val(exponente, iExp, code); { convierte el exponente en integer } + if iExp < TAM { si el exponente es menor que el tama¤o maximo permitido ... } + then if poliN = 1 then + begin + v1[n].coef := rCoef { asigna el valor correspondiente } + v1[n].exp := iExp { asigna el valor correspondiente } + end + else + begin + v1[n].coef := rCoef { asigna el valor correspondiente } + v1[n].exp := iExp { asigna el valor correspondiente } + end; + else est := ERROR; { si no es menor, pone el estado en ERROR } + coeficiente := ''; { una vez asignados, vacia los valores del coeficiente y el } + exponente := ''; { exponente para poder realizar las lecturas de los proximos } + end; + EXP_FIN_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + POLI_FIN: { Si termino la lectura de un polinomio ... } + if poliN = 1 then poliN := 2 { si se leyo el 1er polinomio, se indica que se leera el 2do } + else est := FIN; { si no (ya se leyo el segundo), pone el estado en FIN } + FIN: { Si se finalizaron las tareas ... } + begin + { este codigo es el mismo que el de EXP_FIN, se repite aca solo por si el final del + archivo esta pegado al fin del ultimo exponente, en cuyo caso no pasa por el estado + de EXP_FIN (y, por ende, no se pueden hacer las asignaciones correspondientes } + val(coeficiente, rCoef, code); { convierte el coeficiente en real } + val(exponente, iExp, code); { convierte el exponente en integer } + if iExp < TAM { si el exponente es menor que el tama¤o maximo permitido ... } + then if poliN = 1 then + begin + v1[n].coef := rCoef { asigna el valor correspondiente } + v1[n].exp := iExp { asigna el valor correspondiente } + end + else + begin + v1[n].coef := rCoef { asigna el valor correspondiente } + v1[n].exp := iExp { asigna el valor correspondiente } + end; + else est := ERROR; { si no es menor, pone el estado en ERROR } + coeficiente := ''; { una vez asignados, vacia los valores del coeficiente y el } + exponente := ''; { exponente para poder realizar las lecturas de los proximos } + { fin del codigo identico a EXP_FIN } + if poliN = 2 then cargarVectores := true { si se leyeron los 2 polinomios, devuelve true } + else cargarVectores := false; { si no se leyeron los dos, devuelve false } + seguir := false; { poner seguir en false para que se termine el bucle } + end; + ERROR: { Si hubo un error ... } + begin + cargarVectores := false; { Se devuelve false (hubo un ERROR, no se leyeron bien los vectores) } + seguir := false; { seguir se pone en false para que termine el bucle } + end; + end; { case } + end; { while } + close(f); { se cierra el archivo de lectura de datos } + end; { cargarVectores } + + {########################################################} + + procedure suma(v1, v2: Vector; var vr: Vector); + { procedimiento que suma dos polinomios. + v1: vector que contiene el primer polinomio a sumar + v2: vector que contiene el segundo polinomio a sumar + vr: vector donde se almacenara el resultado de la suma } + + var + i: integer; { indice para usar en el ciclo for } + + begin { suma } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el vector (de tama¤o maximo TAM) } + vr[i] := v1[i] + v2[i]; { suma los coeficientes de los terminos con igual exponente } + end; { suma } + + {########################################################} + + procedure resta(v1, v2: Vector; var vr: Vector); + { procedimiento que resta dos polinomios. + v1: vector que contiene el primer polinomio + v2: vector que contiene el polinomio para restarle al primero + vr: vector donde se almacenara el resultado de la resta } + + var + i: integer; { indice para usar en el ciclo for } + + begin { resta } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el vector (de tama¤o maximo TAM) } + vr[i] := v1[i] - v2[i]; { resta los coeficientes de los terminos con igual exponente } + end; { resta } + + {########################################################} + + procedure producto(v1, v2: Vector; var vr: Vector); + { procedimiento que multiplica dos polinomios. + v1: vector que contiene el primer polinomio a multiplicar + v2: vector que contiene el segundo polinomio a multiplicar + vr: vector donde se almacenara el resultado de la multiplicacion } + + var + i, j: integer; { indices para usar en los ciclos for } + + begin { producto } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el 1er vector (de tama¤o maximo TAM) } + for j := 0 to TAM - 1 do { recorre el 2do vector (de tama¤o maximo TAM) } + vr[i+j] := vr[i+j] + (v1[i] * v2[j]); + { multiplica los coeficientes de los terminos y lo almacena en la posicion del exponente } + { igual a la suma de los exponentes de v1 y v2, sumando el valor previo de dicha posicion } + end; { producto } + + {########################################################} + + function division(v1, v2: Vector; var vr, vResto: Vector): boolean; + { procedimiento que divide dos polinomios. + v1: vector que contiene el polinomio denominador + v2: vector que contiene el polinomio divisor + vr: vector donde se almacenara el resultado de la division + vResto: vector donde se almacenara el resto de la division + devuelve true si el segundo polinomio no es 0 y se efectua la division y + devuelve false si segundo polinomio es 0 y no se puede efectuar la division } + + var + i, j: integer; { indices para usar en los ciclos for } + vRTmp, { vector auxuliares para almacenar el termino actual del resultado } + vTmp: Vector; { vector auxuliares para almacenar el polinomio que es la multiplicacion del + termino actual del resultado por el divisor } + + begin { division } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vResto); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vTmp); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vRTmp); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := TAM - 1 downto 0 do { recorre el 1er vector (de tama¤o maximo TAM) de atras para adelante } + if v1[i] <> 0 then break; + { busca empezando por el indice (exponete) mas alto el primer coeficiente no nulo } + { si lo encuentra sale del for dejando al valor de i como el de dicho inidice } + for j := TAM - 1 downto 0 do { recorre el 2do vector (de tama¤o maximo TAM) de atras para adelante } + if v2[j] <> 0 then break; + { busca empezando por el indice (exponete) mas alto el primer coeficiente no nulo } + { si lo encuentra sale del for dejando al valor de j como el de dicho inidice } + if (j = 0) and (v2[j] = 0) { si el no se encontro ningun coeficiente no nulo, entonces } + then { el polinomio 2 es nulo y no se puede efectuar la division } + begin { se devuelve false y se quedan los vectores resultado en 0 } + division := false; { devuelve false } + exit; { sale del procedimiento } + end; + while i >= j do { si el primer exponente es mayor o igual que el segundo empieza a dividir } + begin + vr[i-j] := v1[i] / v2[j]; { almacena el resultado de la division entre los coeficientes en + la posicion de la resta de ambos } + vRTmp[i-j] := vr[i-j]; { almacena ese resultado en un polinomio temporal cuyo unico termio + no nulo es el del exponente i-j, para luego multiplicarlo } + producto(vRTmp, v2, vTmp);{ multiplica este polinomio por el segundo almacenado el resultado + en otro temporal, para luego hacer la resta } + resta(v1, vTmp, v1); { resta al primer polinomio, v1, (en su estado actual, no el original) + el temporal vTmp y lo almacena en v1, para poder volver a operarlo de + la misma forma } + vRTmp[i-j] := 0; { resetea el termino del temporal vRTmp que se asigno para los calculos } + for i := i downto 0 do { recorre el vector v1 (de tama¤o maximo TAM) de atras para adelante } + if v1[i] <> 0 then break; + { busca empezando por el indice (exponete) i el primer coeficiente no nulo + si lo encuentra sale del for dejando al valor de i como el de dicho inidice } + end; { while } + vResto := v1; { asigna el vector v1 (que ya no se procesara mas al resto } + division := true; { devuelve true indicando que se finalizo con exito } + end; { division } + + {########################################################} + +{ Continuacion del programa principal } + +var + i: integer; { variable auxiliar } + v1, v2, vResult, vResto: Vector; { vectores para hacer las operaciones } + continua: boolean; { valor para obtener los resultados de algunas funciones } + +begin { Comienzo del programa principal } + continua := cargarVectores(v1, v2); + if continua then + begin + muestraVector(v1, 'Polinomio 1 = '); + muestraVector(v2, 'Polinomio 2 = '); + suma(v1, v2, vResult); + muestraVector(vResult, 'Polinomio 1 + Polinomio 2 = '); + resta(v1, v2, vResult); + muestraVector(vResult, 'Polinomio 1 - Polinomio 2 = '); + producto(v1, v2, vResult); + muestraVector(vResult, 'Polinomio 1 * Polinomio 2 = '); + continua := division(v1, v2, vResult, vResto); + if continua + then + begin + muestraVector(vResult, 'Polinomio 1 / Polinomio 2 = '); + muestraVector(vResto, 'Resto = '); + end + else writeln('El segundo polinomio es nulo, por lo tanto no se puede efectuar la division'); + end + else + begin + writeln('ERROR: No se pudieron cargar los datos. Revise que el formato del archivo'); + writeln(' sea correcto y que no este siendo usado por otro programa.'); + end; +end. \ No newline at end of file diff --git a/term_1.pas b/term_1.pas new file mode 100644 index 0000000..eb39173 --- /dev/null +++ b/term_1.pas @@ -0,0 +1,549 @@ +program PolinomiosEnTermino; +{ Programa que lee 2 polinomios desde un archivo de texto para luego + hacer operaciones basicas entre estos (suma, resta, multiplicacion + y division). + El formato del archivo de texto debe ser de la siguiente manera: + + * Se ingresan cada polinomio en lineas sucesivas. + * El primer polinomio puede comenzar a ingresarse en cualquier lugar + del archivo de texto. + * El fin del primer polinomio (y comienzo del segundo) se indica por + medio de 1 o mas lineas en blanco. + * El segundo polinomio puede comenzar a ingresarse en cualquier lugar + del archivo de texto a partir de dicha(s) linea(s) en blanco. + * Cada termino de un polinomio debe estar en la misma linea y comenzar + al principio de esta (excepto el primer termino). + * Los terminos debes estar ordenados de menor a mayor segun el exponente. + * En cada linea se ingresa primero el coeficiente real (puede tener un + signo '-' al comenzar y/o un punto, y solamente uno) y luego el + exponente entero positivo. + * La separacion entre el coeficiente y el exponente debe estar dada por + uno o mas espacios o tabuladores. + * Cualquier caracter incluido en el texto que no sea un degito (0..9), + un punto ('.'), un signo menos ('-'), un espacio (' '), un tabulador + o alguno de los caracteres de nueva linea, dara un error en la + lectura. + * El archivo de texto debe tener formato DOS (es decir, el indicador de + nueva linea debe ser primero un caracter de retorno del carro + seguido inmediatamente por uno de avance de linea). +} + +uses + CRT, DOS; { Declaracion de funciones predefinidas + para crear la interfaz grafica } + +const + VERSION = '0.0.1a (TERM_0)'; { version del programa } + + TAM_MAX = 100; { Tama¤o maximo del vector que almacena + la multiplicacion de polinomios } + TAM = TAM_MAX div 2; { Tama¤o maximo (virtual) del vector que contiene + los vector con los que se va a operar } + CR = chr(13); { caracter de retorno del carro } + LF = chr(10); { caracter de nueva linea } + ENDF = chr(26); { caracter de fin del archivo } + TAB = chr(9); { caracter de tabulacion } + SPACE = chr(32); { caracter de espacio } + +type + { Tipo de dato para identificar el estado de la entrada de datos } + Estado = (INICIO, COEF_BUSCA, COEF, COEF_PUNTO, COEF_FIN, EXP_BUSCA, EXP, EXP_FIN, EXP_FIN_BUSCA, POLI_FIN, FIN, ERROR); + Termino = record + coef: real; + exp: integer; + end; + Vector = array [0..TAM_MAX-1] of Termino; { vector para almacenar los polinomios } + + + {########################################################} + + procedure muestraVector(var v: Vector; s: String); + { procedimiento que imprime el polinomio v en pantalla con un titulo s } + + {########################################################} + + function exponente(exp: integer): String; + + var + s: String; { variable temporal } + + begin { exponente } + case exp of + 0: exponente := ''; { si el exponente es nulo, mustra solo el coeficiente } + 1: exponente := 'X'; { si el exponente es 1, mustra el coeficiente y X } + 2: exponente := 'Xý'; { si el exponente es 2, mustra el coeficiente y Xý } + else begin + str(exp, s); { convierte al exponente en string } + exponente := 'X^' + s; { si el exponente es mayor que 1, mustra el coeficiente y X^exp } + end; { else } + end; { case } + end; { exponente } + + {########################################################} + + + var + i: integer; { indice para usar en el ciclo for } + + begin { muestraVector } + writeln; { separacion de una linea } + write(s); { mustra el mensaje } + for i := TAM_MAX - 1 downto 0 do { recorre el vector de atras para adelante } + if v[i].coef <> 0 then break; { si el coeficiente no es nulo, termina el for dejando a i en ese indice } + if (v[i].exp = 0) and (v[i].coef = 0) then { si el primer exponente que encuentra es 0 y el coeficiente es 0, entonces } + begin { muestra el resultado como 0 y sale del procedimiento } + write('0'); { imprime que el resultado es cero } + writeln; { separacion de una linea } + writeln; { separacion de una linea } + exit; { sale de este procedimiento } + end; + if (abs(v[i].coef) <> 1) or (v[i].exp = 0) { si el modulo del coeficiente es distinto de 1 o si el exp. es 0 } + then if abs(v[i].coef) - trunc(abs(v[i].coef)) = 0 then write(trunc(v[i].coef):1, ' ') {imprime si es un numero entero} + else write(v[i].coef:1:2, ' ') { imprime si es un numero real } + else if v[i].coef = -1 then write('-'); { si es -1 entonces solo escribe el signo del termino } + write(exponente(v[i].exp)); + for i := i - 1 downto 0 do { recorre el vector de atras para adelante } + if v[i].coef <> 0 then { si el coeficiente no es nulo, termina el for dejando a i en ese indice } + begin + if v[i].coef < 0 { si el coeficiente en negativo } + then write(' - ') { le agrega el signo - } + else write(' + '); { si no, le agrega el signo + } + if (abs(v[i].coef) <> 1) or (i = 0) then { si el modulo del coeficiente es distinto de 1 o si el exp. es 0 } + if abs(v[i].coef) - trunc(abs(v[i].coef)) = 0 + then write(trunc(abs(v[i].coef)):1, ' ') { imprime si es entero } + else write(abs(v[i].coef):1:2, ' '); { imprime si es un real } + write(exponente(v[i].exp)); + end; { if } + writeln; { separacion de una linea } + writeln; { separacion de una linea } + end; { muestraVector } + + {########################################################} + + procedure inicializaVector(var v: Vector); + { procedimiento que inicializa un vector de tama¤o tam } + + var i: integer; { indice para usar en el ciclo for } + + begin { inicializaVector } + for i := 0 to TAM_MAX - 1 do { recorre el vector } + begin + v[i].coef := 0.0; { inicializa la variable actual en 0 } + v[i].exp := 0; { inicializa la variable actual en 0 } + end; + end; { inicializaVector } + + {########################################################} + + function ObtenerNombreArchivo: String; + { funcion que obtiene un nombre de archivo valido (es decir, el nombre + de un archivo que exista) } + + {########################################################} + + function fileExists(FileName: String): Boolean; + { funcion extraida de la ayuda del Turbo Pascal 7 + indica si el archivo existe } + + var + F: file; + + begin + {$I-} + Assign(F, FileName); + FileMode := 0; { Set file access to read only } + Reset(F); + Close(F); + {$I+} + FileExists := (IOResult = 0) and (FileName <> ''); + end; { FileExists } + + {########################################################} + + { Continuacion de la funcion ObtenerNombreArchivo } + const + DEFAUL_FILE_NAME = 'datos.txt'; { nombre del archivo por defecto } + + var + tmp: String; { cadena para almacenar el resultado temporal } + + begin { ObtenerNombreArchivo } + { mensaje para entrada del nombre de archivo } + writeln('Ingrese el nombre del archivo con los datos (ENTER = ', DEFAUL_FILE_NAME, '):'); + readln(tmp); { entrada del nombre de archivo } + if tmp = '' then tmp := DEFAUL_FILE_NAME; { se fija si no se ingreso nada y reasigana el nombre } + while not fileExists(tmp) do { repite el proceso hasta que el archivo exista } + begin + write('El archivo ', tmp, ' no existe. Ingrese un nombre correcto'); + if tmp = DEFAUL_FILE_NAME { si es el nombre de archivo predeterminado } + then { entonces, elije un mensaje apropiado } + write(': ') + else + begin { si no es el predeterminado, muestra otro mensaje } + writeln('.'); + write('(ENTER = ', DEFAUL_FILE_NAME, '): '); + end; + readln(tmp); { vuelve a leer el nombre del archivo para ser verificado } + if tmp = '' then tmp := DEFAUL_FILE_NAME; { asigna como nombre de archivo al predeterminado + si no se escribio nada } + end; { fin del loop de verificacion } + ObtenerNombreArchivo := tmp; { asigna el nombre correcto al valor de salida de la funcion } + end; { ObtenerNombreArchivo } + + {########################################################} + + function trans(c: char; e: Estado): Estado; + { establece el estado en el que se encuentra la lectura } + { c es el caracter que se leyo, e es el estado actual de la lectura } + + begin { trans } + case e of { acciona segun es estado actual de la lectura } + INICIO: { estado de inicio de la lectura } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un numero (o negativo), empieza a leer el coeficiente } + SPACE, TAB, CR, LF: trans := COEF_BUSCA; { si es un caracter tipo "espacio", busca el prox. coef. } + else trans := ERROR; { si es otro, da ERROR } + end; + COEF_BUSCA: { estado de busqueda del primer ceoficiente del polinomio } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un numero (o negativo), empieza a leer el coeficiente } + SPACE, TAB, CR, LF: trans := COEF_BUSCA; { si es un caracter tupo "espacio", sigue buscando } + ENDF: trans := FIN; { si es el caracter de fin de archivo, pasa al estado de tarea finalizada } + else trans := ERROR; { si es otro, da ERROR } + end; + COEF: { estado de lectura del coeficiente del termino del polinomio (sin punto decimal) } + case c of { acciona segun el caracter leido } + '0'..'9': trans := COEF; { si es un numero sigue con el mismo estado } + '.': trans := COEF_PUNTO; { si es punto cambia al estado COEF_PUNTO } + SPACE, TAB: trans := COEF_FIN; { si es un espacio o un tabulador, finaliza la lectura del coeficiente } + else trans := ERROR; { si es otra cosa, pasa a estado de error } + end; + COEF_PUNTO: { estado de lectura del coeficiente del termino del polinomio (con punto decimal) } + case c of { acciona segun el caracter leido } + '0'..'9': trans := COEF_PUNTO; { si es un numero sigue con el mismo estado } + SPACE, TAB: trans := COEF_FIN; { si es un espacio o un tabulador, finaliza la lectura del coeficiente } + else trans := ERROR; { si es otra cosa, pasa a estado de error } + end; + COEF_FIN: { estado de fin de la lectura del coeficiente del termino del polinomio } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si el caracter es un numero establece el estado en EXP (exponente) } + SPACE, TAB: trans := EXP_BUSCA; { si es un espacio o tabulador, pasa a buscar el proximo exponente } + else trans := ERROR; { si no es ninguno de los anteriores, el estado pasa a ERROR } + end; + EXP_BUSCA: { estado de busqueda del proximo exponente } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si el caracter es un numero, empieza a leer el exponente } + SPACE, TAB: trans := EXP_BUSCA; { si es un espacio o tabulador, sigue buscando } + else trans := ERROR; { si no es ninguno de los anteriores, el estado pasa a ERROR } + end; + EXP: { estado de lectura del exponente del termino actual del polinomio } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si es un digito, sigue en el mismo estado } + CR: trans := EXP_FIN; { si es un ratorno de carro, finaliza el exponente + (quiere decir que hubo un ) } + ENDF: trans := FIN; { si es el final del archivo, se indica que termino su tarea } + else trans := ERROR; { si es otra cosa, devuelve ERROR } + end; + EXP_FIN: { estado de fin de la lectura del exponente del termino actual del polinomio } + if c = LF then trans := EXP_FIN_BUSCA { debe ser un caracter de nueva linea (para completar el ) } + else trans := ERROR; { si no lo es, devuelve ERROR } + EXP_FIN_BUSCA: { estado de fin de lectura de la nueva linea (luego de finalizar el exponente + ahora decide si termino el polinomio o si sigue leyendo el proximo coeficiente } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un digito (o negativo), pasa a leer en proximo coeficiente } + CR: trans := POLI_FIN; { si es un ratorno de carro o nueva linea, finaliza el polinomio } + else trans := ERROR; { si es otra cosa, devuelve ERROR } + end; + POLI_FIN: { estado de finalizacion del polinomio actual } + if c = LF then trans := COEF_BUSCA { debe ser un caracter de nueva linea (para completar el ), + entonces pasa a buscar el primer coeficiente del nuevo polinomio } + else trans := ERROR; { si no lo es, devuelve ERROR } + FIN: { estado que adquiere cuando se finalizo la tarea } + trans := FIN; { se queda en este estado avisando que termino su tarea } + else { otro estado, no deberia ocurrir, salvo que se le pase a la funcion un estado de ERROR } + trans := ERROR; { si es otro, da ERROR } + end; { case } + end; { trans } + + {########################################################} + + function cargarVectores(var v1, v2: Vector): boolean; + { Funcion que abre el archivo de texto con los datos, lo carga en el vector procesandolo debidamente a medida + que lo lee y, al finalizar, cierra el archivo de texto. + v1 es el primer vector a cargar + v2 es el segundo vector a cargar + devuelve true si la lectura fue hecha con exito, false si hubo un error } + + var + f: Text; { archivo de texto con los datos } + c: char; { caracter que se extrae del archivo de texto } + nombreArchivo: String; { nombre del archivo de datos } + est: Estado; { Indicador del estado actual de la lectura } + asignado, { indicador para saber si ya se asigno el valor al termino actual } + seguir: boolean; { indicador para saber si debe seguir con el proceso } + i, { indice del vector del polinomio para ser inicializado } + iExp, { valor temporal para almacenar al exponente } + code, { almacena el resultado de la funcion val (no se usa porque los + datos ya estan validados } + n, { numero de termino del polinomio actual } + poliN: integer; { numero del polinomio que se esta leyendo } + rCoef: real; { valor temporal para almacenar al coeficiente } + exponente, { string que representa al exponente leido } + coeficiente: String; { string que representa al coeficiente leido } + + begin { cargarVectores } + asignado := false; { inicializacion de variable } + n := -1; { inicializacion de variable } + rCoef := 0.0; { inicializacion de variable } + iExp := 0; { inicializacion de variable } + coeficiente := ''; { inicializacion de variable } + exponente := ''; { inicializacion de variable } + est := INICIO; { empieza con el estado de INICIO } + poliN := 1; { establece que se procesara el primer polinomio } + inicializaVector(v1); { inicializacion del vector 1 (primer polinomio) } + inicializaVector(v2); { inicializacion del vector 2 (segundo polinomio) } + nombreArchivo := ObtenerNombreArchivo; { obtiene el nombre del archivo } + assign(f, nombreArchivo); { asigna la variable al nombre del archivo } + reset(f); { abre el archivo para leerlo desde el principio } + seguir := true; { inicializa seguir e true para comenzar el bucle } + while seguir do begin { continua mientras seguir sea true } + read(f, c); { lee un caracter del archivo de texto } + est := trans(c, est); { establece el nuevo estado de lectura } + case est of { toma una desicion dependiendo del estado en que se encuentre } + INICIO: ; { No hace nada, nunca toma este valor. Solo incica que empezo el proceso } + COEF_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + COEF, COEF_PUNTO: { Si esta leyendo el coeficiente ... } + coeficiente := coeficiente + c; { concatena el caracter a la representacion + de texto del coeficiente } + COEF_FIN: { Si termino de leer el coeficiente ... } + begin + n := n + 1; { incrementa el termino en uno } + asignado := false; { se indica que no esta asignado todavia. } + { Se elije este estado para indicar esto (e incrementar el termino) porque siempre que + finalize bien el polinomio se pasa por ‚l (no pasa lo mismo con EXP_FIN). + La asignacion se realiza cuando termina de leer el exponente } + end; + EXP_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + EXP: { Si esta leyendo el exponente ... } + exponente := exponente + c; { concatena el caracter a la representacion + de texto del exponente } + EXP_FIN: { Si termino de leer el exponente, hace las asignaciones correspondientes } + begin { convirtiendo las cadenas de texto en real e integer, segun el caso } + val(coeficiente, rCoef, code); { convierte el coeficiente en real } + val(exponente, iExp, code); { convierte el exponente en integer } + if iExp < TAM { si el exponente es menor que el tama¤o maximo permitido ... } + then if poliN = 1 then + begin + v1[n].coef := rCoef; { asigna el valor correspondiente } + v1[n].exp := iExp; { asigna el valor correspondiente } + asignado := true; { se indica que se hizo la asignacion. + esto solo tiene sentido si el archivo finaliza justo despues + de leer el ultimo exponente (no pasa po este estado y asignado + queda en false, avisandole a FIN que debe hacer la asignacion } + end + else + begin + v1[n].coef := rCoef; { asigna el valor correspondiente } + v1[n].exp := iExp; { asigna el valor correspondiente } + asignado := true; { se indica que se hizo la asignacion. + esto solo tiene sentido si el archivo finaliza justo despues + de leer el ultimo exponente (no pasa po este estado y asignado + queda en false, avisandole a FIN que debe hacer la asignacion } + end + else est := ERROR; { si no es menor, pone el estado en ERROR } + coeficiente := ''; { una vez asignados, vacia los valores del coeficiente y el } + exponente := ''; { exponente para poder realizar las lecturas de los proximos } + end; + EXP_FIN_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + POLI_FIN: { Si termino la lectura de un polinomio ... } + if poliN = 1 then + begin + poliN := 2; { si se leyo el 1er polinomio, se indica que se leera el 2do } + n := -1; { empieza por el primer termino (vale n = 0 al pasar por COEF_FIN) } + end + else est := FIN; { si no (ya se leyo el segundo), pone el estado en FIN } + FIN: { Si se finalizaron las tareas ... } + begin + cargarVectores := true; { en principio se establece que la lectura se hizo con exito ) } + seguir := false; { poner seguir en false para que se termine el bucle } + { este codigo es similar al de EXP_FIN, se hacen las asignaciones por el caso en que el fin + del archivo esta pegado al fin del ultimo exponente, en cuyo caso no pasa por el estado + de EXP_FIN (y, por ende, no se pueden hacer las asignaciones correspondientes } + if poliN <> 2 { si no se leyeron ambos polinomios ... } + then + cargarVectores := false { devuelve false (no se realizo con exito la lectura } + else { si se leyeron ambos polinomios ... } + if not asignado then { si no se pudo hacer la asignacion ... } + { esto solo tiene sentido si el archivo finaliza justo despues + de leer el ultimo exponente (no pasa por el estado FIN_EXP y + FIN debe hacer la asignacion } + begin + val(coeficiente, rCoef, code); { convierte el coeficiente en real } + val(exponente, iExp, code); { convierte el exponente en integer } + if iExp < TAM { si el exponente es menor que el tama¤o maximo permitido ... } + then + begin + v2[n].coef := rCoef; { asigna el valor correspondiente } + v2[n].exp := iExp; { asigna el valor correspondiente } + end + else + cargarVectores := false; { si no es menor, no se hizo bien la lectura } + end; { if not asignado } + end; { FIN: } + ERROR: { Si hubo un error ... } + begin + cargarVectores := false; { Se devuelve false (hubo un ERROR, no se leyeron bien los vectores) } + seguir := false; { seguir se pone en false para que termine el bucle } + end; + end; { case } + end; { while } + close(f); { se cierra el archivo de lectura de datos } + end; { cargarVectores } + + {########################################################} + + procedure suma(v1, v2: Vector; var vr: Vector); + { procedimiento que suma dos polinomios. + v1: vector que contiene el primer polinomio a sumar + v2: vector que contiene el segundo polinomio a sumar + vr: vector donde se almacenara el resultado de la suma } + + var + i: integer; { indice para usar en el ciclo for } + + begin { suma } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el vector (de tama¤o maximo TAM) } + vr[i] := v1[i] + v2[i]; { suma los coeficientes de los terminos con igual exponente } + end; { suma } + + {########################################################} + + procedure resta(v1, v2: Vector; var vr: Vector); + { procedimiento que resta dos polinomios. + v1: vector que contiene el primer polinomio + v2: vector que contiene el polinomio para restarle al primero + vr: vector donde se almacenara el resultado de la resta } + + var + i: integer; { indice para usar en el ciclo for } + + begin { resta } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el vector (de tama¤o maximo TAM) } + vr[i] := v1[i] - v2[i]; { resta los coeficientes de los terminos con igual exponente } + end; { resta } + + {########################################################} + + procedure producto(v1, v2: Vector; var vr: Vector); + { procedimiento que multiplica dos polinomios. + v1: vector que contiene el primer polinomio a multiplicar + v2: vector que contiene el segundo polinomio a multiplicar + vr: vector donde se almacenara el resultado de la multiplicacion } + + var + i, j: integer; { indices para usar en los ciclos for } + + begin { producto } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el 1er vector (de tama¤o maximo TAM) } + for j := 0 to TAM - 1 do { recorre el 2do vector (de tama¤o maximo TAM) } + vr[i+j] := vr[i+j] + (v1[i] * v2[j]); + { multiplica los coeficientes de los terminos y lo almacena en la posicion del exponente } + { igual a la suma de los exponentes de v1 y v2, sumando el valor previo de dicha posicion } + end; { producto } + + {########################################################} + + function division(v1, v2: Vector; var vr, vResto: Vector): boolean; + { procedimiento que divide dos polinomios. + v1: vector que contiene el polinomio denominador + v2: vector que contiene el polinomio divisor + vr: vector donde se almacenara el resultado de la division + vResto: vector donde se almacenara el resto de la division + devuelve true si el segundo polinomio no es 0 y se efectua la division y + devuelve false si segundo polinomio es 0 y no se puede efectuar la division } + + var + i, j: integer; { indices para usar en los ciclos for } + vRTmp, { vector auxuliares para almacenar el termino actual del resultado } + vTmp: Vector; { vector auxuliares para almacenar el polinomio que es la multiplicacion del + termino actual del resultado por el divisor } + + begin { division } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vResto); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vTmp); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vRTmp); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := TAM - 1 downto 0 do { recorre el 1er vector (de tama¤o maximo TAM) de atras para adelante } + if v1[i] <> 0 then break; + { busca empezando por el indice (exponete) mas alto el primer coeficiente no nulo } + { si lo encuentra sale del for dejando al valor de i como el de dicho inidice } + for j := TAM - 1 downto 0 do { recorre el 2do vector (de tama¤o maximo TAM) de atras para adelante } + if v2[j] <> 0 then break; + { busca empezando por el indice (exponete) mas alto el primer coeficiente no nulo } + { si lo encuentra sale del for dejando al valor de j como el de dicho inidice } + if (j = 0) and (v2[j] = 0) { si el no se encontro ningun coeficiente no nulo, entonces } + then { el polinomio 2 es nulo y no se puede efectuar la division } + begin { se devuelve false y se quedan los vectores resultado en 0 } + division := false; { devuelve false } + exit; { sale del procedimiento } + end; + while i >= j do { si el primer exponente es mayor o igual que el segundo empieza a dividir } + begin + vr[i-j] := v1[i] / v2[j]; { almacena el resultado de la division entre los coeficientes en + la posicion de la resta de ambos } + vRTmp[i-j] := vr[i-j]; { almacena ese resultado en un polinomio temporal cuyo unico termio + no nulo es el del exponente i-j, para luego multiplicarlo } + producto(vRTmp, v2, vTmp);{ multiplica este polinomio por el segundo almacenado el resultado + en otro temporal, para luego hacer la resta } + resta(v1, vTmp, v1); { resta al primer polinomio, v1, (en su estado actual, no el original) + el temporal vTmp y lo almacena en v1, para poder volver a operarlo de + la misma forma } + vRTmp[i-j] := 0; { resetea el termino del temporal vRTmp que se asigno para los calculos } + for i := i downto 0 do { recorre el vector v1 (de tama¤o maximo TAM) de atras para adelante } + if v1[i] <> 0 then break; + { busca empezando por el indice (exponete) i el primer coeficiente no nulo + si lo encuentra sale del for dejando al valor de i como el de dicho inidice } + end; { while } + vResto := v1; { asigna el vector v1 (que ya no se procesara mas al resto } + division := true; { devuelve true indicando que se finalizo con exito } + end; { division } + + {########################################################} + +{ Continuacion del programa principal } + +var + i: integer; { variable auxiliar } + v1, v2, vResult, vResto: Vector; { vectores para hacer las operaciones } + continua: boolean; { valor para obtener los resultados de algunas funciones } + +begin { Comienzo del programa principal } + continua := cargarVectores(v1, v2); + if continua then + begin + muestraVector(v1, 'Polinomio 1 = '); + muestraVector(v2, 'Polinomio 2 = '); + suma(v1, v2, vResult); + muestraVector(vResult, 'Polinomio 1 + Polinomio 2 = '); + resta(v1, v2, vResult); + muestraVector(vResult, 'Polinomio 1 - Polinomio 2 = '); + producto(v1, v2, vResult); + muestraVector(vResult, 'Polinomio 1 * Polinomio 2 = '); + continua := division(v1, v2, vResult, vResto); + if continua + then + begin + muestraVector(vResult, 'Polinomio 1 / Polinomio 2 = '); + muestraVector(vResto, 'Resto = '); + end + else writeln('El segundo polinomio es nulo, por lo tanto no se puede efectuar la division'); + end + else + begin + writeln('ERROR: No se pudieron cargar los datos. Revise que el formato del archivo'); + writeln(' sea correcto y que no este siendo usado por otro programa.'); + end; +end. \ No newline at end of file diff --git a/term_2.pas b/term_2.pas new file mode 100644 index 0000000..3de59a1 --- /dev/null +++ b/term_2.pas @@ -0,0 +1,442 @@ +program PolinomiosEnTermino; +{ Programa que lee 2 polinomios desde un archivo de texto para luego + hacer operaciones basicas entre estos (suma, resta, multiplicacion + y division). + El formato del archivo de texto debe ser de la siguiente manera: + + * Se ingresan cada polinomio en lineas sucesivas. + * El primer polinomio puede comenzar a ingresarse en cualquier lugar + del archivo de texto. + * El fin del primer polinomio (y comienzo del segundo) se indica por + medio de 1 o mas lineas en blanco. + * El segundo polinomio puede comenzar a ingresarse en cualquier lugar + del archivo de texto a partir de dicha(s) linea(s) en blanco. + * Cada termino de un polinomio debe estar en la misma linea y comenzar + al principio de esta (excepto el primer termino). + * Los terminos debes estar ordenados de menor a mayor segun el exponente. + * En cada linea se ingresa primero el coeficiente real (puede tener un + signo '-' al comenzar y/o un punto, y solamente uno) y luego el + exponente entero positivo. + * La separacion entre el coeficiente y el exponente debe estar dada por + uno o mas espacios o tabuladores. + * Cualquier caracter incluido en el texto que no sea un degito (0..9), + un punto ('.'), un signo menos ('-'), un espacio (' '), un tabulador + o alguno de los caracteres de nueva linea, dara un error en la + lectura. + * El archivo de texto debe tener formato DOS (es decir, el indicador de + nueva linea debe ser primero un caracter de retorno del carro + seguido inmediatamente por uno de avance de linea). +} + +uses + CRT, DOS; { Declaracion de funciones predefinidas + para crear la interfaz grafica } + +const + VERSION = '0.2.0a (TERM_2)'; { version del programa } + + TAM_MAX = 100; { Tama¤o maximo del vector que almacena + la multiplicacion de polinomios } + TAM = TAM_MAX div 2; { Tama¤o maximo (virtual) del vector que contiene + los vector con los que se va a operar } + CR = chr(13); { caracter de retorno del carro } + LF = chr(10); { caracter de nueva linea } + ENDF = chr(26); { caracter de fin del archivo } + TAB = chr(9); { caracter de tabulacion } + SPACE = chr(32); { caracter de espacio } + +type + { Tipo de dato para identificar el estado de la entrada de datos } + Estado = (INICIO, COEF_BUSCA, COEF, COEF_PUNTO, COEF_FIN, EXP_BUSCA, EXP, EXP_FIN, EXP_FIN_BUSCA, POLI_FIN, FIN, ERROR); + Termino = record + coef: real; + exp: integer; + end; + Vector = array [0..TAM_MAX-1] of Termino; { vector para almacenar los polinomios } + + + {########################################################} + + procedure muestraVector(var v: Vector; s: String); + { procedimiento que imprime el polinomio v en pantalla con un titulo s } + + {########################################################} + + function exponente(exp: integer): String; + + var + s: String; { variable temporal } + + begin { exponente } + case exp of + 0: exponente := ''; { si el exponente es nulo, mustra solo el coeficiente } + 1: exponente := 'X'; { si el exponente es 1, mustra el coeficiente y X } + 2: exponente := 'Xý'; { si el exponente es 2, mustra el coeficiente y Xý } + else begin + str(exp, s); { convierte al exponente en string } + exponente := 'X^' + s; { si el exponente es mayor que 1, mustra el coeficiente y X^exp } + end; { else } + end; { case } + end; { exponente } + + {########################################################} + + + var + i: integer; { indice para usar en el ciclo for } + + begin { muestraVector } + writeln; { separacion de una linea } + write(s); { mustra el mensaje } + for i := TAM_MAX - 1 downto 0 do { recorre el vector de atras para adelante } + if v[i].coef <> 0 then break; { si el coeficiente no es nulo, termina el for dejando a i en ese indice } + if (v[i].exp = 0) and (v[i].coef = 0) then { si el primer exponente que encuentra es 0 y el coeficiente es 0, entonces } + begin { muestra el resultado como 0 y sale del procedimiento } + write('0'); { imprime que el resultado es cero } + writeln; { separacion de una linea } + writeln; { separacion de una linea } + exit; { sale de este procedimiento } + end; + if (abs(v[i].coef) <> 1) or (v[i].exp = 0) { si el modulo del coeficiente es distinto de 1 o si el exp. es 0 } + then if abs(v[i].coef) - trunc(abs(v[i].coef)) = 0 then write(trunc(v[i].coef):1, ' ') {imprime si es un numero entero} + else write(v[i].coef:1:2, ' ') { imprime si es un numero real } + else if v[i].coef = -1 then write('-'); { si es -1 entonces solo escribe el signo del termino } + write(exponente(v[i].exp)); + for i := i - 1 downto 0 do { recorre el vector de atras para adelante } + if v[i].coef <> 0 then { si el coeficiente no es nulo, termina el for dejando a i en ese indice } + begin + if v[i].coef < 0 { si el coeficiente en negativo } + then write(' - ') { le agrega el signo - } + else write(' + '); { si no, le agrega el signo + } + if (abs(v[i].coef) <> 1) or (i = 0) then { si el modulo del coeficiente es distinto de 1 o si el exp. es 0 } + if abs(v[i].coef) - trunc(abs(v[i].coef)) = 0 + then write(trunc(abs(v[i].coef)):1, ' ') { imprime si es entero } + else write(abs(v[i].coef):1:2, ' '); { imprime si es un real } + write(exponente(v[i].exp)); + end; { if } + writeln; { separacion de una linea } + writeln; { separacion de una linea } + end; { muestraVector } + + {########################################################} + + procedure inicializaVector(var v: Vector); + { procedimiento que inicializa un vector de tama¤o tam } + + var i: integer; { indice para usar en el ciclo for } + + begin { inicializaVector } + for i := 0 to TAM_MAX - 1 do { recorre el vector } + begin + v[i].coef := 0.0; { inicializa la variable actual en 0 } + v[i].exp := 0; { inicializa la variable actual en 0 } + end; + end; { inicializaVector } + + {########################################################} + + function ObtenerNombreArchivo: String; + { funcion que obtiene un nombre de archivo valido (es decir, el nombre + de un archivo que exista) } + + {########################################################} + + function fileExists(FileName: String): Boolean; + { funcion extraida de la ayuda del Turbo Pascal 7 + indica si el archivo existe } + + var + F: file; + + begin + {$I-} + Assign(F, FileName); + FileMode := 0; { Set file access to read only } + Reset(F); + Close(F); + {$I+} + FileExists := (IOResult = 0) and (FileName <> ''); + end; { FileExists } + + {########################################################} + + { Continuacion de la funcion ObtenerNombreArchivo } + const + DEFAUL_FILE_NAME = 'datos.txt'; { nombre del archivo por defecto } + + var + tmp: String; { cadena para almacenar el resultado temporal } + + begin { ObtenerNombreArchivo } + { mensaje para entrada del nombre de archivo } + writeln('Ingrese el nombre del archivo con los datos (ENTER = ', DEFAUL_FILE_NAME, '):'); + readln(tmp); { entrada del nombre de archivo } + if tmp = '' then tmp := DEFAUL_FILE_NAME; { se fija si no se ingreso nada y reasigana el nombre } + while not fileExists(tmp) do { repite el proceso hasta que el archivo exista } + begin + write('El archivo ', tmp, ' no existe. Ingrese un nombre correcto'); + if tmp = DEFAUL_FILE_NAME { si es el nombre de archivo predeterminado } + then { entonces, elije un mensaje apropiado } + write(': ') + else + begin { si no es el predeterminado, muestra otro mensaje } + writeln('.'); + write('(ENTER = ', DEFAUL_FILE_NAME, '): '); + end; + readln(tmp); { vuelve a leer el nombre del archivo para ser verificado } + if tmp = '' then tmp := DEFAUL_FILE_NAME; { asigna como nombre de archivo al predeterminado + si no se escribio nada } + end; { fin del loop de verificacion } + ObtenerNombreArchivo := tmp; { asigna el nombre correcto al valor de salida de la funcion } + end; { ObtenerNombreArchivo } + + {########################################################} + + function trans(c: char; e: Estado): Estado; + { establece el estado en el que se encuentra la lectura } + { c es el caracter que se leyo, e es el estado actual de la lectura } + + begin { trans } + case e of { acciona segun es estado actual de la lectura } + INICIO: { estado de inicio de la lectura } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un numero (o negativo), empieza a leer el coeficiente } + SPACE, TAB, CR, LF: trans := COEF_BUSCA; { si es un caracter tipo "espacio", busca el prox. coef. } + else trans := ERROR; { si es otro, da ERROR } + end; + COEF_BUSCA: { estado de busqueda del primer ceoficiente del polinomio } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un numero (o negativo), empieza a leer el coeficiente } + SPACE, TAB, CR, LF: trans := COEF_BUSCA; { si es un caracter tupo "espacio", sigue buscando } + ENDF: trans := FIN; { si es el caracter de fin de archivo, pasa al estado de tarea finalizada } + else trans := ERROR; { si es otro, da ERROR } + end; + COEF: { estado de lectura del coeficiente del termino del polinomio (sin punto decimal) } + case c of { acciona segun el caracter leido } + '0'..'9': trans := COEF; { si es un numero sigue con el mismo estado } + '.': trans := COEF_PUNTO; { si es punto cambia al estado COEF_PUNTO } + SPACE, TAB: trans := COEF_FIN; { si es un espacio o un tabulador, finaliza la lectura del coeficiente } + else trans := ERROR; { si es otra cosa, pasa a estado de error } + end; + COEF_PUNTO: { estado de lectura del coeficiente del termino del polinomio (con punto decimal) } + case c of { acciona segun el caracter leido } + '0'..'9': trans := COEF_PUNTO; { si es un numero sigue con el mismo estado } + SPACE, TAB: trans := COEF_FIN; { si es un espacio o un tabulador, finaliza la lectura del coeficiente } + else trans := ERROR; { si es otra cosa, pasa a estado de error } + end; + COEF_FIN: { estado de fin de la lectura del coeficiente del termino del polinomio } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si el caracter es un numero establece el estado en EXP (exponente) } + SPACE, TAB: trans := EXP_BUSCA; { si es un espacio o tabulador, pasa a buscar el proximo exponente } + else trans := ERROR; { si no es ninguno de los anteriores, el estado pasa a ERROR } + end; + EXP_BUSCA: { estado de busqueda del proximo exponente } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si el caracter es un numero, empieza a leer el exponente } + SPACE, TAB: trans := EXP_BUSCA; { si es un espacio o tabulador, sigue buscando } + else trans := ERROR; { si no es ninguno de los anteriores, el estado pasa a ERROR } + end; + EXP: { estado de lectura del exponente del termino actual del polinomio } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si es un digito, sigue en el mismo estado } + CR: trans := EXP_FIN; { si es un ratorno de carro, finaliza el exponente + (quiere decir que hubo un ) } + ENDF: trans := FIN; { si es el final del archivo, se indica que termino su tarea } + else trans := ERROR; { si es otra cosa, devuelve ERROR } + end; + EXP_FIN: { estado de fin de la lectura del exponente del termino actual del polinomio } + if c = LF then trans := EXP_FIN_BUSCA { debe ser un caracter de nueva linea (para completar el ) } + else trans := ERROR; { si no lo es, devuelve ERROR } + EXP_FIN_BUSCA: { estado de fin de lectura de la nueva linea (luego de finalizar el exponente + ahora decide si termino el polinomio o si sigue leyendo el proximo coeficiente } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un digito (o negativo), pasa a leer en proximo coeficiente } + CR: trans := POLI_FIN; { si es un ratorno de carro o nueva linea, finaliza el polinomio } + else trans := ERROR; { si es otra cosa, devuelve ERROR } + end; + POLI_FIN: { estado de finalizacion del polinomio actual } + if c = LF then trans := COEF_BUSCA { debe ser un caracter de nueva linea (para completar el ), + entonces pasa a buscar el primer coeficiente del nuevo polinomio } + else trans := ERROR; { si no lo es, devuelve ERROR } + FIN: { estado que adquiere cuando se finalizo la tarea } + trans := FIN; { se queda en este estado avisando que termino su tarea } + else { otro estado, no deberia ocurrir, salvo que se le pase a la funcion un estado de ERROR } + trans := ERROR; { si es otro, da ERROR } + end; { case } + end; { trans } + + {########################################################} + + function cargarVectores(var v1, v2: Vector): boolean; + { Funcion que abre el archivo de texto con los datos, lo carga en el vector procesandolo debidamente a medida + que lo lee y, al finalizar, cierra el archivo de texto. + v1 es el primer vector a cargar + v2 es el segundo vector a cargar + devuelve true si la lectura fue hecha con exito, false si hubo un error } + + var + f: Text; { archivo de texto con los datos } + c: char; { caracter que se extrae del archivo de texto } + nombreArchivo: String; { nombre del archivo de datos } + est: Estado; { Indicador del estado actual de la lectura } + asignado, { indicador para saber si ya se asigno el valor al termino actual } + seguir: boolean; { indicador para saber si debe seguir con el proceso } + i, { indice del vector del polinomio para ser inicializado } + iExp, { valor temporal para almacenar al exponente } + code, { almacena el resultado de la funcion val (no se usa porque los + datos ya estan validados } + n, { numero de termino del polinomio actual } + poliN: integer; { numero del polinomio que se esta leyendo } + rCoef: real; { valor temporal para almacenar al coeficiente } + exponente, { string que representa al exponente leido } + coeficiente: String; { string que representa al coeficiente leido } + + begin { cargarVectores } + asignado := false; { inicializacion de variable } + n := -1; { inicializacion de variable } + rCoef := 0.0; { inicializacion de variable } + iExp := 0; { inicializacion de variable } + coeficiente := ''; { inicializacion de variable } + exponente := ''; { inicializacion de variable } + est := INICIO; { empieza con el estado de INICIO } + poliN := 1; { establece que se procesara el primer polinomio } + inicializaVector(v1); { inicializacion del vector 1 (primer polinomio) } + inicializaVector(v2); { inicializacion del vector 2 (segundo polinomio) } + nombreArchivo := ObtenerNombreArchivo; { obtiene el nombre del archivo } + assign(f, nombreArchivo); { asigna la variable al nombre del archivo } + reset(f); { abre el archivo para leerlo desde el principio } + seguir := true; { inicializa seguir e true para comenzar el bucle } + while seguir do begin { continua mientras seguir sea true } + read(f, c); { lee un caracter del archivo de texto } + est := trans(c, est); { establece el nuevo estado de lectura } + case est of { toma una desicion dependiendo del estado en que se encuentre } + INICIO: ; { No hace nada, nunca toma este valor. Solo incica que empezo el proceso } + COEF_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + COEF, COEF_PUNTO: { Si esta leyendo el coeficiente ... } + coeficiente := coeficiente + c; { concatena el caracter a la representacion + de texto del coeficiente } + COEF_FIN: { Si termino de leer el coeficiente ... } + begin + n := n + 1; { incrementa el termino en uno } + asignado := false; { se indica que no esta asignado todavia. } + { Se elije este estado para indicar esto (e incrementar el termino) porque siempre que + finalize bien el polinomio se pasa por ‚l (no pasa lo mismo con EXP_FIN). + La asignacion se realiza cuando termina de leer el exponente } + end; + EXP_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + EXP: { Si esta leyendo el exponente ... } + exponente := exponente + c; { concatena el caracter a la representacion + de texto del exponente } + EXP_FIN: { Si termino de leer el exponente, hace las asignaciones correspondientes } + begin { convirtiendo las cadenas de texto en real e integer, segun el caso } + val(coeficiente, rCoef, code); { convierte el coeficiente en real } + val(exponente, iExp, code); { convierte el exponente en integer } + if iExp < TAM { si el exponente es menor que el tama¤o maximo permitido ... } + then if poliN = 1 then + begin + v1[n].coef := rCoef; { asigna el valor correspondiente } + v1[n].exp := iExp; { asigna el valor correspondiente } + asignado := true; { se indica que se hizo la asignacion. + esto solo tiene sentido si el archivo finaliza justo despues + de leer el ultimo exponente (no pasa po este estado y asignado + queda en false, avisandole a FIN que debe hacer la asignacion } + end + else + begin + v2[n].coef := rCoef; { asigna el valor correspondiente } + v2[n].exp := iExp; { asigna el valor correspondiente } + asignado := true; { se indica que se hizo la asignacion. + esto solo tiene sentido si el archivo finaliza justo despues + de leer el ultimo exponente (no pasa po este estado y asignado + queda en false, avisandole a FIN que debe hacer la asignacion } + end + else est := ERROR; { si no es menor, pone el estado en ERROR } + coeficiente := ''; { una vez asignados, vacia los valores del coeficiente y el } + exponente := ''; { exponente para poder realizar las lecturas de los proximos } + end; + EXP_FIN_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + POLI_FIN: { Si termino la lectura de un polinomio ... } + if poliN = 1 then + begin + poliN := 2; { si se leyo el 1er polinomio, se indica que se leera el 2do } + n := -1; { empieza por el primer termino (vale n = 0 al pasar por COEF_FIN) } + end + else est := FIN; { si no (ya se leyo el segundo), pone el estado en FIN } + FIN: { Si se finalizaron las tareas ... } + begin + cargarVectores := true; { en principio se establece que la lectura se hizo con exito ) } + seguir := false; { poner seguir en false para que se termine el bucle } + { este codigo es similar al de EXP_FIN, se hacen las asignaciones por el caso en que el fin + del archivo esta pegado al fin del ultimo exponente, en cuyo caso no pasa por el estado + de EXP_FIN (y, por ende, no se pueden hacer las asignaciones correspondientes } + if poliN <> 2 { si no se leyeron ambos polinomios ... } + then + cargarVectores := false { devuelve false (no se realizo con exito la lectura } + else { si se leyeron ambos polinomios ... } + if not asignado then { si no se pudo hacer la asignacion ... } + { esto solo tiene sentido si el archivo finaliza justo despues + de leer el ultimo exponente (no pasa por el estado FIN_EXP y + FIN debe hacer la asignacion } + begin + val(coeficiente, rCoef, code); { convierte el coeficiente en real } + val(exponente, iExp, code); { convierte el exponente en integer } + if iExp < TAM { si el exponente es menor que el tama¤o maximo permitido ... } + then + begin + v2[n].coef := rCoef; { asigna el valor correspondiente } + v2[n].exp := iExp; { asigna el valor correspondiente } + end + else + cargarVectores := false; { si no es menor, no se hizo bien la lectura } + end; { if not asignado } + end; { FIN: } + ERROR: { Si hubo un error ... } + begin + cargarVectores := false; { Se devuelve false (hubo un ERROR, no se leyeron bien los vectores) } + seguir := false; { seguir se pone en false para que termine el bucle } + end; + end; { case } + end; { while } + close(f); { se cierra el archivo de lectura de datos } + end; { cargarVectores } + + {########################################################} + + {########################################################} + +{ Continuacion del programa principal } + +var + i: integer; { variable auxiliar } + v1, v2, vResult, vResto: Vector; { vectores para hacer las operaciones } + continua: boolean; { valor para obtener los resultados de algunas funciones } + +begin { Comienzo del programa principal } + continua := cargarVectores(v1, v2); + if continua then + begin + muestraVector(v1, 'Polinomio 1 = '); + muestraVector(v2, 'Polinomio 2 = '); +{DEBUG} for i := 0 to 10 do {} +{DEBUG} writeln(v1[i].coef, ' X^', v1[i].exp, ' | ', v2[i].coef, ' X^', v2[i].exp); {} +{ suma(v1, v2, vResult); + muestraVector(vResult, 'Polinomio 1 + Polinomio 2 = '); + resta(v1, v2, vResult); + muestraVector(vResult, 'Polinomio 1 - Polinomio 2 = '); + producto(v1, v2, vResult); + muestraVector(vResult, 'Polinomio 1 * Polinomio 2 = '); + continua := division(v1, v2, vResult, vResto); + if continua + then + begin + muestraVector(vResult, 'Polinomio 1 / Polinomio 2 = '); + muestraVector(vResto, 'Resto = '); + end + else writeln('El segundo polinomio es nulo, por lo tanto no se puede efectuar la division'); +} end + else + begin + writeln('ERROR: No se pudieron cargar los datos. Revise que el formato del archivo'); + writeln(' sea correcto y que no este siendo usado por otro programa.'); + end; +end. \ No newline at end of file diff --git a/term_3.pas b/term_3.pas new file mode 100644 index 0000000..3276e83 --- /dev/null +++ b/term_3.pas @@ -0,0 +1,530 @@ +program PolinomiosEnTermino; +{ Programa que lee 2 polinomios desde un archivo de texto para luego + hacer operaciones basicas entre estos (suma, resta, multiplicacion + y division). + El formato del archivo de texto debe ser de la siguiente manera: + + * Se ingresan cada polinomio en lineas sucesivas. + * El primer polinomio puede comenzar a ingresarse en cualquier lugar + del archivo de texto. + * El fin del primer polinomio (y comienzo del segundo) se indica por + medio de 1 o mas lineas en blanco. + * El segundo polinomio puede comenzar a ingresarse en cualquier lugar + del archivo de texto a partir de dicha(s) linea(s) en blanco. + * Cada termino de un polinomio debe estar en la misma linea y comenzar + al principio de esta (excepto el primer termino). + * Los terminos debes estar ordenados de menor a mayor segun el exponente. + * En cada linea se ingresa primero el coeficiente real (puede tener un + signo '-' al comenzar y/o un punto, y solamente uno) y luego el + exponente entero positivo. + * La separacion entre el coeficiente y el exponente debe estar dada por + uno o mas espacios o tabuladores. + * Cualquier caracter incluido en el texto que no sea un degito (0..9), + un punto ('.'), un signo menos ('-'), un espacio (' '), un tabulador + o alguno de los caracteres de nueva linea, dara un error en la + lectura. + * El archivo de texto debe tener formato DOS (es decir, el indicador de + nueva linea debe ser primero un caracter de retorno del carro + seguido inmediatamente por uno de avance de linea). +} + +uses + CRT, DOS; { Declaracion de funciones predefinidas + para crear la interfaz grafica } + +const + VERSION = '0.9.0b (TERM_3)'; { version del programa } + + TAM_MAX = 100; { Tama¤o maximo del vector que almacena + la multiplicacion de polinomios } + TAM = TAM_MAX div 2; { Tama¤o maximo (virtual) del vector que contiene + los vector con los que se va a operar } + CR = chr(13); { caracter de retorno del carro } + LF = chr(10); { caracter de nueva linea } + ENDF = chr(26); { caracter de fin del archivo } + TAB = chr(9); { caracter de tabulacion } + SPACE = chr(32); { caracter de espacio } + +type + { Tipo de dato para identificar el estado de la entrada de datos } + Estado = (INICIO, COEF_BUSCA, COEF, COEF_PUNTO, COEF_FIN, EXP_BUSCA, EXP, EXP_FIN, EXP_FIN_BUSCA, POLI_FIN, FIN, ERROR); + Termino = record { tipo de dato que representa un termino de un polinomio } + coef: real; { parte del coeficiente del termino } + exp: integer; { parte del exponente del termino } + end; { Termino } + Vector = array [0..TAM_MAX-1] of Termino; { vector para almacenar los polinomios } + + + {########################################################} + + procedure muestraVector(var v: Vector; s: String); + { procedimiento que imprime el polinomio v en pantalla con un titulo s } + + {########################################################} + + function exponente(exp: integer): String; + + var + s: String; { variable temporal } + + begin { exponente } + case exp of + 0: exponente := ''; { si el exponente es nulo, mustra solo el coeficiente } + 1: exponente := 'X'; { si el exponente es 1, mustra el coeficiente y X } + 2: exponente := 'Xý'; { si el exponente es 2, mustra el coeficiente y Xý } + else begin + str(exp, s); { convierte al exponente en string } + exponente := 'X^' + s; { si el exponente es mayor que 1, mustra el coeficiente y X^exp } + end; { else } + end; { case } + end; { exponente } + + {########################################################} + + + var + i: integer; { indice para usar en el ciclo for } + + begin { muestraVector } + writeln; { separacion de una linea } + write(s); { mustra el mensaje } + for i := TAM_MAX - 1 downto 0 do { recorre el vector de atras para adelante } + if v[i].coef <> 0 then break; { si el coeficiente no es nulo, termina el for dejando a i en ese indice } + if (v[i].exp = 0) and (v[i].coef = 0) then { si el primer exponente que encuentra es 0 y el coeficiente es 0, entonces } + begin { muestra el resultado como 0 y sale del procedimiento } + write('0'); { imprime que el resultado es cero } + writeln; { separacion de una linea } + writeln; { separacion de una linea } + exit; { sale de este procedimiento } + end; + if (abs(v[i].coef) <> 1) or (v[i].exp = 0) { si el modulo del coeficiente es distinto de 1 o si el exp. es 0 } + then if abs(v[i].coef) - trunc(abs(v[i].coef)) = 0 then write(trunc(v[i].coef):1, ' ') {imprime si es un numero entero} + else write(v[i].coef:1:2, ' ') { imprime si es un numero real } + else if v[i].coef = -1 then write('-'); { si es -1 entonces solo escribe el signo del termino } + write(exponente(v[i].exp)); + for i := i - 1 downto 0 do { recorre el vector de atras para adelante } + if v[i].coef <> 0 then { si el coeficiente no es nulo, termina el for dejando a i en ese indice } + begin + if v[i].coef < 0 { si el coeficiente en negativo } + then write(' - ') { le agrega el signo - } + else write(' + '); { si no, le agrega el signo + } + if (abs(v[i].coef) <> 1) or (i = 0) then { si el modulo del coeficiente es distinto de 1 o si el exp. es 0 } + if abs(v[i].coef) - trunc(abs(v[i].coef)) = 0 + then write(trunc(abs(v[i].coef)):1, ' ') { imprime si es entero } + else write(abs(v[i].coef):1:2, ' '); { imprime si es un real } + write(exponente(v[i].exp)); + end; { if } + writeln; { separacion de una linea } + writeln; { separacion de una linea } + end; { muestraVector } + + {########################################################} + + procedure inicializaVector(var v: Vector); + { procedimiento que inicializa un vector de tama¤o tam } + + var i: integer; { indice para usar en el ciclo for } + + begin { inicializaVector } + for i := 0 to TAM_MAX - 1 do { recorre el vector } + begin + v[i].coef := 0.0; { inicializa la variable actual en 0 } + v[i].exp := 0; { inicializa la variable actual en 0 } + end; + end; { inicializaVector } + + {########################################################} + + function ObtenerNombreArchivo: String; + { funcion que obtiene un nombre de archivo valido (es decir, el nombre + de un archivo que exista) } + + {########################################################} + + function fileExists(FileName: String): Boolean; + { funcion extraida de la ayuda del Turbo Pascal 7 + indica si el archivo existe } + + var + F: file; + + begin + {$I-} + Assign(F, FileName); + FileMode := 0; { Set file access to read only } + Reset(F); + Close(F); + {$I+} + FileExists := (IOResult = 0) and (FileName <> ''); + end; { FileExists } + + {########################################################} + + { Continuacion de la funcion ObtenerNombreArchivo } + const + DEFAUL_FILE_NAME = 'datos.txt'; { nombre del archivo por defecto } + + var + tmp: String; { cadena para almacenar el resultado temporal } + + begin { ObtenerNombreArchivo } + { mensaje para entrada del nombre de archivo } + writeln('Ingrese el nombre del archivo con los datos (ENTER = ', DEFAUL_FILE_NAME, '):'); + readln(tmp); { entrada del nombre de archivo } + if tmp = '' then tmp := DEFAUL_FILE_NAME; { se fija si no se ingreso nada y reasigana el nombre } + while not fileExists(tmp) do { repite el proceso hasta que el archivo exista } + begin + write('El archivo ', tmp, ' no existe. Ingrese un nombre correcto'); + if tmp = DEFAUL_FILE_NAME { si es el nombre de archivo predeterminado } + then { entonces, elije un mensaje apropiado } + write(': ') + else + begin { si no es el predeterminado, muestra otro mensaje } + writeln('.'); + write('(ENTER = ', DEFAUL_FILE_NAME, '): '); + end; + readln(tmp); { vuelve a leer el nombre del archivo para ser verificado } + if tmp = '' then tmp := DEFAUL_FILE_NAME; { asigna como nombre de archivo al predeterminado + si no se escribio nada } + end; { fin del loop de verificacion } + ObtenerNombreArchivo := tmp; { asigna el nombre correcto al valor de salida de la funcion } + end; { ObtenerNombreArchivo } + + {########################################################} + + function trans(c: char; e: Estado): Estado; + { establece el estado en el que se encuentra la lectura } + { c es el caracter que se leyo, e es el estado actual de la lectura } + + begin { trans } + case e of { acciona segun es estado actual de la lectura } + INICIO: { estado de inicio de la lectura } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un numero (o negativo), empieza a leer el coeficiente } + SPACE, TAB, CR, LF: trans := COEF_BUSCA; { si es un caracter tipo "espacio", busca el prox. coef. } + else trans := ERROR; { si es otro, da ERROR } + end; + COEF_BUSCA: { estado de busqueda del primer ceoficiente del polinomio } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un numero (o negativo), empieza a leer el coeficiente } + SPACE, TAB, CR, LF: trans := COEF_BUSCA; { si es un caracter tupo "espacio", sigue buscando } + ENDF: trans := FIN; { si es el caracter de fin de archivo, pasa al estado de tarea finalizada } + else trans := ERROR; { si es otro, da ERROR } + end; + COEF: { estado de lectura del coeficiente del termino del polinomio (sin punto decimal) } + case c of { acciona segun el caracter leido } + '0'..'9': trans := COEF; { si es un numero sigue con el mismo estado } + '.': trans := COEF_PUNTO; { si es punto cambia al estado COEF_PUNTO } + SPACE, TAB: trans := COEF_FIN; { si es un espacio o un tabulador, finaliza la lectura del coeficiente } + else trans := ERROR; { si es otra cosa, pasa a estado de error } + end; + COEF_PUNTO: { estado de lectura del coeficiente del termino del polinomio (con punto decimal) } + case c of { acciona segun el caracter leido } + '0'..'9': trans := COEF_PUNTO; { si es un numero sigue con el mismo estado } + SPACE, TAB: trans := COEF_FIN; { si es un espacio o un tabulador, finaliza la lectura del coeficiente } + else trans := ERROR; { si es otra cosa, pasa a estado de error } + end; + COEF_FIN: { estado de fin de la lectura del coeficiente del termino del polinomio } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si el caracter es un numero establece el estado en EXP (exponente) } + SPACE, TAB: trans := EXP_BUSCA; { si es un espacio o tabulador, pasa a buscar el proximo exponente } + else trans := ERROR; { si no es ninguno de los anteriores, el estado pasa a ERROR } + end; + EXP_BUSCA: { estado de busqueda del proximo exponente } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si el caracter es un numero, empieza a leer el exponente } + SPACE, TAB: trans := EXP_BUSCA; { si es un espacio o tabulador, sigue buscando } + else trans := ERROR; { si no es ninguno de los anteriores, el estado pasa a ERROR } + end; + EXP: { estado de lectura del exponente del termino actual del polinomio } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si es un digito, sigue en el mismo estado } + CR: trans := EXP_FIN; { si es un ratorno de carro, finaliza el exponente + (quiere decir que hubo un ) } + ENDF: trans := FIN; { si es el final del archivo, se indica que termino su tarea } + else trans := ERROR; { si es otra cosa, devuelve ERROR } + end; + EXP_FIN: { estado de fin de la lectura del exponente del termino actual del polinomio } + if c = LF then trans := EXP_FIN_BUSCA { debe ser un caracter de nueva linea (para completar el ) } + else trans := ERROR; { si no lo es, devuelve ERROR } + EXP_FIN_BUSCA: { estado de fin de lectura de la nueva linea (luego de finalizar el exponente + ahora decide si termino el polinomio o si sigue leyendo el proximo coeficiente } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un digito (o negativo), pasa a leer en proximo coeficiente } + CR: trans := POLI_FIN; { si es un ratorno de carro o nueva linea, finaliza el polinomio } + else trans := ERROR; { si es otra cosa, devuelve ERROR } + end; + POLI_FIN: { estado de finalizacion del polinomio actual } + if c = LF then trans := COEF_BUSCA { debe ser un caracter de nueva linea (para completar el ), + entonces pasa a buscar el primer coeficiente del nuevo polinomio } + else trans := ERROR; { si no lo es, devuelve ERROR } + FIN: { estado que adquiere cuando se finalizo la tarea } + trans := FIN; { se queda en este estado avisando que termino su tarea } + else { otro estado, no deberia ocurrir, salvo que se le pase a la funcion un estado de ERROR } + trans := ERROR; { si es otro, da ERROR } + end; { case } + end; { trans } + + {########################################################} + + function cargarVectores(var v1, v2: Vector): boolean; + { Funcion que abre el archivo de texto con los datos, lo carga en el vector procesandolo debidamente a medida + que lo lee y, al finalizar, cierra el archivo de texto. + v1 es el primer vector a cargar + v2 es el segundo vector a cargar + devuelve true si la lectura fue hecha con exito, false si hubo un error } + + var + f: Text; { archivo de texto con los datos } + c: char; { caracter que se extrae del archivo de texto } + nombreArchivo: String; { nombre del archivo de datos } + est: Estado; { Indicador del estado actual de la lectura } + seguir: boolean; { indicador para saber si debe seguir con el proceso } + i, { indice del vector del polinomio para ser inicializado } + iExp, { valor temporal para almacenar al exponente } + code, { almacena el resultado de la funcion val (no se usa porque los + datos ya estan validados } + poliN: integer; { numero del polinomio que se esta leyendo } + rCoef: real; { valor temporal para almacenar al coeficiente } + exponente, { string que representa al exponente leido } + coeficiente: String; { string que representa al coeficiente leido } + + begin { cargarVectores } + rCoef := 0.0; { inicializacion de variable } + iExp := 0; { inicializacion de variable } + coeficiente := ''; { inicializacion de variable } + exponente := ''; { inicializacion de variable } + est := INICIO; { empieza con el estado de INICIO } + poliN := 1; { establece que se procesara el primer polinomio } + inicializaVector(v1); { inicializacion del vector 1 (primer polinomio) } + inicializaVector(v2); { inicializacion del vector 2 (segundo polinomio) } + nombreArchivo := ObtenerNombreArchivo; { obtiene el nombre del archivo } + assign(f, nombreArchivo); { asigna la variable al nombre del archivo } + reset(f); { abre el archivo para leerlo desde el principio } + seguir := true; { inicializa seguir e true para comenzar el bucle } + while seguir do begin { continua mientras seguir sea true } + read(f, c); { lee un caracter del archivo de texto } + est := trans(c, est); { establece el nuevo estado de lectura } + case est of { toma una desicion dependiendo del estado en que se encuentre } + INICIO: ; { No hace nada, nunca toma este valor. Solo incica que empezo el proceso } + COEF_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + COEF, COEF_PUNTO: { Si esta leyendo el coeficiente ... } + coeficiente := coeficiente + c; { concatena el caracter a la representacion + de texto del coeficiente } + COEF_FIN: ; { Si termino de leer el coeficiente, no hace nada, la asignacion + se realiza cuando termina de leer el exponente (es necesario + para establecer el indice del vector } + EXP_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + EXP: { Si esta leyendo el exponente ... } + exponente := exponente + c; { concatena el caracter a la representacion + de texto del exponente } + EXP_FIN: { Si termino de leer el exponente, hace las asignaciones correspondientes } + begin { convirtiendo las cadenas de texto en real e integer, segun el caso } + val(coeficiente, rCoef, code); { convierte el coeficiente en real } + val(exponente, iExp, code); { convierte el exponente en integer } + if iExp < TAM { si el exponente es menor que el tama¤o maximo permitido ... } + then if poliN = 1 + then { si es el polinomio 1 } + begin + v1[iExp].coef := rCoef; { asigna el valor correspondiente } + v1[iExp].exp := iExp; { asigna el valor correspondiente } + end + else { si es el polinomio 2 } + begin + v2[iExp].coef := rCoef; { asigna el valor correspondiente } + v2[iExp].exp := iExp; { asigna el valor correspondiente } + end + else est := ERROR; { si no es menor, pone el estado en ERROR } + coeficiente := ''; { una vez asignados, vacia los valores del coeficiente y el } + exponente := ''; { exponente para poder realizar las lecturas de los proximos } + end; + EXP_FIN_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + POLI_FIN: { Si termino la lectura de un polinomio ... } + if poliN = 1 then poliN := 2 { si se leyo el 1er polinomio, se indica que se leera el 2do } + else est := FIN; { si no (ya se leyo el segundo), pone el estado en FIN } + FIN: { Si se finalizaron las tareas ... } + begin + cargarVectores := true; { en principio se establece que la lectura se hizo con exito ) } + seguir := false; { poner seguir en false para que se termine el bucle } + { este codigo es similar al de EXP_FIN, se hacen las asignaciones por el caso en que el fin + del archivo esta pegado al fin del ultimo exponente, en cuyo caso no pasa por el estado + de EXP_FIN (y, por ende, no se pueden hacer las asignaciones correspondientes } + val(coeficiente, rCoef, code); { convierte el coeficiente en real } + val(exponente, iExp, code); { convierte el exponente en integer } + if iExp < TAM { si el exponente es menor que el tama¤o maximo permitido ... } + then if poliN = 2 + then { si es el polinomio 2 } + begin + v2[iExp].coef := rCoef; { asigna el valor correspondiente } + v2[iExp].exp := iExp; { asigna el valor correspondiente } + end + else cargarVectores := false { si es el primero, no se hizo bien la lectura } + else cargarVectores := false; { si no es menor, no se hizo bien la lectura } + end; + ERROR: { Si hubo un error ... } + begin + cargarVectores := false; { Se devuelve false (hubo un ERROR, no se leyeron bien los vectores) } + seguir := false; { seguir se pone en false para que termine el bucle } + end; + end; { case } + end; { while } + close(f); { se cierra el archivo de lectura de datos } + end; { cargarVectores } + + {########################################################} + + procedure suma(v1, v2: Vector; var vr: Vector); + { procedimiento que suma dos polinomios. + v1: vector que contiene el primer polinomio a sumar + v2: vector que contiene el segundo polinomio a sumar + vr: vector donde se almacenara el resultado de la suma } + + var + i: integer; { indice para usar en el ciclo for } + + begin { suma } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el vector (de tama¤o maximo TAM) } + begin + vr[i].coef := v1[i].coef + v2[i].coef; { suma los coeficientes de los terminos con igual exponente } + vr[i].exp := i; { establece como valor del exponente al indice } + end; + end; { suma } + + {########################################################} + + procedure resta(v1, v2: Vector; var vr: Vector); + { procedimiento que resta dos polinomios. + v1: vector que contiene el primer polinomio + v2: vector que contiene el polinomio para restarle al primero + vr: vector donde se almacenara el resultado de la resta } + + var + i: integer; { indice para usar en el ciclo for } + + begin { resta } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el vector (de tama¤o maximo TAM) } + begin + vr[i].coef := v1[i].coef - v2[i].coef; { resta los coeficientes de los terminos con igual exponente } + vr[i].exp := i; { establece como valor del exponente al indice } + end; + end; { resta } + + {########################################################} + + procedure producto(v1, v2: Vector; var vr: Vector); + { procedimiento que multiplica dos polinomios. + v1: vector que contiene el primer polinomio a multiplicar + v2: vector que contiene el segundo polinomio a multiplicar + vr: vector donde se almacenara el resultado de la multiplicacion } + + var + i, j: integer; { indices para usar en los ciclos for } + + begin { producto } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el 1er vector (de tama¤o maximo TAM) } + for j := 0 to TAM - 1 do { recorre el 2do vector (de tama¤o maximo TAM) } + begin + vr[i+j].coef := vr[i+j].coef + (v1[i].coef * v2[j].coef); + { multiplica los coeficientes de los terminos y lo almacena en la posicion del exponente } + { igual a la suma de los exponentes de v1 y v2, sumando el valor previo de dicha posicion } + vr[i+j].exp := i+j; { establece como exponente a la suma de los otros dos } + end; + end; { producto } + + {########################################################} + + function division(v1, v2: Vector; var vr, vResto: Vector): boolean; + { procedimiento que divide dos polinomios. + v1: vector que contiene el polinomio denominador + v2: vector que contiene el polinomio divisor + vr: vector donde se almacenara el resultado de la division + vResto: vector donde se almacenara el resto de la division + devuelve true si el segundo polinomio no es 0 y se efectua la division y + devuelve false si segundo polinomio es 0 y no se puede efectuar la division } + + var + i, j: integer; { indices para usar en los ciclos for } + vRTmp, { vector auxuliares para almacenar el termino actual del resultado } + vTmp: Vector; { vector auxuliares para almacenar el polinomio que es la multiplicacion del + termino actual del resultado por el divisor } + + begin { division } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vResto); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vTmp); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vRTmp); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := TAM - 1 downto 0 do { recorre el 1er vector (de tama¤o maximo TAM) de atras para adelante } + if v1[i].coef <> 0 then break; + { busca empezando por el indice (exponete) mas alto el primer coeficiente no nulo } + { si lo encuentra sale del for dejando al valor de i como el de dicho inidice } + for j := TAM - 1 downto 0 do { recorre el 2do vector (de tama¤o maximo TAM) de atras para adelante } + if v2[j].coef <> 0 then break; + { busca empezando por el indice (exponete) mas alto el primer coeficiente no nulo } + { si lo encuentra sale del for dejando al valor de j como el de dicho inidice } + if (j = 0) and (v2[j].coef = 0) { si el no se encontro ningun coeficiente no nulo, entonces } + then { el polinomio 2 es nulo y no se puede efectuar la division } + begin { se devuelve false y se quedan los vectores resultado en 0 } + division := false; { devuelve false } + exit; { sale del procedimiento } + end; + while i >= j do { si el primer exponente es mayor o igual que el segundo empieza a dividir } + begin + vr[i-j].coef := v1[i].coef / v2[j].coef; { almacena el resultado de la division entre los coeficientes en } + vr[i-j].exp := v1[i].exp - v2[j].exp; { coeficientes en la posicion de la resta de ambos } + vRTmp[i-j].coef := vr[i-j].coef; { almacena ese resultado en un polinomio temporal cuyo unico termio } + vRTmp[i-j].exp := vr[i-j].exp; { no nulo es el del exponente i-j, para luego multiplicarlo } + producto(vRTmp, v2, vTmp);{ multiplica este polinomio por el segundo almacenado el resultado + en otro temporal, para luego hacer la resta } + resta(v1, vTmp, v1); { resta al primer polinomio, v1, (en su estado actual, no el original) + el temporal vTmp y lo almacena en v1, para poder volver a operarlo de + la misma forma } + vRTmp[i-j].coef := 0.0; {resetea el coeficiente del termino del temporal vRTmp que se asigno para los calculos} + vRTmp[i-j].exp := 0; { resetea el exponente del termino del temporal vRTmp que se asigno para los calculos } + for i := i downto 0 do { recorre el vector v1 (de tama¤o maximo TAM) de atras para adelante } + if v1[i].coef <> 0 then break; + { busca empezando por el indice (exponete) i el primer coeficiente no nulo + si lo encuentra sale del for dejando al valor de i como el de dicho inidice } + end; { while } + vResto := v1; { asigna el vector v1 (que ya no se procesara mas al resto } + division := true; { devuelve true indicando que se finalizo con exito } + end; { division } + + {########################################################} + +{ Continuacion del programa principal } + +var + i: integer; { variable auxiliar } + v1, v2, vResult, vResto: Vector; { vectores para hacer las operaciones } + continua: boolean; { valor para obtener los resultados de algunas funciones } + +begin { Comienzo del programa principal } + continua := cargarVectores(v1, v2); + if continua then + begin + muestraVector(v1, 'Polinomio 1 = '); + muestraVector(v2, 'Polinomio 2 = '); + suma(v1, v2, vResult); + muestraVector(vResult, 'Polinomio 1 + Polinomio 2 = '); + resta(v1, v2, vResult); + muestraVector(vResult, 'Polinomio 1 - Polinomio 2 = '); + producto(v1, v2, vResult); + muestraVector(vResult, 'Polinomio 1 * Polinomio 2 = '); + continua := division(v1, v2, vResult, vResto); + if continua + then + begin + muestraVector(vResult, 'Polinomio 1 / Polinomio 2 = '); + muestraVector(vResto, 'Resto = '); + end + else writeln('El segundo polinomio es nulo, por lo tanto no se puede efectuar la division'); + end + else + begin + writeln('ERROR: No se pudieron cargar los datos. Revise que el formato del archivo'); + writeln(' sea correcto y que no este siendo usado por otro programa.'); + end; +end. \ No newline at end of file diff --git a/term_4.pas b/term_4.pas new file mode 100644 index 0000000..0776536 --- /dev/null +++ b/term_4.pas @@ -0,0 +1,665 @@ +program PolinomiosEnTermino; +{ Programa que lee 2 polinomios desde un archivo de texto para luego + hacer operaciones basicas entre estos (suma, resta, multiplicacion + y division). + El formato del archivo de texto debe ser de la siguiente manera: + + * Se ingresan cada polinomio en lineas sucesivas. + * El primer polinomio puede comenzar a ingresarse en cualquier lugar + del archivo de texto. + * El fin del primer polinomio (y comienzo del segundo) se indica por + medio de 1 o mas lineas en blanco. + * El segundo polinomio puede comenzar a ingresarse en cualquier lugar + del archivo de texto a partir de dicha(s) linea(s) en blanco. + * Cada termino de un polinomio debe estar en la misma linea y comenzar + al principio de esta (excepto el primer termino). + * Los terminos debes estar ordenados de menor a mayor segun el exponente. + * En cada linea se ingresa primero el coeficiente real (puede tener un + signo '-' al comenzar y/o un punto, y solamente uno) y luego el + exponente entero positivo. + * La separacion entre el coeficiente y el exponente debe estar dada por + uno o mas espacios o tabuladores. + * Cualquier caracter incluido en el texto que no sea un degito (0..9), + un punto ('.'), un signo menos ('-'), un espacio (' '), un tabulador + o alguno de los caracteres de nueva linea, dara un error en la + lectura. + * El archivo de texto debe tener formato DOS (es decir, el indicador de + nueva linea debe ser primero un caracter de retorno del carro + seguido inmediatamente por uno de avance de linea). +} + +uses + CRT, DOS; { Declaracion de funciones predefinidas + para crear la interfaz grafica } + +const + VERSION = '1.2.0r (TERM_4)'; { version del programa } + + TAM_MAX = 100; { Tama¤o maximo del vector que almacena + la multiplicacion de polinomios } + TAM = TAM_MAX div 2; { Tama¤o maximo (virtual) del vector que contiene + los vector con los que se va a operar } + CR = chr(13); { caracter de retorno del carro } + LF = chr(10); { caracter de nueva linea } + ENDF = chr(26); { caracter de fin del archivo } + TAB = chr(9); { caracter de tabulacion } + SPACE = chr(32); { caracter de espacio } + +type + { Tipo de dato para identificar el estado de la entrada de datos } + Estado = (INICIO, COEF_BUSCA, COEF, COEF_PUNTO, COEF_FIN, EXP_BUSCA, EXP, EXP_FIN, EXP_FIN_BUSCA, POLI_FIN, FIN, ERROR); + Termino = record { tipo de dato que representa un termino de un polinomio } + coef: real; { parte del coeficiente del termino } + exp: integer; { parte del exponente del termino } + end; { Termino } + Vector = array [0..TAM_MAX-1] of Termino; { vector para almacenar los polinomios } + + + {########################################################} + + procedure muestraVector(var v: Vector; s: String); + { procedimiento que imprime el polinomio v en pantalla con un titulo s } + + {########################################################} + + function exponente(exp: integer): String; + + var + s: String; { variable temporal } + + begin { exponente } + case exp of + 0: exponente := ''; { si el exponente es nulo, mustra solo el coeficiente } + 1: exponente := 'X'; { si el exponente es 1, mustra el coeficiente y X } + 2: exponente := 'Xý'; { si el exponente es 2, mustra el coeficiente y Xý } + else begin + str(exp, s); { convierte al exponente en string } + exponente := 'X^' + s; { si el exponente es mayor que 1, mustra el coeficiente y X^exp } + end; { else } + end; { case } + end; { exponente } + + {########################################################} + + + var + i: integer; { indice para usar en el ciclo for } + + begin { muestraVector } + textcolor(lightcyan); { pone el color del texto en cian claro } + writeln; { separacion de una linea } + write(s); { mustra el mensaje } + textcolor(lightmagenta); { pone el color del texto en magenta claro } + for i := TAM_MAX - 1 downto 0 do { recorre el vector de atras para adelante } + if v[i].coef <> 0 then break; { si el coeficiente no es nulo, termina el for dejando a i en ese indice } + if (v[i].exp = 0) and (v[i].coef = 0) then { si el primer exponente que encuentra es 0 y el coeficiente es 0, entonces } + begin { muestra el resultado como 0 y sale del procedimiento } + write('0'); { imprime que el resultado es cero } + writeln; { separacion de una linea } + writeln; { separacion de una linea } + exit; { sale de este procedimiento } + end; + if (abs(v[i].coef) <> 1) or (v[i].exp = 0) { si el modulo del coeficiente es distinto de 1 o si el exp. es 0 } + then if abs(v[i].coef) - trunc(abs(v[i].coef)) = 0 then write(trunc(v[i].coef):1, ' ') {imprime si es un numero entero} + else write(v[i].coef:1:2, ' ') { imprime si es un numero real } + else if v[i].coef = -1 then write('-'); { si es -1 entonces solo escribe el signo del termino } + write(exponente(v[i].exp)); + for i := i - 1 downto 0 do { recorre el vector de atras para adelante } + if v[i].coef <> 0 then { si el coeficiente no es nulo, termina el for dejando a i en ese indice } + begin + if v[i].coef < 0 { si el coeficiente en negativo } + then write(' - ') { le agrega el signo - } + else write(' + '); { si no, le agrega el signo + } + if (abs(v[i].coef) <> 1) or (i = 0) then { si el modulo del coeficiente es distinto de 1 o si el exp. es 0 } + if abs(v[i].coef) - trunc(abs(v[i].coef)) = 0 + then write(trunc(abs(v[i].coef)):1, ' ') { imprime si es entero } + else write(abs(v[i].coef):1:2, ' '); { imprime si es un real } + write(exponente(v[i].exp)); + end; { if } + writeln; { separacion de una linea } + writeln; { separacion de una linea } + end; { muestraVector } + + {########################################################} + + procedure inicializaVector(var v: Vector); + { procedimiento que inicializa un vector de tama¤o tam } + + var i: integer; { indice para usar en el ciclo for } + + begin { inicializaVector } + for i := 0 to TAM_MAX - 1 do { recorre el vector } + begin + v[i].coef := 0.0; { inicializa la variable actual en 0 } + v[i].exp := 0; { inicializa la variable actual en 0 } + end; + end; { inicializaVector } + + {########################################################} + + function ObtenerNombreArchivo: String; + { funcion que obtiene un nombre de archivo valido (es decir, el nombre + de un archivo que exista) } + + {########################################################} + + function fileExists(FileName: String): Boolean; + { funcion extraida de la ayuda del Turbo Pascal 7 + indica si el archivo existe } + + var + F: file; + + begin + {$I-} + Assign(F, FileName); + FileMode := 0; { Set file access to read only } + Reset(F); + Close(F); + {$I+} + FileExists := (IOResult = 0) and (FileName <> ''); + end; { FileExists } + + {########################################################} + + { Continuacion de la funcion ObtenerNombreArchivo } + const + DEFAUL_FILE_NAME = 'datos.txt'; { nombre del archivo por defecto } + + var + tmp: String; { cadena para almacenar el resultado temporal } + + begin { ObtenerNombreArchivo } + { mensaje para entrada del nombre de archivo } + clrscr; { borra la pantalla } + textcolor( Yellow ); { establece el color para el texto a amarillo } + gotoxy( 25, 3 ); { va a las coordenas de pantalla 25 horizontal, 3 verical } + writeln( 'OPERACIONES ENTRE POLINOMIOS' ); { titulo } + gotoxy( 25, 4 ); { va a las coordenas de pantalla 25 horizontal, 4 verical } + writeln( '~~~~~~~~~~~ ~~~~~ ~~~~~~~~~~' ); { subrayado del titulo } + textcolor( LightCyan ); { establece el color para el texto a cian claro } + gotoxy( 1, 7 ); { va a las coordenas de pantalla 1 horizontal, 7 verical } + writeln(' Ingrese el nombre del archivo con los datos (ENTER = ', DEFAUL_FILE_NAME, '):'); + readln(tmp); { entrada del nombre de archivo } + if tmp = '' then tmp := DEFAUL_FILE_NAME; { se fija si no se ingreso nada y reasigana el nombre } + while not fileExists(tmp) do { repite el proceso hasta que el archivo exista } + begin + clrscr; { borra la pantalla } + textcolor( Yellow ); { establece el color para el texto a amarillo } + gotoxy( 25, 3 ); { va a las coordenas de pantalla 19 horizontal, 3 verical } + writeln( 'OPERACIONES ENTRE POLINOMIOS' ); { titulo } + gotoxy( 25, 4 ); { va a las coordenas de pantalla 19 horizontal, 4 verical } + writeln( '~~~~~~~~~~~ ~~~~~ ~~~~~~~~~~' ); { subrayado del titulo } + textcolor( LightCyan ); { establece el color para el texto a cian claro } + gotoxy( 1, 7 ); { va a las coordenas de pantalla 1 horizontal, 7 verical } + write(' El archivo ', tmp, ' no existe. Ingrese un nombre correcto'); + if tmp = DEFAUL_FILE_NAME { si es el nombre de archivo predeterminado } + then { entonces, elije un mensaje apropiado } + write(': ') + else + begin { si no es el predeterminado, muestra otro mensaje } + writeln('.'); + write(' (ENTER = ', DEFAUL_FILE_NAME, '): '); + end; + readln(tmp); { vuelve a leer el nombre del archivo para ser verificado } + if tmp = '' then tmp := DEFAUL_FILE_NAME; { asigna como nombre de archivo al predeterminado + si no se escribio nada } + end; { fin del loop de verificacion } + ObtenerNombreArchivo := tmp; { asigna el nombre correcto al valor de salida de la funcion } + end; { ObtenerNombreArchivo } + + {########################################################} + + function trans(c: char; e: Estado): Estado; + { establece el estado en el que se encuentra la lectura } + { c es el caracter que se leyo, e es el estado actual de la lectura } + + begin { trans } + case e of { acciona segun es estado actual de la lectura } + INICIO: { estado de inicio de la lectura } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un numero (o negativo), empieza a leer el coeficiente } + SPACE, TAB, CR, LF: trans := COEF_BUSCA; { si es un caracter tipo "espacio", busca el prox. coef. } + else trans := ERROR; { si es otro, da ERROR } + end; + COEF_BUSCA: { estado de busqueda del primer ceoficiente del polinomio } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un numero (o negativo), empieza a leer el coeficiente } + SPACE, TAB, CR, LF: trans := COEF_BUSCA; { si es un caracter tupo "espacio", sigue buscando } + ENDF: trans := FIN; { si es el caracter de fin de archivo, pasa al estado de tarea finalizada } + else trans := ERROR; { si es otro, da ERROR } + end; + COEF: { estado de lectura del coeficiente del termino del polinomio (sin punto decimal) } + case c of { acciona segun el caracter leido } + '0'..'9': trans := COEF; { si es un numero sigue con el mismo estado } + '.': trans := COEF_PUNTO; { si es punto cambia al estado COEF_PUNTO } + SPACE, TAB: trans := COEF_FIN; { si es un espacio o un tabulador, finaliza la lectura del coeficiente } + else trans := ERROR; { si es otra cosa, pasa a estado de error } + end; + COEF_PUNTO: { estado de lectura del coeficiente del termino del polinomio (con punto decimal) } + case c of { acciona segun el caracter leido } + '0'..'9': trans := COEF_PUNTO; { si es un numero sigue con el mismo estado } + SPACE, TAB: trans := COEF_FIN; { si es un espacio o un tabulador, finaliza la lectura del coeficiente } + else trans := ERROR; { si es otra cosa, pasa a estado de error } + end; + COEF_FIN: { estado de fin de la lectura del coeficiente del termino del polinomio } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si el caracter es un numero establece el estado en EXP (exponente) } + SPACE, TAB: trans := EXP_BUSCA; { si es un espacio o tabulador, pasa a buscar el proximo exponente } + else trans := ERROR; { si no es ninguno de los anteriores, el estado pasa a ERROR } + end; + EXP_BUSCA: { estado de busqueda del proximo exponente } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si el caracter es un numero, empieza a leer el exponente } + SPACE, TAB: trans := EXP_BUSCA; { si es un espacio o tabulador, sigue buscando } + else trans := ERROR; { si no es ninguno de los anteriores, el estado pasa a ERROR } + end; + EXP: { estado de lectura del exponente del termino actual del polinomio } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si es un digito, sigue en el mismo estado } + CR: trans := EXP_FIN; { si es un ratorno de carro, finaliza el exponente + (quiere decir que hubo un ) } + ENDF: trans := FIN; { si es el final del archivo, se indica que termino su tarea } + else trans := ERROR; { si es otra cosa, devuelve ERROR } + end; + EXP_FIN: { estado de fin de la lectura del exponente del termino actual del polinomio } + if c = LF then trans := EXP_FIN_BUSCA { debe ser un caracter de nueva linea (para completar el ) } + else trans := ERROR; { si no lo es, devuelve ERROR } + EXP_FIN_BUSCA: { estado de fin de lectura de la nueva linea (luego de finalizar el exponente + ahora decide si termino el polinomio o si sigue leyendo el proximo coeficiente } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un digito (o negativo), pasa a leer en proximo coeficiente } + CR: trans := POLI_FIN; { si es un ratorno de carro o nueva linea, finaliza el polinomio } + else trans := ERROR; { si es otra cosa, devuelve ERROR } + end; + POLI_FIN: { estado de finalizacion del polinomio actual } + if c = LF then trans := COEF_BUSCA { debe ser un caracter de nueva linea (para completar el ), + entonces pasa a buscar el primer coeficiente del nuevo polinomio } + else trans := ERROR; { si no lo es, devuelve ERROR } + FIN: { estado que adquiere cuando se finalizo la tarea } + trans := FIN; { se queda en este estado avisando que termino su tarea } + else { otro estado, no deberia ocurrir, salvo que se le pase a la funcion un estado de ERROR } + trans := ERROR; { si es otro, da ERROR } + end; { case } + end; { trans } + + {########################################################} + + function cargarVectores(var v1, v2: Vector): boolean; + { Funcion que abre el archivo de texto con los datos, lo carga en el vector procesandolo debidamente a medida + que lo lee y, al finalizar, cierra el archivo de texto. + v1 es el primer vector a cargar + v2 es el segundo vector a cargar + devuelve true si la lectura fue hecha con exito, false si hubo un error } + + var + f: Text; { archivo de texto con los datos } + c: char; { caracter que se extrae del archivo de texto } + nombreArchivo: String; { nombre del archivo de datos } + est: Estado; { Indicador del estado actual de la lectura } + seguir: boolean; { indicador para saber si debe seguir con el proceso } + i, { indice del vector del polinomio para ser inicializado } + iExp, { valor temporal para almacenar al exponente } + code, { almacena el resultado de la funcion val (no se usa porque los + datos ya estan validados } + poliN: integer; { numero del polinomio que se esta leyendo } + rCoef: real; { valor temporal para almacenar al coeficiente } + exponente, { string que representa al exponente leido } + coeficiente: String; { string que representa al coeficiente leido } + + begin { cargarVectores } + rCoef := 0.0; { inicializacion de variable } + iExp := 0; { inicializacion de variable } + coeficiente := ''; { inicializacion de variable } + exponente := ''; { inicializacion de variable } + est := INICIO; { empieza con el estado de INICIO } + poliN := 1; { establece que se procesara el primer polinomio } + inicializaVector(v1); { inicializacion del vector 1 (primer polinomio) } + inicializaVector(v2); { inicializacion del vector 2 (segundo polinomio) } + nombreArchivo := ObtenerNombreArchivo; { obtiene el nombre del archivo } + assign(f, nombreArchivo); { asigna la variable al nombre del archivo } + reset(f); { abre el archivo para leerlo desde el principio } + seguir := true; { inicializa seguir e true para comenzar el bucle } + while seguir do begin { continua mientras seguir sea true } + read(f, c); { lee un caracter del archivo de texto } + est := trans(c, est); { establece el nuevo estado de lectura } + case est of { toma una desicion dependiendo del estado en que se encuentre } + INICIO: ; { No hace nada, nunca toma este valor. Solo incica que empezo el proceso } + COEF_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + COEF, COEF_PUNTO: { Si esta leyendo el coeficiente ... } + coeficiente := coeficiente + c; { concatena el caracter a la representacion + de texto del coeficiente } + COEF_FIN: ; { Si termino de leer el coeficiente, no hace nada, la asignacion + se realiza cuando termina de leer el exponente (es necesario + para establecer el indice del vector } + EXP_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + EXP: { Si esta leyendo el exponente ... } + exponente := exponente + c; { concatena el caracter a la representacion + de texto del exponente } + EXP_FIN: { Si termino de leer el exponente, hace las asignaciones correspondientes } + begin { convirtiendo las cadenas de texto en real e integer, segun el caso } + val(coeficiente, rCoef, code); { convierte el coeficiente en real } + val(exponente, iExp, code); { convierte el exponente en integer } + if iExp < TAM { si el exponente es menor que el tama¤o maximo permitido ... } + then if poliN = 1 + then { si es el polinomio 1 } + begin + v1[iExp].coef := rCoef; { asigna el valor correspondiente } + v1[iExp].exp := iExp; { asigna el valor correspondiente } + end + else { si es el polinomio 2 } + begin + v2[iExp].coef := rCoef; { asigna el valor correspondiente } + v2[iExp].exp := iExp; { asigna el valor correspondiente } + end + else est := ERROR; { si no es menor, pone el estado en ERROR } + coeficiente := ''; { una vez asignados, vacia los valores del coeficiente y el } + exponente := ''; { exponente para poder realizar las lecturas de los proximos } + end; + EXP_FIN_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + POLI_FIN: { Si termino la lectura de un polinomio ... } + if poliN = 1 then poliN := 2 { si se leyo el 1er polinomio, se indica que se leera el 2do } + else est := FIN; { si no (ya se leyo el segundo), pone el estado en FIN } + FIN: { Si se finalizaron las tareas ... } + begin + cargarVectores := true; { en principio se establece que la lectura se hizo con exito ) } + seguir := false; { poner seguir en false para que se termine el bucle } + { este codigo es similar al de EXP_FIN, se hacen las asignaciones por el caso en que el fin + del archivo esta pegado al fin del ultimo exponente, en cuyo caso no pasa por el estado + de EXP_FIN (y, por ende, no se pueden hacer las asignaciones correspondientes } + val(coeficiente, rCoef, code); { convierte el coeficiente en real } + val(exponente, iExp, code); { convierte el exponente en integer } + if iExp < TAM { si el exponente es menor que el tama¤o maximo permitido ... } + then if poliN = 2 + then { si es el polinomio 2 } + begin + v2[iExp].coef := rCoef; { asigna el valor correspondiente } + v2[iExp].exp := iExp; { asigna el valor correspondiente } + end + else cargarVectores := false { si es el primero, no se hizo bien la lectura } + else cargarVectores := false; { si no es menor, no se hizo bien la lectura } + end; + ERROR: { Si hubo un error ... } + begin + cargarVectores := false; { Se devuelve false (hubo un ERROR, no se leyeron bien los vectores) } + seguir := false; { seguir se pone en false para que termine el bucle } + end; + end; { case } + end; { while } + close(f); { se cierra el archivo de lectura de datos } + end; { cargarVectores } + + {########################################################} + + procedure suma(v1, v2: Vector; var vr: Vector); + { procedimiento que suma dos polinomios. + v1: vector que contiene el primer polinomio a sumar + v2: vector que contiene el segundo polinomio a sumar + vr: vector donde se almacenara el resultado de la suma } + + var + i: integer; { indice para usar en el ciclo for } + + begin { suma } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el vector (de tama¤o maximo TAM) } + begin + vr[i].coef := v1[i].coef + v2[i].coef; { suma los coeficientes de los terminos con igual exponente } + vr[i].exp := i; { establece como valor del exponente al indice } + end; + end; { suma } + + {########################################################} + + procedure resta(v1, v2: Vector; var vr: Vector); + { procedimiento que resta dos polinomios. + v1: vector que contiene el primer polinomio + v2: vector que contiene el polinomio para restarle al primero + vr: vector donde se almacenara el resultado de la resta } + + var + i: integer; { indice para usar en el ciclo for } + + begin { resta } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el vector (de tama¤o maximo TAM) } + begin + vr[i].coef := v1[i].coef - v2[i].coef; { resta los coeficientes de los terminos con igual exponente } + vr[i].exp := i; { establece como valor del exponente al indice } + end; + end; { resta } + + {########################################################} + + procedure producto(v1, v2: Vector; var vr: Vector); + { procedimiento que multiplica dos polinomios. + v1: vector que contiene el primer polinomio a multiplicar + v2: vector que contiene el segundo polinomio a multiplicar + vr: vector donde se almacenara el resultado de la multiplicacion } + + var + i, j: integer; { indices para usar en los ciclos for } + + begin { producto } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el 1er vector (de tama¤o maximo TAM) } + for j := 0 to TAM - 1 do { recorre el 2do vector (de tama¤o maximo TAM) } + begin + vr[i+j].coef := vr[i+j].coef + (v1[i].coef * v2[j].coef); + { multiplica los coeficientes de los terminos y lo almacena en la posicion del exponente } + { igual a la suma de los exponentes de v1 y v2, sumando el valor previo de dicha posicion } + vr[i+j].exp := i+j; { establece como exponente a la suma de los otros dos } + end; + end; { producto } + + {########################################################} + + function division(v1, v2: Vector; var vr, vResto: Vector): boolean; + { procedimiento que divide dos polinomios. + v1: vector que contiene el polinomio denominador + v2: vector que contiene el polinomio divisor + vr: vector donde se almacenara el resultado de la division + vResto: vector donde se almacenara el resto de la division + devuelve true si el segundo polinomio no es 0 y se efectua la division y + devuelve false si segundo polinomio es 0 y no se puede efectuar la division } + + var + i, j: integer; { indices para usar en los ciclos for } + vRTmp, { vector auxuliares para almacenar el termino actual del resultado } + vTmp: Vector; { vector auxuliares para almacenar el polinomio que es la multiplicacion del + termino actual del resultado por el divisor } + + begin { division } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vResto); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vTmp); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vRTmp); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := TAM - 1 downto 0 do { recorre el 1er vector (de tama¤o maximo TAM) de atras para adelante } + if v1[i].coef <> 0 then break; + { busca empezando por el indice (exponete) mas alto el primer coeficiente no nulo } + { si lo encuentra sale del for dejando al valor de i como el de dicho inidice } + for j := TAM - 1 downto 0 do { recorre el 2do vector (de tama¤o maximo TAM) de atras para adelante } + if v2[j].coef <> 0 then break; + { busca empezando por el indice (exponete) mas alto el primer coeficiente no nulo } + { si lo encuentra sale del for dejando al valor de j como el de dicho inidice } + if (j = 0) and (v2[j].coef = 0) { si el no se encontro ningun coeficiente no nulo, entonces } + then { el polinomio 2 es nulo y no se puede efectuar la division } + begin { se devuelve false y se quedan los vectores resultado en 0 } + division := false; { devuelve false } + exit; { sale del procedimiento } + end; + while i >= j do { si el primer exponente es mayor o igual que el segundo empieza a dividir } + begin + vr[i-j].coef := v1[i].coef / v2[j].coef; { almacena el resultado de la division entre los coeficientes en } + vr[i-j].exp := v1[i].exp - v2[j].exp; { coeficientes en la posicion de la resta de ambos } + vRTmp[i-j].coef := vr[i-j].coef; { almacena ese resultado en un polinomio temporal cuyo unico termio } + vRTmp[i-j].exp := vr[i-j].exp; { no nulo es el del exponente i-j, para luego multiplicarlo } + producto(vRTmp, v2, vTmp);{ multiplica este polinomio por el segundo almacenado el resultado + en otro temporal, para luego hacer la resta } + resta(v1, vTmp, v1); { resta al primer polinomio, v1, (en su estado actual, no el original) + el temporal vTmp y lo almacena en v1, para poder volver a operarlo de + la misma forma } + vRTmp[i-j].coef := 0.0; {resetea el coeficiente del termino del temporal vRTmp que se asigno para los calculos} + vRTmp[i-j].exp := 0; { resetea el exponente del termino del temporal vRTmp que se asigno para los calculos } + for i := i downto 0 do { recorre el vector v1 (de tama¤o maximo TAM) de atras para adelante } + if v1[i].coef <> 0 then break; + { busca empezando por el indice (exponete) i el primer coeficiente no nulo + si lo encuentra sale del for dejando al valor de i como el de dicho inidice } + end; { while } + vResto := v1; { asigna el vector v1 (que ya no se procesara mas al resto } + division := true; { devuelve true indicando que se finalizo con exito } + end; { division } + + {########################################################} + + procedure mensajeSalida; { muestra un mensaje en la salida del programa } + + begin + writeln; { linea en blanco } + NormVideo; { reestablece los colores a los valores por defecto } + clrscr; { borra la pantalla } + writeln; { linea en blanco } + textcolor(white); { cambia el color del texto } + writeln(' OPERACIONES ENTRE POLINOMIOS versi¢n ', VERSION); { mensaje con version del programa } + NormVideo; { reestablece los colores a los valores por defecto } + writeln(' Desarrollado por: JavierGrijalba'); { mensaje con los integrantes del grupo } + writeln(' Leandro Lucarella'); + writeln(' Erasmo Troncovich'); + writeln(' Diego Wojmicki'); + writeln(' para la Facultad de Ingenier¡a de la Universidad de Buenos Aires.'); + writeln(' Consultas y/o sugerencias a:'); + writeln; + textcolor(LightMagenta); { cambia el color del texto } + write(' lluca@cnba.uba.ar'); + NormVideo; { reestablece los colores a los valores por defecto } + write(' o '); + textcolor(LightMagenta); { cambia el color del texto } + writeln('grijalba@cvtci.com.ar'); + NormVideo; { reestablece los colores a los valores por defecto } + writeln; + writeln(' (c) 1999 - Todos los derechos reservados.'); + delay(750); + end; + + + {########################################################} + + +var + i: integer; { variable auxiliar } + v1, v2, vResult, vResto: Vector; { vectores para hacer las operaciones } + seguir, { indicador para saber si sigue corriendo el programa } + noNulo, { indicador para saber si en la division el divisor es nulo } + continua: boolean; { indicador para saber si se leyeron bien los polinomios } + tecla: char; { entrada de teclado del usuario para elegir una opcion } + +begin { programa principal } + textbackground( Blue ); { establece el color para el fondo a azul } + continua := cargarVectores(v1, v2); { carga los vectores del archivo de datos } + if continua then { si se leyeron bien ... } + begin + seguir := true; { inicializa la variable en true para que entre en el ciclo while } + while seguir do { mientras el usuario no salga del programa } + begin + clrscr; { borra la pantalla } + textcolor(Yellow); { establece el color para el texto a amarillo } + gotoxy( 25, 3 ); { va a las coordenas de pantalla 19 horizontal, 3 verical } + writeln( 'OPERACIONES ENTRE POLINOMIOS' ); { titulo } + gotoxy( 25, 4 ); { va a las coordenas de pantalla 19 horizontal, 4 verical } + writeln( '~~~~~~~~~~~ ~~~~~ ~~~~~~~~~~' ); { subrayado del titulo } + textcolor(LightCyan); { establece el color para el texto a cian claro } + gotoxy( 1, 7 ); { va a las coordenas de pantalla 1 horizontal, 7 verical } + writeln( ' Elija que desea hacer:' ); { mensaje } + writeln( ' ----- --- ----- ------' ); { mensaje } + textcolor(LightGray); { establece el color para el texto a gris claro } + writeln; { mensaje con las opciones ... } + writeln; + writeln( ' 1.- Ver el polinomio 1.' ); + writeln( ' 2.- Ver el polinomio 2.' ); + writeln( ' 3.- Sumar los polinomios.' ); + writeln( ' 4.- Restar el polinomio 2 al polinomio 1 (poli1 - poli2).' ); + writeln( ' 5.- Restar el polinomio 1 al polinomio 2 (poli2 - poli1).' ); + writeln( ' 6.- Multiplicar los polinomios.' ); + writeln( ' 7.- Polinomio 1 dividido polinomio 2 (poli1 / poli2).' ); + writeln( ' 8.- Polinomio 2 dividido polinomio 1 (poli2 / poli1).' ); + writeln( ' 0.- Salir.' ); + gotoxy(1, 23); { va a las coordenas de pantalla 1 horizontal, 23 verical } + textcolor(White ); { establece el color para el texto a blanco } + write(' Ingrese su opci¢n: '); + textcolor(Yellow); { establece el color para el texto a amarillo } + tecla := readkey; { lee una tecla del usuario indicando la opcion que elijio } + while ((tecla < '1') or (tecla > '8')) and (tecla <> '0') do { mientras sea una tecla no admitida } + begin + textcolor(White); { establece el color para el texto a blanco } + gotoxy( 1, 23 ); { va a las coordenas de pantalla 1 horizontal, 7 verical } + write(' Ingrese su opci¢n ("1" a "8" o "0"): ' ); + textcolor(Yellow); { establece el color para el texto a amarillo } + tecla := readkey; { lee una tecla del usuario indicando la opcion que elijio } + end; { while } + if tecla = '0' then { si la opcion fue salir del programa ... } + begin + mensajeSalida; { presenta un mensaje de salida } + exit; { sale del programa } + end; + clrscr; { borra la pantalla } + textcolor(Yellow); { establece el color para el texto a amarillo } + gotoxy(19, 3); { va a las coordenas de pantalla 19 horizontal, 3 verical } + writeln( 'OPERACIONES ENTRE POLINOMIOS'); { titulo } + gotoxy(19, 4); { va a las coordenas de pantalla 19 horizontal, 4 verical } + writeln('~~~~~~~~~~~ ~~~~~ ~~~~~~~~~~'); { subrayado del titulo } + textcolor(LightCyan); { establece el color para el texto a cian claro } + gotoxy(1, 7); { va a las coordenas de pantalla 1 horizontal, 7 verical } + case tecla of + '1': muestraVector(v1, ' Polinomio 1 = '); + '2': muestraVector(v2, ' Polinomio 2 = '); + '3': begin + suma(v1, v2, vResult); + muestraVector(vResult, ' Polinomio 1 + Polinomio 2 = '); + end; { case 3 } + '4': begin + resta(v1, v2, vResult); + muestraVector(vResult, ' Polinomio 1 - Polinomio 2 = '); + end; { case 4 } + '5': begin + resta(v2, v1, vResult); + muestraVector(vResult, ' Polinomio 2 - Polinomio 1 = '); + end; { case 5 } + '6': begin + producto(v1, v2, vResult); + muestraVector(vResult, ' Polinomio 1 * Polinomio 2 = '); + end; { case 6 } + '7': begin + noNulo := division(v1, v2, vResult, vResto); + if noNulo + then + begin + muestraVector(vResult, ' Polinomio 1 / Polinomio 2 = '); + muestraVector(vResto, ' Resto = '); + end + else writeln(' El polinomio 2 es nulo, por lo tanto no se puede efectuar la division.'); + end; { case 7 } + '8': begin + noNulo := division(v2, v1, vResult, vResto); + if noNulo + then + begin + muestraVector(vResult, 'Polinomio 2 / Polinomio 1 = '); + muestraVector(vResto, 'Resto = '); + end + else writeln(' El polinomio 1 es nulo, por lo tanto no se puede efectuar la division.'); + end; { case 8 } + '0': ; { no hace nada, nunca deberia entrar en este case } + end; { case } + writeln; { los siguientes mensajes son para que el usuario pueda ver los datos y luego } + writeln; { presione una tecla para continuar } + textcolor(white); { pone el color del texto en blanco } + writeln(' Presione una tecla para continuar ...'); + tecla := readkey; + end; { while } + end + else { si los vectores no se leyeron bien ... } + begin { presenta un mensaje de error } + writeln('ERROR: No se pudieron cargar los datos. Revise que el formato del archivo'); + writeln(' sea correcto y que no este siendo usado por otro programa.'); + end; +end. { procedure menuGenerar } \ No newline at end of file diff --git a/term_5.pas b/term_5.pas new file mode 100644 index 0000000..c01c2a7 --- /dev/null +++ b/term_5.pas @@ -0,0 +1,665 @@ +program PolinomiosEnTermino; +{ Programa que lee 2 polinomios desde un archivo de texto para luego + hacer operaciones basicas entre estos (suma, resta, multiplicacion + y division). + El formato del archivo de texto debe ser de la siguiente manera: + + * Se ingresan cada polinomio en lineas sucesivas. + * El primer polinomio puede comenzar a ingresarse en cualquier lugar + del archivo de texto. + * El fin del primer polinomio (y comienzo del segundo) se indica por + medio de 1 o mas lineas en blanco. + * El segundo polinomio puede comenzar a ingresarse en cualquier lugar + del archivo de texto a partir de dicha(s) linea(s) en blanco. + * Cada termino de un polinomio debe estar en la misma linea y comenzar + al principio de esta (excepto el primer termino). + * Los terminos debes estar ordenados de menor a mayor segun el exponente. + * En cada linea se ingresa primero el coeficiente real (puede tener un + signo '-' al comenzar y/o un punto, y solamente uno) y luego el + exponente entero positivo. + * La separacion entre el coeficiente y el exponente debe estar dada por + uno o mas espacios o tabuladores. + * Cualquier caracter incluido en el texto que no sea un degito (0..9), + un punto ('.'), un signo menos ('-'), un espacio (' '), un tabulador + o alguno de los caracteres de nueva linea, dara un error en la + lectura. + * El archivo de texto debe tener formato DOS (es decir, el indicador de + nueva linea debe ser primero un caracter de retorno del carro + seguido inmediatamente por uno de avance de linea). +} + +uses + CRT, DOS; { Declaracion de funciones predefinidas + para crear la interfaz grafica } + +const + VERSION = '1.2.2r (TERM_5)'; { version del programa } + + TAM_MAX = 100; { Tama¤o maximo del vector que almacena + la multiplicacion de polinomios } + TAM = TAM_MAX div 2; { Tama¤o maximo (virtual) del vector que contiene + los vector con los que se va a operar } + CR = chr(13); { caracter de retorno del carro } + LF = chr(10); { caracter de nueva linea } + ENDF = chr(26); { caracter de fin del archivo } + TAB = chr(9); { caracter de tabulacion } + SPACE = chr(32); { caracter de espacio } + +type + { Tipo de dato para identificar el estado de la entrada de datos } + Estado = (INICIO, COEF_BUSCA, COEF, COEF_PUNTO, COEF_FIN, EXP_BUSCA, EXP, EXP_FIN, EXP_FIN_BUSCA, POLI_FIN, FIN, ERROR); + Termino = record { tipo de dato que representa un termino de un polinomio } + coef: real; { parte del coeficiente del termino } + exp: integer; { parte del exponente del termino } + end; { Termino } + Vector = array [0..TAM_MAX-1] of Termino; { vector para almacenar los polinomios } + + + {########################################################} + + procedure muestraVector(var v: Vector; s: String); + { procedimiento que imprime el polinomio v en pantalla con un titulo s } + + {########################################################} + + function exponente(exp: integer): String; + + var + s: String; { variable temporal } + + begin { exponente } + case exp of + 0: exponente := ''; { si el exponente es nulo, mustra solo el coeficiente } + 1: exponente := 'X'; { si el exponente es 1, mustra el coeficiente y X } + 2: exponente := 'Xý'; { si el exponente es 2, mustra el coeficiente y Xý } + else begin + str(exp, s); { convierte al exponente en string } + exponente := 'X^' + s; { si el exponente es mayor que 1, mustra el coeficiente y X^exp } + end; { else } + end; { case } + end; { exponente } + + {########################################################} + + + var + i: integer; { indice para usar en el ciclo for } + + begin { muestraVector } + textcolor(lightcyan); { pone el color del texto en cian claro } + writeln; { separacion de una linea } + write(s); { mustra el mensaje } + textcolor(lightmagenta); { pone el color del texto en magenta claro } + for i := TAM_MAX - 1 downto 0 do { recorre el vector de atras para adelante } + if v[i].coef <> 0 then break; { si el coeficiente no es nulo, termina el for dejando a i en ese indice } + if (v[i].exp = 0) and (v[i].coef = 0) then { si el primer exponente que encuentra es 0 y el coeficiente es 0, entonces } + begin { muestra el resultado como 0 y sale del procedimiento } + write('0'); { imprime que el resultado es cero } + writeln; { separacion de una linea } + writeln; { separacion de una linea } + exit; { sale de este procedimiento } + end; + if (abs(v[i].coef) <> 1) or (v[i].exp = 0) { si el modulo del coeficiente es distinto de 1 o si el exp. es 0 } + then if abs(v[i].coef) - trunc(abs(v[i].coef)) = 0 then write(trunc(v[i].coef):1, ' ') {imprime si es un numero entero} + else write(v[i].coef:1:2, ' ') { imprime si es un numero real } + else if v[i].coef = -1 then write('-'); { si es -1 entonces solo escribe el signo del termino } + write(exponente(v[i].exp)); + for i := i - 1 downto 0 do { recorre el vector de atras para adelante } + if v[i].coef <> 0 then { si el coeficiente no es nulo, termina el for dejando a i en ese indice } + begin + if v[i].coef < 0 { si el coeficiente en negativo } + then write(' - ') { le agrega el signo - } + else write(' + '); { si no, le agrega el signo + } + if (abs(v[i].coef) <> 1) or (i = 0) then { si el modulo del coeficiente es distinto de 1 o si el exp. es 0 } + if abs(v[i].coef) - trunc(abs(v[i].coef)) = 0 + then write(trunc(abs(v[i].coef)):1, ' ') { imprime si es entero } + else write(abs(v[i].coef):1:2, ' '); { imprime si es un real } + write(exponente(v[i].exp)); + end; { if } + writeln; { separacion de una linea } + writeln; { separacion de una linea } + end; { muestraVector } + + {########################################################} + + procedure inicializaVector(var v: Vector); + { procedimiento que inicializa un vector de tama¤o tam } + + var i: integer; { indice para usar en el ciclo for } + + begin { inicializaVector } + for i := 0 to TAM_MAX - 1 do { recorre el vector } + begin + v[i].coef := 0.0; { inicializa la variable actual en 0 } + v[i].exp := 0; { inicializa la variable actual en 0 } + end; + end; { inicializaVector } + + {########################################################} + + function ObtenerNombreArchivo: String; + { funcion que obtiene un nombre de archivo valido (es decir, el nombre + de un archivo que exista) } + + {########################################################} + + function fileExists(FileName: String): Boolean; + { funcion extraida de la ayuda del Turbo Pascal 7 + indica si el archivo existe } + + var + F: file; + + begin + {$I-} + Assign(F, FileName); + FileMode := 0; { Set file access to read only } + Reset(F); + Close(F); + {$I+} + FileExists := (IOResult = 0) and (FileName <> ''); + end; { FileExists } + + {########################################################} + + { Continuacion de la funcion ObtenerNombreArchivo } + const + DEFAUL_FILE_NAME = 'datos.txt'; { nombre del archivo por defecto } + + var + tmp: String; { cadena para almacenar el resultado temporal } + + begin { ObtenerNombreArchivo } + { mensaje para entrada del nombre de archivo } + clrscr; { borra la pantalla } + textcolor( Yellow ); { establece el color para el texto a amarillo } + gotoxy( 30, 3 ); { va a las coordenas de pantalla 25 horizontal, 3 verical } + writeln( 'PolinomiosEnTermino' ); { titulo } + gotoxy( 30, 4 ); { va a las coordenas de pantalla 25 horizontal, 4 verical } + writeln( '~~~~~~~~~~~~~~~~~~~' ); { subrayado del titulo } + textcolor( LightCyan ); { establece el color para el texto a cian claro } + gotoxy( 1, 7 ); { va a las coordenas de pantalla 1 horizontal, 7 verical } + writeln(' Ingrese el nombre del archivo con los datos (ENTER = ', DEFAUL_FILE_NAME, '):'); + readln(tmp); { entrada del nombre de archivo } + if tmp = '' then tmp := DEFAUL_FILE_NAME; { se fija si no se ingreso nada y reasigana el nombre } + while not fileExists(tmp) do { repite el proceso hasta que el archivo exista } + begin + clrscr; { borra la pantalla } + textcolor( Yellow ); { establece el color para el texto a amarillo } + gotoxy( 30, 3 ); { va a las coordenas de pantalla 25 horizontal, 3 verical } + writeln( 'PolinomiosEnTermino' ); { titulo } + gotoxy( 30, 4 ); { va a las coordenas de pantalla 25 horizontal, 4 verical } + writeln( '~~~~~~~~~~~~~~~~~~~' ); { subrayado del titulo } + textcolor( LightCyan ); { establece el color para el texto a cian claro } + gotoxy( 1, 7 ); { va a las coordenas de pantalla 1 horizontal, 7 verical } + write(' El archivo ', tmp, ' no existe. Ingrese un nombre correcto'); + if tmp = DEFAUL_FILE_NAME { si es el nombre de archivo predeterminado } + then { entonces, elije un mensaje apropiado } + write(': ') + else + begin { si no es el predeterminado, muestra otro mensaje } + writeln('.'); + write(' (ENTER = ', DEFAUL_FILE_NAME, '): '); + end; + readln(tmp); { vuelve a leer el nombre del archivo para ser verificado } + if tmp = '' then tmp := DEFAUL_FILE_NAME; { asigna como nombre de archivo al predeterminado + si no se escribio nada } + end; { fin del loop de verificacion } + ObtenerNombreArchivo := tmp; { asigna el nombre correcto al valor de salida de la funcion } + end; { ObtenerNombreArchivo } + + {########################################################} + + function trans(c: char; e: Estado): Estado; + { establece el estado en el que se encuentra la lectura } + { c es el caracter que se leyo, e es el estado actual de la lectura } + + begin { trans } + case e of { acciona segun es estado actual de la lectura } + INICIO: { estado de inicio de la lectura } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un numero (o negativo), empieza a leer el coeficiente } + SPACE, TAB, CR, LF: trans := COEF_BUSCA; { si es un caracter tipo "espacio", busca el prox. coef. } + else trans := ERROR; { si es otro, da ERROR } + end; + COEF_BUSCA: { estado de busqueda del primer ceoficiente del polinomio } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un numero (o negativo), empieza a leer el coeficiente } + SPACE, TAB, CR, LF: trans := COEF_BUSCA; { si es un caracter tupo "espacio", sigue buscando } + ENDF: trans := FIN; { si es el caracter de fin de archivo, pasa al estado de tarea finalizada } + else trans := ERROR; { si es otro, da ERROR } + end; + COEF: { estado de lectura del coeficiente del termino del polinomio (sin punto decimal) } + case c of { acciona segun el caracter leido } + '0'..'9': trans := COEF; { si es un numero sigue con el mismo estado } + '.': trans := COEF_PUNTO; { si es punto cambia al estado COEF_PUNTO } + SPACE, TAB: trans := COEF_FIN; { si es un espacio o un tabulador, finaliza la lectura del coeficiente } + else trans := ERROR; { si es otra cosa, pasa a estado de error } + end; + COEF_PUNTO: { estado de lectura del coeficiente del termino del polinomio (con punto decimal) } + case c of { acciona segun el caracter leido } + '0'..'9': trans := COEF_PUNTO; { si es un numero sigue con el mismo estado } + SPACE, TAB: trans := COEF_FIN; { si es un espacio o un tabulador, finaliza la lectura del coeficiente } + else trans := ERROR; { si es otra cosa, pasa a estado de error } + end; + COEF_FIN: { estado de fin de la lectura del coeficiente del termino del polinomio } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si el caracter es un numero establece el estado en EXP (exponente) } + SPACE, TAB: trans := EXP_BUSCA; { si es un espacio o tabulador, pasa a buscar el proximo exponente } + else trans := ERROR; { si no es ninguno de los anteriores, el estado pasa a ERROR } + end; + EXP_BUSCA: { estado de busqueda del proximo exponente } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si el caracter es un numero, empieza a leer el exponente } + SPACE, TAB: trans := EXP_BUSCA; { si es un espacio o tabulador, sigue buscando } + else trans := ERROR; { si no es ninguno de los anteriores, el estado pasa a ERROR } + end; + EXP: { estado de lectura del exponente del termino actual del polinomio } + case c of { acciona segun el caracter leido } + '0'..'9': trans := EXP; { si es un digito, sigue en el mismo estado } + CR: trans := EXP_FIN; { si es un ratorno de carro, finaliza el exponente + (quiere decir que hubo un ) } + ENDF: trans := FIN; { si es el final del archivo, se indica que termino su tarea } + else trans := ERROR; { si es otra cosa, devuelve ERROR } + end; + EXP_FIN: { estado de fin de la lectura del exponente del termino actual del polinomio } + if c = LF then trans := EXP_FIN_BUSCA { debe ser un caracter de nueva linea (para completar el ) } + else trans := ERROR; { si no lo es, devuelve ERROR } + EXP_FIN_BUSCA: { estado de fin de lectura de la nueva linea (luego de finalizar el exponente + ahora decide si termino el polinomio o si sigue leyendo el proximo coeficiente } + case c of { acciona segun el caracter leido } + '-', '0'..'9': trans := COEF; { si es un digito (o negativo), pasa a leer en proximo coeficiente } + CR: trans := POLI_FIN; { si es un ratorno de carro o nueva linea, finaliza el polinomio } + else trans := ERROR; { si es otra cosa, devuelve ERROR } + end; + POLI_FIN: { estado de finalizacion del polinomio actual } + if c = LF then trans := COEF_BUSCA { debe ser un caracter de nueva linea (para completar el ), + entonces pasa a buscar el primer coeficiente del nuevo polinomio } + else trans := ERROR; { si no lo es, devuelve ERROR } + FIN: { estado que adquiere cuando se finalizo la tarea } + trans := FIN; { se queda en este estado avisando que termino su tarea } + else { otro estado, no deberia ocurrir, salvo que se le pase a la funcion un estado de ERROR } + trans := ERROR; { si es otro, da ERROR } + end; { case } + end; { trans } + + {########################################################} + + function cargarVectores(var v1, v2: Vector): boolean; + { Funcion que abre el archivo de texto con los datos, lo carga en el vector procesandolo debidamente a medida + que lo lee y, al finalizar, cierra el archivo de texto. + v1 es el primer vector a cargar + v2 es el segundo vector a cargar + devuelve true si la lectura fue hecha con exito, false si hubo un error } + + var + f: Text; { archivo de texto con los datos } + c: char; { caracter que se extrae del archivo de texto } + nombreArchivo: String; { nombre del archivo de datos } + est: Estado; { Indicador del estado actual de la lectura } + seguir: boolean; { indicador para saber si debe seguir con el proceso } + i, { indice del vector del polinomio para ser inicializado } + iExp, { valor temporal para almacenar al exponente } + code, { almacena el resultado de la funcion val (no se usa porque los + datos ya estan validados } + poliN: integer; { numero del polinomio que se esta leyendo } + rCoef: real; { valor temporal para almacenar al coeficiente } + exponente, { string que representa al exponente leido } + coeficiente: String; { string que representa al coeficiente leido } + + begin { cargarVectores } + rCoef := 0.0; { inicializacion de variable } + iExp := 0; { inicializacion de variable } + coeficiente := ''; { inicializacion de variable } + exponente := ''; { inicializacion de variable } + est := INICIO; { empieza con el estado de INICIO } + poliN := 1; { establece que se procesara el primer polinomio } + inicializaVector(v1); { inicializacion del vector 1 (primer polinomio) } + inicializaVector(v2); { inicializacion del vector 2 (segundo polinomio) } + nombreArchivo := ObtenerNombreArchivo; { obtiene el nombre del archivo } + assign(f, nombreArchivo); { asigna la variable al nombre del archivo } + reset(f); { abre el archivo para leerlo desde el principio } + seguir := true; { inicializa seguir e true para comenzar el bucle } + while seguir do begin { continua mientras seguir sea true } + read(f, c); { lee un caracter del archivo de texto } + est := trans(c, est); { establece el nuevo estado de lectura } + case est of { toma una desicion dependiendo del estado en que se encuentre } + INICIO: ; { No hace nada, nunca toma este valor. Solo incica que empezo el proceso } + COEF_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + COEF, COEF_PUNTO: { Si esta leyendo el coeficiente ... } + coeficiente := coeficiente + c; { concatena el caracter a la representacion + de texto del coeficiente } + COEF_FIN: ; { Si termino de leer el coeficiente, no hace nada, la asignacion + se realiza cuando termina de leer el exponente (es necesario + para establecer el indice del vector } + EXP_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + EXP: { Si esta leyendo el exponente ... } + exponente := exponente + c; { concatena el caracter a la representacion + de texto del exponente } + EXP_FIN: { Si termino de leer el exponente, hace las asignaciones correspondientes } + begin { convirtiendo las cadenas de texto en real e integer, segun el caso } + val(coeficiente, rCoef, code); { convierte el coeficiente en real } + val(exponente, iExp, code); { convierte el exponente en integer } + if iExp < TAM { si el exponente es menor que el tama¤o maximo permitido ... } + then if poliN = 1 + then { si es el polinomio 1 } + begin + v1[iExp].coef := rCoef; { asigna el valor correspondiente } + v1[iExp].exp := iExp; { asigna el valor correspondiente } + end + else { si es el polinomio 2 } + begin + v2[iExp].coef := rCoef; { asigna el valor correspondiente } + v2[iExp].exp := iExp; { asigna el valor correspondiente } + end + else est := ERROR; { si no es menor, pone el estado en ERROR } + coeficiente := ''; { una vez asignados, vacia los valores del coeficiente y el } + exponente := ''; { exponente para poder realizar las lecturas de los proximos } + end; + EXP_FIN_BUSCA: ; { No hace nada, solo espera hasta que hayan datos significativos } + POLI_FIN: { Si termino la lectura de un polinomio ... } + if poliN = 1 then poliN := 2 { si se leyo el 1er polinomio, se indica que se leera el 2do } + else est := FIN; { si no (ya se leyo el segundo), pone el estado en FIN } + FIN: { Si se finalizaron las tareas ... } + begin + cargarVectores := true; { en principio se establece que la lectura se hizo con exito ) } + seguir := false; { poner seguir en false para que se termine el bucle } + { este codigo es similar al de EXP_FIN, se hacen las asignaciones por el caso en que el fin + del archivo esta pegado al fin del ultimo exponente, en cuyo caso no pasa por el estado + de EXP_FIN (y, por ende, no se pueden hacer las asignaciones correspondientes } + val(coeficiente, rCoef, code); { convierte el coeficiente en real } + val(exponente, iExp, code); { convierte el exponente en integer } + if iExp < TAM { si el exponente es menor que el tama¤o maximo permitido ... } + then if poliN = 2 + then { si es el polinomio 2 } + begin + v2[iExp].coef := rCoef; { asigna el valor correspondiente } + v2[iExp].exp := iExp; { asigna el valor correspondiente } + end + else cargarVectores := false { si es el primero, no se hizo bien la lectura } + else cargarVectores := false; { si no es menor, no se hizo bien la lectura } + end; + ERROR: { Si hubo un error ... } + begin + cargarVectores := false; { Se devuelve false (hubo un ERROR, no se leyeron bien los vectores) } + seguir := false; { seguir se pone en false para que termine el bucle } + end; + end; { case } + end; { while } + close(f); { se cierra el archivo de lectura de datos } + end; { cargarVectores } + + {########################################################} + + procedure suma(v1, v2: Vector; var vr: Vector); + { procedimiento que suma dos polinomios. + v1: vector que contiene el primer polinomio a sumar + v2: vector que contiene el segundo polinomio a sumar + vr: vector donde se almacenara el resultado de la suma } + + var + i: integer; { indice para usar en el ciclo for } + + begin { suma } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el vector (de tama¤o maximo TAM) } + begin + vr[i].coef := v1[i].coef + v2[i].coef; { suma los coeficientes de los terminos con igual exponente } + vr[i].exp := i; { establece como valor del exponente al indice } + end; + end; { suma } + + {########################################################} + + procedure resta(v1, v2: Vector; var vr: Vector); + { procedimiento que resta dos polinomios. + v1: vector que contiene el primer polinomio + v2: vector que contiene el polinomio para restarle al primero + vr: vector donde se almacenara el resultado de la resta } + + var + i: integer; { indice para usar en el ciclo for } + + begin { resta } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el vector (de tama¤o maximo TAM) } + begin + vr[i].coef := v1[i].coef - v2[i].coef; { resta los coeficientes de los terminos con igual exponente } + vr[i].exp := i; { establece como valor del exponente al indice } + end; + end; { resta } + + {########################################################} + + procedure producto(v1, v2: Vector; var vr: Vector); + { procedimiento que multiplica dos polinomios. + v1: vector que contiene el primer polinomio a multiplicar + v2: vector que contiene el segundo polinomio a multiplicar + vr: vector donde se almacenara el resultado de la multiplicacion } + + var + i, j: integer; { indices para usar en los ciclos for } + + begin { producto } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := 0 to TAM - 1 do { recorre el 1er vector (de tama¤o maximo TAM) } + for j := 0 to TAM - 1 do { recorre el 2do vector (de tama¤o maximo TAM) } + begin + vr[i+j].coef := vr[i+j].coef + (v1[i].coef * v2[j].coef); + { multiplica los coeficientes de los terminos y lo almacena en la posicion del exponente } + { igual a la suma de los exponentes de v1 y v2, sumando el valor previo de dicha posicion } + vr[i+j].exp := i+j; { establece como exponente a la suma de los otros dos } + end; + end; { producto } + + {########################################################} + + function division(v1, v2: Vector; var vr, vResto: Vector): boolean; + { procedimiento que divide dos polinomios. + v1: vector que contiene el polinomio denominador + v2: vector que contiene el polinomio divisor + vr: vector donde se almacenara el resultado de la division + vResto: vector donde se almacenara el resto de la division + devuelve true si el segundo polinomio no es 0 y se efectua la division y + devuelve false si segundo polinomio es 0 y no se puede efectuar la division } + + var + i, j: integer; { indices para usar en los ciclos for } + vRTmp, { vector auxuliares para almacenar el termino actual del resultado } + vTmp: Vector; { vector auxuliares para almacenar el polinomio que es la multiplicacion del + termino actual del resultado por el divisor } + + begin { division } + inicializaVector(vr); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vResto); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vTmp); { inicializa al vector resultado en 0 para evitar que quede "basura" } + inicializaVector(vRTmp); { inicializa al vector resultado en 0 para evitar que quede "basura" } + for i := TAM - 1 downto 0 do { recorre el 1er vector (de tama¤o maximo TAM) de atras para adelante } + if v1[i].coef <> 0 then break; + { busca empezando por el indice (exponete) mas alto el primer coeficiente no nulo } + { si lo encuentra sale del for dejando al valor de i como el de dicho inidice } + for j := TAM - 1 downto 0 do { recorre el 2do vector (de tama¤o maximo TAM) de atras para adelante } + if v2[j].coef <> 0 then break; + { busca empezando por el indice (exponete) mas alto el primer coeficiente no nulo } + { si lo encuentra sale del for dejando al valor de j como el de dicho inidice } + if (j = 0) and (v2[j].coef = 0) { si el no se encontro ningun coeficiente no nulo, entonces } + then { el polinomio 2 es nulo y no se puede efectuar la division } + begin { se devuelve false y se quedan los vectores resultado en 0 } + division := false; { devuelve false } + exit; { sale del procedimiento } + end; + while i >= j do { si el primer exponente es mayor o igual que el segundo empieza a dividir } + begin + vr[i-j].coef := v1[i].coef / v2[j].coef; { almacena el resultado de la division entre los coeficientes en } + vr[i-j].exp := v1[i].exp - v2[j].exp; { coeficientes en la posicion de la resta de ambos } + vRTmp[i-j].coef := vr[i-j].coef; { almacena ese resultado en un polinomio temporal cuyo unico termio } + vRTmp[i-j].exp := vr[i-j].exp; { no nulo es el del exponente i-j, para luego multiplicarlo } + producto(vRTmp, v2, vTmp);{ multiplica este polinomio por el segundo almacenado el resultado + en otro temporal, para luego hacer la resta } + resta(v1, vTmp, v1); { resta al primer polinomio, v1, (en su estado actual, no el original) + el temporal vTmp y lo almacena en v1, para poder volver a operarlo de + la misma forma } + vRTmp[i-j].coef := 0.0; {resetea el coeficiente del termino del temporal vRTmp que se asigno para los calculos} + vRTmp[i-j].exp := 0; { resetea el exponente del termino del temporal vRTmp que se asigno para los calculos } + for i := i downto 0 do { recorre el vector v1 (de tama¤o maximo TAM) de atras para adelante } + if v1[i].coef <> 0 then break; + { busca empezando por el indice (exponete) i el primer coeficiente no nulo + si lo encuentra sale del for dejando al valor de i como el de dicho inidice } + end; { while } + vResto := v1; { asigna el vector v1 (que ya no se procesara mas al resto } + division := true; { devuelve true indicando que se finalizo con exito } + end; { division } + + {########################################################} + + procedure mensajeSalida; { muestra un mensaje en la salida del programa } + + begin + writeln; { linea en blanco } + NormVideo; { reestablece los colores a los valores por defecto } + clrscr; { borra la pantalla } + writeln; { linea en blanco } + textcolor(white); { cambia el color del texto } + writeln(' PolinomiosEnTermino versi¢n ', VERSION); { mensaje con version del programa } + NormVideo; { reestablece los colores a los valores por defecto } + writeln(' Desarrollado por: JavierGrijalba'); { mensaje con los integrantes del grupo } + writeln(' Leandro Lucarella'); + writeln(' Erasmo Troncovich'); + writeln(' Diego Wojmicki'); + writeln(' para la Facultad de Ingenier¡a de la Universidad de Buenos Aires.'); + writeln(' Consultas y/o sugerencias a:'); + writeln; + textcolor(LightMagenta); { cambia el color del texto } + write(' lluca@cnba.uba.ar'); + NormVideo; { reestablece los colores a los valores por defecto } + write(' o '); + textcolor(LightMagenta); { cambia el color del texto } + writeln('grijalba@cvtci.com.ar'); + NormVideo; { reestablece los colores a los valores por defecto } + writeln; + writeln(' (c) 1999 - Todos los derechos reservados.'); + delay(750); + end; + + + {########################################################} + + +var + i: integer; { variable auxiliar } + v1, v2, vResult, vResto: Vector; { vectores para hacer las operaciones } + seguir, { indicador para saber si sigue corriendo el programa } + noNulo, { indicador para saber si en la division el divisor es nulo } + continua: boolean; { indicador para saber si se leyeron bien los polinomios } + tecla: char; { entrada de teclado del usuario para elegir una opcion } + +begin { programa principal } + textbackground( Blue ); { establece el color para el fondo a azul } + continua := cargarVectores(v1, v2); { carga los vectores del archivo de datos } + if continua then { si se leyeron bien ... } + begin + seguir := true; { inicializa la variable en true para que entre en el ciclo while } + while seguir do { mientras el usuario no salga del programa } + begin + clrscr; { borra la pantalla } + textcolor(Yellow); { establece el color para el texto a amarillo } + gotoxy( 30, 3 ); { va a las coordenas de pantalla 25 horizontal, 3 verical } + writeln( 'PolinomiosEnTermino' ); { titulo } + gotoxy( 30, 4 ); { va a las coordenas de pantalla 25 horizontal, 4 verical } + writeln( '~~~~~~~~~~~~~~~~~~~' ); { subrayado del titulo } + textcolor(LightCyan); { establece el color para el texto a cian claro } + gotoxy( 1, 7 ); { va a las coordenas de pantalla 1 horizontal, 7 verical } + writeln( ' Elija que desea hacer:' ); { mensaje } + writeln( ' ----- --- ----- ------' ); { mensaje } + textcolor(LightGray); { establece el color para el texto a gris claro } + writeln; { mensaje con las opciones ... } + writeln; + writeln( ' 1.- Ver el polinomio 1.' ); + writeln( ' 2.- Ver el polinomio 2.' ); + writeln( ' 3.- Sumar los polinomios.' ); + writeln( ' 4.- Restar el polinomio 2 al polinomio 1 (poli1 - poli2).' ); + writeln( ' 5.- Restar el polinomio 1 al polinomio 2 (poli2 - poli1).' ); + writeln( ' 6.- Multiplicar los polinomios.' ); + writeln( ' 7.- Polinomio 1 dividido polinomio 2 (poli1 / poli2).' ); + writeln( ' 8.- Polinomio 2 dividido polinomio 1 (poli2 / poli1).' ); + writeln( ' 0.- Salir.' ); + gotoxy(1, 23); { va a las coordenas de pantalla 1 horizontal, 23 verical } + textcolor(White ); { establece el color para el texto a blanco } + write(' Ingrese su opci¢n: '); + textcolor(Yellow); { establece el color para el texto a amarillo } + tecla := readkey; { lee una tecla del usuario indicando la opcion que elijio } + while ((tecla < '1') or (tecla > '8')) and (tecla <> '0') do { mientras sea una tecla no admitida } + begin + textcolor(White); { establece el color para el texto a blanco } + gotoxy( 1, 23 ); { va a las coordenas de pantalla 1 horizontal, 7 verical } + write(' Ingrese su opci¢n ("1" a "8" o "0"): ' ); + textcolor(Yellow); { establece el color para el texto a amarillo } + tecla := readkey; { lee una tecla del usuario indicando la opcion que elijio } + end; { while } + if tecla = '0' then { si la opcion fue salir del programa ... } + begin + mensajeSalida; { presenta un mensaje de salida } + exit; { sale del programa } + end; + clrscr; { borra la pantalla } + textcolor(Yellow); { establece el color para el texto a amarillo } + gotoxy( 30, 3 ); { va a las coordenas de pantalla 25 horizontal, 3 verical } + writeln( 'PolinomiosEnTermino' ); { titulo } + gotoxy( 30, 4 ); { va a las coordenas de pantalla 25 horizontal, 4 verical } + writeln( '~~~~~~~~~~~~~~~~~~~' ); { subrayado del titulo } + textcolor(LightCyan); { establece el color para el texto a cian claro } + gotoxy(1, 7); { va a las coordenas de pantalla 1 horizontal, 7 verical } + case tecla of + '1': muestraVector(v1, ' Polinomio 1 = '); + '2': muestraVector(v2, ' Polinomio 2 = '); + '3': begin + suma(v1, v2, vResult); + muestraVector(vResult, ' Polinomio 1 + Polinomio 2 = '); + end; { case 3 } + '4': begin + resta(v1, v2, vResult); + muestraVector(vResult, ' Polinomio 1 - Polinomio 2 = '); + end; { case 4 } + '5': begin + resta(v2, v1, vResult); + muestraVector(vResult, ' Polinomio 2 - Polinomio 1 = '); + end; { case 5 } + '6': begin + producto(v1, v2, vResult); + muestraVector(vResult, ' Polinomio 1 * Polinomio 2 = '); + end; { case 6 } + '7': begin + noNulo := division(v1, v2, vResult, vResto); + if noNulo + then + begin + muestraVector(vResult, ' Polinomio 1 / Polinomio 2 = '); + muestraVector(vResto, ' Resto = '); + end + else writeln(' El polinomio 2 es nulo, por lo tanto no se puede efectuar la division.'); + end; { case 7 } + '8': begin + noNulo := division(v2, v1, vResult, vResto); + if noNulo + then + begin + muestraVector(vResult, 'Polinomio 2 / Polinomio 1 = '); + muestraVector(vResto, 'Resto = '); + end + else writeln(' El polinomio 1 es nulo, por lo tanto no se puede efectuar la division.'); + end; { case 8 } + '0': ; { no hace nada, nunca deberia entrar en este case } + end; { case } + writeln; { los siguientes mensajes son para que el usuario pueda ver los datos y luego } + writeln; { presione una tecla para continuar } + textcolor(white); { pone el color del texto en blanco } + writeln(' Presione una tecla para continuar ...'); + tecla := readkey; + end; { while } + end + else { si los vectores no se leyeron bien ... } + begin { presenta un mensaje de error } + writeln('ERROR: No se pudieron cargar los datos. Revise que el formato del archivo'); + writeln(' sea correcto y que no este siendo usado por otro programa.'); + end; +end. { procedure menuGenerar } \ No newline at end of file -- 2.43.0