SOLUCION DE PROBLEMAS CON AUTOMATAS
- adiós - dijo
- adiós - dijo el zorro - he aquí mi secreto. Es muy simple:
no se ve bien sino con el corazón. Lo esencial es invisible a los ojos.
- lo esencial es invisible a los ojos.- Repitió el principito a fin de acordarse.
" el principito " - Antoine de Saint Exupery
00 - PREFACIO
Me recibí de ingeniero en las postrimerías del reinado de las reglas de calculo, comenzaban a difundirse las computadoras, aparecieron las calculadoras electrónicas, las computadoras de mesa, los costos bajaron en modo sorprendente, las prestaciones subieron en modo asombroso.
El calculo analógico fue rápidamente sustituido por el calculo digital.
Mi vida profesional comenzó con calculadoras electromecánicas y regla de calculo, repetir un calculo era una penitencia ...
Un día un compañero de trabajo me mostró lo fácil que era lograr que una computadora de mesa ejecutara instrucciones, fue esa computadora que me enseño computación, mis programas aunque útiles eran oscuros y difíciles de seguir aun para mi que los había hecho.
Intuía la importancia de la computación y la gran importancia que debían tener ciertas cosas que no lograba distinguir claramente.
Entre en contacto con otras computadoras de mesa, me hice hábil en programar en lenguajes próximos al lenguaje de maquina, y desarrolle nuevas mañas y artilugios para resolver mis problemas.
En 1977 conocí a Cesar Orlando Archuby, que mientras me ayudaba a hacer algunos programas que requería mi trabajo, comenzó a hacerme recorrer los maravillosos caminos de la programación.
Así comencé a ver con claridad aquellas cosas que en el pasado intuía pero no lograba entender
En 1979 cesar dicto un cursillo para estudiantes del ultimo año de las carreras de ingeniería electricista y mecánica, asistí al curso un poco para aprender y otro poco para ayudar.
La claridad con que el profesor exponía los temas me indujo a pasar en limpio los apuntes de estas clases, y dárselos, pero el profesor nunca los repaso ni los corrigió.
Cuando yo insistía con mi amigo de que hiciera este trabajo el respondía que seguramente ya estaba todo hecho, era todo tan obvio ... Transcurridos tres años en este tira y afloja, cada uno por su lado descubrimos los libros de Reggini y de Papert ... Ves - me dijo mi amigo - como yo tenia razón, ya se ha escrito sobre el tema en modo abundante y mejor de como yo lo hubiera hecho.
Volví a leer una vez mas los apuntes del cursillo, sinceramente creo que no merecen ser dejados de lado. Y obligado por otros motivos a permanecer a pocos metros de una terminal de computadora, aproveche algunas de estas horas para pasar en limpio este apunte.
El lector debe tener presente que yo soy el único responsable de los errores, el mérito de todos los aciertos es de mi amigo Cesar.
Alfredo Rifaldi - enero 1983
01 - INTRODUCCION
Como ya se dijo, este apunte surgió de un curso dictado en 1979 a alumnos del ultimo año de las carreras de ingeniería electricista y mecánica de la facultad de ingeniería de la universidad nacional de la plata.
El objetivo del curso es que los alumnos adquieran habilidad en el planteo de algoritmos de solución de problemas.
La importancia de esta habilidad crece día a día a causa de la difusión de computadoras y minicomputadoras.
Si bien en el futuro llegaran alumnos cuya formación incluye el dominio de estas técnicas, todavía quedan algunas generaciones sin esta formación, y para los que estén formados un repaso no vendar mal.
No es objetivo de este apunte la enseñanza de un lenguaje de dialogo con la computadora, para esta tarea se dispone normalmente de excelentes interpretes, los programadores.
Quien quiera realizar correctamente un programa en lenguaje adecuado para la computadora, deberá utilizar su manual, si el programa es en fortran se recomienda el uso de los textos indicados en la bibliografía (b.5), (b.6), (b.7).
02 - PRIMERA CLASE
Un sujeto es capaz de realizar acciones, entonces se dice que el sujeto tiene un conjunto de acciones no vacío.
Una acción es un evento que se cumple en un lapso, y que produce un resultado previsto y bien determinado.
Las acciones que este sujeto es capaz de realizar se califican de acciones simples, el sujeto no sabe realizar acciones complejas, las desconoce, denominamos autómata a este sujeto.
Existe un sujeto superior que describe la acción compleja como sucesión (conjunto ordenado) de acciones simples.
Una acción compleja que puede ser descompuesta en un numero finito de acciones simples se llama proceso.
Es necesario que el sujeto superior efectúe la descripción de esta sucesión, organizada así la tarea, la actividad, el sujeto inferior aprende a hacer la acción compleja.
La acción compleja se ha convertido en acción simple. La descripción de acciones simples es el algoritmo que conduce a la solución del problema.
Algoritmo es una ley que gobierna una entera clase de procesos de elaboración y control de datos.
El problema debe ser descripto en forma algebraica con un algoritmo, este traducido al lenguaje (codificado) que comprende el autómata permite que este ultimo aprenda a ejecutar la tarea.
El algoritmo codificado se convierte en un programa. Las computadoras son calculadoras con capacidad de almacenamiento de programas.
Las computadoras (la materia - hardware) disponen normalmente de una batería de programas de uso general, los programas específicos deben desarrollarse (los programas forman el software - lo etéreo).
Un programa esta formado por instrucciones, sentencias, que deben ser comprendidas unívocamente por el autómata.
El lenguaje de programación debe estar definido en modo suficientemente preciso para que el autómata lo interprete, un programa de computadora llega a un detalle de precisión formal que sorprende (y molesta) al que se inicia.
El lenguaje obedece a reglas muy rígidas, las razones que obligan a esto son las limitadas instrucciones que el autómata reconoce y ejecuta con obediencia absoluta, sin aplicar ningún sentido critico.
Los que se inician se disgustan a veces por este comportamiento servil de la computadora, esta es una cualidad positiva de la computadora y con el tiempo se la aprecia, esta cualidad no puede (ni debe) pretenderse de los seres humanos.
03 - SEGUNDA CLASE
Un algoritmo para determinar un resultado por un método iterativo tiene un numero de pasos infinito, las sucesivas aproximaciones se van acercando a un valor final.
Para un dado paso el error tiene cierto valor, y los pasos sucesivos permiten una mejor aproximación. La solución encontrada es satisfactoria cuando el error se ha reducido a un valor suficiente.
Se dice que un algoritmo se ha agotado cuando la solución que se obtiene no puede ser mas mejorada, esto no significa haber llegado a la solución del problema.
Este concepto puede no ser inmediato de comprender, si el lector calcula con una computadora el valor limite de la serie armónica, llegara a la conclusión que la serie armónica (computable) es convergente.
El conjunto infinito de los números reales es sustituido en la computadora por un conjunto finito de representantes, y esto es causa de error, y pone difíciles problemas de aproximación en los procesos de computadora que utilizan números reales, estos procesos son llamados numéricos, y numérico es sinónimo de no exacto.
Este conjunto de representantes tiene un valor máximo y un valor (absoluto) mínimo, fuera de estos valores se producen el "overflow" y el "underflow".
Hay operaciones que hacen perder precisión al calculo, son causa de errores y exigen atención, la resta de números del mismo orden, la división por cero o por números muy pequeños, la suma o multiplicación de números muy grandes, la multiplicación de números muy pequeños.
Para controlar que se ha llegado a la solución no es suficiente comparar el valor de la nueva solución con la anterior, debe calcularse en cambio el valor de la función para la solución que se controla.
Cuando se realiza un algoritmo lo importante es la claridad. Un algoritmo puede necesitar de otro, es fundamental que el algoritmo principal siga siendo tal, en consecuencia el algoritmo secundario no debe ser insertado dentro del principal, se perdería claridad.
En todo trabajo se debe separar lo esencial de lo accesorio, "el árbol no debe ocultar el bosque".
La técnica que organiza el trabajo de esta forma es normal en todos los ordenes de la vida.
La construcción del algoritmo se debe realizar con un procedimiento de etapas sucesivas, y cada etapa debe bajar a un mayor grado de detalle.
El trabajo se describe en pasos globales, fácilmente comprensibles, y para cada paso se construye el algoritmo correspondiente.
El trabajo debe estar descripto por una serie de operaciones complejas encadenadas, pero la claridad de la descripción debe ser evidente.
En esta forma el problema se descompone en subrutinas o funciones que sintetizan operaciones complejas, permitiendo la claridad de la descripción.
Es importante destacar que un texto de programa es comprensible cuando se lo puede recorrer en una mirada, si el texto es largo esto es imposible, y entonces su comprensión exige varias horas de estudio.
Las subrutinas y funciones permiten abreviar el texto y mejoran sus características de comprensión, esta es quizás su mas valiosa virtud, y el principal motivo por el cual se debe modularizar un programa dividiéndoselo de esta manera.
Es recomendable que cada vez que en la descripción del problema se encuentre una operación compleja se pase la tarea de resolución a una subrutina o función.
Este método de trabajo, además de la claridad meridiana de descripción de los problemas, permite formarse una biblioteca de subrutinas o funciones que facilitan enormemente la tarea de plantear la solución de otros problemas.
04 - TERCERA CLASE
Los datos deben ser comunicados al autómata, pueden ingresar por distintas formas, por teclado de una maquina de escribir, por lectora de manuscritos, por lectora de cintas o tarjetas perforadas, por cintas magnéticas o discos previamente grabados.
Los caracteres disponibles en los lenguajes son letras, números, y caracteres especiales. Los nombres se forman con letras y números, los caracteres especiales se utilizan para determinadas operaciones.
El planteo algoritmo de un problema es un planteo de tipo general el correspondiente programa en un lenguaje es un tipo de programa particular.
Normalmente un programa en un lenguaje no es directamente utilizable en otro lenguaje.
Es importante el planteo general de los problemas, independizándolos del lenguaje, esta documentación tiene un valor particular porque es básica para la versión directa a cualquier lenguaje.
Las traducciones de un lenguaje a otro a veces son dificultosas, varios son los lenguajes utilizados, fortran, algol, cobol, pl/1, basic, pascal ... Nunca debe olvidarse que el lenguaje de programación es un medio.
Los problemas aparecen en forma global, en consecuencia se los debe enfocar en esta forma.
No debe ser confundida la estructura algoritmica de un problema, con la estructura matemática.
Mientras se esta en etapa de programación los detalles no son importantes.
En los equipos de trabajo existe un jefe (top) que dirige la tarea, y subordinados (down) que la ejecutan.
El top de un problema puede ser el down de otro, y viceversa, cuando es top tiene la responsabilidad de la coordinación.
El top realiza el trabajo central, principal, las tareas accesorias las pasa a los down ... Luego, muchas veces es la misma persona que realiza las tareas de down.
De todos modos la organización permite un buen rendimiento. Cuando el trabajo debe ejecutarse en tiempos breves, esta organización permite ejecutar tareas en paralelo y reducir tiempos.
Con esta organización se gana en claridad, y se respetan los principios antes enunciados relativos a subrutinas y funciones.
No siempre el trabajo puede organizarse en modo top-down, en algunos casos, cuando gran cantidad de subrutinas ya se encuentran desarrolladas en trabajos anteriores la tarea debe ser bottom-up, serán los subordinados que impondrán al jefe sus condiciones.Los trabajos en general incluirán ambas modalidades.
05 - CUARTA CLASE
El problema que se presenta frecuentemente es ejecutar, hacer, ciertas operaciones una vez, y otra, y otra, controlar si se ha ejecutado la cantidad correspondiente de veces, incrementar el contador, y seguir.
Esta estructura característica es el ciclo, que especifica la repetición de una acción, la computadora no se cansa nunca y obedece ciegamente, puede repetir infinidad de veces la misma acción sin perder seguridad ni precisión.
El ciclo debe terminar, para ello dentro del ciclo debe haber un control, y algo debe cambiar para que finalmente se salga de el.
Para este tipo de operaciones es útil realizar un diagrama de flujo que muestra el camino a hacer y el retorno.
En los diagramas de flujo son también representables los saltos condicionados o no, el diagrama se complica, las líneas de flujo se cruzan, la comprensión se dificulta.
Todo problema puede ser descripto con un diagrama de flujo lineal, o con mínima cantidad de saltos, y eventualmente todos hacia adelante y no hacia atrás.
En algunos lenguajes los saltos se comandan con la instrucción "go to", quien no habiendo estudiado programación se acostumbra a usar esta instrucción puede llegar a creer que esta resolviendo en modo ingenioso sus problemas con el uso y el abuso del go to.
Esta instrucción debe evitarse, hay que programar sin go to, quien ya programo utilizándolo puede llegar a creer que esto es imposible, en rigor esta posibilidad depende del lenguaje, si se programa en fortran o en basic, no es fácil, pero debe tratar de evitarse esta instrucción, con ello los programas serán mas fácilmente comprensibles (ya que se linealizaran y no serán necesarios los diagramas de flujo para entenderlos).
El uso de las subrutinas y de las funciones permite evitar los go to y linealizar los diagramas de flujo.
Los problemas retorcidos deben ser linealizados, para ello se replantean de manera que no sea necesario un diagrama de flujo para entenderlos.
Un factor que influye en la complicación del problema es la estructura de datos, debe buscarse la que facilita al máximo la solución, la correcta estructura de datos facilita en particular el acceso de las subrutinas a los datos.
06 - INSTRUCCIONES ESTRUCTURADAS
La posibilidad de lograr un "buen programa" esta condicionada a las instrucciones que se tienen disponibles.
Wirth en su libro de programación sistemática (b.2) propone algunas sentencias que permiten resolver todos los casos de programación que se presentan.
Lamentablemente el fortran que normalmente se tiene disponible (este era el lenguaje disponible en una computadora IBM 1620 que se usaba para este curso, quien lee estos apuntes puede disponer de otros lenguajes, Basic, Pascal, ... y debe adaptar las instrucciones al lenguaje de que dispone) no posee todas estas instrucciones, pero con comentarios y un poco de esfuerzo de imaginación se puede salvar esta dificultad.
Una gran ayuda para lograr esto es el uso de tarjetas (a la época de estas notas cada renglón del programa era una tarjeta perforada, hoy esta palabra debe entenderse como renglones) de comentarios, otro consejo útil es programar con subrutinas, además evitando los go to se consiguen programas mas claros.
La sentencia "beguin-end"- se utiliza a modo de paréntesis para incluir entre ellas un grupo de instrucciones de manera que se destaque la asociación de este conjunto. Esto puede lograrse con tarjetas de comentarios.
Los comentarios se indican con la letra C (o el asterisco *) en la primera columna, las instrucciones ejecutables inician de la séptima columna y no pueden llegar mas allá de la columna 72, la sexta columna se utiliza para indicar continuación cuando la instrucción no cabe en un renglón, las cinco primeras columnas se utilizan para poner números que identifican la instrucción.
C BEGUIN (PROCED) |
||||| INSTRUCCIONES I |
C END (PROCED) |
O incluyendo en una subrutina el grupo de instrucciones.
||||| ... |
||||| CALL PROCED |
||||| ... |
||||| END |
||||| SUBROUTINE PROCED |
||||| INSTRUCCIONES I |
||||| RETURN |
||||| END |
La "if-then-else"- se utiliza para instrucciones condicionales.
Con las instrucciones del fortran normal se puede lograr el "if-then"
||||| IF (CONDICION D) INSTRUCCION I |
Si las instrucciones a ejecutar son varias deberán incluirse en una subrutina.
||||| IF (CONDICION D) CALL PROCED |
El grupo completo de instrucciones "if-then-else" es mas difícil de construir.
||||| .... |
||||| IF (CONDICION D) CALL THEN |
||||| IF (NO CONDICION D) CALL ELSE |
||||| ..... |
||||| END |
||||| SUBROUTINE THEN |
||||| INSTRUCCIONES I1 |
||||| RETURN |
||||| ENTRY ELSE |
||||| INSTRUCCIONES I2 |
||||| RETURN |
||||| END |
El lenguaje Basic permite escribir en esta forma las instrucciones que producen el mismo efecto, esta posibilidad apareció el las nuevas versiones de Fortran.
||||| .... |
||||| IF (CONDICION D) THEN |
||||| INSTRUCCIONES I1 |
||||| ELSE |
||||| INSTRUCCIONES I2 |
||||| ENDIF |
||||| ...... |
||||| END |
Vale la pena observar que escritas así las instrucciones puede producirse un error si el grupo i1 modifica el estado de la condición d, por este motivo, y para no tener dos if en el programa principal se debe hacer de esta otra manera.
||||| .... |
||||| CALL CONDIC |
||||| ....... |
||||| END |
||||| SUBROUTINE CONDIC |
||||| IF (CONDICION D) GO TO 111 |
C ELSE - NO SE CUMPLE LA CONDICION |
||||| INSTRUCCIONES I2 |
||||| RETURN |
| 111 CONTINUE |
C THEN - SE CUMPLE LA CONDICION |
||||| INSTRUCCIONES I1 |
||||| RETURN |
||||| END |
Las "while-do" y "repit-until" - se utilizan para instrucciones repetitivas. También estas pueden construirse en subrutinas.
||||| .... |
||||| CALL WHILE |
||||| ....... |
||||| END |
||||| SUBROUTINE WHILE |
| 111 CONTINUE |
||||| IF (CONDICION D) RETURN |
||||| INSTRUCCIONES I |
||||| GO TO 111 |
||||| RETURN |
||||| END |
||||| .... |
||||| CALL REPIT |
||||| ....... |
||||| END |
||||| SUBROUTINE REPIT |
| 111 CONTINUE |
||||| INSTRUCCIONES I |
||||| IF (CONDICION D) RETURN |
||||| GO TO 111 |
||||| RETURN |
||||| END |
Estos modos de construir las instrucciones son riesgosos, debe controlarse que en algún momento se cumpla la condición para salir del lazo. Las instrucciones internas del lazo deben cambiar alguno de los valores que aparecen en la condición.
Cuando la condición puede ser descripta por un contador la instrucción utilizable es el do del fortran.
C WHILE (J<=N2) DO I - MIENTRAS J ES MENOR O IGUAL A N2 HAZ I |
||||| DO 111 J=N1,N2,NS |
||||| INSTRUCCIONES I |
| 111 CONTINUE |
Las instrucciones se ejecutan desde j=n1,incrementando j en ns, hasta que j resulta mayor de n2, el control se hace antes de ejecutar las instrucciones.
Dentro del do puede meterse un control de condición que fuerce la salida.
C WHILE DW DO IW - MIENTRAS DW HAZ IW |
||||| DO 111 I=1,N |
||||| IF (CONDICION DW) GO TO 222 |
||||| INSTRUCCIONES IW |
| 111 CONTINUE |
C SALIDA SIN CUMPLIR LA CONDICION - ERROR |
||||| STOP |
| 222 CONTINUE |
C SE CUMPLE LA CONDICION |
C REPIT IR UNTIL DR - REPITE IR HASTA DR |
||||| DO 111 I=1,N |
||||| INSTRUCCIONES IR |
||||| IF (CONDICION DR) GO TO 222 |
| 111 CONTINUE |
C SALIDA SIN CUMPLIR LA CONDICION - ERROR |
||||| STOP |
| 222 CONTINUE |
C SE CUMPLE LA CONDICION |
La "case-of"- es una instrucción de selección
C CASE E OF V1,I1;....;VN,IN END |
||||| IF (E=V1) CALL INSTR1 |
||||| ...... |
||||| IF (E=VN) CALL INSTRN |
Las subrutinas insrt1...n hacen los trabajos correspondientes, por cierto que no deben modificar el valor de e.
Si las condiciones del selector son menor, igual o mayor de cero se puede usar el if aritmético del fortran.
C CASE E OF (<0),I1;(=0),I2;(>0),I3 END |
||||| IF (E) 11,22,33 |
|| 11 CONTINUE |
||||| INSTRUCCIONES I1 |
||||| GO TO 99 |
|| 22 CONTINUE |
||||| INSTRUCCIONES I2 |
||||| GO TO 99 |
|| 33 CONTINUE |
||||| INSTRUCCIONES I3 |
|| 99 CONTINUE |
C END CASE-OF |
Ha visto el lector como casi se puede programar sin go to.
07 - CONCLUSIONES
Es cierto que se puede escribir un programa sin usar computadora, y los conceptos principales de programación se pueden explicar y comprender independientemente de la computadora.
Sin embargo, si se desean obtener resultados, si se desea aprender es necesario experimentar, un programa de computadora que utiliza una pequeña partición de memoria durante pocos segundos y que da por resultado un par de hojas impresas, debe ser elaborado y devuelto en un cuarto de hora, si esto no es así el entusiasmo por la computación se apagara ...
Se debe disponer entonces de un centro de calculo que logre brindar este servicio, tal como exige Wirth en el prologo de su libro.
Una gran virtud de la computadora es que una vez recibida una ejecución con errores, y encontrada la causa, en poco tiempo puede tenerse el trabajo corregido, las consecuencias de los errores no importan, lo que importa es la causa, entonces no debe haber castigo, la modalidad de trabajo debe ser reflexiva, no impulsiva, sale bien un programa "bien pensado" ... Compare el lector este método de aprendizaje con otros y vera que maravilloso mundo podemos tener por delante si sabemos aprovecharlo.
08 - BIBLIOGRAFIA
(b.1) Horacio C. Reggini - Alas para la mente . Logo: ... - Ediciones Galápago - Buenos Aires 1982 -
(b.2) Wirth N. - Introducción a la programación sistemática - Editorial el Ateneo - Buenos Aires 1982
(b.3) Ridolfi Pierluigi - Applicazioni del fortran - Franco Angeli Editore -
(b.4) Huelsman Lawrence P. - Digital Computations in Basic Circuit Theory - Mc-Graw-Hill Inc. - 1968
(b.5) Gordon Jacobo - Fortran II y Fortran IV - Edición del autor - La Plata -
(b.6) Mc Cracken Daniel D. - Programación Fortran IV -Editorial Limusa-Wiley S.A. - México -
(b.7) Italo Hilario Farina - Fortran IV Curso de programación para ... Editorial Univ. Buenos Aires 1976
(b.8) Papert Seymour - Desafío a la mente Computadoras y educación - Ediciones Galápago Buenos Aires
APENDICE 1 - LENGUAJE FORTRAN
Uno de los lenguajes bastante utilizados es el fortran, utiliza tarjetas o archivos de 80 columnas, si en la primera columna hay una letra c se trata de un comentario, que no es tenido en cuenta por el compilador fortran.
Las columnas 1 a 5 opcionalmente indican el numero de instrucción, conviene utilizar pocos números y con alguna lógica.
Cuando en la columna 6 hay cualquier carácter que no sea blanco o cero, se interpreta que es continuación de la instrucción anterior, en tal caso las columnas 1 a 5 estarán en blanco.
De columnas 7 a 72 inclusive se escribe la instrucción fortran, las columnas 73 a 80 no son utilizadas por el fortran y pueden utilizarse para identificar el registro.
En fortran el signo igual = significa asignación de valor, algunos lenguajes utilizan una flecha, que es mas clara.
Variable fortran, es un nombre de hasta seis caracteres, el primero debe ser alfabético, y los restantes alfanuméricos, los caracteres especiales están excluidos.
Expresión aritmética fortran, es equivalente a una expresión algebraica valida, expresión es una formula que especifica un valor en base a operadores y operandos conocidos.
En fortran existe jerarquía de los operadores y niveles de paréntesis como en el álgebra
||||| X = A + B - C + (A * B / C) * A |
Como visto una expresión puede ser escrita en uno o mas renglones las variables pueden ser reales o enteras, las variables enteras tienen nombres que comienzan con las letras i, j, k, l, m, n y pueden ser declaradas en modo explícito.
||||| INTEGER ENTERO, A, BB |
En las expresiones no es aconsejable usar aritmética mixta, mezcla de variables enteras, y reales, salvo en la exponenciacion.
||||| VARIAB = BASE ** KEXPO |
Aunque no indispensable es conveniente que toda operación se realice después de haber fijado (convertido de real o flotante a entero o fijo) o flotado (viceversa) la variable.
||||| AA = FLOAT(NA) |
||||| NA = FIXED(AA) |
Debe tenerse mucho cuidado con las expresiones de aritmética entera, porque el orden de las operaciones altera el resultado por los redondeos intermedios cuando hay cocientes.
Para la lectura de datos la instrucción utilizada es read, debiendo indicarse el formato de los datos.
||||| READ 100, X, Y, Z, A, B |
| 100 FORMAT(8F10.0) |
En esta forma se entran hasta 8 valores reales por tarjeta, cada uno ocupa 10 columnas, es importante indicar el punto decimal.
||||| READ (LECTOR,100) X, Y, Z, A, B |
De esta manera habiéndose definido la lectora, lector = 5, se produce la lectura.
||||| READ (LECTOR,100,END=999) X, Y, Z, A, B |
||||| ... |
| 999 CONTINUE |
C SE TERMINARON LAS TARJETAS EN LA LECTORA |
En esta forma si no se encuentran tarjetas en la lectora el programa continua en 999 sin dar mensaje de error por fin de tarjetas.
Si los datos son números enteros debe cuidarse que estén encolumnados a la izquierda.
||||| READ (LECTOR,120) I, J, K, X ,Y ,Z |
| 120 FORMAT(3I3,1X,7F10.0) |
Así se leen tres números enteros, cada uno ocupa tres columnas, luego queda una columna libre 1x, y luego se leen hasta siete valores reales de 10 columnas cada uno.
El utilizar formatos mas complejos de lectura obliga a poner mucha atención en la confección de los datos, esta dificultad produce errores inevitables, por eso especialmente cuando no se tiene experiencia debe tratar de simplificarse la tarea al máximo.
Para poder utilizar la computadora además se deben escribir los datos y los resultados.
||||| PRINT 200, HI, HJ, HK, X, Y, Z |
| 200 FORMAT(1X,10F12.6) |
El formato producirá la impresión de hasta 10 valores, cada uno de hasta 12 símbolos, números, punto, y signo, seis cifras después de la coma.
El primer espacio en blanco 1x de la línea de impresión sirve para el control de carro, el espacio en blanco cambia renglón, el '1' cambia hoja, el '0' salta un renglón, el '+' sobreimprime un renglón, el '-' salta dos renglones.
||||| WRITE(IMPRES,220) X ,Y ,Z |
| 220 FORMAT('0','X = ',F10.3,' Y = ',F10.3,' Z = ',F10.3) |
Producira la impresión de los carteles entre comillas y los resultados de las variables intercalados.
El numero de la impresora es impres = 6, u otro valor declarado oportunamente. El numero de las impresoras y de las lectoras debe definirse y declararse con las tarjetas de control, puede haber varias lectoras y varias impresoras, inicialmente no es conveniente utilizar estas facilidades.
Un ejemplo puede ser utilisimo:
C PROGRAMA DE SUMA |
||||| READ 100, A |
||||| READ 100, B |
C TAMBIEN SE PODRIAN LEER AMBOS DATOS EN LA MISMA TARJETA |
C READ 100, A, B |
C Y SE AHORRARIA UNA TARJETA DE ENTRADA |
||||| C = A + B |
||||| PRINT 220, A ,B ,C |
| 100 FORMAT(8F10.0) |
| 220 FORMAT('0','A = ',F10.3,' B = ',F10.3, |
|||||* ' C = A + B = ',F10.3) |
||||| STOP |
||||| END |
La bifurcación incondicional se indica con "go to 111" donde 111 es el numero de una instrucción fortran que debe figurar en el programa.
La instrucción siguiente a un go to debe estar identificada con un numero, de lo contrario el programa nunca podrá llegar a ella.
La bifurcación condicionada puede ser el "if" aritmético o el lógico, el aritmético selecciona un camino de tres posibles según sea la condición menor, igual, o mayor que cero.
||||| IF (E) 11,22,33 |
|| 11 CONTINUE |
C EL VALOR DE E CUMPLE E<0 |
||||| INSTRUCCIONES I1 |
||||| ..... |
|| 22 CONTINUE |
C EL VALOR DE E CUMPLE E=0 |
||||| INSTRUCCIONES I2 |
||||| ..... |
|| 33 CONTINUE |
C EL VALOR DE E CUMPLE E>0 |
||||| INSTRUCCIONES I3 |
El if lógico es mas fácil de usar, las operaciones lógicas pueden ser varias pero inicialmente conviene presentar solo un par, en los manuales se encontraran las otras y el modo de usarlas.
Las operaciones lógicas que presentaremos inicialmente son ".lt." menor que (less than) y ".ge." Mayor o igual (greather equal), veamos un ejemplo de uso, supongamos que se desean leer varias tarjetas y sumar sus valores, el final se indica con el valor 9999.
C PROGRAMA DE SUMA DE VALORES |
||||| SUM = 0 |
|| 11 CONTINUE |
||||| READ 100, X |
||||| IF (X .GE. 9999.) GO TO 222 |
||||| PRINT 220, X |
| 100 FORMAT(F10.0) |
| 220 FORMAT('0','X = ',F10.3) |
||||| SUM = SUM + X |
||||| GO TO 11 |
| 222 CONTINUE |
||||| PRINT 230 |
| 230 FORMAT('0','----------------------') |
||||| PRINT 240, SUM |
| 240 FORMAT('0','S = ',F10.3) |
||||| STOP |
||||| END |
Cuando se desea utilizar una subrutina debe declarársela, el nombre de la subrutina cumple con las mismas reglas que el nombre de la variable, pero solo sirve de referencia, la subrutina debe devolver resultados al menos en un argumento.
La función es parecida a la subrutina, el nombre define si es real o entera, el resultado se devuelve en el nombre, también se pueden modificar otros argumentos.
Ambas deben terminar con return y end, un ejemplo puede ser útil.
C PROGRAMA DE SUMA, QUE UTILIZA SUBRUTINAS Y FUNCIONES |
||||| CALL DATOS (A,B) |
||||| C = CALCUL (A,B) |
||||| PRINT 220, A ,B ,C |
| 220 FORMAT('0','A = ',F10.3,' B = ',F10.3, |
|||||* ' C = A + B = ',F10.3) |
||||| STOP |
||||| END |
||||| SUBROUTINE DATOS (A,B) |
||||| READ 100, A |
||||| READ 100, B |
| 100 FORMAT(F10.0) |
||||| RETURN |
||||| END |
||||| FUNCTION CALCUL (A,B) |
||||| C = A + B |
||||| CALCUL = C |
||||| RETURN |
||||| END |
Una poderosa instrucción del fortran que permite linealizar y simplificar la descripción de los problemas es la instrucción "do"
||||| DO 111 I=N1,N2,NS |
||||| INSTRUCCIONES I |
| 111 CONTINUE |
Esta instrucción se interpreta de la siguiente manera, hacer hasta la instrucción 111 con i variando desde n1 hasta n2 con saltos de ns, siendo n1, n2, ns variables o constantes enteras, i es una variable entera que no puede modificarse dentro del do.
Cada vez que se ejecuta el do se controla que i no sea mayor de n2, alcanzado el limite se continua con la instrucción siguiente a 111, este modo de salir del do es llamado normal, el valor de i no debe ser utilizado, del do puede salirse en forma compulsiva, con un salto condicionado interno, en este caso el valor de i puede usarse.
Dentro de un do puede haber otro do anidado, es admisible el fin múltiple de varios do.
Dentro de un do interior no debe haber instrucciones de índice exterior, ya que se ejecutarían inútilmente todas las veces, análogamente dentro de un do no debe haber instrucciones independientes del índice.
El lector habrá observado que se ha adoptado como costumbre terminar los do con el continue, esto no es indispensable pero es conveniente por claridad.
Cuando un grupo de variables puede organizarse en un vector es útil emplear la notación de subíndices, para ello es necesario declarar la dimensión.
||||| DIMENSION X(10) |
Significa que se puede tener hasta 10 variables x(1),...,x(i),..., x(10), en el programa el índice puede ser variable.
Si se debe representar una matriz se escribirán sus dos o mas dimensiones, y un elemento genérico será m(i, j) donde i puede indicar la fila y j la columna.
APENDICE 2 - LENGUAJE BASIC
Las PC vinieron de la mano con un lenguaje muy flexible el Basic, que se escribe en renglones de longitud casi libre, si en el renglón hay un signo ' (apóstrofe) a partir de el se trata de un comentario, que no es tenido en cuenta por el interprete Basic.
Inicialmente cada renglón debía identificarse con un numero, luego esta condición se transformo en opcional, conviene utilizar pocos números y con alguna lógica.
En Basic el signo igual = significa asignación de valor, algunos dialectos utilizan una flecha.
Variable Basic, es un nombre de varios caracteres, el primero debe ser alfabético, y los restantes alfanuméricos, los caracteres especiales están excluidos.
Expresión aritmética basic, es equivalente a una expresión algebraica valida, expresión es una formula que especifica un valor en base a operadores y operandos conocidos.
En basic existe jerarquía de los operadores y niveles de paréntesis como en el álgebra
X = A + B - C + (A * B / C) * A |
Como visto una expresión puede ser escrita en uno o mas renglones las variables pueden ser reales o enteras.
VARIAB = BASE ^ KEXPO |
Para la lectura de datos la instrucción utilizada es input.
INPUT X, Y, Z, A, B |
En esta forma se entran hasta 5 valores por teclado, separados por comas.
Si se desea leer datos de un archivo, es necesario declararlo, e indicar su nombre, y un numero de dispositivo.
OPEN "ARCHIVO" FOR INPUT AS # 5 |
... |
INPUT #5, X, Y, Z, A, B |
... |
En esta forma el programa durante su ejecución abrirá el archivo llamado "ARCHIVO" esperando encontrar en el 5 datos numéricos, si no se encuentran dará mensaje de error por fin de datos.
Para poder utilizar la computadora además se deben escribir los resultados.
PRINT HI, HJ, HK, X, Y, Z |
El basic permite escribir sin especificar el formato, se pueden poner textos que aclaren el significado del resultado.
PRINT " RESULTADO = "; X ;Y ;Z |
Producira la impresión de los carteles entre comillas y los resultados.
Un ejemplo puede ser utilisimo.
' PROGRAMA DE SUMA |
' A + B = C |
INPUT " A "; A |
INPUT " B "; B |
C = A = B |
PRINT "SUMA: "; A; " + "; B; " = "; C |
END |
La bifurcación condicionada puede ser el "if".
IF (E) THEN |
INSTRUCCIONES I1 |
ELSEIF (EE) THEN |
INSTRUCCIONES I2 |
ELSE |
INSTRUCCIONES I3 |
ENDIF |
... |
El if es lógico, las operaciones lógicas pueden ser varias pero inicialmente conviene presentar solo un par, en la ayuda (help) se encontraran las otras y el modo de usarlas.
Las operaciones lógicas que presentaremos inicialmente son "<." menor que y ">=" Mayor o igual, veamos un ejemplo de uso, supongamos que se desean ingresar varios datos y sumar sus valores, el final se indica con el valor 9999.
' PROGRAMA DE SUMA DE VALORES |
SUM = 0 |
11 ' CONTINUE |
INPUT " INGRESE VALOR X = ", X |
IF (X > 9999.) GO TO 222 |
SUM = SUM + X |
GO TO 11 |
222 ' CONTINUE |
PRINT " ----------------" |
PRINT SUM |
END |
Cuando se desea utilizar una subrutina debe declarársela, la subrutina debe devolver resultados al menos en un argumento. Debe terminar con END SUB, en algunos dialectos no existe la subrutina como aquí descripta.
' PROGRAMA DE SUMA, QUE UTILIZA SUBRUTINAS |
CALL DATOS (A,B) |
..... |
PRINT A ,B ,C |
END |
SUB DATOS (A,B) |
INPUT A |
INPUT B |
END SUB |
Una poderosa instrucción que permite linealizar y simplificar la descripción de los problemas es la instrucción "FOR NEXT"
FOR I=N1 TO N2 STEP NS |
INSTRUCCIONES I |
NEXT |
Esta instrucción se interpreta de la siguiente manera, hacer hasta la instrucción NEXT con i variando desde n1 hasta n2 con saltos de ns, siendo n1, n2, ns variables, i es una variable que no puede modificarse dentro del FOR NEXT.
Cada vez que se ejecuta el FOR se controla que i no sea mayor de n2, alcanzado el limite se continua con la instrucción siguiente a NEXT, este modo de salir del FOR es llamado normal, el valor de i , del FOR NEXT puede salirse en forma compulsiva, con un salto condicionado interno, en este caso el valor de i puede usarse.
Dentro de un do puede haber otro do anidado, es admisible el fin múltiple de varios do.
Dentro de un do interior no debe haber instrucciones de índice exterior, ya que se ejecutarían inútilmente todas las veces, análogamente dentro de un do no debe haber instrucciones independientes del índice.
El lector habrá observado que se ha adoptado como costumbre terminar los do con el continue, esto no es indispensable pero es conveniente por claridad.
Cuando un grupo de variables puede organizarse en un vector es útil emplear la notación de subíndices, para ello es necesario declarar la dimensión.
||||| DIM X(10) |
Significa que se puede tener hasta 10 variables x(1),...,x(i),..., x(10), en el programa el índice puede ser variable.
Si se debe representar una matriz se escribirán sus dos o mas dimensiones, y un elemento genérico será m(i, j) donde i puede indicar la fila y j la columna.
APENDICE 3 - EJERCICIOS PROPUESTOS
Se proponen una serie de problemas que deberían ser resueltos a medida que avanza la lectura de este apunte, si no se logra resolverlos convendrá repetir la lectura o pedir ayuda a un amigo aventajado.
La numeración de los problemas es doble, la primera cifra identifica la clase a la que corresponde, la segunda el problema.
problema 1-1 - describir el algoritmo de la suma. El autómata posee una tabla de sumar de 10x10, y debe sumar dos números de varias cifras.
problema 1-2 - describir el algoritmo de extracción de la raíz cuadrada de un numero, el autómata sabe sumar, restar, multiplicar y dividir.
problema 1-3 - describir el algoritmo de extracción de la raíz cuadrada que utiliza el método de newton, por sucesivas aproximaciones x(i) = (x(i-1) + n/x(i-1))/2, siendo n el numero y x(i) la aproximación i. Describir como se debe hacer el trabajo con una calculadora que tiene las cuatro operaciones y dos registros de memoria.
problema 1-4 - describir el algoritmo de resolución de la ecuación de segundo grado. Tener en cuenta los distintos casos de soluciones reales y complejas.
problema 1-5 - describir el algoritmo de suma de un vector. El autómata además conoce la notación de subíndices.
problema 1-6 - describir el algoritmo de suma de elementos de una matriz fila por fila, columna por columna.
problema 2-1 - describir el algoritmo que determina los términos del desarrollo del binomio de newton, separar las subrutinas que calculan el numero combinatorio y el factorial.
- (a+b)**n = sumatoria a**i * b**(n-i) * comb(n,i) desde i=1 a n
- Comb(n,i) = factorial(n) * factorial(i) / factorial(n-i)
problema 2-2 - mejorar los problemas de la clase 1 utilizando el criterio de separar subrutinas y o funciones.
problema 3-1 - desarrollar en lenguaje fortran los problemas de las clases anteriores.
problema 3-2 - realizar un programa que interpola linealmente entre pares de puntos, dados varios puntos en el plano.
problema 3-3 - para la quebrada del problema anterior, realizar el programa que determina el área entre coordenadas dadas.
problema 4-1 - rehacer los problemas anteriores utilizando la instrucción do.
problema 4-2 - realizar una subrutina que clasifica los elementos de un vector de mayor a menor y viceversa. Describir el algoritmo.
problema 4-3 - dada una matriz nxm sumar filas, columnas, hallar promedios por fila o columna y general.
problema 4-4 - construir una serie de subrutinas que realicen operaciones sobre complejos, pares de números, suma, resta, multiplicación, división, inversa, modulo, ángulo.
problema 4-5 - construir una serie de subrutinas que realicen operaciones sobre vectores de tres dimensiones, suma, resta, producto escalar, vectorial, modulo, determinación del versor.