tecnología de la información -...

133
Tecnología de la Información INICIACIÓN A LA PROGRAMACIÓN EN PASCAL Uso del compilador gratuito: Free-Pascal José Emilio Bascuñana Fernández

Upload: phunghanh

Post on 01-May-2018

215 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

Tecnología de la

Información

INICIACIÓN A LA PROGRAMACIÓN

EN PASCAL

Uso del compilador gratuito: Free-Pascal

José Emilio Bascuñana Fernández

Page 2: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

2

INTRODUCCIÓN 1.- Concepto de computación o informática El concepto de computación o informática puede definirse como la ciencia que estudia los conocimientos científicos y técnicos que permiten el tratamiento automático de la información por medio de máquinas de cálculo automático, electrónicas o computadores. 2.- Concepto de algoritmo Los algoritmos tienen su origen en los matemáticos hindúes y árabes. La palabra algoritmo proviene de la traducción al latín de un libro de aritmética escrito por un matemático árabe conocido por Al’Kahwarizmi. Un algoritmo es la descripción de un método preciso para resolver automáticamente un problema. Desde el punto de vista de la computación, un algoritmo consta de una representación de los datos que se manejan, y de una secuencia ordenada de instrucciones u órdenes que resuelven el problema planteado. Un algoritmo debe ser un conjunto ordenado de pasos o instrucciones que especifican, de forma precisa y sin ambigüedades, la secuencia de operaciones que se han de realizar para resolver un problema. Los métodos más habituales para representar cualquier algoritmo son: - Diagramas de flujo u organigramas. - Pseudocódigos, que son lenguajes específicos. - Lenguaje natural. - Métodos formales matemáticos. 3.- Lenguajes de programación Un lenguaje de programación no deja de ser un lenguaje que permite comunicar una serie de conceptos acerca de un mismo tema entre dos elementos(máquinas, humanos, etc) que conocen y comprenden ese mismo lenguaje. Constará de los siguientes elementos:

- Alfabeto. - Léxico. - Sintaxis. -Semántica. 3.1.- Lenguajes máquina

El alfabeto que utiliza para escribir las instrucciones es el binario, es decir, 0 y 1 (es el único

directamente ejecutable por el ordenador) Ya nadie programa utilizando este tipo de lenguaje.

3.2.- Lenguajes ensambladores Se trata de lenguajes de programación bastante próximos al lenguaje máquina. Aquí se

sustituyen las cadenas binarias por un conjunto de códigos nemotécnicos más sencillos de recordar y utilizar. Depende de cada máquina en concreto.

3.3.- Lenguajes de alto nivel Son los más próximos al lenguaje natural y, por lo tanto, los más utilizados hoy en día. Pueden expresar instrucciones muy complejas (que se traducirán a gran cantidad de instrucciones máquina) y no serán directamente ejecutables por el ordenador. Para que esto pueda ocurrir se usan lenguajes compilados que utilizan un programa especial llamado compilador que es un programa capaz de traducir un conjunto de instrucciones de alto nivel a código máquina directamente ejecutable por el ordenador.

Page 3: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

3

Programación en Pascal

I. INTRODUCCIÓN A PASCAL 1. Tipos de datos, constantes y variables Un programador puede necesitar representar números enteros, caracteres alfanuméricos, personas o listados de empleados en su programa, por lo que necesitará dispones de diferentes tipos que permitan codificar la información que necesita para resolver el problema planteado. Normalmente existen los siguientes tipos de datos: - Tipos simples: Se utilizan para representar datos numéricos (enteros y reales), datos alfanuméricos (caracteres) y datos lógicos o booleanos. - Tipos estructurados: Permiten representar tablas, listas, cadenas, etc. - Tipos definidos por el programador: Utilizan como base los tipos simples y estructurados y permiten al programador crear una abstracción de la información que desea manipular en su programa. Constantes (CONST): Su valor no cambia a lo largo de la ejecución del programa. Variables (VAR): El valor de un dato puede cambiar a lo largo de la ejecución del programa. 2. Símbolos e identificadores en pascal Un identificador es una palabra válida que puede ser utilizada para representar el nombre de una variable, de una constante, de un programa o de un subprograma en el lenguaje considerado. Su sintaxis es:

IDENTICADOR: Letra <Letra/digito/subrayado>

* Ejemplo: Son identificadores válidos: peso, altura_base, dato1, nombre_apellidos. El vocabulario válido en Pascal está formado por: • Letras: Pueden utilizarse 52 letras diferentes, 26 mayúsculas y 26 minúsculas. (Sin Ñ y ñ). • Dígitos: Los comprendidos entre 0 y 9. • Signos de puntuación y caracteres especiales: Como, por ejemplo, =, -, *, +, <, >, [, ], (, ), etc. • Operador de asignación: := • Operadores aritméticos: +, -, *, /, DIV(cociente entero), MOD (resto de la división entera). (+ también concatena cadenas) • Operadores lógicos: <, >, =, <>, <=, >= • Cadenas de caracteres: Una cadena de caracteres se construye en Pascal como la unión de un conjunto de letras, dígitos y/o caracteres especiales en cualquier orden. Aparecerá delimitada por el símbolo comilla, seguida por un conjunto de caracteres:

‘cadena de letras, dígitos y/o caracteres especiales’ * Ejemplos: Cadena vacía: ‘ ‘ Cadena de cuatro dígitos: ‘1234’ Cadena formada por caracteres alfabéticos: ‘Luís y María-Tornado bailan’

Page 4: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

4

• Números: Se construyen usando la regla <signo> numero < . numero> <e/E +/- numero> (Aquí los símbolos < y > significan opcional) * Ejemplos: 1234 es el número positivo 1234 23.08 es el número real 23,08 -32.3E+2 equivale a -32.3 10+2 = -3230 • Palabras estándar: - Para identificar los tipos de datos predefinidos en Pascal: INTEGER, REAL, CHAR, BOOLEAN, SHORTING, LONGINT, etc. - Para identificar funciones o procedimientos (subprogramas) predefinidos en Pascal: WRITE; READ; ABS, FUNCTION, etc. - Palabras Reservadas: tienen un significado semántico especial. Por ejemplo, la palabra PROGRAM se utilizará para representar el nombre del programa. Otros ejemplos de palabras reservadas son: CONST; TYPE; VAR; BEGIN; END; WHILE; DO; REPEAT; UNTIL; NOT; IF THEN; ELSE; FOR; FUNCTION; PROCEDURE, etc. Estas palabras no pueden usarse como identificadores debido a que todas ellas tienen un significado especial en Pascal. Una buena costumbre para programar es utilizar letras mayúsculas para las palabras reservadas y las minúsculas para los identificadores definidos por el usuario (excepto la primera letra que suele ir en mayúscula); si el identificador está formado por varias palabras, normalmente se separan por un subrayado o se pone en mayúscula la primera letra de cada palabra. Así el código será más legible. 3. Comentarios en pascal

Permiten que cualquier código sea más legible. Son partes del programa que realmente no

hacen nada, es decir, no se ejecutan. Hay dos formas de escribir comentarios:

{comentario} o también (*comentario*) 4. Estructura de un programa en pascal

Un programa en Pascal consta de dos partes claramente diferenciadas. Por un lado, una parte de declaraciones, en la que se declaran los nombres y tipos de variables, nombre de constantes, tipos de datos a utilizar en el programa , etc, seguida por una parte de instrucciones, que contiene el conjunto de instrucciones encargadas de codificar el algoritmo diseñado. De esta forma, un programa en Pascal puede considerarse dividido en las siguientes partes:

• Una Cabecera de programa:

PROGRAM Nombre_Programa (lista de archivos);

Donde la lista de archivos es opcional y, si aparece, corresponde a un conjunto de archivos que serán utilizados por el programa. Por ejemplo Input, Output. • Una sección de declaración de datos y subprogramas. Esta sección puede dividirse en el conjunto de elementos que pueden ser declarados: - Declaración de constantes:

* Ejemplo:

CONST a=25; (* La constante a no variará su valor a lo largo del programa*) numero_pi= 3.141592;

Page 5: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

5

Mi_nombre= J̀osé Emilio´; Color= Rojo;

- Declaración de tipos de datos: Se identifican mediante la palabra reservada TYPE y permite definir datos no predefinidos por el lenguaje. * Ejemplo:

TYPE color = (rojo, verde, amarillo); - Declaración de variables: Se utiliza la palabra reservada VAR para definir variables globales que van a ser utilizadas. - Declaración de funciones y procedimientos que el programa necesite. En esta sección se declaran los dos tipos de subprogramas que pueden construirse en Pascal. Cada uno de ellos podrá identificarse mediante una palabra reservada, FUNCTION para al caso de las funciones y PROCEDURE para el de los procedimientos.

• Un bloque de sentencias o “programa principal”. Este bloque estará delimitado por las palabras reservadas BEGIN y END, con la particularidad de que esta última terminará con un punto y no con punto y coma “;” como la mayoría de las instrucciones en Pascal. La estructura general de un programa en Pascal se muestra en el cuadro siguiente. PROGRAM Inicial; CONST numero_pi= 3.141592; VAR num1, num2: integer; X: real; TieneHijos: boolean; Nombre, Apellidos: String; FUNCTION factorial(numero:integer):integer; BEGIN Sentencias; ………….. END; PROCEDURE sistema (VAR parametro1:real; parametro2:real;……); BEGIN Sentencias; ………….. END; BEGIN (*Programa principal*) Sentencia1; Sentencia2; ………….. END. • Programa 1

Escribe y ejecuta el siguiente programa que permite mostrar en pantalla un mensaje: PROGRAM Bienvenida; BEGIN Writeln(‘ Bienvenido a la programación en Pascal ‘); Readln( ); END. 5. Clasificación de los tipos de datos en Pascal

Page 6: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

6

En función de cómo se reserva la memoria necesaria para almacenar la información, una primera clasificación de los tipos de datos es: • Tipos o datos estáticos. Es el caso de los tipos simples, estructurados o del tipo cadena. Cuando se declaran estos tipos, se reserva la cantidad de memoria necesaria. • Tipos o datos dinámicos. Durante la ejecución de un programa puede darse el caso de necesitar solicitar más memoria para almacenar una información. Para resolver este problema, Pascal utiliza el tipo puntero que permite solicitar (y liberar) la cantidad de memoria que necesita el programa durante su ejecución.

En función del tipo de información que almacenan los datos puede hablarse de los siguientes tipos: • Tipos simples. Son directamente utilizables por el programador y permiten representar un dato con características muy concretas. Por ejemplo, datos numéricos (enteros, reales), datos lógicos, datos de tipo carácter, etc. • Tipos cadena. Permiten representar cadenas o grupos de caracteres (código ASCII), utilizando un único identificador como nombre de la variable tipo cadena. • Tipos estructurados. Deben ser, en cierta forma, definidos por el programador. Un dato estructurado permite crear una colección de datos de un mismo tipo(como los arrays, los conjuntos o los archivos) o de diferentes tipos (como los registros) y manipularlos como si de una única estructura se tratase. Es decir, en lugar de tener cuatro variables de tipo entero, pueden agruparse y crear una lista (o array) formada por cuatro datos de tipo entero. Aquí se deberá especificar el tamaño de la colección datos y el tipo de éstos.

* Ejemplo:

La declaración VAR Posicion= array[1..4] of integer; reserva en memoria una lista de 4 datos enteros:

• Tipo puntero. Permite la implementación de datos dinámicos en Pascal. Este tipo de datos permite solicitar memoria al sistema de forma dinámica. Es decir, utilizando el tipo puntero (y una función predefinida de Pascal llamada new) puede solicitarse en tiempo de ejecución la cantidad de memoria necesaria. Ahora bien, cuando una cantidad de memoria es solicitada al sistema, ésta se marca como ocupada para que ningún otro proceso o programa pueda sobrescribir (y por tanto destruir) datos. Para liberar memoria se usa una función predefinida en Pascal, dispose. 5.1 Tipos simples en Pascal

Los tipos simples en Pascal son: Integer, Char, Bolean, Real, Enumerados y Subrangos. Estos seis tipos de datos pueden clasificarse de la forma siguiente:

• Tipos simples���

.Re:.,,,,:

alordinalesNo

SubrangoEnumeradosBooleanCharIntegerOrdinales

• Tipos simples���

.:.,,Re,:Pr

SunrangosyEnumeradosrprogramadoelporDefinidos

CharBooleanalIntegeredefinidos

5.1.1 Tipos simples ordinales Un tipo de dato es ordinal si: - Existe un primero y un último elemento. - Cada elemento, excepto el último tiene un elemento que le sigue llamado sucesor.

Page 7: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

7

- Cada elemento, excepto el primero, tiene un elemento que le precede llamado antecesor. Estos tipos son, en Pascal, Integer, Char, Booloan, Enumerados y Subrangos. Para cualquier tipo de datos ordinal pueden definirse tres funciones que permiten obtener información sobre ellos: ord(x), succ(x) y pred(x). 5.1.2 Tipos enteros en Pascal Existen varias formas de declarar variables de tipo entero en Pascal:

Tipo Nºde bytes Rango SHORTINT 1 -128..127 INTEGER 2 -32768..32767 LONGINT 4 -2147483648..2147483647

BYTE 1 0..255 WORD 2 0..65535

5.1.3 Tipo real en Pascal Los números reales se pueden representar de dos formas en Pascal: • Notación decimal = parte_entera.parte_decimal. • Notación científica = mantisa*10exponente.

23.904 ; 3E4 = 13*104=130000 ; -3.22E+3 = -3.22*103 = -3220 ; 4.5E-2 = 4.510-2 =0.0451 El tipo REAL es el más utilizado y admite cinco subtipos diferentes, según el número de dígitos con significado:

Tipo Nº Bytes Dígitos representables Rango REAL 6 De 11 a 12 2.9*10-39..1.7*1038

SINGLE 4 De 7 a 8 1.5*10-45..3.4*1038 DOUBLE 8 De 15 a 16 5.0*10-324..1.7*10308 EXTENDED 10 De 19 a 20 1.9*10-4851..1.1*104932 COMP 8 De 19 a 20 -9.2*10-18..9.2*1018 5.1.4 Tipo Boolean El tipo lógico, o Boolean, definido en Pascal representa a un conjunto de datos que sólo pueden tomar dos valores constantes predefinidos: - Cierto, TRUE (T) - Falso, FALSE (F) Además de las funciones ORD, SUCC y PRED, Pascal proporciona otra tres que devuelven valores voléanos en función del parámetro o dato que se les proporcione: • ODD(Numero). Esta función devuelve el valor true si el número es impar y false si es par. • EOLN,EOF. Estas funciones se utilizan para procesar archivos. • NOT (negación). Si el valor de una variable es true lo transforma en false , y viceversa. • AND (conjunción). Permite realizar la Y-Lógica, o conjunción, de dos variables lógicas. Esta función devuelve el valor true si ambos operadores están a true. En caso contrario devuelve false. • OR (disyunción). Permite realizar la O-Lógica, o disyunción, de dos variables lógicas. Se caracteriza porque sólo se obtiene como resultado false si ambos operadores están a false. En caso contrario devuelve true.

La prioridad de los operadores lógicos es : NOT> AND> OR 5.1.5 Tipo Char

Page 8: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

8

Este topo se utiliza para representar el conjunto de caracteres alfanuméricos del ordenador. (En Pascal, el código ASCII extendido). Para declarar variables de este tipo se usa la palabra reservada CHAR. Sobre este tipo de variables se puede usar la función CHR(x) que devuelve el carácter que corresponde al ordinal x. Ejemplo: CHR(68)= D̀´

5.1.6 Tipo Enumerado Define un conjunto de valores nuevos definidos por el programador. La sintaxis es: TYPE

Nombre_tipo_enumerado=(ident1, ident2,…….identN); VAR

Dato: Nombre_tipo_enumerado; * Ejemplo

TYPE Semana=(lunes, martes, miércoles, juebes, viernes, sábado, domingo);

VAR Dia: semana; Los únicos operadores que pueden utilizarse con este tipo son los de asignación (para cargar un valor a la variable). Tampoco se pueden leer desde el teclado ni escribirse en pantalla directamente. 5.1.7 Tipo Subrango Es un tipo ordinal simple definido por el programador, cuyos elementos están comprendidos entre un límite inferior y uno superior. Se pueden definir subrangos de cualquier tipo ordinal: enteros, caracteres, enumerados previamente definidos, etc. La sintaxis es: TYPE Nombre_subrango= limite_inferior .. limite_superior; VAR Dato: Nombre_subrango; * Ejemplo

TYPE Semana=(lunes, martes, miércoles, jueves, viernes, sábado, domingo);

DiasLaborables = lunes .. viernes; VAR

Laborable:DiasLaborables; diasMes: 1 .. 31; meses: 1 .. 12; 6. Prioridad entre operadores lógicos y aritméticos

La mostramos en la tabla siguiente:

Operador Prioridad ( , ) 1(superior) NOT 2 /. *, DIV, MOD, AND 3

Page 9: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

9

+, -, OR 4 <, >, =,<=, >=, <> 5 (inferior)

7. Funciones aritméticas predefinidas en Pascal

Función Significado abs(x) Valor absoluto de x round(x) Redondeo x a su entero más cercano sqr(x) Cuadrado de x sqrt(x) Raíz cuadrada de x exp(x) Función exponencial ex ln(x) Logaritmo neperiano de x cos(x) Coseno de x (en radianes) sin(x) Seno de x (en radianes) arctan(x) Arcotangente de x (en radianes) trunc(x) Truncar x a su parte entera

8. Sentencia de asignación La sentencia de asignación se utiliza para asignar (almacenar) valores en las variables que han sido previamente declaradas. La instrucción de asignación sitúa un valor en una posición concreta de la memoria. La variable que se encuentra a la izquierda del símbolo de asignación (:=) tiene que ser un tipo igual o compatible al valor o tipo de la expresión que se encuentra a la derecha. La sintaxis de la instrucción de asignación es:

Variable:= expresión;

8. Sentencias de entrada Existen dos procedimientos predefinidos: READ y READLN para aceptar una variable o un conjunto de variables separadas por comas, además readln puede ser utilizada sin variable alguna. La sintaxis es: Read(variable); Read(variable1, variable2, ….., variableN); Readln(variable); Readln(variable1, variable2, ….variableN); Readln; Mientras que readln, después de leer todos los valores para las variables de entrada, avanza hasta la siguiete línea de entrada donde se leerán los siguientes valores, read no lo hace. El efecto que produce readln, sin variables es que la ejecución del programa no continúa hasta que se pulse una tecla. Solo se pueden leer datos de tipo entero, real, carácter o cadenas (string), pero no booleanos ni de tipo enumerado. Los valores y el tipo de cada valor deben concordar con el tipo de variable que se va a asignar; si no es así, se producirá un error. 9. Sentencias de salida La salida de datos, o escritura, es un término que se aplica a una operación de salida de valores hacia un periférico (monitor, impresoras, etc).

Page 10: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

10

Existen dos procedimientos predefinidos: WRITE y WRITELN para aceptar una variable o un conjunto de variables separadas por comas, además writeln puede ser utilizada sin variable alguna. La sintaxis es: Write(variable); Write(variable1, variable2, ….., variableN); Writeln(variable); Writeln(variable1, variable2, ….variableN); Writeln; Writeln, después de escribir todos los valores para las variables, avanza hasta la línea siguiente, esdecir, produce un salto de línea; write no lo hace, deja el cursor en la última posición donde ha escrito un dato. Writeln, sin variables de entrada, finaliza la salida en esa línea. • Descriptores de formato Pascal permite especificar de forma simple el formato de la salida añadiendo descriptores de formato a las variables de salida. La sintaxis es: :w :w:d donde w y d representan a dos expresiones de tipo entero. : w especifica que el valor que se va a mostrar utilizará un total de w espacios. El valor a visualizar se justifica a la derecha. Los valores reales se muestran en forma exponencial. :w:d se utilizan para mostrar valores reales de forma decimal. :w es la anchura del campo, mientras que :d indica el número de dígitos decimales que deben ser visualizados. ( el punto del decimal cuenta como un carácter). • Programa 2 Escribe el siguiente programa y ejecútalo para comprobar el funcionamiento de las sentencias que aparecen en él: Program pruebaEscritura; Var nombre:string[20]; edad:0..100; peso:real; sexo:char; altura:real; BEGIN nombre:='Pedro'; edad:=25; peso:= 75.60; sexo:='M'; altura:=1.96; writeln('Salida de datos: '); writeln('_______________ '); writeln; (*El texto encerrado entre comillas se escribe tal cual*) writeln('Nombre: ', nombre); writeln('Edad: ',edad, ' Peso: ',peso:3:5,' Sexo: ',sexo); writeln('Altura: ',altura:5:2); readln; END.

Page 11: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

11

Al ejecutarlo, produce la salida siguiente:

• Programa 3 Escribe el siguiente programa que intercambia entre sí los valores de dos variables enteras leídas por teclado; se usa una variable auxiliar aux para no perder el primer dato leído x al asignarle el segundo y.

Program Intercambiovariables; Var x,y, aux:integer; BEGIN Write('Introduce un valor entero x: '); readln(x); Write('Introduce otro valor entero y: '); readln(y); (*Intercambio los valores*) aux:=x; x:=y; y:=aux; Writeln; Writeln('Ahora el valor de x es: ',x,' y el valor de y es: ',y); Readln( ); (*Hasta que no se pulse una tecla no seguirá la ejecución del programa*) END. La salida en pantalla al ser ejecutado es:

• Programa 4

Escribe un programa que sume dos números enteros a y b leídos por teclado y muestre el resultado en pantalla.

• Programa 5

Escribe un programa que calcule el área del círculo y la longitud de una circunferencia de radio r leído por teclado. Utiliza la constante pi=3.141592.

• Programa 6

Escribe un programa que calcule el área total de un ortoedro del que se leen su largo, su ancho y su altura.

• Programa 7

Page 12: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

12

Escribe un programa que calcule el cuadrado y la raíz cuadrada, con 2 cifras decimales, de un número natural N introducido por teclado y produzca una salida de la forma siguiente:

• Programa 8 Escribe un programa que lea números enteros representativos de día, mes y año e imprima esta fecha bajo la forma dd/mm/aa.

• Programa 9

Escribe un programa que responda si un número, introducido por teclado, es o no múltiplo de 3. Utiliza la función MOD. La ejecución debe mostrar la pantalla siguiente:

• Programa 10

Escribe un programa que permita hallar la imagen de la función 17)( 2 +−= xxxf para tres valores x1, x2 y x3 reales introducidos por teclado. Una posible solución sería: Program FuncionCuadratica; var x1,x2,x3:real; f1,f2,f3:real; BEGIN write('Introduce un numero real x1: '); readln(x1); f1:=sqr(x1)-7*x1+1; write('Introduce un numero real x2: '); readln(x2); f2:=sqr(x2)-7*x2+1; write('Introduce un numero real x3: '); readln(x3); f3:=sqr(x3)-7*x3+1; writeln('Las imagenes de ',x1:2:2,' ',x2:2:2,' y ',x3:2:2); writeln('son repectivamente ',f1:2:4,' ',f2:2:4,' y ',f3:2:4); readln(); END. y la salida que produce es:

•• Programa 11. Decidir si un año es o no Bisiesto

Page 13: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

13

El siguiente programa decide si un año es o no bisiesto. Un año es bisiesto si es divisible por cuatro excepto los años que son múltiplos de cien a no ser que lo sean de 400. program bisiesto; uses crt; var n: integer;(* El operador MOD calcula el resto de la división entera de dos enteros*) BEGIN clrscr; writeln('introduce n: '); readln(n); writeln('¿es bisiesto?', (((n mod 4=0) and (n mod 100 <>0)) or (n mod 400=0))); Readln();

END.

* Considera la siguiente formación rectangular

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ……………..……………………

Escribe programas para los cálculos siguientes:

•• Programa 12. Decidir si dos números están en la misma columna

Program numeroscolumna; uses crt; var n,m: integer; BEGIN clrscr; write('introduce un número positivo entero: '); readln(n); write('introduce otro número positivo entero: '); readln(m); writeln(' ¿están en la misma columna? : ', (((n-1) mod 5)= ((m-1) mod 5))); Readln(); END.

•• Programa 13. Decidir la fila en la que está un número dado

Program fila; uses crt; var n,k,f: integer; BEGIN clrscr; write('introduce un número positivo entero: '); read(n); k:=n-1; f:=k div 5; writeln('la fila correspondiente es: ',f); Readln();

Page 14: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

14

END. •• Programa 14. Decidir si dos números están en la misma fila

Program numerosfila; uses crt; var n,m: integer; BEGIN clrscr; write('introduce un número positivo entero: '); readln(n); write('introduce otro número positivo entero: '); readln(m); writeln('¿están en la misma fila?: ', ((n-1) div 5)=((m-1) div 5))); Readln(); END.

• Programa 15

Escribe un programa que lea un ángulo expresado en segundos, y escriba su medida en grados sexagesimales, minutos y segundos.

• Programa 16 Escribe un programa para que salga por pantalla el nombre del lector y su dirección con el formato de un sobre postal. • Programa 17 Escribe un programa que calcule el volumen de un cilindro de radio y altura dados. • Programa 18 Escribe un programa que calcule la altura de un cono de volumen y radio de la base dados. • Programa 19 Escribe un programa que transforme en segundos un ángulo dado en grados, minutos y segundos. • • Programa 20 Escribe un programa que calcule las soluciones de una ecuación de segundo grado de la que se leen sus coeficientes. • Programa 21 Escribe un programa que decida si un número entero es múltiplo de seis, respondiendo True o False. • Programa 22 Escribe un programa que calcule la media aritmética y geométrica de dos enteros positivos. • Programa 23 Escribe un programa que escriba el número de tres cifras abc, introduciendo a, b y c por el teclado. Asï, para a=2, b=5 y c=7 tendremos 7+5.10+2.100= 257 • Programa 24 Escribe un programa que calcule el radio de un círculo, conocida su área. • Programa 25

Page 15: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

15

Escribe un programa que lea un entero positivo y decida si es cuadrado perfecto, respondiendo True o False.

Page 16: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

16

II PROGRAMACIÓN ESTRUCTURADA EN PASCAL

1. Introducción

Para que la programación sea estructurada, los programas han de ser propios, es decir, cumple: - Tiene un solo punto de entrada y uno de salida. - Toda acción del algoritmo es accesible. - No tiene bucles infinitos. El teorema de la programación estructurada dice que: Todo algoritmo (y, or lo tanto, todo programa) puede escribirse utilizando únicamente tres tipos de estructuras de control: - secuencial: es la más simple y permite ejecutar un conjunto de sentencias de forma secuencial, es decir, sucesivamente. - selectiva: o condicional permite tomar alternativas a la hora de ejecutar un bloque de instrucciones. Este tipo de estructura de control permite la selección entre dos alternativas en función del resultado de la evaluación de una condición lógica. Suele representarse, en la mayoría de lenguajes, de la forma IF condición THEN instrucción-1 ELSE instrucción-2. - repetitiva que permite ejecutar una instrucción o bloque de instrucciones de forma repetida hasta que alguna condición de tipo lógico determina el final de la ejecución de las instrucciones. 2. Ejecución de sentencias en Pascal

En Pascal se utiliza el símbolo “;” para indicar donde termina una sentencia y comienza la siguiente.

Sentencia1; Sentencia2; .................

SentenciaN; 3. Sentencias condicionales

Estas sentencias permiten ejecutar determinadas instrucciones según el valor de una expresión booleana o selector. En Pascal existen dos tipos de sentencias condicionales: IF y CASE. 3.1 Sentencia IF-THEN Es la sentencia de selección más simple. Solamente se ejecutan la(s) instrucciones si la expresión_booleana es cierta. Su sintaxis es: If expresión_booleana THEN Instrucción; ó bien If expresión_booleana THEN BEGIN Instrucción1; Instrucción2; …………… InstrucciónN; END; 3.2 Sentencia IF-THEN-ELSE En este caso, si la expresión_booleana es cierta se ejecutarán las instrucciones siguientes a THEN, y, si es falsa, las que siguen a ELSE. Su sintaxis es: If expresión_booleana THEN

Page 17: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

17

Instrucción1 ELSE Instrucción2; ó bien If expresión_booleana THEN

BEGIN Instrucción1; Instrucción2; …………… Instrucción:N; END ELSE BEGIN

Instrucción1; Instrucción2; …………… Instrucción:N; END; Observemos que antes de ELSE nunca se escribe “;” • • Programa 26. Comparar dos números enteros

El siguiente programa compara dos números enteros, leídos por teclado Program Comparar; Uses crt; VAR a,b:integer; BEGIN clrscr; write('Introduce a: '); readln(a); write('Introduce b: '); readln(b); if a=b then writeln('Los números son iguales') (*observa que delante de else no hay ”;” *) else Begin if a>b then writeln(' El más grande es: ',a) (*observa que aquí tampoco hay”;” *) else writeln(' El más grande es: ',b); End; Readln(); END.

• • Programa 27. Hallar el mayor de tres enteros

El siguiente programa decide cuál de tres enteros, leídos por teclado, es el mayor. Program NumeroMayor; Uses crt; VAR a,b,c,mayor:integer; BEGIN clrscr;

Page 18: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

18

write('Introduce a: '); readln(a); write('Introduce b: '); readln(b); write('Introduce c: '); readln(c); mayor:=a; if b>mayor then mayor:=b; if c>mayor then mayor:=c; writeln('El mayor es: ',mayor); Readln(); END.

3.3 Anidamiento de sentencia IF Las sentencias IF pueden “anidarse”, es decir, una sentencia IF puede estar contenida dentro de otra. Si se usan varias sentencias IF y una única ELSE, ésta se asocia al IF más cercano. La sintaxis de este tipo de estructuras es:

If condicion1 THEN Bloque_de_sentencias1 ELSE IF condicion2 THEN Bloque_de_sentencias2 ELSE IF condición3 THEN Bloque_de_sentencias3 ELSE Bloque_de_sentencias4

4. Funciones en Pascal Una función es un tipo de subprograma definible por el programador. Realizan una serie de cálculos y devuelven un resultado. Cualquier función debe ser declarada en la sección de declaración de subprograma tal como se indicó en la estructura general de un programa en Pascal. Cualquier función está formada por tres elementos fundamentales: cabecera, sección de declaraciones y cuerpo de la función. Su sintaxis es:

FUNCTION nombre (parámetro1:tipo1, …………. parámetroN:tipoN): Tipo (* Tipo significa el tipo de dato que devuelve la función*) Declaraciones locales (*aquí se declaran las constantes, variables, etc locales*) BEGIN Cuerpo de la función (* Instrucciones necesarias para calcular el valor de la función*) nombre:= valor devuelto por la función; (*esta sentencia es obligatoria: nombre de la función a la izquierda y expresión a la derecha*) END;

4.1 Llamada a una función en el programa principal Una vez declarada una función, se la llamará haciendo referencia a s identificador-nombre y dado que devuelve un solo resultado, éste se asignará a una variable del mismo tipo.

• • Programa 28. Programa que decide si tres longitudes a, b y c forman un triángulo

Page 19: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

19

Tres números reales determinan un triángulo si la suma de dos lados cualesquiera es mayor que el lado restante.

Program EsTriangulo; Uses crt; Var a,b,c: real; Function estriangulo(x,y,z:real):boolean; (*Aquí se define la función*) Begin (* Este es el cuerpo de la función*) estriangulo:=((x+y)>z) and ((x+z)>y) and ((y+z)>x) ; End; BEGIN (*Programa principal*) clrscr; Write( 'Introduce el primer lado: '); Readln(a); Write( 'Introduce el segundo lado: '); Read(b); Write( 'Introduce el tercer lado: '); Readln(c); (*Una función de tipo Booleano devuelve TRUE o FALSE *) Writeln(' ¨Es un triangulo ?: ',estriangulo(a,b,c)); (*Aquí se llama a la función*)

Readln(); END.

• • Programa 29

Escribe el programa 10 utilizando una función.

• • Programa 30. Decidir si dados tres números enteros forman un triángulo rectángulo

Program TrianguloRectangulo; Uses crt; Var a,b,c: real; (*La función SQR calcula el cuadrado del número al que se aplique*) Function estriangulo(x,y,z:real):boolean; (*Una función de tipo Booleano devuelve TRUE o FALSE *) Begin (* La suma de dos lados cualesquiera debe superar al restante*) estriangulo:=((x+y)>z) and ((x+z)>y) and ((y+z)>x) ; End; Function rectangulo(x,y,z:real):boolean; Begin (* Debe cumplirse El teorema de Pitágoras*) rectangulo:=(sqr(x)=sqr(y)+sqr(x)) or (sqr(y)=sqr(x)+sqr(z)) or (sqr(z)=sqr(x)+sqr(y)); End; BEGIN (*Programa principal*) clrscr; Write( 'Introduce el primer lado: '); Readln(a); Write( 'Introduce el segundo lado: '); Read(b); Write( 'Introduce el tercer lado: '); Readln(c); Writeln(' ¨Es un triángulo Rectangulo?: ',(estriangulo(a,b,c)) and (rectangulo(a,b,c)));

Readln(); END.

• • • Programa 31. Decidir si dados tres números enteros forman un triángulo equilátero

Page 20: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

20

Program TrianguloEquilatero; Uses crt; Var a,b,c: real; Function estriangulo(x,y,z:real):boolean; Begin (* La suma de dos lados cualesquiera debe superar al restante*) estriangulo:=((x+y)>z) and ((x+z)>y) and ((y+z)>x) ; End; Function equilatero(x,y,z:real):boolean; Begin equilatero:=((x=y)) and ((y=z)); End; BEGIN (*Programa principal*) clrscr; Write( 'Introduce el primer lado: '); Readln(a); Write( 'Introduce el segundo lado: '); Read(b); Write( 'Introduce el tercer lado: '); Readln(c); Writeln(' ¨Es un triangulo equilatero?: ',(estriangulo(a,b,c)) and (equilatero(a,b,c))); Readln(): END. * Considera la siguiente formación rectangular

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

……………..……………………

• • • Programa 32. Decidir el número que está en una fila y columnas dadas

Program Rectangular; uses crt; Var i,j,x : integer; Const N=5; function calcularNumero(a,b:integer):integer; begin calcularNumero:=N*a+b+1; end; BEGIN writeln ('Dame una fila: '); readln (i); writeln ('Dame una columna: '); readln (j); x:=calcularNumero(i,j); writeln ('El numero que corresponde a la fila ',i,' y a la columna ' ,j,' es: ',x); readln; clrscr; END.

Page 21: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

21

• • • Programa 33. Calcula los radios de las circunferencias tangentes interior y exterior a tres dadas, tangentes entre sí. (Ver dibujo)

Datos: r1, r2 y r3: radios de circunferencias dadas. Formula: 22222 )4321()4321(2 ssssssss +++=+++ donde

11

1r

s = , 2

12

rs = ,

31

3r

s = (Observemos que son datos )

41

4r

s = y los radios buscados son los dos r4 , en valor absoluto, que se obtienen al despejar s4 de la fórmula inicial:

De la fórmula inicial tenemos: Llamo S= s1+s2+s3 y Scuad= 222 321 sss ++ Tenemos: 22 )4()4(2 sSsScuad +=+ de donde 02424 22 =−+− ScuadSSss

22

282

4ScuadSScuadS

s±=±= y, por tanto

���

���

−=

+=

)2

2(44

)22

(4

ScuadSABSr

ScuadSABSr

PROGRAM besoExacto; uses crt; VAR r1,r2,r3,r4,r44,S,Scuad,dis:real; BEGIN clrscr; writeln('Dame el primer radio: '); readln(r1); writeln('Dame el segundo radio: '); readln(r2); writeln('Dame el tercer radio: '); readln(r3); S:=1/r1+1/r2+1/r3; (*calculo s1+s2+s3*) Scuad:=sqr(1/r1)+sqrt(1/r2)+sqr(1/r3);(*Calculo s1^2+s2^2+s3^2*) (*vamos a resolver la ecuacion de segundo grado*) (*s4^2-2Ss4+S^2-2Scuad=0*) (*esta ecuacion resulta de despejar s4 en la formula*) (*2*(Scuad+s4^2)=(S+s4)^2*) (*que nos ha dado el problema*) dis:=2*Scuad; (*con esto hallamos el discriminante de la ecuacion cuadrada*) (*las soluciones serán r4 y r44*) r4:=2/Abs(S+sqrt(2*Scuad));

Page 22: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

22

r44:=2/Abs(S-sqrt(2*Scuad)); writeln('los radios de las circunferencias tangentes son aprox: ',r4:3:5, ' y ',r44:3:5); readln; END.

• • • Programa 34. Intercambiar los valores de dos variables introducidas por teclado

Program Intercambiovariables; Uses crt; Var x,y, aux:integer; BEGIN clrscr; Write('Introduce un valor entero x: '); readln(x); Write('Introduce otro valor entero y: '); readln(y); (*Intercambio los valores*) aux:=x; x:=y; y:=aux; Writeln(); Writeln('Ahora el valor de x es: ',x,' y el valor de y es: ',y); Readln(); END.

• • • Programa 35. Comparar 22.2 con

Program Comparar;(*Compara la diferencia de 22.2 con para un epsilon dado*)

(* Observemos que aunque 22.2 = , el ordenador toma 2 como un decimal aproximado*) Const epsilon=0.0000001; uses crt; function diferencia(a,b:real):boolean; Begin diferencia:=(a-b<epsilon); End; BEGIN (*Programa principal*) clrscr; writeln ('¿La diferencia es menor que epsilon?',diferencia(sqrt(2)*sqrt(2),2)); readln( ); END. * Considera la siguiente formación triangular de números

1 2 3

4 5 6 7 8 9 10 ………………………..

• • • Programa 36. Número en posición

Page 23: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

23

Escribe un programa que calcule el número que aparece en la posición c de la fila f ( f>=1 y ¿qué condición debe cumplir c?

Program Numero_en_Posicion; Uses crt; Var f,c:integer; N:real; BEGIN (*observemos que dada una fila f, el número c de columnas de esa fila es f*) (*Por tanto el número de columna no puede exceder al nº de fila*) clrscr; write('Introduce la fila f >=1: '); readln(f); write('Introduce la columna c con 1<=c<=',f,': '); readln(c); IF c>f THEN Begin writeln('La columna ',c,' es mayor que la fila ',f); writeln('vuelve a ejecutar el programa'); end ELSE Begin N:=((f-1)*f)/2+c; writeln('El número correspondiente a la fila ',f,' y a la columna ',c,' es: ',N:2:1); End; Readln(); END.

• • • Programa 37. Fila de un número

Escribe un programa que calcule la fila que ocupa un número N Program Fila_Numero; Uses crt; Var f,N:integer; aux:real; BEGIN (*obsevemos que dada una fila f, el n£mero c de columnas de esa fila es f*) clrscr; write('Introduce un numero natural N: '); readln(N); aux:=1+sqrt(1+8*N)/2; f:=Trunc(aux)-1; writeln('La fila correspondiente al numero ',N,' es: ',f); readln(); END.

• • • Programa 38. ¿Están en la misma fila?

Escribe un programa que decida si dos números N y M están en la misma fila. Program Misma_Fila; Uses crt; Var f1,f2,N,M:integer; aux1,aux2:real; BEGIN clrscr; write('Introduce un numero natural N: ');

Page 24: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

24

readln(N); write('Introduce un numero natural M: '); readln(M); aux1:=1+sqrt(1+8*N)/2; aux2:=1+sqrt(1+8*M)/2; f1:=Trunc(aux1)-1; f2:=Trunc(aux2)-1; IF f1=f2 THEN writeln('Los numeros ',N,' y ',M,' estan en la misma fila') ELSE writeln('Los numeros ',N,' y ',M,' no estan en la misma fila'); readln(); END.

• • • Programa 39. ¿Están en la misma diagonal?

Escribe un programa que decida si dos números N y M están en la misma diagonal Program MismaDiagonal; Uses crt; Var f1,f2,c1,c2,N,M,resto1,resto2:integer; aux1,aux2:real; BEGIN clrscr; write('Introduce un numero natural N: '); readln(N); write('Introduce un numero natural M: '); readln(M); aux1:=1+sqrt(1+8*N)/2; aux2:=1+sqrt(1+8*M)/2; f1:=Trunc(aux1)-1; f2:=Trunc(aux2)-1; IF f1=f2 THEN writeln('Los numeros ',N,' y ',M,' no están en la misma diagonal') ELSE Begin resto1:=f1 mod 2; resto2:=f2 mod 2; If (resto1<>0) and (resto2<>0) then Begin c1:=N mod f1; c2:=M mod f2; if c1=0 then c1:=f1; if c2=0 then c2:=f2; end; If (resto1<>0) and (resto2=0) then Begin c1:=N mod f1; if c1=0 then c1:=f1; c2:=(M mod f2+ (f2 div 2))mod f2; if c2=0 then c2:=f2; End; If (resto1=0) and (resto2<>0) then Begin c2:=M mod f2;

Page 25: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

25

if c2=0 then c2:=f2; c1:=(N mod f1+ (f1 div 2))mod f1; if c1=0 then c1:=f1; End; If (resto1=0) and (resto2=0) then Begin c2:=(N mod f1+ (f1 div 2))mod f1; c2:=(M mod f2+ (f2 div 2))mod f2; if c2=0 then c2:=f2; if c1=0 then c1:=f1; End; End; IF (abs(c1-c2)=abs(f1-f2)) or (c1=c2) THEN writeln('Los numeros estan en la misma diagonal') ELSE writeln('Los numeros no estan en la misma diagonal'); readln(); END.

• • • Programa 40. Hallar el mayor de cuatro números Program MayorCuatro; Uses crt; Var a,b,c,d,m,n,mayor:integer; BEGIN clrscr; Write('Introduce cuatro enteros dejando un espacio entre ellos: '); Readln(a,b,c,d); IF a>b THEN m:=a ELSE m:=b; IF c>d THEN n:=c ELSE n:=d; IF m>n THEN mayor:=m ELSE mayor:=n; Writeln('El mayor es: ', mayor); Readln(); END.

• • • Programa 41. Cuadrante de un punto Escribe un programa que determine en qué cuadrante del plano está un punto P(x,y) cuyas coordenadas se len por teclado. Program Cuadrante; Uses crt; Var x,y:integer; BEGIN clrscr; Write('Introduce las coordenadas del punto P(x,y) dejando un espacio entre ellos: '); Readln(x,y); IF x>0 THEN If y>=0 Then Writeln('Está en cuadrante I')

Page 26: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

26

Else Writeln('Está en cuadrante IV') ELSE If y>=0 Then Writeln('Está en cuadrante II') Else Writeln('Está en cuadrante III'); IF (x=0) or (y=0) THEN writeln('Está en alguno de los ejes coordenados'); Readln(); END.

• • • Programa 42. ¿Es un rectángulo? Teniendo en cuenta que un rectángulo se puede representar en un plano a partir de cuatro puntos, escribe un programa que determine si dados cuatro puntos del plano, éstos determinan un rectángulo.

Pista1.- La distancia entre los puntos P(x1,y1) y Q(x2,y2) es d= 221

221 )()( yyxx −+−

Pista2.- Recuerda que en un rectángulo, los lados deben ser de igual longitud dos a dos y también ambas diagonales deben ser de la misma longitud. La ejecución del programa mostrará la salida siguiente:

Program EsRectangulo; Uses crt; Var x1,y1,x2,y2,x3,y3,x4,y4:integer; Function cuadrado(a:real):real; Begin cuadrado:=a*a; End; Function distancia(a,b,c,d:real):real; Begin distancia:=sqrt(cuadrado(a-c)+cuadrado(b-d)); End; BEGIN clrscr; Writeln('Los puntos se introducen de forma consecutiva'); writeln; Write('Introduce las coordenadas del punto A(x1,y1) dejando un espacio entre ellos: '); Readln(x1,y1); Write('Introduce las coordenadas del punto B(x2,y2) dejando un espacio entre ellos: '); Readln(x2,y2); Write('Introduce las coordenadas del punto C(x3,y3) dejando un espacio entre ellos: '); Readln(x3,y3); Write('Introduce las coordenadas del punto D(x4,y4) dejando un espacio entre ellos: ');

Page 27: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

27

Readln(x4,y4); IF distancia(x1,y1,x2,y2)=distancia(x3,y3,x4,y4) THEN IF distancia(x1,y1,x4,y4)=distancia(x2,y2,x3,y3) THEN IF distancia(x1,y1,x3,y3)=distancia(x2,y2,x4,y4) THEN Writeln('Se trata de un rectangulo') ELSE Writeln('No se trata de un rectangulo') ELSE Writeln('No se trata de un rectangulo') ELSE Writeln('No se trata de un rectangulo'); Readln(); END.

• • • Programa 43. Conversión Mayúscula-minúscula y recíprocamente Al trabajar con caracteres se pueden usar dos funciones predefinidas en Pascal que ya hemos mencionado con anterioridad: se trata de las funciones ORD(x) que devuelve el ordinal que corresponde al carácter x y la función CHR(x) que devuelve el carácter correspondiente al ordinal x. Los ordinales de las letras del alfabeto son consecutivos, esto es: ‘a’---- n (natural) ‘A’---- k (natural) ‘b’---- n+1 ‘B’---- k+1 ………………. …………………. ‘z’----- n+26 ‘Z’---- k+26 Observa que n+26 y k no tienen por qué ser consecutivos. Así, dado un carácter c en Minúscula, para hallar el carácter c en Mayúscula se calcula su ordinal ORD(c) y se le resta ORD(‘a’). Con esto sabemos qué lugar en el orden consecutivo de minúsculas corresponde al carácter c. Por último basta sumar a la resta anterior ORD(‘A’) y aplicar al resultado la función CHR para obtener el carácter c en mayúsculas:

Chr( Ord(c)-Ord(‘a’)+Ord(‘A’) )

De forma análoga pasamos de un carácter dado en Mayúscula a su correspondiente en minúscula Escribe un programa que convierta en mayúscula una letra minúscula leída por el teclado y en minúscula si la letra leída es mayúscula. La ejecución del programa deberá producir la salida siguiente:

Program MinusMayus; Uses crt; Const k= Ord('A'); n= Ord('a');

Page 28: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

28

Var c:char; BEGIN clrscr; Write('Introduce un caracter: '); Readln(c); IF ('a'<=c)and(c<='z') THEN writeln('La conversion a mayuscula y su valor es: ',Chr(k+Ord(c)-n)) ELSE

IF ('A'<=c)and(c<='Z') THEN writeln('La conversion a min£scula y su valor es: ',Chr(Ord(c)-k+n)) ELSE writeln('No es una letra'); Readln(); END.

• • • Programa 44. ¿Es un rectángulo?Halla su centro Se trata de escribir un programa que permita hallar el Centro de un rectángulo dado mediante cuatro puntos del plano. Bastará modificar el programa 42 para hallar el punto medio de cualquiera de sus dos diagonales. Program CentroRectangulo; Uses crt; Var x1,y1,x2,y2,x3,y3,x4,y4:integer; Function cuadrado(a:real):real; Begin cuadrado:=a*a; End; Function distancia(a,b,c,d:real):real; Begin distancia:=sqrt(cuadrado(a-c)+cuadrado(b-d)); End; BEGIN clrscr; Writeln('Los puntos se introducen de forma consecutiva'); writeln; Write('Introduce las coordenadas del punto A(x1,y1) dejando un espacio entre ellos: '); Readln(x1,y1); Write('Introduce las coordenadas del punto B(x2,y2) dejando un espacio entre ellos: '); Readln(x2,y2); Write('Introduce las coordenadas del punto C(x3,y3) dejando un espacio entre ellos: '); Readln(x3,y3); Write('Introduce las coordenadas del punto D(x4,y4) dejando un espacio entre ellos: '); Readln(x4,y4); IF distancia(x1,y1,x2,y2)=distancia(x3,y3,x4,y4) THEN IF distancia(x1,y1,x4,y4)=distancia(x2,y2,x3,y3) THEN IF distancia(x1,y1,x3,y3)=distancia(x2,y2,x4,y4) THEN

Page 29: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

29

Begin (*UNICA MODIFICACION RESPECTO AL PROGRAMA ¨EsRectangulo?*) Writeln('Se trata de un rectangulo'); Writeln('Su punto medio es: ',(x1+x4)/2:5:2 , (y1+y2)/2:5:2); End ELSE Writeln('No se trata de un rectangulo') ELSE Writeln('No se trata de un rectangulo') ELSE Writeln('No se trata de un rectangulo'); Readln(); END.

• • • Programa 45. Rectángulo en Rectángulo Consideremos dos rectángulos R(A; B; C; D) y R (̀A ,̀ B ,̀ C ,̀ D )̀ en la forma que se muestran en la siguiente figura, con diagonales comunes

Vamos a hacer un programa que decida si el segundo rectángulo está contenido en el primero. Para ello, una vez leídos los vértices de cada uno y decidir si se trata de rectángulos, calcularemos su centro común. (Esto está ya resuelto anteriormente). La decisión de si el segundo rectángulo está contenido en el primero la tomaremos en función de la diferencia, en valor absoluto, de la segunda coordenada del centro con cada una de las segundas coordenadas del punto A y A .̀ Utilizaremos la función rectángulo que nos dirá si, dados los cuatro vértices, lo es. Program RectanguloEnRectangulo; Uses crt; Var x1,y1,x2,y2,x3,y3,x4,y4:integer; r1,s1,r2,s2,r3,s3,r4,s4:integer; centro2:real; Function cuadrado(a:real):real; Begin cuadrado:=a*a; End; Function distancia(a,b,c,d:real):real; Begin distancia:=sqrt(cuadrado(a-c)+cuadrado(b-d)); End; Function Esrectangulo(a1,b1,a2,b2,a3,b3,a4,b4:integer):boolean; Begin If distancia(a1,b1,a2,b2)=distancia(a3,b3,a4,b4) Then If distancia(a1,b1,a4,b4)=distancia(a2,b2,a3,b3) Then If distancia(a1,b1,a3,b3)=distancia(a2,b2,a4,b4) Then Esrectangulo:=True Else Writeln('No se trata de un rectangulo') Else Writeln('No se trata de un rectangulo') Else Writeln('No se trata de un rectangulo'); End;

Page 30: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

30

BEGIN clrscr; Writeln('Datos del primer rectangulo'); writeln('---------------------------'); Writeln('Los puntos se introducen de forma consecutiva A, B, C, D'); writeln; Write('Introduce las coordenadas del punto A(x1,y1) dejando un espacio entre ellos: '); Readln(x1,y1); Write('Introduce las coordenadas del punto B(x2,y2) dejando un espacio entre ellos: '); Readln(x2,y2); Write('Introduce las coordenadas del punto C(x3,y3) dejando un espacio entre ellos: '); Readln(x3,y3); Write('Introduce las coordenadas del punto D(x4,y4) dejando un espacio entre ellos: '); Readln(x4,y4); Writeln('Datos del segundo rectangulo'); writeln('----------------------------'); Writeln('Los puntos se introducen de forma consecutiva Aï, Bï, Cï, Dï'); writeln; Write('Introduce las coordenadas del punto A(r1,s1) dejando un espacio entre ellos: '); Readln(r1,s1); Write('Introduce las coordenadas del punto B(r2,s2) dejando un espacio entre ellos: '); Readln(r2,s2); Write('Introduce las coordenadas del punto C(r3,s3) dejando un espacio entre ellos: '); Readln(r3,s3); Write('Introduce las coordenadas del punto D(r4,s4) dejando un espacio entre ellos: '); Readln(r4,s4); IF (Esrectangulo(x1,y1,x2,y2,x3,y3,x4,y4)) AND (Esrectangulo(r1,s1,r2,s2,r3,s3,r4,s4)) THEN If ((x1+x4)/2=(r1+r4)/2) And ((y1+y2)/2=(s1+s2)/2) Then Begin centro2:=(y1+y2)/2; If (Abs(centro2-y1))>(Abs(centro2-s1)) Then writeln('El segundo rectangulo esta contenido en el primero') Else writeln('El segundo rectangulo no esta contenido en el primero'); End Else writeln('Los rectangulos no estan en posicion de la figura considerada') ELSE writeln('Alguno de los puntos dados no determinan rectangulo'); Readln(); END.

5. Sentencia CASE Aunque no tan general como la sentencia IF permite seleccionar entre distintas opciones utilizando una variable selectora. La sintaxis general es: CASE selector OF valor 1: sentencia 1; valor 2, valor 3, valor 4: sentencia 2; valor5: sentencia 3; …. valor n: sentencia n;

Page 31: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

31

(ELSE sentencia n+1(*opcional*) END; El selector no puede ser de tipo real o string.

• • Programa 46. Caracteres Escribe, utilizando la sentencia CASE, un programa que decida si un carácter leído por teclado es un número, una letra minúscula, mayúscula o un carácter especial. Program letras; Var caracter: char; BEGIN Write(‘Pulsa una tecla’); Readln(carácter); CASE carácter OF ‘0’..’9’ : writeln(‘cifra’); ‘a’..’z’ : writeln(‘letra minuscula’); ‘A’..’Z’: writeln(‘letra mayuscula’); ELSE writeln(‘carácter especial); END; END. 6. Sentencias repetitivas La estructura iterativa o bucle es una estructura de control básica de la Programación Estructurada. Este tipo de estructuras permiten ejecutar una misma sentencia (o bloque de sentencias) un cierto número de veces. Pascal dispone de tres sentencias diferentes que permiten implementar bucles: la sentencia WHILE, la sentencia FOR y la sentencia REPEAT-UNTIL. Se diferencian principalmente en el número de iteraciones que realizan y en cuándo y cómo es evaluada la expresión lógica que determina el momento de la finalización del bucle. 6.1 El bucle WHILE Al utilizar esta estructura de control, no se conoce de antemano el número de repeticiones, o iteraciones, que deben ejecutarse. Por tanto, el cuerpo del bucle se repite mientras se cumpla una determinada condición (booleana). Cuando se utiliza un bucle de este tipo el programador debe asegurarse que la expresión se hará falsa en algún momento. La sintaxis de un bucle WHILE es: WHILE expresión DO BEGIN sentencia 1; sentencia 2; ………….. sentencia n; END; Debe tenerse en cuenta que la expresión se evalúa al principio y, si es verdadera, se ejecuta el cuerpo del bucle (sentencias) volviendo a evaluarse la expresión; si la expresión es falsa se salta el cuerpo del bucle y se continúa con la ejecución del programa.

• • Programa 47. Listado de números hasta el cien

Page 32: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

32

Escribe un programa que escriba en pantalla los 100 primeros naturales, siete por línea.

Program listadocien; uses crt; var cont:integer; BEGIN clrscr; cont:=1; while cont<=100 do begin write(cont,' '); if cont mod 7=0 then writeln(); cont:=cont+1; end; readln(); End.

• • Programa 48. Listado hasta un n dado Modifica el programa anterior para que liste los n primeros naturales, siete por línea. La ejecución debe mostrar la pantalla siguiente:

Program listadoN; uses crt; var cont,n:integer; BEGIN clrscr; write('introduce un numero natural: '); readln(n); cont:=1; while cont<=n do begin write(cont,' '); if cont mod 7=0 then writeln(); cont:=cont+1; end; readln(); End.

• • • Programa 49. Factorial de un número Escribe un programa que calcule el factorial de un número entero positivo.

( Recuerda n!=n.(n-1).(n-2)…….3.2.1); (0!=1); (1!=1)

Page 33: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

33

Program factorial ; uses crt; var n1,n,f:integer; BEGIN clrscr; write('introduce un numero natural positivo: '); readln(n); writeln(); while n<0 do (*esto solo valida el número introducido*) begin write('introduce un numero natural positivo: '); readln(n); end; n1:=n ; f:=1; while n>1 do begin f:=f*n; n:=n-1; end; writeln('el factorial de ',n1, ' es: ',f); readln(); End.

• • • Programa 50. Número de cifras de un número Escribe un programa que determine el número de cifras de un entero introducido por teclado. Program numeroCifras; uses crt; var n1, n,ncifras:integer; BEGIN clrscr; write('introduce un numero entero: '); readln(n); n1:=n; if n<0 then n:=-n; ncifras:=0; while n>0 do begin ncifras:=ncifras+1; n:=n div 10; end; writeln('el numero de cifras de ',n1, ' es: ',ncifras); readln(); End.

• • • Programa 51. ¿Es primo?

Page 34: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

34

Escribe un programa que determine si un número natural es o no primo. Program primo; uses crt; var n,raiz,i:integer; esprimo:boolean; x:real; BEGIN clrscr; write('introduce un numero natural positivo: '); readln(n); while n<0 do begin write('introduce un numero natural positivo: '); readln(n); end; x:=sqrt(n); raiz:=round (x); esprimo:=TRUE; i:=2; while esprimo and (i<=raiz) do begin if n mod i=0 then esprimo:=FALSE else i:=i+1; end; writeln('¨es primo?:',esprimo); readln(); End.

• • • Programa 52. Rotación Imaginemos las letras del alfabeto ordenadas y dispuestas en círculo, esto es, a la derecha de la A, la B, luego la C y así sucesivamente; a la derecha de la Z, la B nuevamente. Definimos una rotación de longitud n como aquella que lleva a una determinada letra n posiciones a su derecha. Escribe un programa que permita calcular una rotación n arbitraria. El valor n y la letra inicial son leídos por el programa. La ejecución mostrará la pantalla siguiente:

Program rotacion; uses crt; const k=ord('A'); r=ord('Z'); var letra,letraresultado:char; n,y:integer; BEGIN clrscr; write('introduce una letra mayuscula: '); readln(letra);

Page 35: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

35

write('introduce la longitud de la rotacion: '); readln(n); y:=ord(letra); (*Este programa se podría hacer usando una única instrucción:*) (* siguiente:= CHR(inicio+(ORD(letra)-ORD(‘A’)+n) mod (ORD(‘Z’)-ORD(‘A’)+1) *) if y+n<=r then begin letraresultado:=chr((y+n)mod(r+1)); writeln('la nueva letra es: ', letraresultado); end else letraresultado:=chr(k+y+n-1); readln(); END.

• • • Programa 53. Sistema 2x2

Escribe un programa que decida si un sistema de dos ecuaciones con dos incógnitas es compatible determinado, compatible indeterminado o incompatible.

���

=+=+

222

111

cybxa

cybxa

• • Programa 54. Suma de naturales

Escribe un programa que calcule la suma de los n primeros números naturales. El número n se introduce por teclado. La salida del programa será de la forma siguiente:

Program sumaNaturales; uses crt; var n,Suma,cont:integer; BEGIN clrscr; write('Introduce un natural: '); readln(n); Suma:=0; cont:=1; WHILE cont<=n DO Begin Suma:=Suma+cont; cont:=cont+1; End; writeln(); writeln('La suma de los ',n,' primeros numeros naturales es: ',Suma); Readln(); END.

• • Programa 55. Suma de naturales pares Modifica el programa anterior para que sume los n primeros números pares

Page 36: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

36

Program sumaNaturalesPares; uses crt; var n,Suma,i,cont:integer; BEGIN clrscr; write('Introduce un natural: '); readln(n); Suma:=0; cont:=2; i:=1; WHILE i<=n DO Begin Suma:=Suma+cont; cont:=cont+2; i:=i+1; End; writeln(); writeln('La suma de los ',n,' primeros numeros naturales pares es: ',Suma); Readln(); END.

• • • Programa 56. N primeros primos Escribe un programa que escriba en pantalla los n primeros números primos donde n se lee por teclado. La salida será:

Program Nprimos; uses crt; var m,cont,num:integer; Function primo(n:integer):boolean; Var x:real; i,raiz:integer; esprimo:boolean; Begin x:=sqrt(n); raiz:=round (x); esprimo:=TRUE; i:=2; while esprimo and (i<=raiz) do begin if n mod i=0 then esprimo:=FALSE else i:=i+1; end;

Page 37: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

37

primo:=esprimo; End; BEGIN (*Programa principal*) clrscr; write('¿Cuántos números primos quieres escribir?: '); readln(m); while m<0 do begin write(' ¿Cuántos números primos quieres escribir?: '); readln(m); end; writeln(); cont:=1; num:=2; WHILE cont<=m DO Begin If primo(num) Then

Begin cont:=cont+1; Write(num,', '); End; num:=num+1; End; readln(); END.

• • • Programa 57. Suma N primeros primos Modifica el programa anterior para que además calcule la suma de los N primeros primos. La salida será:

• • Programa 58. Tabla de multiplicar Escribe un programa que imprima la tabla de multiplicar del número que se lee como dato.

• • Programa 59. Controlar pH Escribe un programa que ayude a controlar el pH de una piscina. El pH sólo puede tener valores entre 0 y 14, ambos inclusive.. En caso de que el valor esté fuera de dicho rango se mostrará un mensaje de error. Si el pH es mayor que 7 se mostrará el mensaje”pH básico, echar ácido clorhídrico”. Si el pH es menor que 7 se mostrará el mensaje”pH ácido, echar cloro”. Si el pH es 7 se mostrará el mensaje “ pH correcto”. El programa leerá como dato el pH.

Page 38: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

38

• • Programa 60. Hora correcta Escribe un programa que lea una hora como hh mm ss y diga si es correcta. Por ejemplo, no es correcta la hora 28 12 32 y sí lo es 5 0 34.

• • Programa 61. Triángulo de Floyd Escribe un programa que lea un número y escriba el triángulo de Floyd con tantas líneas como indique el número leído. Por ejemplo, para el número 5 el resultado en pantalla sería:

Program TrianguloFloyd; uses crt; var n,i,j,cont:integer; BEGIN clrscr; write('Introduce un natural: '); readln(n); writeln(); i:=1; cont:=1; WHILE i<=n DO Begin j:=1; While (j<=i) do Begin write(cont,' '); cont:=cont+1; j:=j+1; End; i:=i+1; writeln(); End; readln(); END.

• • • Programa 62. Volcán Escribe un programa que dibuje en pantalla la siguiente figura compuesta por líneas de 2, 4, 8, 16, y 64 asteriscos respectivamente:

Program Volcan; uses crt;

Page 39: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

39

Var n,c,i,j,Pot:integer; BEGIN clrscr; write(‘¿cuántas líneas quieres mostrar:? '); readln(n); i:=1; writeln; WHILE i<=n DO BEGIN c:=1; j:=1; Pot:=1; while j<=i do (*Este bucle calcula la potencia 2i *) Begin Pot:=2*Pot; j:=j+1; End; while c<=Pot do (*Este bucle escribe tantos asteriscos como valga 2i *) Begin write(' * '); c:=c+1; End; writeln(); i:=i+1; END; readln(); END.

• • • Programa 63. Mosaico Escribe un programa que dibuje en pantalla el mosaico siguiente:

Program Mosaico; uses crt; Var n,i,j,c:integer; BEGIN clrscr; i:=1; WHILE i<=10 DO Begin j:=1; while j<=10 do Begin If ((i+j)mod 2=0) Then write(' - ') Else write(' * '); j:=j+1; End; i:=i+1;

Page 40: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

40

writeln; End; readln(); END.

• • • Programa 64. Mosaico2 Modifica el programa anterior para perita escribir un mosaico de n filas y m columnas donde n y m se introducen por teclado:

Program Mosaico2; uses crt; Var n,m,i,j:integer; BEGIN clrscr; write('Introduce el numero de filas: '); readln(n); write('Introduce el numero de columnas: '); readln(m); writeln; i:=1; WHILE i<=m DO Begin j:=1; while j<=n do Begin If ((i+j)mod 2=0) Then write(' - ') Else write(' * '); j:=j+1; End; i:=i+1; writeln; End; readln(); END. 6.2 El bucle FOR A diferencia del bucle WHILE, el bucle FOR ejecuta un número de veces fijo un conjunto de sentencias. En este tipo de bucle, el cuerpo del bucle se ejecuta para todos los valores de un rango especificado. La sintaxis de un bucle FOR es: FOR variable_control:=expresión_inicial TO expresión_final DO BEGIN sentencia 1;

Page 41: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

41

sentencia 2; ………….. sentencia n; END; o también FOR variable_control:=expresión_inicial DOWNTO expresión_final DO BEGIN sentencia 1; sentencia 2; ………….. sentencia n; END; La variable de control, la expresión inicial y la expresión final deben ser del mismo tipo. Ambas expresiones se evalúan una única vez y representan el límite inferior y el límite superior que determinan el rango de valores que se asignarán a la variable de control. En el FOR TO DO la variable de control toma como valor inicial expresión_inicial y se incrementa en una unidad en cada ejecución del cuerpo hasta alcanzar el valor de expresión_final y en el tipo FOR DOWNTO DO la variable de control disminuye en una unidad. Importante: La variable de control no puede modificarse en el cuerpo del bucle FOR.

• • Programa 65. Suma N números Escribe un programa, utilizando el bucle FOR que sume los N primeros números impares donde N se lee por teclado.

• • Programa 66. Números decrecientes Escribe un programa que escriba en pantalla los N primeros números naturales en orden decreciente, 10 por línea donde N se lee por teclado.

• • Programa 67. Tabla de multiplicar Escribe un programa que escriba en pantalla la tabla de multiplicar de un número natural N leído por teclado.

• • • Programa 68. Factorial de un número Escribe un programa que calcule el factorial de un natural N utilizando un bucle FOR. La salida en pantalla será la siguiente:

Program FACTORIALfor; uses crt; Var N,i, Fact:integer; BEGIN clrscr; write('Introduce un numero natural N: ');

Page 42: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

42

readln(N); Fact:=1; FOR i:=1 TO n DO Fact:=Fact*i; writeln; writeln('El factorial de ',N,' es ',N,'!= ',Fact); readln(); END.

• • • Programa 69. Ecuación Diofántica Se llama ecuación diofántica a cualquier ecuación algebraica, generalmente de varias variables, planteada sobre el conjunto de los números enteros o los números naturales. Escribe un programa que calcule las soluciones naturales de la ecuación diofántica x+y=n y presente la salida siguiente en pantalla:

Program ECUACIONdiofantica; uses crt; Var N,i,j:integer; BEGIN clrscr; write('Introduce un numero natural N: '); readln(N); writeln; writeln('Las soluciones de la ecuaci¢n diofantica x + y = ',N,' son los pares:'); writeln; FOR i:=1 TO N DO FOR j:=i TO N DO If i+j=N Then Begin writeln('x= ',i,' ; y= ',j); writeln; End; readln(); END.

• • • Programa 70. Suma Marciana Escribe un programa que encuentre las posible cifras t, d, p, c que cumplen la suma

t d p t c

--------------- d p t

y produzca la salida siguiente:

Page 43: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

43

Program sumaMARCIANA; uses crt; Var i,j,k,r:integer; BEGIN clrscr; writeln; writeln('Las soluciones son: '); writeln; FOR i:=1 TO 9 DO FOR j:=1 TO 9 DO FOR k:=1 TO 9 DO FOR r:=1 TO 9 DO If i*100+j*10+k+10*i+r=j*100+k*10+i Then Begin writeln('t= ',i,'; d= ',j,'; p= ',k,'; c= ',r); writeln; End; readln(); END.

• • • Programa 71. El problema del marinero Tenemos una pasarela 3x6, rodeada de agua, en la que se mueve un marinero, señalado con x, con movimientos 0: arriba; 1: adelante y 2: abajo.

x

El marinero se mueve según una función aleatoria que genera un 0, 1 ó 2. Escribe un programa que muestre ese movimiento y responda si ha caído al agua o ha llegado al final de la pasarela, señalada en sombra. Program Marinero; uses crt; Function MovAleatorio():integer; Begin MovAleatorio:=random(3); End; Procedure PintarPasarela(a,b,l,m:integer); Var i,j:integer; Begin For j:=0 to m do

Page 44: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

44

Begin For i:=0 to (l-1) do if(i=a)and(j=b) then write('x') else write('-'); writeln; End; End; VAR x,y,movimiento:integer; BEGIN (*programa principal*) clrscr; x:=0; y:=1; PintarPasarela(x,y,5,2); Writeln('Pulsa una tecla'); readln(); randomize(); WHILE (x<5) and (y<=2) and (y>=0) DO Begin movimiento:=MovAleatorio(); if movimiento=0 then y:=y-1; if movimiento=1 then x:=x+1; if movimiento=2 then y:=y+1; Writeln(); PintarPasarela(x,y,5,2); writeln; If(x=5) then Writeln('Ha llegado a su destino'); if(y<0) or (y>2) then writeln('Se ha caido al agua'); Writeln('Pulsa una tecla'); readln(); End; END.

• • • Programa 72. Actividad adecuada Escribe un programa que, dada una temperatura, indique la actividad más adecuada para dicha temperatura teniendo en cuenta los criterios siguientes:

ACTIVIDAD TEMPERATURA IDÓNEA Natación temp>30

Tenis 20<temp<=30 Golf 10<temp<=20 Esquí 5<temp<=10 Parchís temp<=5

Program ActividadAdecuada; uses crt; Var temp:real; actividad:string; BEGIN clrscr; write('Introduce la temperatura ambiental: '); readln(temp); If temp>30 then actividad:='Natacion'

Page 45: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

45

Else If temp>20 then actividad:='Tenis' Else If temp>10 then actividad:='Golf' Else If temp>5 then actividad:='Esqui' Else actividad:='Parchis'; Writeln('La actividad adecuada es ',actividad); readln(); END.

• • • Programa 73. Operaciones Aritméticas Escribe un programa que nos permita introducir dos números naturales y una operación (suma, resta, multiplicación o división) y calcule el resultado de dicha operación, presentándolo en pantalla en el siguiente formato:

Program OperacionesDIVERSAS; uses crt; Var num1,num2,resultado:integer; operacion:char; BEGIN clrscr; write('Introduce el primer numero: '); readln(num1); write('Introduce el segundo numero: '); readln(num2); write('Introduce la operacion (+, -, *, /): '); readln(operacion); CASE operacion OF '+': resultado:=num1+num2; '-': resultado:=num1-num2; '*': resultado:=num1*num2; '/': resultado:=num1 div num2; end; If operacion<>'/' then Begin writeln(num1:15); writeln(operacion:3,num2:12); writeln('------':16); writeln(resultado:15); End Else Begin writeln(num1:15,' | ',num2:6); writeln('------':24); writeln(num1 mod num2:15,' ',resultado:6); end;

Page 46: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

46

readln(); END.

• • • Programa 74. Número de cifras en una base Escribe un programa que determine cuántas cifras tiene un número n si lo expresamos en una cierta base 2. Program NumeroCIFRAS; uses crt; Const BASE=2; Var n,m,cont:integer; BEGIN clrscr; write('Introduce una cantidad en base 10: '); readln(n); m:=abs(n); cont:=1; writeln; WHILE m>=BASE DO Begin m:=m div BASE; cont:=cont+1; End; write('El numero de cifras de la cantidad ',n); write(' expresada en base ',BASE,' es ',cont); readln(); END.

• • • Programa 75. Primo siguiente Escribe un programa que lea un entero num y calcule el menor primo mayor o igual que num. Se trata de modificar el programa que determinaba si un entero era o no primo.

Program SiguientePRIMO; uses crt; Var aux,num:integer; Function primo(n:integer):boolean; Var x:real; i,raiz:integer; esprimo:boolean; Begin x:=sqrt(n); raiz:=round (x); esprimo:=TRUE; i:=2; while esprimo and (i<=raiz) do begin if n mod i=0 then esprimo:=FALSE else i:=i+1;

Page 47: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

47

end; primo:=esprimo; End; BEGIN (*Programa principal*) clrscr; write('Intoduce un entero: '); readln(num); aux:=num; WHILE not(primo(aux)) DO aux:=aux+1; writeln('El menor primo menor o igual que ',num,' es ',aux); readln(); END.

• • • Programa 76. Fracción irreducible Escribe un programa que obtenga la fracción irreducible de una dada. Observa que para ello basta dividir numerado y denominador por el máximo común divisor de ambos.

Program FraccionIRREDUCIBLE; uses crt; Function MCD(n,m:integer):integer; Var menor,cont:integer; maxcomdiv:boolean; Begin If n mod m=0 then MCD:=m Else If m mod n=0 then MCD:=n Else Begin if n<m then menor:=n else menor:=m; cont:=menor div 2; maxcomdiv:=True; WHILE (cont>=1) and maxcomdiv DO Begin If (n mod cont=0)and(m mod cont=0) Then Begin MCD:=cont; maxcomdiv:=false; End Else cont:=cont-1; End; End; End;

Page 48: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

48

VAR numerador,denominador:integer; divisorcomun:integer; numirreducible,denirreducible:integer; BEGIN (*Programa Principal*) clrscr; write('Introduce el numerador de la fraccion: '); readln(numerador); write('Introduce el denominador de la fraccion: '); readln(denominador); divisorcomun:=MCD(numerador,denominador); numirreducible:=numerador div divisorcomun; denirreducible:=denominador div divisorcomun; writeln; writeln('La fraccion irreducible es:'); writeln(numirreducible:10); writeln('----':12); writeln(denirreducible:10); readln(); END. 6.3 El bucle REPEAT-UNTIL La diferencia con los bucles anteriores es que la condición se evalúa al final del bucle, lo cual implica que el cuerpo se ejecute, al menos, una vez. No necesita incluir las palabras reservadas BEGIN y END. La sintaxis de un bucle REPEAT-UNTIL es: REPEAT sentencia 1; sentencia 2; ………….. sentencia n; UNTIL expresión_lógica;

• • Programa 77. Factorial Escribe un programa que calcule el factorial de un número utilizando un bucle Repeat-Until-. 7. Tipos estructurados en Pascal Un tipo estructurado es aquel que permite crear colecciones de datos de un mismo tipo(como los arrays o los archivos) o de diferentes tipos(como los registros), t manipularlos como si se tratase de una única estructura.

Page 49: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

49

������

������

���

���

���

Puntero

File

cord

Set

String

Array

doEstructura

realordinalNo

subrangoenumeradocharbooleanegerOrdinalSimple

TIPO

Re

:.,,,,int:

7.1 El Tipo Array Un array es una lista o conjunto de elementos que tiene las siguientes características:

- Dispone de un primer elemento y un último elemento. - Tiene un único identificador o nombre que representa a todos los elementos. - Todos los elementos son de un mismo tipo. - Puede accederse a cada uno de los elementos de la lista a través de un identificador

único, o nombre y una variable denominada índice. - Un array es una estructura de datos estática; por la tanto, cuando se define, la cantidad

de memoria necesaria debe ser calculada en tiempo de compilación y reservada en memoria principal.

Los elementos de un array están almacenados en posiciones contiguas de la memoria y se puede acceder de forma directa o aleatoria a cualquiera de sus elementos. Por ejemplo, para almacenar las notas finales de informática de 25 alumnos se puede utilizar un array de tamaño 40 datos de tipo real: En cada casilla i-ésima figura la nota del alumno número i. Así, si el array se llama Notas, accederemos a la casilla i-ésima con Notas[i] . La sintaxis para declarar un array es: Identificador= ARRAY [Tipo_indice] OF TipoBase Tipoindice se utiliza para recorrer los elementos del array. El tipo de datos utilizado para este índice ha de ser ordinal. TipoBase indica el tipo concreto al que pertenecen los elementos almacenados en el array. Normalmente a este tipo de arrays se les llama unidimensional, listas o vectores. Es posible utilizar delante de la palabra ARRAY la palabra reservada PACKED. Esto permite construir arrays empaquetados ( o PACKED ARRAY ) de caracteres. Este tipo de arrays se utiliza para optimizar la cantidad de memoria ocupada. Un array puede definirse en la sección de declaración de tipos o en la sección de declaración de variables. Para definir un array de dos dimensiones utilizaremos declaraciones del tipo

A: ARRAY[1..10][1..3]; TYPE Lista= ARRAY [1..100] OF real;

Page 50: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

50

VAR Precios: Lista; Notas: ARRAY [1..100] OF integer; Ejemplo Si tenemos declarado un array L:ARRAY[1..10] OF integer; Son válidas las asignaciones siguientes: L[1]:=3; L[2]:=14; L[1]:=L[1]+L[2]; L[5]:=3+5;

• • • Programa 78. Máximo de un Array Escribe un programa que lea, por teclado, los datos enteros de un array de longitud 8 y calcule el valor máximo introducido.

Program MaximoARRAY; uses crt; CONST L=8; VAR A:Array[1..L] of integer; i,max:integer; BEGIN clrscr; For i:=1 to L do (*Con esto leemos los datos*) Begin write('Introduce el dato de posici¢n ',i,': '); readln(A[i]); End; max:=A[1]; For i:=2 to L do if A[i]>max then max:=A[i]; writeln('El valor maximo de los datos introducidos es: ',max); readln(); END.

• • • Programa 79. Array Aleatorio. Escritura directa y vuelta. Escribe un programa que genere con números aleatorios del 0 al 11 un array de longitud 10, lo escriba después en el orden en que se han generado y, por último intercambie los datos, del primero al último y vuelva a escribir el array. Program Aleatorio; uses crt; CONST L=10; VAR A:Array[1..L] of integer; i,aux,m:integer; BEGIN clrscr;

Page 51: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

51

randomize; For i:=1 to L do (* Aqui leemos los datos *) A[i]:=random(10); For i:=1 to L do (* Aqui escribimos los datos *) write(A[i],' '); writeln; m:=L div 2; For i:=1 to m do (* Aqui intercambiamos las posiciones *) Begin aux:=A[i]; A[i]:=A[L-i+1]; A[L-i+1]:=aux; End; For i:=1 to L do (* Aqui escribimos los datos *) write(A[i],' '); readln(); END.

• • • Programa 80. Números como caracteres. Escribe un programa que lea en un array de longitud L dada, una serie de números como caracteres y forme a partir de ellos el número que forman. Ejemplo: ‘2’, ‘5’, ‘8’, ‘3’----------- 2583 Program NumerosCARACTERES; uses crt; CONST L=5; VAR A:Array[1..L] of char; i,numero:integer; BEGIN clrscr; For i:=1 to L do (* Aqui leemos los datos *) Begin write('Introduce el caracter numerico ',i,' '); readln(A[i]); End; numero:=0; i:=1; (* Ahora formamos el numero *) WHILE (i<=L) and Not(ord(A[i])=0) DO Begin numero:=numero*10+ord(A[i])-ord('0'); i:=i+1; End; writeln; writeln('El numero formado es: ',numero); readln(); END.

• • • Programa 81. Adivinación. Consideremos el siguiente juego entre los jugadores A (adivino) y P (pensador): P piensa un número comprendido entre 1 y N(digamos 1000, por ejemplo), y A trata de adivinarlo mediante tanteos sucesivos, hasta dar con él. Por cada tanteo de A, P da una respuesta orientativa de entre las siguientes:

Page 52: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

52

Fallaste. El número pensado es menor que el tuyo. Fallaste. El número pensado es mayor. Acertaste al fin.

Naturalmente, caben diferentes estrategias para el adivino: - Una posibilidad, si el adivino no tiene prisa en acabar, consiste en tantear números

sucesivamente: primero el 1, después el 2, etc, hasta acertar. - Otra estrategia, sin duda la más astuta, consiste en tantear el número central de los

posibles de modo que, al fallar, se limiten las posibilidades a la mitad (por eso se llama bipartición a este modo de proceder).

- También es posible jugar caprichosamente, tanteando un número al azar entre los posibles. Al igual que la anterior, esta estrategia también reduce el intervalo de posibilidades sensiblemente.

Se plantea desarrollar tres programas independientes: uno deberá desempeñar el papel del pensador, otro el del adivino (usando la estrategia de bipartición), y un tercero deberá efectuar la simulación del juego, asumiendo ambos papeles (y donde el adivino efectúa los tanteos a capricho). Program AdivinacionBIPARTICION; uses crt; CONST N=1000; VAR numeroazar,mitad,mitad1,mitad2:integer; BEGIN clrscr; randomize; numeroazar:=random(1001); writeln('El pensador acaba de pensar un n£mero entre 1 y ',N); writeln; mitad:=round(N div 2); (* Aqui se busca la mitad de los posibles *) writeln('El Adivino dice que es el ',mitad); mitad2:=N; mitad1:=0; WHILE mitad<>numeroazar DO Begin If mitad<numeroazar Then Begin writeln('El adivino dice que es el ',mitad); writeln('El pensador dice: Fallaste, el numero es mayor. PULSA TECLA'); readln(); mitad1:=mitad; mitad:=mitad1+round((mitad2-mitad1)div 2); End; If mitad>numeroazar Then Begin writeln('El adivino dice que es el ',mitad); writeln('El pensador dice: Fallaste, el numero es menor. PULSA TECLA'); readln(); mitad2:=mitad; mitad:=mitad1+round((mitad2-mitad1) div 2); End; End; writeln('El adivino dice que es el ',mitad); Writeln('!ACERTASTE-, el numero era el, ',mitad); readln(); END.

Page 53: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

53

• • • Programa 82. Mínimo de cuatro números Escribe un programa que calcule el mínimo de cuatro números utilizando únicamente tres comparaciones Program minimoDEcuatroNUMEROS; VAR n1,n2,n3,n4,min: real; BEGIN Readln(n1,n2,n3,n4);ç If n1>n2 then n1:=n2; If n3>n4 then n3:=n4; If n1>n3 then min:=n3; Else min:=n1; Writeln(‘El mínimo es: ‘,min:8:2); END.

• • • Programa 83. ¿Me puede decir la hora? Escribe un programa que reciba tres valores de entrada, que corresponden a horas, minutos y segundos y responda si se trata de una hora correcta. Program horas_CORRECTAS; VAR horas,minutos,segundos:integer; BEGIN Write(‘Introduce las horas, minutos y segundos: ); Readln(horas,minutos,segundos); If (0<=horas) and (horas<=23) then If (0<=minutos) and (minutos<=59) then If (0<=segundos) and (segundos<=59) then Writeln(‘Hora correcta’) Else writeln(‘Segundos incorrectos’) Else writeln(‘Horas incorrectas’); END.

• • • Programa 84. Fechas correctas. Si consideramos tres números enteros, para día, mes y año, escribe un programa que indique si dichos números se refieren a una fecha correcta. (Hay que tener en cuenta que en los años bisiestos, febrero tiene 29 días). Program fechas_CORRECTAS; VAR dia,mes,anyo:integer; largo, bisiesto:bolean; BEGIN Write(‘Introduce el dia, el mes y el año: ‘); Readln(dia,mes,anyo); If anyo<0 then writeln(¿Año incorrecto’) Else If (mes<1) or (mes>12) then writeln(‘Mes incorrecto’) Else Begin largo:=(mes=1) or(mes=3) or (mes=59 or (mes=7) or (mes=8) or (mes=10) or (mes=12); If largo then

Page 54: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

54

If ( (dia<1) or (dia>31) then writeln(‘Día incorrecto’); Else writeln(‘Fecha correcta’) Else If (mes<>2) Then If(dia<1) or (dia>30) then writeln(‘Dia incorrecto’) Else writeln(‘Fecha correcta’) Else Begin Bisiesto:=(anyo mod 4=0) and (anyo mod 100<>0) or (anyo mod 400=0)); If bisiesto Then If (dia<1) or (dia>29) then writeln(‘Dia incorrescto’) Else writeln(?Fecha correcta’) Else If (dia<1) or (dia>28) then writeln(‘Dia incorrecto’) Else writeln(‘Fecha correcta’); End; End; END.

• • • Programa 85. Círculo Escribe un programa que dibuje el siguiente “círculo”: * ***** ******* ******* ********* ******* ******* ***** * Program circuloCONASTERISCOS; Const radio=10; Var x,y:integer; BEGIN For y:=radio downto –radio do Begin for x:=-radio to radio do If ((sqr(x)+sqr(y))<=sqr(radio)) Then write(‘*’) Else write(‘ ‘); End; Writeln; End; END.

• • • Programa 86. Aproximación del número pi Construye un programa que calcule aproximaciones del numero pi utilizando el método de Borwein:

20 =x ; 41

1 2=y 220 +=∏

��

��

+=+

n

nnx

xx1

21

1 1

1

1 +

+

=+n

n

nn

n y

xxy

y 11

1 ++

∏=∏ −n

nnn y

x

Program AproximacionPIBORWEIN; Var n,i:integer;

Page 55: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

55

x, y, pi:real; BEGIN Write(‘Introduce el valor de n: ‘); Readln(n); x:=(1/2)*(sqrt(2))+1/(sqrt(sqrt(2)))); (*x1*) y:= sqrt(sqrt(2)); (*y1*); pi:= (2+sqrt(2))*((x+1)/(y+1)); (*pi*) writeln(‘Aproximación ‘,1,’->’,pi); for i:=2 to n do begin y:=(y*sqrt(x))+ 1/(sqrt(x)))/(y+1)); x:= (1/2)*(sqrt(x))+1/(sqrt(x))); pi:=pi*((x+1)/(y+1)); writeln((‘Aproximación ‘,i,’->’,pi); end; END.

Page 56: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

56

TRABAJO: CORRECCIÓN DE ERRORES

EN TRANSMISIÓN DE DATOS He elegido como soporte para el código C una array de cadenas de caracteres por la facilidad que esto supone a la hora de introducir datos así como para acceder a cada carácter de la cadena. La función y subprogramas siguientes presuponen que en el programa principal hay definidas las constantes y tipos de datos siguientes: CONST N=4; L=5; TYPE Palabra=string[L]; C=array[1..N] of Palabra; 1) Distancia de Hamming (Función) Sean pal1 y pal2 dos palabras de igual longitud L pertenecientes a un código C. Calculamos la distancia de Hamming, número de posiciones en que difieren las dos palabras, mediante una función. Function Hamming(pal1,pal2:Palabra):integer; Var distancia,i:integer; Begin distancia:=0; For i:=1 to L do If pal1[i]<>pal2[i] Then distancia:=distancia+1; Hamming:=distancia; End. 2) Distancia mínima de un código (Procedimiento o subprograma) Sea C={p1, p2, ….., pN}un código de N palabras de longitud dada L. Se define la mínima distancia del código C así:

{ }jiCppppdCd jiji ≠∈= ,,/),(min)( El subprograma o procedimiento que se muestra utiliza la función Hamming del apartado anterior para calcular d(C). Los parámetros del procedimiento son la variable codigo que se toma por valor y la variable ka que va por referencia y que se utilizará en procedimientos siguientes para determinar si se puede descodificar el mensaje que se ha recibido. Procedure distanciaMINIMACODIGO(codigo:C;Var ka:integer); Var i,j,distmin:integer; Begin distmin:=L; (*La distancia máxima posible es L*) For i:=1 to N-1 Do For j:=i+1 to N Do (*Comparamos cada palabra del código con sus siguientes en el array*) If Hamming(codigo[i],codigo[j])<distmin Then distmin:=Hamming(codigo[i],codigo[j]); writeln('La distancia minima en el codigo dado C es: ',distmin); writeln('------------------------------------------'); writeln; If odd(distmin) then ka:= distmin div 2

Page 57: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

57

Else ka:=(distmin-1) div 2; (*Determinamos ka según d(C)>=2*ka+1*) writeln('Podemos detectar si se han producido hasta ',2*ka,' errores'); write('y podemos corregir hasta ',ka,' errores'); End; 3) Simulación de ruido (Procedimiento o subprograma) Vamos a simular un canal de transmisión de datos ruidoso; se envía un mensaje de L bits mediante un mensaje de tipo Palabra el cual puede recibirse “distorsionado” teniendo en cuenta que: - Todos los bits de un mensaje tiene la misma probabilidad de ser recibidos con error.

- La probabilidad p con la que cada bit transmitido se recibe con error ha de ser menor que21

.

Los parámetros del procedimiento son la probabilidad p que se fije y las palabras (mensajes) que se transmiten mens y que se reciben distorsionados mensruido ambas por variable porque serán utilizados como datos en subprogramas siguientes. PROCEDURE transmisionRUIDOSA(p:real;Var mens:Palabra;Var mensruido:Palabra); Var compara,cont:integer; aleat:real; Begin writeln; write('Transmite un mensaje del codigo, de ',L,' caracteres ceros y unos: '); readln(mens); compara:=0; For cont:=1 To N Do (*Controlamos que el mensaje introducido está en el código*) If mens<>CodigoC[cont] Then compara:=compara+1; while (length(mens)<L) Or (compara=N) Do Begin write('Mensaje no valido,transmite un mensaje de ',L,' caracteres ceros y unos: '); readln(mens); compara:=0; For cont:=1 To N Do If mens<>CodigoC[cont] Then compara:=compara+1; End; mensruido:=mens; (*El siguiente bucle produce fallo en cada posición del mensaje según p*) For cont:=1 To L Do Begin aleat:=random(); If aleat<p Then If mensruido[cont]='0' then mensruido[cont]:='1' Else mensruido[cont]:='0'; End; writeln; writeln('Mensaje recibido: ',mensruido); write('----------------'); writeln; End; (*Fin del procedimiento*) 4) Detección de errores (Procedimiento o subprograma)

Page 58: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

58

Vamos a simular la detección de errores. El subprograma toma como datos el mensaje me que se transmitió, el mensaje meruido que se recibió (posiblemente distorsionado) y la variable nerrores por referencia en la que se calcula el número de no coincidencias entre ambos y que se usará como dato en el subprograma siguiente de correción de errores. PROCEDURE deteccionERRORES(me,meruido:Palabra;Var nerrores:integer); Begin nerrores:=Hamming(me,meruido); writeln; writeln('El numero de errores en la transmision ha sido: ',nerrores); End; 5) Correcion de errores (Procedimiento o subprograma) El procedimiento recibe como datos el mensaje mensaerror que se recibió y el número de no coincidencias con el mensaje original nfallos. El subprograma recorre todas las palabras del código, busca aquella para la que la distancia de Hamming con el mensaje transmitido mensaerror coincida con nfallos y la escribe en pantalla como mensaje corregido. PROCEDURE correccionERRORES(mensaerror:Palabra;nfallos:integer); Var r:integer; Begin Write('El mensaje corregido es: '); For r:=1 To N Do (*Recorremos el código para encontrar la palabra*) If Hamming(CodigoC[r],mensaerror)=nfallos then writeln(CodigoC[r]); Write('______________________'); End; 6) Simulación global El bloque de instrucciones siguientes corresponde al programa principal aunque solo adquiere su operatividad cuando se enmarca dentro de un programa en el que estén definidas las variables que utiliza y los procedimientos a los que llama. BEGIN (*PROGRAMA PRINCIPAL*) clrscr; Writeln('INTRODUCCION DEL CODIGO DE ',N,' PALABRAS DE ',L,' BITS CADA UNA'); writeln('--------------------------------------------------------'); For con1:=1 To N Do Begin write('Introduce una secuencia de ',L,' dígitos, ceros y unos seguidos: '); readln(CodigoC[con1]); While length(CodigoC[con1])<L Do (*Controlamos la longitud de cada palabra*) Begin writeln('Secuencia errónea'); write('Introduce una secuencia de, ',L,' digitos, ceros y unos: '); readln(CodigoC[con1]); End; End; writeln; writeln('EL CODIGO INTRODUCIDO ES:'); writeln; For con1:=1 To N Do (*Escribimos el código en pantalla separado del margen izquierdo 25*)

Page 59: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

59

writeln(CodigoC[con1]:25); writeln; distanciaMINIMACODIGO(CodigoC,k); (*Llamada a procedimiento*) writeln; writeln; write('Introduce la probabilidad <0.5 con la que cada bit se transmite con error: '); readln(prob); writeln; writeln; write('̈Quieres enviar un mensaje?(s/n): '); readln(car); (*Leemos un character*) randomize(); WHILE car='s' DO (*Mientras pulsemos ‘s’ seguimos trasmitiendo*) Begin transmisionRUIDOSA(prob,mensa,mensaruido); (*Llamada a procedimiento*) deteccionERRORES(mensa,mensaruido,nufallos); (*Llamada a procedimiento*) If nufallos>k Then writeln('No es posible descodificar') Else If nufallos=0 Then writeln('Mensaje transmitido sin errores') Else (*solo corregimos errores si es posible hacerlo*) correccionERRORES(mensaruido,nufallos); (*Llamada a procedimiento*) writeln; writeln; writeln('SI QUIERES CAMBIAR DE CODIGO, CONTESTA "n", PULSA INTRO Y CAMBIA LAS CONSTANTES DEL PROGRAMA'); writeln; write('̈Quieres enviar otro mensaje dentro del mismo codigo?(s/n): '); readln(car); End; END. (*FIN DEL PROGRAMA*)

Page 60: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

60

PROGRAMA COMPLETO Mostramos a continuación el programa completo de simulación total del uso de un código corrector de errores en la transmisión de mensajes. Program simulacionCANALRUIDOSO; uses crt; CONST N=4; L=5; TYPE Palabra=string[L]; C=array[1..N] of Palabra; VAR con1,nufallos,k,numerror:integer; CodigoC:C; prob:real; mensa,mensaruido:Palabra; car:char; (*La siguiente función calcula el número de posiciones en que difieren dos palabras de igual longitud*) FUNCTION Hamming(pal1,pal2:Palabra):integer; Var distancia,i:integer; Begin distancia:=0; For i:=1 to L Do (*Cada no coincidencia, aumenta la distancia*) If pal1[i]<>pal2[i] Then distancia:=distancia+1; Hamming:=distancia; End; (*Fin de la función*) (*El siguiente procedimiento calcula la distancia mínima en un código C de N palabras de L caracteres*) PROCEDURE distanciaMINIMACODIGO(codigo:C;Var ka:integer); Var i,j,distmin:integer; Begin distmin:=L; (*La distancia m xima posible es L*) For i:=1 To N-1 Do For j:=i+1 To N Do If Hamming(codigo[i],codigo[j])<distmin Then distmin:=Hamming(codigo[i],codigo[j]); writeln('La distancia minima en el codigo dado C es: ',distmin); writeln('------------------------------------------'); writeln; If odd(distmin) then ka:= distmin div 2 Else ka:=(distmin-1) div 2; writeln('Podemos detectar si se han producido hasta ',2*ka,' errores'); write('y podemos corregir hasta ',ka,' errores'); End; (*Fin del procedimiento*) (*El siguiente procedimiento simula la transmisión de datos*) (*Tiene en cuenta que cada dato puede transmitirse erróneamente con probabilidad p dada*) PROCEDURE transmisionRUIDOSA(p:real;Var mens:Palabra;Var mensruido:Palabra);

Page 61: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

61

Var compara,cont:integer; aleat:real; Begin writeln; write('Transmite un mensaje del codigo, de ',L,' caracteres ceros y unos: '); readln(mens); compara:=0; For cont:=1 To N Do (*Controlamos que el mensaje introducido está en el código*) If mens<>CodigoC[cont] Then compara:=compara+1; while (length(mens)<L) Or (compara=N) Do Begin write('Mensaje no valido,transmite un mensaje de ',L,' caracteres ceros y unos: '); readln(mens); compara:=0; For cont:=1 To N Do If mens<>CodigoC[cont] Then compara:=compara+1; End; mensruido:=mens; (*El siguiente bucle produce fallo en cada posición del mensaje según p*) For cont:=1 To L Do Begin aleat:=random(); If aleat<p Then If mensruido[cont]='0' then mensruido[cont]:='1' Else mensruido[cont]:='0'; End; writeln; writeln('Mensaje recibido: ',mensruido); write('----------------'); writeln; End; (*Fin del procedimiento*) (*Compara los mensajes transmitido y recibido e informa de los nerrores cometidos*) PROCEDURE deteccionERRORES(me,meruido:Palabra;Var nerrores:integer); Begin nerrores:=Hamming(me,meruido); writeln; writeln('El numero de errores en la transmision ha sido: ',nerrores); End; (* Lleva a cabo la corrección de errores*) PROCEDURE correccionERRORES(mensaerror:Palabra;nfallos:integer); Var r:integer; Begin Write('El mensaje corregido es: '); For r:=1 To N Do (*Recorremos el código para encontrar la palabra*) If Hamming(CodigoC[r],mensaerror)=nfallos then writeln(CodigoC[r]); Write('______________________'); End; BEGIN (*PROGRAMA PRINCIPAL*)

Page 62: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

62

clrscr; Writeln('INTRODUCCION DEL CODIGO DE ',N,' PALABRAS DE ',L,' BITS CADA UNA'); writeln('--------------------------------------------------------'); For con1:=1 To N Do Begin write('Introduce una secuencia de ',L,' dígitos, ceros y unos seguidos: '); readln(CodigoC[con1]); While length(CodigoC[con1])<L Do (*Controlamos la longitud de cada palabra*) Begin writeln('Secuencia errónea'); write('Introduce una secuencia de, ',L,' digitos, ceros y unos: '); readln(CodigoC[con1]); End; End; writeln; writeln('EL CODIGO INTRODUCIDO ES:'); writeln; For con1:=1 To N Do (*Escribimos el código en pantalla separado del margen izquierdo 25*) writeln(CodigoC[con1]:25); writeln; distanciaMINIMACODIGO(CodigoC,k); (*Llamada a procedimiento*) writeln; writeln; write('Introduce la probabilidad <0.5 con la que cada bit se transmite con error: '); readln(prob); writeln; writeln; write('̈Quieres enviar un mensaje?(s/n): '); readln(car); (*Leemos un character*) randomize(); WHILE car='s' DO (*Mientras pulsemos ‘s’ seguimos trasmitiendo*) Begin transmisionRUIDOSA(prob,mensa,mensaruido); (*Llamada a procedimiento*) deteccionERRORES(mensa,mensaruido,nufallos); (*Llamada a procedimiento*) If nufallos>k Then writeln('No es posible descodificar') Else If nufallos=0 Then writeln('Mensaje transmitido sin errores') Else (*solo corregimos errores si es posible hacerlo*) correccionERRORES(mensaruido,nufallos); (*Llamada a procedimiento*) writeln; writeln; writeln('SI QUIERES CAMBIAR DE CODIGO, CONTESTA "n", PULSA INTRO Y CAMBIA LAS CONSTANTES DEL PROGRAMA'); writeln; write('̈Quieres enviar otro mensaje dentro del mismo codigo?(s/n): '); readln(car); End; END. (*FIN DEL PROGRAMA*) A continuación mostramos algunas ejecuciones:

Page 63: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

63

En la siguiente ejecución no hay errores en el mensaje transmitido:

En la siguiente ejecución no se puede descodificar:

Page 64: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

64

En la siguiente ejecución, se produce un error en la transmisión y éste es corregido:

Page 65: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

65

Segundo Cuatrimestre

• • • Programa 1. Fecha Correcta

Escribe un programa que lea una fecha (dd/mm) y decida si es o no correcta Program fechacorrecta; uses crt; var d,m:integer; mes31:boolean; BEGIN clrscr; write('introduce el dia: '); readln(d); write('introduce el mes: '); readln(m); if (m<1) or (m>12) then write('mes incorrecto') else begin mes31:=(m=1)or(m=3)or(m=5)or(m=7)or(m=8)or(m=10)or(m=12); if mes31 then if (d<1) or (d>31) then write('dia incorrecto') else writeln('fecha correcta') else if (m<>2) then if (d<1) or (d>30) then write('dia incorrecto') else writeln('fecha correcta') else if (d<1) or (d>28) then write('dia incorrecto') else writeln('fecha correcta'); end; readln(); END.

• • • Programa 2. CifrasCubo Escribe un programa que calcule e imprima en pantalla los números de tres cifras tales que coinciden con la suma de los cubos de sus cifras. Program cifrascubo; (*buscar numeros de 3cifras para que la suma del cubo de sus cifras sea igual al numero*) uses crt; var num,i,j,k:integer; function potencia(base,exponente:integer):integer; var i,pot:integer; begin pot:=1; for i:=1 to exponente do pot:=pot*base; potencia:=pot; end; BEGIN

Page 66: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

66

clrscr; writeln('los numeros buscados son: '); for i:=1 to 9 do for j:=0 to 9 do for k:=0 to 9 do begin num:=100*i+10*j+k; if num=potencia(i,3)+potencia(j,3)+potencia(k,3) then writeln(num); end; readln(); END.

• • • Programa 3. Impares Consecutivos Escribe un programa que calcule el mayor natural n tal que la suma de los n impares consecutivos sea menor o igual que una cantidad c positiva o cero introducida por teclado. Program mayorimpar; (* calcula el mayor n tal que la suma de n impares consecutivos es menor o igual que una cantidad c positiva o cero*) uses crt; var n,c:integer; suma,impar:integer; BEGIN clrscr; write('introduce c positiva o cero: '); readln(c); while c<0 do (*controlamos que c>=0 *) begin write('introduce c positiva o cero: '); readln(c); end; suma:=0; impar:=1; n:=0; while suma<=c do begin suma:=suma+impar; impar:=impar+2; n:=n+1; end; writeln('el numero de impares consecutivos es: ',n-1); readln(); END.

• • • Programa 4. Números Amigos Escribe un programa que decida si dos números naturales n y m son amigos, es decir, si la suma de los divisores de n desde 1 hasta n-1 es igual a m. Program amigos; (*dos numeros son amigos si la suma de los divisores del primero hasta n-1 es igual al segundo*)

Page 67: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

67

uses crt; var n,m:integer; sonamigos:boolean; function escolega(dato1,dato2:integer):boolean; var mitad,i,suma:integer; begin mitad:= dato1 div 2; suma:=0; for i:=1 to mitad do if dato1 mod i=0 then suma:=suma+i; escolega:=dato2=suma; end; BEGIN clrscr; repeat write('introduce el primer numero: '); readln(n); until n>=0; repeat write('introduce el segundo numero: '); readln(m); until m>=0; sonamigos:=(escolega(n,m)) and (escolega(m,n)); write('los numeros son amigos?',sonamigos); readln(); END.

• • • Programa 5. Media-Varianza-Desviación Típica Escribe un programa que calcule la media, varianza y desviación típica de n datos x1……xn.

ianzadesvTípicaxn

xn

ianzaxn

median

ii

n

ii

n

ii var

11var

12

12

1

2

1

=��

��

−== ���===

Program mediavardesttip; uses crt; CONST N=5; var i:integer; lista:array[1..N]of integer; media,varianza,desv:real; BEGIN clrscr; for i:=1 to N do begin write('introduce el valor ',i,': '); readln(lista[i]); end; media:=0; varianza:=0; for i:=1 to N do

Page 68: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

68

begin media:=media+lista[i]; varianza:=varianza+sqr(lista[i]); end; varianza:=varianza/N - sqr(media)/sqr(N); media:=media/N; desv:=sqrt(varianza); writeln; writeln('la media es: ', media:2:5); writeln('la varianza es: ', varianza:2:5); writeln('la desviacion tipica es: ',desv:2:5); readln(); END.

• • • Programa 6. Número friki Escribe un programa que decida si un número natural es friki, es decir, no es rectangular, su anterior es cuadrado perfecto y su siguiente es rectangular. Un número es rectangular si es producto de dos números naturales p,q>=2. Program numerofriki; (*un numero es friki si no es rectang,su anterior escuadrado perfecto y su siguiente es rectangular*) uses crt; var m:integer; friki:boolean; function rectangular(n:integer):boolean; var i,factor1,factor2:integer; resultado:boolean; begin i:=2; resultado:=false; while (i<n) and (not(resultado)) do begin if (n mod i=0) then begin factor1:=i; factor2:=n div i; if (factor1<>factor2) then resultado:=true; end; i:=i+1; end; rectangular:=resultado; end; function cuadperfect(p:integer):boolean; var i:integer; escuadrado:boolean; begin i:=1; escuadrado:=false; while (i<p) and (not (escuadrado)) do begin if p div i=i then escuadrado:=true; i:=i+1; end; cuadperfect:=escuadrado; end;

Page 69: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

69

BEGIN clrscr; repeat write('introduce un numero: '); readln(m); until m>0; friki:=(not(rectangular(m))) and (cuadperfect(m-1)) and (rectangular(m+1)); write('el numero es friki? ', friki); readln(); END.

• • • Programa 7. Variaciones-Combinaciones-Permutaciones Escribe un programa que calcule las variaciones y combinaciones de m elementos tomados de n en n y las permutaciones de n elementos. Las fórmulas son:

!)1)........(1.( ,,, nP

P

VCnmmmV n

n

nmnmnm ==+−−=

Program varpercom; uses crt; var m,n,variac,permut,combin:integer; function variaciones(m,n:integer):integer; var i,vari:integer; begin vari:=1; for i:=1 to n do begin vari:=vari*m; m:=m-1; end; variaciones:=vari; end; function permutaciones(n:integer):integer; var i,per:integer; begin per:=1; for i:=2 to n do per:=per*i; permutaciones:=per; end; procedure combinaciones(m,n:integer; Var comb:integer); begin comb:=variaciones(m,n) div permutaciones(n); writeln(‘ Las combinaciones de , m ,’elementos tomados de ‘,n,’ en ‘,n ‘ son: ‘,comb); end; BEGIN clrscr; repeat write('introduce un natural positivo: ');

Page 70: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

70

readln(m); until m>0; repeat write('introduce un numero natural menor o igual que el anterior: '); readln(n); until (n>=0) and (n<=m); variac:=variaciones(m,n); combinaciones(m,n,combin); writeln('las variaciones de ',m,' y ', n,' son: ',variac); writeln(); writeln(); repeat write('introduce un numero positivo o cero: '); readln(n); until n>=0; permut:=permutaciones(n); writeln('las permutaciones de ', n,' son: ',permut); readln(); END.

• • • Programa 8. Ecuación de segundo grado Escribe un programa que resuelva una ecuación de segundo grado. PROGRAM SEGUNDO_GRADO(INPUT,OUTPUT); TYPE TSolucion=(infinito,dos,uno,cero); VAR a,b,c,discriminante:INTEGER; numeroSoluciones:TSolucion; solucion1,solucion2:REAL; BEGIN WRITE('Coeficiente del termino de segundo grado: '); READLN(a); WRITE('Coeficiente del termino de primer grado: '); READLN(b); WRITE('Coeficiente del termino independiente: '); READLN(c); IF (a=0) THEN IF (b=0) THEN IF (c=0) THEN numeroSoluciones:=infinito ELSE numeroSoluciones:=cero ELSE BEGIN numeroSoluciones:=uno; solucion1:=-c/b; END ELSE BEGIN discriminante:=SQR(b)-4*a*c; IF (discriminante<0) THEN numeroSoluciones:=cero ELSE IF (discriminante=0) THEN BEGIN numeroSoluciones:=uno; solucion1:=-b/(2*a); END ELSE BEGIN numeroSoluciones:=dos; solucion1:=(-b+SQRT(discriminante))/(2*a); solucion2:=(-b-SQRT(discriminante))/(2*a); END; END;

Page 71: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

71

CASE numeroSoluciones OF infinito: WRITELN('Soluciones infinitas'); dos: WRITELN('Solucion doble: ',solucion1:5:3, ' y ',solucion2:5:3); uno: WRITELN('Solucion £nica: ',solucion1:5:3); cero: WRITELN('No hay solucion'); END; END.

• • • Programa 9. Cifrado CayoJulio Escribe un programa que cifre un mensaje en mayúsculas según un desplazamiento de letras, por ejemplo si transmito una B el desplamiento es 3, transmitiremos E. Program cifradoCAYOJULIO; uses crt; VAR d:INTEGER; original,codigo,recuperado:STRING; PROCEDURE cifrar(desplazamiento:INTEGER;mensaje:STRING;VAR resultado:STRING); VAR i:INTEGER; cLetra,cCaracter:INTEGER; BEGIN resultado:=mensaje; FOR i:=1 TO LENGTH(mensaje) DO BEGIN cLetra:=ORD(mensaje[i]); IF ((cLetra>=ORD('a')) AND (cLetra<=ORD('z'))) THEN cLetra:=ORD('A')+(cLetra-ORD('a')); IF ((cLetra>=ORD('A')) AND (cLetra<=ORD('Z'))) THEN BEGIN cCaracter:=cLetra+desplazamiento; IF (cCaracter>ORD('Z')) THEN cCaracter:=ORD('A')+(cCaracter MOD ORD('Z')-1); resultado[i]:=CHR(cCaracter); END; END; END; PROCEDURE descifrar(desplazamiento:INTEGER;mensaje:STRING;VAR resultado:STRING); VAR i:INTEGER; cLetra,cCaracter:INTEGER; BEGIN resultado:=mensaje; FOR i:=1 to LENGTH(mensaje) DO BEGIN cLetra:=ORD(mensaje[i]); IF ((cLetra>=ORD('a')) AND (cLetra<=ORD('z'))) THEN cLetra:=ORD('A')+(cLetra-ORD('a')); IF ((cLetra>=ORD('A')) AND (cLetra<=ORD('Z'))) THEN BEGIN cCaracter:=cLetra-desplazamiento; IF (cCaracter<ORD('A')) THEN cCaracter:=ORD('Z')-(ORD('A') MOD cCaracter-1); resultado[i]:=CHR(cCaracter); END; END; END; (* ************************************************************************ *) BEGIN (* Programa principal *) REPEAT WRITE('Introduce el desplazamiento: ');

Page 72: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

72

READLN(d); UNTIL (d>0); WRITE('Introduce el mensaje original: '); READLN(original); cifrar(d,original,codigo); WRITELN('El mensaje codificado es: ',codigo); descifrar(d,codigo,recuperado); WRITELN('El mensaje decodificado es: ',recuperado); END. (* Programa principal *)

• • • Programa 10. Cuatro cifras Escribe un programa que muestre en pantalla, 11 por línea y 20 por pantalla, los números de cuatro cifras tales que la suma de las unidades y las centenas supere a la suma de las otras dos cifras. Program cuatrodigitos; uses crt; procedure sumacuatro; var cont,cont2,uni,dec,cen,mil,numero:integer; begin cont:=0; cont2:=0; for mil:=1 to 9 do for cen:=0 to 9 do for dec:=0 to 9 do for uni:=0 to 9 do if uni+cen>dec+mil then begin numero:=mil*1000+cen*100+dec*10+uni; write(numero,' '); cont:=cont+1; if cont mod 11 =0 then begin writeln(); cont2:=cont2+1; if cont2 mod 20=0 then begin writeln('pulsa una tecla para continuar'); readln(); end; end; end; end; BEGIN clrscr; sumacuatro; readln(); END.

• • • Programa 11. Nprimos Escribe un programa que saque en pantalla los N primeros números primos. N se introduce por teclado.

Page 73: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

73

Program Nprimos; uses crt; var M:integer; function esprimo(n:integer):boolean; var i:integer; resultado:boolean; x:real; begin x:=round(sqrt(n)); resultado:=true; i:=2; while (i<=x) and (resultado) do begin if n mod i =0 then resultado:=false; i:=i+1; end; esprimo:=resultado; end; procedure calculoprimos(N:integer); var contador,numero:integer; begin numero:=2; contador:=0; while contador<N do begin if esprimo(numero) then begin writeln(numero); contador:=contador+1; end; numero:=numero+1; end; end; BEGIN clrscr; write('¨cuantos primos quieres escribir? '); readln(M); calculoprimos(M); readln(); END.

• • • Programa 12. Nprimospor línea Modifica el programa anterior para que salgan por pantalla cinco primos por línea. Program Nprimosporlinea; uses crt; var M:integer; function esprimo(n:integer):boolean; var i:integer; resultado:boolean; x:real; begin

Page 74: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

74

x:=round(sqrt(n)); resultado:=true; i:=2; while (i<=x) and (resultado) do begin if n mod i =0 then resultado:=false; i:=i+1; end; esprimo:=resultado; end; procedure calculoprimos(N:integer); var contador,numero:integer; begin numero:=2; contador:=0; while contador<N do begin if esprimo(numero) then begin write(numero,' '); contador:=contador+1; if contador mod 5=0 then writeln; end; numero:=numero+1; end; end; BEGIN clrscr; write('¨cuantos primos quieres escribir? '); readln(M); calculoprimos(M); readln(); END.

• • • Programa 13. Primos mellizos Escribe un programa que cuente e imprima los pares de primos mellizos menores que una cierta cota c . Dos primos son mellizos si su diferencia es 2. Program primosmellizos; uses crt; var c,cant:integer; function esprimo(n:integer):boolean; var i:integer; resultado:boolean; x:real; begin x:=round(sqrt(n)); resultado:=true; i:=2; while (i<=x) and (resultado) do begin

Page 75: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

75

if n mod i =0 then resultado:=false; i:=i+1; end; esprimo:=resultado; end; procedure mellizos(cota:integer; VAR cantidad:integer); var primero,segundo:integer; begin cantidad:=0; primero:=3; segundo:=5; while segundo<=cota do begin if esprimo(primero) and esprimo(segundo) then begin writeln('(',primero,',',segundo,')'); cantidad:=cantidad+1; end; primero:=segundo; segundo:=segundo+2; end; end; BEGIN clrscr; repeat write('introduce una cota positiva: '); readln(c); until c>0; writeln('los pares son: '); mellizos(c,cant); write('la cantidad de primos mellizos menores o iguales que ',c,' es: ',cant); readln(); END.

• • • Programa 14. Suma N primos Modifica el programa 11 para que sume los N primeros números primos.

• • • Programa 15. Ordenar un array Escribe un programa que lea un array de ocho posiciones, lo ordene de menor a mayor y lo imprima. Program ordenararray; uses crt; var i,j,aux:integer; C:array[1..8]of integer; BEGIN clrscr; for i:=1 to 8 do

Page 76: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

76

begin write('introduce el numero de la posicion ',i,' :'); readln(C[i]); end; for i:=1 to 7 do for j:=i+1 to 8 do if C[i]>C[j] then begin aux:=C[i]; C[i]:=C[j]; C[j]:=aux; end; write('el array ordenado de menor a mayor es: '); for i:=1 to 8 do write(C[i],' '); writeln; write('el array ordenado de mayor a menor es: '); for i:=8 downto 1 do write(C[i],' '); readln(); END. 7.2 El Tipo Record Un registro (RECORD) es una estructura de datos estática, formada por un conjunto finito de elementos heterogéneos. Cada uno de estos elementos se llama CAMPO. Para ello es necesario especificar un identificador y un tipo. La sintaxis que permite declarar un registro es : TYPE Tipo_rgistro= RECORD Campo1: tipo1; Campo2: tipo2; …. Campok: tipok; END; Varios campos pueden aparecer en la misma línea, separados por una coma, si son del mismo tipo. También es posible definir Registros que contengan Registros o arrays. Ejemplo Define una estructura de datos que permita almacenar la siguiente información relativa a una persona:

- Nombre: cadena de texto (String) de cómo máximo 50 caracteres. - Apellidos: cadena de texto (String) de cómo máximo 50 caracteres. - Sexo: (H:hombre, M: mujer). - Fecha de nacimiento:

o Dia:subrango entre 1 ..31 o Mes: subrango entre enero..diciembre o Anio:subrango entre 0..2050

TYPE Tipo_mes=(enero, fenbrero, marzo, abril, mayo, junio, julio, agosto, septiembre, octubre, noviembre, diciembre);

Page 77: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

77

Tipo_persona= RECORD nombre,apellidos:STRING(50); sexo:char dia: 1..31;

mes: Tipo_mes; anio:0..2050;

END; VAR sonia:Tipopersona;

Typo_persona

sonia.nombre se refiere al nombre de la persona. Como los campos dia, mes y anyo son relativos al mismo concepto, podemos utilizar dos registros: uno anidado dentro del otro: TYPE Tipo_mes=(enero, fenbrero, marzo, abril, mayo, junio, julio, agosto, septiembre, octubre, noviembre, diciembre); Tipo_fecha: RECORD Dia:1..31; Mes: Tipo_mes; Anio:0..2050; END; Tipo_persona=RECORD nombre,apellidos:STRING(50); sexo:char;

fecha_nac:Tipo_fecha; END;

Los registros se pueden pasar como parámetros en los procedimientos. Se puede asignar un registro a otro si som del mismo tipo.

• Trabajo para entregar. Ajedrez Te proponemos un juego basado en el ajedrez, en el que el usuario mueve una pieza del ajedrez (el rey) y el ordenador mueve a sus cuatro adversarios (cuatro caballos). El rey, al comienzo de la partida, está en un lado del tablero y los caballos en el lado opuesto:

Fila1

Fila 8

Para ganar la partida, el usuario debe dirigir al Rey hasta alcanzar el lado opuesto del tablero. Los caballos, mejados por el ordenador, deben intentar comerse al Rey.

nombre apellidos sexo dia Mes anio

C C C C R

Page 78: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

78

En cada turno, el Rey se puede mover una casilla en cualquiera de las direcciones ( adelante, atrás, a los lados y hacia las diagonales ).

- El ordenador mueve un solo caballo por turno. Cada caballo se mueve el L, para cualquier dirección.

- Siempre empieza moviendo el Rey. - Si un caballo se come al Rey, la partida termina. - Si el Rey se come un caballo, la partida continúa y, por tanto, el ordenador juega con una

pieza menos. - El Rey gana cuando alcanza el otro lado del tablero ( la fila 8)

Program Ajedrez;(*Jugamos con 4 caballos y un Rey*) USES crt; CONST num_piezas=5; tamtablero=8; TYPE TypePosicion=Record x,y:integer; End; TypeTablero=array[1..num_piezas]of TypePosicion; VAR mov,numcaballos,ncab,movimiento:integer; seguir:boolean; mitablero:TypeTablero; PROCEDURE informacion; Begin writeln('_________________AJEDREZ_________________'); writeln('REGLAS DE JUEGO: '); writeln('- Tenemos un tablero 8x8 con 4 caballos C y un rey R.'); writeln('- El ordenador mueve en cada turno un unico caballo, eligiendolo segun: '); writeln(' 1) si hay posibilidad de comerse al rey'); writeln(' 2) si se ve amenazado por el rey'); writeln(' 3) aleatorio en caso contrario, evitando ser amenazado por el Rey'); writeln; writeln('- El usuario mueve en su turno al rey R, realizando un movimiento del 1 al 8, segun: '); writeln(' 1 2 3 '); writeln(' 4 R 5 '); writeln(' 6 7 8 '); writeln; end; PROCEDURE inicializartablero(Var tablero:TypeTablero); Var i,columna:integer; Begin tablero[1].x:=tamtablero; tablero[1].y:=tamtablero div 2; columna:=1; writeln('Situacion inicial: '); For i:=2 To num_piezas Do Begin tablero[i].x:=1; tablero[i].y:=columna; columna:=columna+2; End;

Page 79: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

79

End;(*Fin del procedimiento*) PROCEDURE imprimirtablero(ta:TypeTablero); (*Indica las posiciones de Caballos y Rey*) Var i:integer; Begin writeln; writeln('El rey esta en la posici¢n: fila ',ta[1].x,' columna ',ta[1].y); For i:=2 To num_piezas Do writeln('El caballo ',i-1,' esta en la posici¢n: fila ',ta[i].x,' columna ',ta[i].y); writeln; End; FUNCTION escasillavalida(casilla:TypePosicion):boolean; Begin (*Indica si el movimiento realizado esta en el tablero*) escasillavalida:=(casilla.x>=1) and (casilla.x<=tamtablero) and (casilla.y>=1) and (casilla.y<=tamtablero); End;(*Fin de funcion*) FUNCTION soncasillasiguales(casilla1,casilla2:TypePosicion):boolean; Begin soncasillasiguales:=(casilla1.x=casilla2.x) and (casilla1.y=casilla2.y); End;(*Fin de funcion*) FUNCTION HayRey(m,n:integer;table:TypeTablero):boolean; (*Nos dice si hay Rey en la posicion m, n del tablero*) Begin HayRey:=(table[1].x=m) and (table[1].y=n); End;(*Fin de funcion*) FUNCTION HayCaballo(m,n:integer;table:TypeTablero):boolean; (*Nos dice si hay Caballo en la posicion m, n del tablero*) Var k:integer; posibilidad:boolean; Begin k:=2; posibilidad:=True; HayCaballo:=False; Begin While (k<=num_piezas) and (posibilidad) Do Begin If (table[k].x=m) and (table[k].y=n) Then Begin HayCaballo:=True; posibilidad:=False; End; k:=k+1; End; End; End;(*Fin de funcion*) PROCEDURE imprimir(tablero:TypeTablero);(*Imprime el tablero en forma de cuadro*) Var i,j:integer; Begin For i:=1 To tamtablero Do Begin

Page 80: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

80

write(' '); For j:=1 To tamtablero Do If HayRey(i,j,mitablero) Then write('R ') Else If HayCaballo(i,j,mitablero) Then write('C ') Else write('* '); writeln; writeln; End; End;(*Fin del procedimiento*) PROCEDURE moverRey(Var rey:TypePosicion;direccion:integer;VAR tablero:TypeTablero;Var ncaballos:integer); Var posicion:TypePosicion; j:integer; Begin posicion.x:=rey.x; posicion.y:=rey.y; Case direccion Of 1:Begin posicion.x:=posicion.x-1; posicion.y:=posicion.y-1; End; 2:posicion.x:=posicion.x-1; 3:Begin posicion.x:=posicion.x-1; posicion.y:=posicion.y+1; End; 4:posicion.y:=posicion.y-1; 5:posicion.y:=posicion.y+1; 6:Begin posicion.x:=posicion.x+1;posicion.y:=posicion.y-1;End; 7:posicion.x:=posicion.x+1; 8:Begin posicion.x:=posicion.x+1; posicion.y:=posicion.y+1; End; End; If escasillavalida(posicion) Then Begin rey:=posicion; For j:=2 To num_piezas Do If (tablero[j].x=rey.x) and (tablero[j].y=rey.y) Then Begin tablero[j].x:=0; tablero[j].y:=0; ncaballos:=ncaballos-1; End End Else writeln('Movimiento no valido:Has perdido el turno'); End;(*Fin del procedimiento moverRey*) Function Amenaza(re,ca:TypePosicion):boolean; (*Estudia si el rey amenaza al caballo*) Begin If ((abs(re.x-ca.x)=1) and (abs(re.y-ca.y)=1)) Or ((abs(re.x-ca.x)=0) and (abs(re.y-ca.y)=1)) Or ((abs(re.x-ca.x)=1) and (abs(re.y-ca.y)=0)) Then Amenaza:=True; End; PROCEDURE simulamovercaballo(VAR tabl:TypeTablero;VAR numcab:integer;VAR mueve:integer);

Page 81: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

81

(*Antes de mover caballo, explora el mejor movimiento posible en dos sentidos:*) (*Si algun caballo puede comerse al Rey, guarda su numero en "ncab"*) (*y el movimiento correspondiente en "mueve"*) (*Si el Rey amenaza un caballo, se guarda su numero en "cab" para moverlo despues*) Var posible,vuelta:boolean; k,t:integer; posic:TypePosicion; Begin posible:=true; k:=2; numcab:=0; mueve:=0; While (k<=num_piezas) and (posible) Do Begin If tabl[k].x<>0 Then Begin (*Vemos si hay algun caballo "ncab" y movimiento "mueve" que puede comerse al rey*) t:=1; (*Recorremos todos los caballos con todos sus movimientos*) vuelta:=true; While (t<=tamtablero) and (vuelta) Do Begin posic.x:=tabl[k].x; posic.y:=tabl[k].y; Case t Of 1: Begin posic.x:=posic.x-2;posic.y:=posic.y-1;End; 2: Begin posic.x:=posic.x-2;posic.y:=posic.y+1;End; 3: Begin posic.x:=posic.x-1;posic.y:=posic.y-2;End; 4: Begin posic.x:=posic.x-1;posic.y:=posic.y+2;End; 5: Begin posic.x:=posic.x+1;posic.y:=posic.y-2;End; 6: Begin posic.x:=posic.x+1;posic.y:=posic.y+2;End; 7: Begin posic.x:=posic.x+2;posic.y:=posic.y-1;End; 8: Begin posic.x:=posic.x+2;posic.y:=posic.y+1;End; End; If escasillavalida(posic) Then If soncasillasiguales(posic,tabl[1]) Then Begin mueve:=t; numcab:=k; vuelta:=False; posible:=False; End Else If Amenaza(tabl[1],tabl[k]) Then numcab:=k; (*Seleccionamos si hay caballo que puede ser comido por el rey*) t:=t+1; End; End; k:=k+1; End; End;(*Fin del procedimiento*) PROCEDURE movercaballo(caballo:integer;mov:integer;Var tab:TypeTablero); Var posici:TypePosicion; mover,i:integer; cambiarmov:boolean;

Page 82: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

82

Begin randomize; posici.x:=tab[caballo].x; posici.y:=tab[caballo].y; write('MUEVE EL ORDENADOR: Pulsa una tecla: '); readln(); writeln('----------------'); If mov<>0 THEN(*El caballo, "caballo" se come al Rey*) BEGIN tab[1].x:=0; tab[1].y:=0; Case mov Of 1: Begin posici.x:=posici.x-2;posici.y:=posici.y-1;End; 2: Begin posici.x:=posici.x-2;posici.y:=posici.y+1;End; 3: Begin posici.x:=posici.x-1;posici.y:=posici.y-2;End; 4: Begin posici.x:=posici.x-1;posici.y:=posici.y+2;End; 5: Begin posici.x:=posici.x+1;posici.y:=posici.y-2;End; 6: Begin posici.x:=posici.x+1;posici.y:=posici.y+2;End; 7: Begin posici.x:=posici.x+2;posici.y:=posici.y-1;End; 8: Begin posici.x:=posici.x+2;posici.y:=posici.y+1;End; End; tab[caballo].x:=posici.x; tab[caballo].y:=posici.y; END ELSE BEGIN mover:=mov; mov:=random(8)+1; Case mov Of 1: Begin posici.x:=posici.x-2;posici.y:=posici.y-1;End; 2: Begin posici.x:=posici.x-2;posici.y:=posici.y+1;End; 3: Begin posici.x:=posici.x-1;posici.y:=posici.y-2;End; 4: Begin posici.x:=posici.x-1;posici.y:=posici.y+2;End; 5: Begin posici.x:=posici.x+1;posici.y:=posici.y-2;End; 6: Begin posici.x:=posici.x+1;posici.y:=posici.y+2;End; 7: Begin posici.x:=posici.x+2;posici.y:=posici.y-1;End; 8: Begin posici.x:=posici.x+2;posici.y:=posici.y+1;End; End; cambiarmov:=False; For i:=2 to 5 Do If i<>caballo Then If ((tab[i].x=posici.x) and (tab[i].y=posici.y)) Or (Amenaza(mitablero[1],posici)) Then cambiarmov:=True; While not(escasillavalida(posici)) or (cambiarmov) Do Begin posici.x:=tab[caballo].x; posici.y:=tab[caballo].y; mover:=random(8)+1; Case mover Of 1: Begin posici.x:=posici.x-2;posici.y:=posici.y-1;End; 2: Begin posici.x:=posici.x-2;posici.y:=posici.y+1;End; 3: Begin posici.x:=posici.x-1;posici.y:=posici.y-2;End; 4: Begin posici.x:=posici.x-1;posici.y:=posici.y+2;End; 5: Begin posici.x:=posici.x+1;posici.y:=posici.y-2;End;

Page 83: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

83

6: Begin posici.x:=posici.x+1;posici.y:=posici.y+2;End; 7: Begin posici.x:=posici.x+2;posici.y:=posici.y-1;End; 8: Begin posici.x:=posici.x+2;posici.y:=posici.y+1;End; End; cambiarmov:=False; For i:=2 to 5 Do If i<>caballo Then If ((tab[i].x=posici.x) and (tab[i].y=posici.y)) Or (Amenaza(mitablero[1],posici)) Then cambiarmov:=True; End; Write('SE MUEVE EL CABALLO: ', caballo-1); Writeln(' ; EL MOVIMIENTO ES: ',mover); tab[caballo].x:=posici.x; tab[caballo].y:=posici.y; End; End; (*Fin del procedimiento*) BEGIN(*Programa Principal*) clrscr; informacion; writeln; writeln('Pulsa una tecla para continuar'); readln(); inicializartablero(mitablero); imprimirtablero(mitablero); imprimir(mitablero); seguir:=true; numcaballos:=num_piezas-1; randomize; WHILE seguir DO Begin Repeat write('INTRODUCE EL MOVIMIENTO DEL REY: '); readln(mov); write('------------------------------'); until (mov>=1) and (mov<=8); moverRey(mitablero[1],mov,mitablero,numcaballos); imprimirtablero(mitablero); imprimir(mitablero); If (mitablero[1].x=1) OR (numcaballos=0) Then Begin seguir:=false; writeln('-HAS GANADO!'); writeln('Pulsa una tecla para terminar'); readln(); End Else(*elegir caballo adecuadamente o al azar*) Begin simulamovercaballo(mitablero,ncab,movimiento); If ncab=0 Then Begin Repeat ncab:=random(4)+2; until mitablero[ncab].x<>0; End;

Page 84: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

84

movercaballo(ncab,movimiento,mitablero); imprimirtablero(mitablero); imprimir(mitablero); If mitablero[1].x=0 Then Begin seguir:=False; writeln('EL CABALLO ',ncab-1,' SE HA COMIDO AL REY'); writeln('HAS PERDIDO: PULSA UNA TECLA PARA FINALIZAR'); writeln('-------------------------------------------'); readln(); End; End; End; END. 8. RECURSIVIDAD Las técnicas recursivas permiten lograr soluciones simples, elegantes y naturales a problemas que de otro modo serían muy difíciles de resolver. Es un tema difícil para los alumnos que se inician en programación, por ello hay que comenzar con ejemplos sencillos que nos permitan seguir paso a paso su ejecución. 8.1 Conceptos básicos de recursividad Se dice que un subprograma es recursivo (procedimiento o función) si contiene llamadas o invocaciones a sí mismo. Un procedimiento recursivo tendría este aspecto: PROCEDURE ProcRecursivo(……...); VAR (* Variables locales *) ……………………. BEGIN ………………… ProcRecursivo(…….) (*Llamada recursiva*) ……………….. END; Y una función recursiva podría ser: FUNCTION FuncRecursiva(……….): tipo; VAR (* Variables locales *) …………………….. BEGIN …………………….. Variable:=FuncRecursiva(……...) (* Llamada recursiva *) ……………. END; Esto implica que una llamada a un subprograma recursivo pueda generar una o más invocaciones a él mismo, que asu vez genera otras invocaciones, y así sucesivamente.

Page 85: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

85

A primera vista, parece que un subprograma recursivo nunca terminará, pero si la definición está bien hecha y los parámetros de entrada son adecuados, alguna llamada activará un subprogramaque no generará nuevas llamadas, con lo cual éste terminará y devolerá el control a la llamada anterior, que a su vez terminará, y así sucesivamente, hasta que todas las llamadas terminen. Una de las funciones recursivas más sencillas es la función factorial que vamos a utilizar para ver el funcionamiento de la recursividad como técnica de programación: El factorial de un natural n es n!=n.(n-1)! para n>1 1!=1 Como se ve, la definición tiene una parte recursiva ( que es la primera línea ) pues se define el factorial de n como el producto de n por el factorial de n-1, para n mayor que 1. Sin embargo, la segunda línea de la definición no es recursiva y define el caso base. En general, cualquier definición recursiva tendrá dos casos diferenciados: el caso recursivo y el caso base o no recursivo.

• • • Programa 17. Factorial de un número Escribe un programa recursivo en Pascal que calcule mediante una función el factorial de un natural n. Program Factorial; Uses crt; Var resultado:integer; Function factorial (n:integer):integer; Begin If n=0 then factorial:=1 Else factorial:=n*factorial(n-1); End; BEGIN Clrscr; Writeln(‘Introduce un natural m: ‘); Readln(m); Resultado:=factorial(m); Writeln(‘El factorial de ‘,m,’ es: ‘,resultado); END. La ejecución del programa es, para m = 4, la siguiente: factorial=4*factorial(3). factorial=4*3*factorial(2). factorial=4*3*2*factorial(1). factorial=4*3*2*1*factorial(0) (* Caso Base *) factorial=4*3*2*1 El seguimiento de lo que ocurre en la pila cuando se llama a factorial de 5 es:

Fact.(0) Fact.(1) Fact.(1) Fact.(1) Fact.(2) Fact.(2) Fact.(2) Fact.(2) Fact.(2)

Page 86: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

86

Fact.(3) Fact.(3) Fact.(3) Fact.(3) Fact.(3) Fact.(3) Fact.(3) Fact.(4) Fact.(4) Fact.(4) Fact.(4) Fact.(4) Fact.(4) Fact.(4) Fact.(4) Fact.(4) Fact.(5) Fact.(5) Fact.(5) Fact.(5) Fact.(5) Fact.(5) Fact.(5) Fact.(5) Fact.(5) Fact.(5) Fact.(5) Paso1 Paso2 Paso3 Paso4 Paso5 Paso6 Paso7 Paso8 Paso9 Paso10 Paso11 Paso12

Hemos señalado en negrita la llamada recursiva. Cuando se diseña un procedimiento o función recursiva siempre hay que asegurar que existe una condición de salida; es decir, si se cumple esa condición, estaremos en el caso base, donde no se prodeucen llamadas recursivas. Las llamadas recursivas deben aproximarse al caso base.

• • Programa 18. Sucesión de Fibonacci Escribe una función recursiva que calcule el término n de la sucesión de Fibonacci:

0, 1, 1, 2, 3, 5, 8, 13, 21, ….. Utilizaremos la siguiente definición recursiva: Fib(n)=n si n=0, o n=1; Fib(n)=Fib(n-1)+Fib(n-2) , si n>1 Function Fib(n:integer):integer; BEGIN If n=0 Then Fib:=0 Else If n=1 Then Fib:=1 Else Fib:=Fib(n-1)+Fib(n-2); END; La función es tremendamente ineficiente y sería mas adecuado un método iterativo. Veámoslo: Function Fib (n:integer):integer; Var i,x,y,z:integer; BEGIN If (n=0 ) or (n=1) then Fib:=n Else Begin x:=0; y:=1; For i:=2 to n do Begin z:=x+y; x:=y; y:=z; End; Fib:=z; End; END. La forma recursiva tardaría años en calcular el término 100 y el iterativos pocos segundos.

• • Programa 19. Potencia Escribe una función recursiva que calcule la potencia entera de un número real. Function Potencia(base:real;expon:integer):real BEGIN

Page 87: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

87

If expon=1 Then Potencia:=base Else Potencia:=base*Potencia(base,expon-1); END;

• • Programa 20. Suma elementos Array Escribe una función recursiva que calcule la suma de los elementos de un Array. Supongamos que el array tiene n elementos. El caso de parada ocurre cuando el array sólo tiene un elemento, es decir, cuando el índice es n=1, siendo el valor de la suma lista[1] (array de un elemento). Si n no es o, debemos añadir el valor del último elemento lista[n] a la suma del subarray con índices 1..n-1. Dicho de otra forma, la suma de los n elementos de un array es:

- caso de n=1: el valor del elemento. - Caso general(n>1): el valor del último elemento más la suma de los elementos del

subarray restante (n-1 elementos). lista:array[1..n] of integer; FUNCTION sumar(v:lista;n:integer):integer; BEGIN If n=1 then sumar:=v[n] Else sumar:=v[n]+sumar(v,n-1); END;

• • • Programa 21. Número de dígitos de un natural Dado un número natural n, diseña y escribe un subprograma recursivo en Pascal para calcular el número de dígitos de n. FUNCTION numdigitos(n:integer):integer; (*n>=0*) BEGIN If n<10 then numdigitos:=1 Else numdigitos:=1+numdigitos(n div 10); END; La TRAZA de la ejecución para n=3274 es: numdigitos(3274=1+numdigitos(327)=1+1+numdigitos(32)=1+1+1+numdigitos(3)=4

• • • Programa 22. Número de veces que un dígito aparece en un natural Dado un número natural n, diseña y escribe un subprograma recursivo en Pascal para calcular el número de veces que un digito d aparece en n. FUNCTION numveces(n,d:integer):integer;

Page 88: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

88

(*n,d>=0*) BEGIN If n<10 Then If n=d then numveces:=1 else numveces:=0 Else If (n mod 10=d) Then numveces:=1+numveces(n div 10,d) Else numveces:=numveces(n div 10,d); END;

• • • Programa 23. Número de dígitos incrementales Definimos como número de dígitos incrementales a todo natural n=dm dm-1……. d1d0 tal que di+1<=di para todo i=0, …m-1. Diseña y escribe una función recursiva en Pascal que, dado un número natural n, decida si es o no de dígitos incrementales. FUNCTION esincremental(n:integer):boolean; VAR d1,d2:integer; BEGIN If n<10 Then esincremental:=true Else Begin

d1:=n mod 10; d2:=(n div 10) mod 10; If (d1<d2) then

esincremental:=false Else

esincremental:=esincremental(n div 10); End; END;

• • • Programa 24. Representación binaria La representación binaria de un número natural n se obtiene con los restos que resultan de dividir sucesivamente n por 2, hasta que el dividendo es nulo. Para construir el correspondiente número binario, dichos restos se utilizan en orden inverso al que fueron obtenidos. Diseña y escribe un subprograma recursivo en Pascal que, dado un natural n, calcule su representación binaria. FUNCTION reprebinaria(n:integer, inicio:boolean):string; BEGIN If n=0 Then

If inicio Then reprebinaria:=’0’ Else reprebinaria:=’ ‘

Else If (n mod 2=0) Then reprebinaria:=reprebinaria(n div 2, False)+’0’ Else reprebinaria:=reprebinaria(n div 2,False)+’1’; reprebinaria:=reprebinaria(n div 2,False)+chr(n mod 2)+ord(‘0’; END;

Page 89: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

89

• • • Programa 25. Inverso simple

Definimos como inverso simple de una cadena de caracteres al inverso de la cadena sin repeticiones sucesivas. Por ejemplo, el inverso simple de la cadena de caracteres aaabccdddaaebb es la secuencia beadcba. Diseña y escribe en Pascal un subprograma recursivo que calcule el inverso simple de una cadena de caracteres de la que se conoce su longitud. FUNCTION inversimple(cadena:string):string; VAR longitud:integer; Corte:string; BEGIN longitud:=length(cadena) If longitud<=1Then inversimple:=cadena Else Begin corte:=copy(cadena,1,longitud-1) If cadena[longitud]=cadena[longitud-1]

Then inversimple:=inversimple(corte) Else inversimple:=cadena[longitud]+inversimpl(corte);

End; END;

• • • Programa 26. Caminos posibles Diseña y escribe en Pascal un programa que utilice un subprograma recursivo que nos dé los caminos posible que hay entre un origen A(0,0) y un destino B(x,y) en el plano coordenado y en el que los movimientos permitidos son en vertical y horizontal (punto a punto). PROGRAM ENTREPUNTOS(INPUT,OUTPUT); CONST N=20; TYPE TypePunto=RECORD x,y:INTEGER; END; TypeCamino=ARRAY[1..N] OF TypePunto; (* ************************************************************************ *) FUNCTION sonPuntosIguales(p1,p2:TypePunto):BOOLEAN; BEGIN sonPuntosIguales:=(p1.x=p2.x) AND (p1.y=p2.y); END; FUNCTION hayCamino(p1,p2:TypePunto):BOOLEAN; BEGIN hayCamino:=(p1.x<=p2.x) AND (p1.y<=p2.y); END; PROCEDURE buscarCaminos(origen,destino:TypePunto; VAR recorrido:TypeCamino;longitud:INTEGER); VAR i:INTEGER; arriba,derecha:TypePunto; BEGIN IF (longitud=1) THEN BEGIN recorrido[longitud]:=origen;

Page 90: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

90

longitud:=longitud+1; END; IF sonPuntosIguales(origen,destino) THEN BEGIN WRITELN('** Recorrido encontrado **'); FOR i:=1 TO longitud-1 DO WRITE('(',recorrido[i].x,' ',recorrido[i].y,') '); WRITELN; WRITELN('** Fin del recorrido encontrado **'); END ELSE BEGIN arriba.x:=origen.x; arriba.y:=origen.y+1; IF hayCamino(arriba,destino) THEN BEGIN recorrido[longitud]:=arriba; buscarCaminos(arriba,destino,recorrido,longitud+1); END; derecha.x:=origen.x+1; derecha.y:=origen.y; IF hayCamino(derecha,destino) THEN BEGIN recorrido[longitud]:=derecha; buscarCaminos(derecha,destino,recorrido,longitud+1); END; END; END; (* ************************************************************************ *) VAR miOrigen,miDestino:TypePunto; miRecorrido:TypeCamino; BEGIN (* Programa principal *) miOrigen.x:=0; miOrigen.y:=0; WRITE('Introduce la coordenada x del punto destino: '); READLN(miDestino.x); WRITE('Introduce la coordenada y del punto destino: '); READLN(miDestino.y); buscarCaminos(miOrigen,miDestino,miRecorrido,1); END. (* Programa principal *)

• • • Programa 27. Máximo común divisor de dos números Diseña y escribe una función recursiva en Pascal que, dado dos naturales a y b, calcule su máximo común divisor. FUNCTION mcd(a,b:integer):integer; BEGIN (*se supone a>b*) If a mod b=0 Then mcm:=b Else mcd:=mcd(b,a mod b); END;

• • • Programa 28. Invertir un número Realizar un método recursivo que imprima en pantalla las cifras de un número dado en orden inverso. PROCEDURE invertir(n:integer); BEGIN

Page 91: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

91

If n<10) Then write(n) Else Begin write(n mod 10); invertir(n div 10): End; END.

• • • Programa 29. Pertenencia de un elemento a un array Desarrolla una función dentro de un programa que determine de forma recursiva si un determinado elemento pertenece a un array. Dicha función será booleana y recibirá como parámetros el propio array y el elemento que se quiere buscar. El programa completo es el siguiente: PROGRAM EsMiembroarray; CONST max=10; TYPE rango=1..max; Tlista=array[rango] of integer; VAR N, elemento, i:integer; Lista:Tlista; FUNCTION EsMiembro(lista:Tlista;elemento, N:integer):boolean; BEGIN If N=1 Then (*array de 1 elemento*) EsMiembro:=lista[1]=elemento (*caso base*) Else If lista[N]=elemento Then (*mira si está en la posición N *) (* si está, salimos: otro caso base *) EsMiembro:=True Else (* caso general *) EsMiembro:=Esmiembro(lista,elemento,N-1); END; BEGIN (*Programa principal *) For i:=1 To max Do (* Introducir los datos del array *) Begin write(‘Introduce el elemento ‘,i,’: ‘); readln(Lista[i]); End; writeln(‘¿Qué elemento quieres buscar?: ‘); readln(elemento); If EsMiembro(lista,elemento,max) Then writeln(elemento,’ esta en el array’) Else writeln(elemento,’ no esta en el array’); End.

• • • Programa 30. Multiplicación Rusa

Page 92: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

92

Realiza un programa con una función recursiva que reciba dos números enteros y realice su multiplicación “ a la rusa “. El método consiste en formar dos columnas, una por cada operando. Las columnas se forman aplicando repetidamente los pasos siguientes:

- Dividir por dos el multiplicando y poner el cociente debajo. - Duplicar el multiplicador y poner el resultado debajo. - Cuando la columna del multiplicando llega a valor 1 se termina. - Se suman los valores del multiplicando que corresponden a valores impares de la

columna de multiplicandos. El resultado es el producto. Ejemplo Multiplicar por el método ruso los números 43 y 500.

1000+4000+16000=21500 que es 43x500 El caso de parada ocurrirá cuando el multiplicador sea 1. En otro caso se hará una llamada recursiva a la función con los parámetros siguientes: el multiplicador dividido por 2 (división entera) y el doble del multiplicador. Pero dentro de la parte recursiva hay que distinguir los casos d4 multiplicando par o impar. Cuando se impar, hay que devolver la suma del multiplicador y el valor que devuelva la llamada recursiva. Cuando sea par, se devolverá simplemente el valor que dvuelva la llamada recursiva, es decir, simplementese arrastrará el valor que reciba. El programa completo sería: PROGRAM mulRusa; FUNCTION rusa(x,y:integer); BEGIN If x>=1 Then If (x mod 2<>=) Then (*es par*) rusa:=y+rusa(x div 2,y*2) Else (*x es par*) Rusa:=rusa(x div 2,y*2) Else (*x es 0*) Rusa:=0; END; BEGIN (*Programa principal*) Writeln(rusa(43,500)) END. 8.2 Recursión cruzada Se produce cuando un programa llama a otro y éste a su vez al primero.Se presenta un problema para definir los subprogramas: FORWARD Ejemplo PROCEDURE segundo(lista parámetros);FORWARD; PROCEDURE primero (lista parámetros); BEGIN (*primero*)

segundo(……..);; END; PROCEDURE segundo(lista parámetros);

43 500 21 1000 10 2000 5 4000 2 8000 1 16000

Page 93: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

93

BEGIN (*segundo*) primero(.); END;

• • • Programa 31. Desplazamiento de un vector a la derecha Diseña y escribe un programa iterativo en Pascal que, dado un vector de enteros no necesariamente ordenado, desplace todos sus elementos una posición a la derecha sin utilizar vectores auxiliares. Escribe una versión recursiva de dicho programa. program desplazamiento; (*Versión iterativa*) uses crt; CONST n=5; TYPE tvector=array[1..n]of integer; var mivector:tvector; i:integer; Procedure desplazar (var vector:tvector); var ant,sig,j:integer; begin ant:=vector[1]; sig:=vector[2]; for j:=2 to n do begin vector[j]:=ant; ant:=sig; if j<n then sig:=vector[j+1] else vector[1]:=ant; end; end; BEGIN(*Programa principal*) clrscr; for i:=1 to n do begin write('introduce el numero de la posicion ',i,' :'); readln(mivector[i]); end; write('el vector introducido es: '); for i:=1 to n do write(mivector[i], ' '); desplazar (mivector); writeln; write('el vector desplazado es: ');

Page 94: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

94

for i:=1 to n do write(mivector[i], ' '); readln(); END. program desplazarecursivo; (*Versión recursiva*) uses crt; CONST n=5; TYPE tvector=array[1..n]of integer; VAR mivector:tvector; Procedure desplazar(Var vector:tvector;pos:integer;ant:integer;sig:integer); Begin If pos=n Then Begin Vector[pos]:=ant;

vector[1]:=sig; End Else Begin vector[pos]:=ant; desplazar(vector, pos+1,sig,vector[pos+1]); End; End; BEGIN(*Programa principal*) clrscr; for i:=1 to n do begin write('introduce el numero de la posicion ',i,' :'); readln(mivector[i]); end; write('el vector introducido es: '); for i:=1 to n do write(mivector[i], ' '); desplazar (mivector,2,mivector[1],mivector[2]); writeln; write('el vector desplazado es: '); for i:=1 to n do write(mivector[i], ' '); readln(); END.

• • • Programa 32. Número de veces Diseña y escribe un subprograma iterativo en Pascal que, dado un vector de enteros no necesariamente ordenado, calcule el número de veces que aparece el máximo y el mínimo de sus elementos en una sola pasada. Escribe una versión recursiva de dicho subprograma. CONST n=10; TYPE Tvector=array[1..n] of integer; PROCEDURE maximominimo(VAR v:Tvector;var max,numvecesmax,min,numvecesmin:integer);

Page 95: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

95

Var i:integer; Begin max:=v[1]; numvecesmax:=1; min:=v[1]; numvecesmin:=1; For i:=2 to n Do Begin If (v[i]>max then Begin max:=v[i];

numvecesmax:=1; End

Else If (v[i]=max then numvecesmax:=numvecesmax+1; If (v[i]<min then Begin min:=v[i];

numvecesmin:=1; End

Else If (v[i]=min then numvecesmin:=numvecesmin+1; End; End;

Vesión recursiva:

• • • Programa 33. Coincidencias con el factorial de la posición Diseña y escribe un subprograma recursivo en Pascal que, dado un vector de enteros, decida si existe algún elemento del mismo cuyo valor coincida con el factorial de su posición. Suponemos definida una función que calcula el factorial de un natural: Program coincidefact; CONST n=10; TYPE Tvector=array[1..n] of integer; VAR mivector:Tvector; resultado:boolean; FUNCTION coincidefactorial(Var v:Tvector;pos:integer); Var Begin If pos>n Then Coincidefactorial:=true Else If v[pos]=factorial(pos) then coincidefactiorial:=true Else coincidefactorial:=coincidefactorial(v,pos+1); (*El último If se puede sustituir por:*) (*coincidefactorial:=(v[pos]=factorial(pos) or coincidefactorial(v,pos+1)*) End; BEGIN

Page 96: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

96

inicializar(mivector); (*habría que tener este procedimiento*) resultado:=coincidefactorial(mivector,1); END.

• • • Programa 34. Entre dos valores Diseña y escribe un subprograma recursivo en Pascal que, dado un vector de enteros, decida si todos los elementos se encuentran entre dos valores. Program acotado; CONST n=10; TYPE= array[1..n] of integer; VAR resultado:boolean; mvector:Tvector; cotasup,cotainf:integer: FUNCTION vectoracotado(Var v:Tvector;cinf,csup:integer;pos:integer); Begin If pos>n then vectoracotado:=trae Else If (v[pos]>=cinf) and (v[pos]<=csup) Then vectoracotado:=vectoracotado(v,cinf,csup,pos+1) Else vector acotado:=false; (*Este último If se puede sustituir por:*) (*vectoracotado:=(v[pos]>=cinf) and (v[pos]<=csup) and vectoracotado(v,cinf,csup,pos+1)*) End; BEGIN inicializar(mivector); (*se incluye como procedimiento*) write(‘Introduce la cota inferior: ‘); readln(cotainf); write(‘Introduce la cota superior: ‘); readln(cotasup); resultado:=vectoracotado(mivector,cotainf,cotasup,1); writeln(¿Están todos entre ‘,cotainf,’ y ‘,cotasup, ‘ ¿’,resultado); END.

• • • Programa 35. Búsqueda dicotómica/Binaria Escribe un procedimiento iterativo y otro recursivo en Pascal que determine si un número dado está o no en un vector (array) ordenado y nos de su posición.. ITERATIVO Procedure Busquedabinaria(Var v:array[1..n] of integer; elem:integer; Var posición:integer); Var Linf,Lsup,Lmedio:integer; Encontrado:bolean; Begin Linf:=1; Lsup:=n; encontrado:=false; Repeat Begin Lmedio:=(Lsup+Linf) div 2; If elem=v[Lmedio] then

Page 97: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

97

Begin encontrado:=true;

posicion:=Lmedio; Else If elem<v[Lmedio] Then Lsup:=Lmedio-1 Else Linf:=Lmedio+1 End; Until (encontrado) or (Linf>Lsup); End; RECURSIVO Procedure Busquedabinaria (v:array[1..n] of integer;Linf,Lsup,elem:integer); Begin Pos:=(Linf+Lsup) div 2; If pos>=1 then If elem=v[pos] then write(pos) Else If elem<v[pos] then Begin Lsup:=pos; Busquedabinaria(v,Linf,Lsup,elem,pos); End

Else Begin Linf:=pos; Busquedabinaria(v,Linf,Lsup,elem,pos); End; End; BEGIN (*Programa principal*) Busquedabinaria(mivector,1,n,elemento,posicion)_; END.

• • • Programa 36. La floristería La floristería Margarita Tulipanes y sus gorgojos prepara ramos de flores con azucenas, claveles, lilas, rosas y violetas. Recibe pedidos y realiza envíos a cualquier lugar del país, guardando por cada ramo enviado los datos siguientes:

- Las variedades de flores que componen cada ramo y la cantidad de cada una de ellas. - El remitente, del que se almacena el nombre, el primer apellido y el domicilio. Si el

remitente reside fuera de Madrid se guarda la calle, la localidad de residencia y el código postal, mientras que si reside en la capital basta conocer la calle.

- El destinatario del pedido, del que se almacena la misma información que para el remitente.

- El precio del ramo. 1.- Define un tipo de datos que premita representar la información anterior. 2.- Define un tipo de datos que represente la información de todos los ramos de flores que fueron enviados en un día. TYPE

typeflor=(azucenas, claveles, lilas, rosas,violetas); tpecomposicion=array[typeflor] of integer; typeprovincia=(madrid,resto); typepersona= record

Page 98: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

98

nombre,apellido:string[20]; calle:string[40]; case lugar: typeprovincia of madrid: (dir:string[40]); resto: (direcc=record ciudad: string[20]; codigopostal: string[5]; end; typeRamo=Record composicion:typecomposicion; remitente,destinatario:typepresona; precio:real End; typeenvios:array[1..n]of typeramo; typefloristeria=record envios:typeenvios;

num_envios:0..n; end;

VAR margarita:typefloristeria; Para acceder a las rosas del envío 3 haremos margarita.envios.composicion[rosas]

• • • Programa 37. Atención a la tercera edad En el municipio de Valpardillo del conejo se está desarollando un programa de atención a la tercera edad cuyas actividades se basan en la media de edad de los ciudadanos empadronados en el municipio. Para calcular este dato, se ha elaborado un archivo compuesto por registros de tipo TypePersona, el cual se define como sigue: TypeFecha= RECORD dia, mes,anyo:integer; END;

TypePersona=RECORD nombre,apellidos:STRING[20]dia, mes,anyo:integer; nacimiento:TypeFecha; END; TypePersona

Nombre Apellidos

Fecha dia mes anyo

Diseña y escribe un subprograma en Pascal que, dado un archivo de registros de tipo TypePersona, calcule la media de sus edades. La fecha del reloj del sistema puede obtenerse mediante la rutina getDate() de TurboPascal, incluida en la unidad WinDos y cuya cabecera es la siguiente: PROCEDURE getDate(VAR anyo, mes, dia,diasemana:WORD) PROGRAM edad; CONST n=20; TYPE TypeFecha= RECORD dia, mes,anyo:integer;

Page 99: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

99

END;

TypePersona=RECORD nombre,apellidos:STRING[20]dia, mes,anyo:integer; nacimiento:TypeFecha; END; VAR vector:array[1..n]of TypePersona; anyoactual,mesactual,diaactual:integer;

diasactual:Strig[10]; i:integer;

FUNCTION calcularedad(persona:TypePersona):integer; Var edadaprox,edad:integer Begin getdate(anyoactual,mesactual,diaactual,diasactual); edadaprox:=(anyoactual-persona.nacimiento.anyo); If (mesactual<persona.nacimiento.mes) Then

edadaprox:=edadaprox-1 Else If (mesactual>persona.nacimiento.mes) Then edadaprox:=edadaprox+1 edad:=edadaprox; End; BEGIN (*Programa principal*)

• • • Programa 38. Descomposición de un natural en sumas Diseña y escribe un subprograma recursivo en Pascal que, dado un natural n, calcule todas las descomposiciones de n como suma de naturales. program descomponer; uses crt; CONST n=20; type cam=array[1..n] of integer; var num,longi:integer; solucion:cam; FUNCTION haysolucion(m:integer; camin:cam; long,R:integer):boolean; var i,suma:integer; begin suma:=0; for i:=1 to long do suma:=suma+camin[long]; suma:=suma+R; haysolucion:=suma<=m; end; PROCEDURE descomponer(n:integer; camino:cam; longitud:integer); var j,k,suma:integer; begin if longitud=1 then camino[longitud]:=0;

Page 100: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

100

for j:=1 to n do if haysolucion(n,camino,longitud,j) then begin longitud:=longitud+1; camino[longitud]:=j; descomponer(n,camino,longitud); suma:=0; for k:=2 to longitud do suma:=suma+camino[k]; if suma=n then begin for k:=2 to longitud do write(camino[k], ' '); writeln; end; end; end; BEGIN clrscr; write('¨que numero quieres descomponer?: '); readln(num); descomponer(num,solucion,0); readln; END.

• • • Programa 39. ¿ N es primo? Escribe un programa que determine si un número es primo utilizando el siguiente algoritmo: Se divide el número N entre 2,3,5,7,11,13,17,19,13,….. (saltando los múltiplos de 3) hasta N . Si alguna división es exacta, parar (n es compuesto). En otro caso es primo

• • • Programa 40. Circunferencia Escribe un programa que lea tres puntos del plano P1, P2, P3 y determine, en caso de que no estén alineados, los valores a, b y c de la ecuación de la circunferencia que pasa por ellos:

022 =++++ cbyaxyx El programa determinará también el radio y la longitud de dicha circunferencia.

• • • Programa 41. Aproximación del número π Escribe un programa que calcule aproximadamente el número π utilizando las fórmulas siguientes:

a) ...71

51

31

14

+−+−=π

b) .....11*9

17*5

13*1

18

+++=π

Page 101: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

101

• • • Programa 42. Sumas

Sea a ¡ = )2(1

100/2 iii + y �

=

=n

iin as

1

. Escribe un programa que calcule y escriba en pantalla los

valores 10s , 20s , 30s , …., 200s

PROGRAMAS EN FORTRAN

• • • Programa 1. Números Raros

Un posible código que resuelve el problema es el siguiente: PROGRAM numeros_raros IMPLICIT NONE CHARACTER(LEN=20) filesol INTEGER i DOUBLE PRECISION a,b,c,g3,g5,raiz_cubica,raiz_quinta !El nombre del fichero de datos lo conoce el programa PRINT*, 'Los datos se han leido desde el fichero datosp1' OPEN (11, FILE='datosp1') !Lectura del nombre del fichero resultados

Page 102: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

102

WRITE (*,'(A)',ADVANCE='NO') 'introduce el nombre de fichero de resultados: ' READ (*,'(A)') filesol OPEN (12, FILE=filesol) !PROGRAMA PRINCIPAL WRITE (12,*) 'PRACTICA P1´ WRITE (12,*) '===========================================================================================' WRITE (12,9000) ' CASO','a', 'b', 'c', 'g3(a,b,c)' 9000 FORMAT (A,10X,A,15X,A,18X,A,21X,A) WRITE (12,*) '===========================================================================================' !Para los 10 primeros datos a,b,c calculamos g3 mediante la funcion raiz_cubica DO i=1,10 READ(11,*) a,b,c g3=raiz_cubica(a*SQRT(b)+c)-raiz_cubica(a*SQRT(b)-c) !Escritura de resultados en Fichero filesol WRITE (12,9010) i,a,b,c,g3 9010 FORMAT (2X,I2,2X,F12.1,6X,F12.1,6X,F12.1,6X,G35.30) ENDDO WRITE (12,*) '===========================================================================================' WRITE (12,*) ' ' WRITE (12,*) ' ' WRITE (12,*) '===========================================================================================' WRITE (12,9000) ' CASO','a', 'b', 'c', 'g5(a,b,c)' WRITE (12,*) '===========================================================================================' !Para los 10 ultimos datos a,b,c calculamos g5 mediante la funcion raiz_quinta DO i=11,20 READ(11,*) a,b,c g5=raiz_quinta(a*SQRT(b)+c)-raiz_quinta(a*SQRT(b)-c) !Escritura de resultados en Fichero filesol WRITE (12,9010) i,a,b,c,g5 ENDDO WRITE (12,*) '===========================================================================================' END !FIN DEL PROGRAMA PRINCIPAL !Creamos las funciones DOUBLE PRECISION FUNCTION raiz_cubica(num) IMPLICIT NONE DOUBLE PRECISION num DOUBLE PRECISION logaritmodelnumero

Page 103: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

103

logaritmodelnumero=log(num) raiz_cubica=exp(logaritmodelnumero/3.) END FUNCTION raiz_cubica DOUBLE PRECISION FUNCTION raiz_quinta(num) IMPLICIT NONE DOUBLE PRECISION num DOUBLE PRECISION logaritmodelnumero logaritmodelnumero=log(num) raiz_quinta=exp(logaritmodelnumero/5.) END FUNCTION raiz_quinta

• • • Programa 2. Divisibilidad

Un posible código que resuelve el problema es el siguiente: PROGRAM divisibilidad_entre7 IMPLICIT NONE CHARACTER(LEN=20) filedat, filesol INTEGER a,i,j,k,resto,N(46),rN,cifra,T(6),Ttotal,rT !Lectura de los nombres de los ficheros de datos y resultados WRITE (*,'(A)') 'Los datos se han leido desde el fichero datosp2 ' OPEN (11, FILE='datosp2') WRITE (*,'(/A)',ADVANCE='NO') 'Introduce el nombre de fichero de resultados: ' READ (*,'(A)') filesol

Page 104: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

104

OPEN (12, FILE=filesol) !PROGRAMA PRINCIPAL !Para cada dato leido calculamos T, rN y rT. !Ti=suma de las cifras i,i+6,i+12,i+18... de N !rN=MODULO(N,7) !rT=MODULO(T,7) WRITE (12,*) ' PRACTICA P2: WRITE (12,*) '==============================================================================' WRITE (12,9000) ' |CASO|','N', '| T |', 'rN |','rT |' 9000 FORMAT (A,25X,A,27X,A,2X,A,2X,A) WRITE (12,*) '==============================================================================' DO i=1,10 READ(11,*) a,(N(j),j=1,a) ! Leemos el vector de cifras del número i-ésimo ¡ T(1:6)=0 !inicializamos el vector T a cero DO j=0,a-1 cifra=N(a-j) !La variable cifra toma los valores de las cifras de N, empezando por las unidades k=MOD(j,6) !La variable k nos permite sumar la cifra de lugar j en la posicion k del vector T T(k+1)=T(k+1)+cifra !Si j modulo 6 es k, hacemos k+1 porque el vector T no tiene posicion 0,empieza en 1 ENDDO Ttotal=T(1)-T(4)+3*(T(2)-T(5))+2*(T(3)-T(6)) rT=MODULO(Ttotal,7) rN=resto(N,a) !Cálculo del resto rN del número N leído, mediante la función resto !que simula la división explícita entre 7 !Escritura de resultados en Fichero filesol WRITE (12,'(A,I2,A)',ADVANCE='NO') ' ',i,' ' DO j=1,a WRITE(12,'(I1)',ADVANCE='NO')N(j) ENDDO DO j=a+1,46 WRITE(12,'(A)',ADVANCE='NO') ' ' ENDDO WRITE (12,'(7X,I3,4X,I2,4X,I2)',ADVANCE='NO') Ttotal,rN,rT IF (i<10) WRITE(12,'(/,A)')' -----------------------------------------------------------------------------' ENDDO WRITE (12,'(/,A)') '===============================================================================' END INTEGER FUNCTION resto(M,b) INTEGER M(46),cont,n,res,b res=MOD(M(1),7) DO cont=2,b n=M(cont)+res*10 res= MOD(n,7) ENDDO resto=res

Page 105: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

105

END FUNCTION

• • • Programa 3. Decisión: Primo Leemos varios enteros de un fichero de datos y decidimos si son primos o no conforme a la salida siguiente:

Un posible código que resuelve el problema es el siguiente: PROGRAM numeroPRIMO ! Este programa determina si una lista de 30 numeros enteros leidos desde un fichero de datos son primos o no. ! Para ello divide sucesivamente por 2, 3, 5, 7, 11, 13, 17, .... ! Salta los múltiplos de 3 hasta la parte entera de la raíz cuadrada de N IMPLICIT NONE INTEGER, PARAMETER:: numenteros=30 INTEGER num,i,d LOGICAL primo ! PROGRAMA PRINCIPAL CALL escritura DO i=1,numenteros READ(11,*) num CALL esprimo(num,primo,d) WRITE(12,'(I7,10X,L5)', ADVANCE='NO') num,primo If (d/=1) THEN WRITE(12,'(4X,A,I3,A)') 'Es un numero compuesto: ',d,' es un divisor'

Page 106: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

106

ELSE WRITE(12,'(4X,A)') 'Es un numero primo' ENDIF ENDDO END ! FIN DEL PROGRAMA PRINCIPAL SUBROUTINE esprimo(N,pri,divisor) !La funcion primo decide (TRUE/FALSE) si su argumento entero N es o no primo INTEGER N,div,divisor LOGICAL pri pri=.TRUE. divisor=1 !Inicialmente suponemos que es primo IF (MOD(N,2)==0 .AND.N>2) THEN ! Nos aseguramos si es múltiplo de 2 o de 3 pri=.FALSE. divisor=2 RETURN ENDIF IF (MOD(N,3)==0 .AND. N>3) THEN pri=.FALSE. divisor=3 ELSE div=5 DO IF (div**2<= N ) THEN !Para no pasarnos de raiz de N como posibles divisores IF (MOD(div,3)/=0) THEN !Para saltarnos los multiplos de 3 IF((MOD(N,div)==0)) THEN pri=.FALSE. divisor=div ! La función primo toma el valor false si encuentra algún divisor! EXIT ! Ya sabemos que no es primo y terminamos ENDIF ENDIF ELSE EXIT ! Si hemos pasado de raiz de N como posible divisor, ya no puede tener mas ENDIF div=div+2 ! Probamos con el siguiente divisor posible ENDDO ENDIF END SUBROUTINE esprimo SUBROUTINE escritura CHARACTER (LEN=20) filesol,filedat !Lectura del nombre del fichero de datos WRITE (*,'(/A)') 'Los datos han sido leidos desde el fichero datosp3' OPEN (11, FILE='datosp3') !Lectura del nombre del fichero resultados WRITE (*,'(/A)',ADVANCE='NO') 'Introduce el nombre de fichero de resultados: ' READ (*,'(A)') filesol OPEN (12, FILE=filesol) WRITE(12,*) '====================================================================' WRITE(12,*) ' Practica opcional P3: DECIDIMOS SI VARIOS ENTEROS SON PRIMOS O NO ' WRITE(12,*) WRITE(12,'(2X,A,11X,A)') 'ENTERO','PRIMO (T=TRUE F=FALSE) Y UN DIVISOR' WRITE(12,*) '-------------------------------------------------------------------'

Page 107: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

107

END SUBROUTINE

• • • Programa 4. Ecuación de segundo grado con coeficientes reales y complejos

Un posible código que resuelve el problema es el siguiente: PROGRAM ecuacion_2grado IMPLICIT NONE CHARACTER(LEN=20) filesol INTEGER i,indice DOUBLE PRECISION a,b,c,x1,x2 DOUBLE COMPLEX v,w,z,aux,x11,x22 !El nombre del fichero de datos lo conoce el programa PRINT*, 'Los datos se han leido desde el fichero datosp4' OPEN (11, FILE='datosp4') !Lectura del nombre del fichero resultados WRITE (*,'(A)',ADVANCE='NO') 'Introduce el nombre de fichero de resultados: ' READ (*,'(A)') filesol OPEN (12, FILE=filesol) !PROGRAMA PRINCIPAL WRITE (12,*) 'PRACTICA P4: WRITE (12,*) '===================================================================================================', & '====================' WRITE (12,'(A,12X,A,22X,A,22X,A,25X,A,20X,A)') ' CASO','a', 'b', 'c', 'x1', 'x2' WRITE (12,*) '===================================================================================================', & '===================='

Page 108: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

108

DO i=1,8 READ(11,*) a,b,c CALL resolver (a, b, c, x1, x2, indice) WRITE(12,'(1X,I1,3(6X,E17.10))',ADVANCE='NO') i,a,b,c SELECT CASE (indice) CASE (0) WRITE(12,'(A)') ' a=b=0. No existe ecuacion' CASE (1) WRITE(12,'(6X,E20.7,11X,A)') x1,'------' !ecuacion de primer grado CASE (2) WRITE(12,'(6X,E20.7)') x1,'(doble)' !raiz real doble CASE (3) WRITE(12,'(6X,2E20.7)') x1, x2, !raices complejas conjugadas CASE (4) WRITE(12,'(6X,2E20.7)') x1,x2 !raices reales simples ENDSELECT WRITE(12,*) '-------------------------------------------------------------------------------------------------', & '----------------------' ENDDO READ(11,*) v,w,z !Caso de coeficientes v,w,z complejos aux=w**2-4*v*z !Resolvemos la ecuacion de 2ºgrado vx**2+w*x+z=0 aux=SQRT(aux) x11= (-w+aux)/(2*v) x22=(-w-aux)/(2*v) !WRITE(12,'(1X,I1,3(1X,A,2(1X,F10.7),A),2(1X,A,2(1X,F10.7),A))') 9,'(',v,')','(',w,')','(',z,')','(',x11,')','(',x22,')' !WRITE (12,*) '===================================================================================================', & ! '====================' WRITE(12,'(1X,I1,3X,3(A,F10.7,",",F10.7,A),4X,2(A,F10.7,",",F10.7,A))') 9,'(',v,')','(',w,')','(',z,')','(',x11,')','(',x22,')' WRITE (12,*) '===================================================================================================', & '====================' END !FIN PROGRAMA PRINCIPAL !SUBRUTINAS ------------------------------------------------------------------------------------------ SUBROUTINE resolver (a, b, c, x1, x2, indice) !subrutina que resuelve una ecuacion de segundo grado DOUBLE PRECISION a, b, c, x1, x2,disc INTEGER indice indice = 0 ! no existe ecuacion IF (a==0.0 .AND. b==0.0) RETURN IF (a==0.0) THEN indice = 1 ! ecuacion de primer grado x1 = -c/b x2 = x1 RETURN ENDIF disc = b**2 - 4*a*c IF (disc==0.0) THEN indice = 2 ! raiz real doble

Page 109: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

109

x1 = -b /(2.*a) x2 = x1 RETURN ENDIF IF (disc<0) THEN indice = 3 ! raices complejas conjugadas x1 = -b /(2.*a) ! x1 contiene la parte real x2 = SQRT(-disc)/(2.*a) ! x2 contiene la parte imaginaria ELSE indice = 4 ! raices reales simples x1 = (-b+SQRT(disc))/(2.*a) x2 = (-b-SQRT(disc))/(2.*a) ENDIF END SUBROUTINE

• • • Programa 5. Circunferencia

Un posible código que resuelve el problema es el siguiente: PROGRAM circunferencia INTEGER, PARAMETER:: niterac=5 DOUBLE PRECISION, PARAMETER::pi=3.141592654 DOUBLE PRECISION puntos(3,2),ox,oy,r,L,S,radio,a,b,c INTEGER i,j LOGICAL haycircunferencia

Page 110: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

110

!PROGRAMA PRINCIPAL CALL cabecera !Subrutina en la que se len los ficheros y se realiza la escritura inicial DO i=1,niterac READ(11,*) (puntos(j,1), puntos(j,2), j=1,3) !Leemos los datos del fichero CALL centro(puntos,ox,oy,haycircunferencia) !Subrutina que calcula el centro de la circunferencia,en caso de que exista IF (haycircunferencia) THEN !Puntos no alineados !calculamos el radio llamando a la funcion radio,la longitud y el area del circulo r=radio(ox,oy,puntos(1,1),puntos(1,2)) L=2*pi*r S=pi*r**2 !Calculo coeficientes a, b y c de la ecuacion x**2 + y**2 + a*x + b*y + c = 0 a=-2*ox b=-2*oy c=ox**2+oy**2-r**2 !Escritura en fichero de salida 9000 FORMAT (1X,A,F5.3,A,F5.3,A,3X,A,E20.12,2X,A,E15.9,2X,A,E23.16,1X,A) 9010 FORMAT (1X,A,F5.3,A,F5.3,A,3X,A,E20.12,2X,A,21X,A,E23.16,1X,A) WRITE(12,9000) '| P1(',puntos(1,1),',',puntos(1,2),')','| a=',a,'| ox=',ox,'| r=',r,'|' WRITE(12,9000) '| P2(',puntos(2,1),',',puntos(2,2),')','| b=',b,'| oy=',oy,'| L=',L,'|' WRITE(12,9010) '| P3(',puntos(3,1),',',puntos(3,2),')','| c=',c,'|','| S=',S,'|' WRITE(12,*) '------------------------------------------------------------------------------------------------' ELSE ! Puntos alineados 9020 FORMAT (1X,A,F5.3,A,F5.3,A,3X,A,75X,A) 9011 FORMAT (1X,A,F5.3,A,F5.3,A,3X,A,16X,A) WRITE(12,9020) '| P1(',puntos(1,1),',',puntos(1,2),')','|','|' WRITE(12,9011) '| P2(',puntos(2,1),',',puntos(2,2),')','| PUNTOS ALINEADOS: NO HAY CIRCUNFERENCIA QUE PASE POR ELLOS','|' WRITE(12,9020) '| P3(',puntos(3,1),',',puntos(3,2),')','|','|' WRITE(12,*) '------------------------------------------------------------------------------------------------' ENDIF ENDDO END ! FIN DEL PROGRAMA PRINCIPAL !SUBRUTINAS--------------------------------------------------------------------------------------------------------- SUBROUTINE cabecera CHARACTER(LEN=20) filesol WRITE (*,'(A)') 'Los datos se han leido desde el fichero datosp5 ' OPEN (11, FILE='datosp5') WRITE (*,'(A)',ADVANCE='NO') 'introduce el nombre de fichero de resultados: ' READ (*,'(A)') filesol OPEN (12, FILE=filesol) WRITE (12,*) '=================================================================================================' WRITE (12,*) ' Practica P5: CIRCUNFERENCIA ' WRITE(12,*)

Page 111: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

111

WRITE(12,*) '=================================================================================================' 9020 FORMAT (1X,A,12X,A,16X,A,14X,A,21X,A) WRITE(12,9020) '| Puntos','| Ecuacion','| Centro','| Radio','|' WRITE(12,*) '-------------------------------------------------------------------------------------------------' END SUBROUTINE cabecera SUBROUTINE centro(punt,ox1,oy1,haycirc) DOUBLE PRECISION,INTENT(IN)::punt(3,*) !almacenamos las coordenadas de los 3 puntos DOUBLE PRECISION,INTENT(OUT)::ox1,oy1 ! coordenadas del centro de la circunferencia que pase por los 3 puntos anteriores LOGICAL,INTENT(OUT):: haycirc !variable logica que controla la existencia de la circunferencia (ptos no alineados) !variables locales DOUBLE PRECISION m1,m2, pmedios(2,2),n1,n2 INTEGER k,control1,control2 haycirc=.TRUE. m1=(punt(2,2)-punt(1,2))/(punt(2,1)-punt(1,1)) !calculamos la pendiente de la recta P1P2 m2=(punt(3,2)-punt(1,2))/(punt(3,1)-punt(1,1)) !calculamos la pendiente de la recta P1P3 control1=int(m1*10**12) control2=int(m2*10**12) !El punto de interseccion de ambas mediatrices sera el centro de la circunferencia. IF (control1/=control2) THEN DO k=1,2 pmedios(k,1)=(punt(1,1)+punt(k+1,1))/2 !en cada vuelta creamos el punto medio de los segmentos P1P2 y P1P3 pmedios(k,2)=(punt(1,2)+punt(k+1,2))/2 ENDDO m1=-1/m1 !Pendiente de la mediatriz de la recta P1P2 m2=-1/m2 !Pendiente de la mediatriz de la recta P1P3 n1=pmedios(1,2)-m1*pmedios(1,1) !ordenadas en el origen de ambas mediatrices n2=pmedios(2,2)-m2*pmedios(2,1) !Resolvemos el sistema. Coordenadas del centro O=(ox,oy) ox1=(n2-n1)/(m1-m2) oy1=m1*ox1+n1 ELSE haycirc=.FALSE. ENDIF END SUBROUTINE centro !FUNCIONES --------------------------------------------------------------------------------------------------------- DOUBLE PRECISION FUNCTION radio(c1,c2,x,y) !Calculamos el radio hallando la distancia del centro a un punto de la circunf. DOUBLE PRECISION c1,c2,x,y,aux aux=(c1-x)**2 + (c2-y)**2 radio=sqrt(aux) END FUNCTION radio

• • • Programa 6. Polinomio Interpolador de Lagrange

Page 112: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

112

Un posible código que resuelve el problema es el siguiente: !POLINOMIO DE INTERPOLACION DE LAGRANGE ! Dados los puntos (xi,yi) i=1...n con todos los xi distintos,leidos del fichero datosp3, el programa en primer lugar !ordena las abscisas de menor a mayor y calcula a=min{xi} y b=max{xi}. Despues divide el intervalo [a,b] en 100 partes !iguales. Para cada abscisa obtenida en la division,escribe su valor en el polinomio interpolador de Lagrange. PROGRAM interpolacionlagrange IMPLICIT NONE INTEGER, PARAMETER:: nmax=20 INTEGER npuntos !El programa trabaja con n puntos que pedira al usuario, valor almacenado en la variable npuntos. DOUBLE PRECISION puntos(2,nmax),paso,nuevaabscisa,aprox,polinomiolagrange DOUBLE PRECISION, EXTERNAL:: Li INTEGER i !PROGRAMA PRINCIPAL 10 WRITE(*,'(/A)',ADVANCE='NO') '¿Cuantos puntos quieres utilizar?(no mas de 20) ' READ*, npuntos IF (npuntos>20) THEN PRINT*, 'Numero de puntos demasiado grande' GOTO 10 !volvemos a pedir el numero de puntos, hasta que sea correcto ENDIF CALL escritura CALL lectura(npuntos,puntos,2) CALL ordenar(npuntos,puntos,2) WRITE (12,'(/A,F5.2)') '-> La abscisa menor es: ', puntos(1,1) !asi conocemos el intervalo WRITE (12,'(/A,F5.2)') '-> La abscisa mayor es: ', puntos(1,npuntos) 9010 FORMAT(/A,F5.2,A,F5.2,A) WRITE (12,9010) '-> Por tanto, trabajamos en el intervalo: [',puntos(1,1),',',puntos(1,npuntos),']' !Dividimos el intervalo en 100 partes iguales paso=(puntos(1,npuntos)-puntos(1,1))/100 !amplitud de los subintervalos WRITE(12,9010) 'Los puntos obtenidos al dividir el intervalo [',puntos(1,1),',',puntos(1,npuntos),'] en 100 partes iguales' WRITE(12,*) 'y sus correspondintes valores en el polinomio interpolador de Lagrange son: ' WRITE(12,'(18X,A,18X,A)') 'Xi','Yi' WRITE(12,'(9X,A)') '---------------------------------------' !Para cada abscisa de la division, hallamos su valor en el polinomio interpolador de Lagrange nuevaabscisa=puntos(1,1) DO i=1,99 nuevaabscisa=nuevaabscisa+paso

Page 113: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

113

!llamada a la funcion polinomiolagrange en la que uno de sus argumentos es,a su vez,otra funcion Li que calcula los !polinomios basicos de Lagrange aprox=polinomiolagrange(nuevaabscisa,npuntos,puntos,Li) WRITE (12,'(A,I2,A,5X,F15.10,2X,A,F20.10)') '[',i,']',nuevaabscisa,'|',aprox ENDDO END !FIN DEL PROGRAMA PRINCIPAL ! SUBRUTINAS ------------------------------------------------------------------------------------------------------- SUBROUTINE escritura !Escritura inicial CHARACTER(LEN=20) filesol WRITE (*,'(/A)') 'Los datos se han leido desde el fichero de datos datosp6' OPEN (11, FILE='datosp6') WRITE (*,'(/A)',ADVANCE='NO') 'introduce el nombre de fichero de resultados: ' READ (*,'(A)') filesol OPEN (12, FILE=filesol) WRITE(12,*)´============================================================================================================' WRITE(12,*) 'Dados los puntos (xi,yi) i=1...n con todos los xi distintos,leidos del fichero datosp3:' WRITE(12,'(7X,A)') ' 1) Se ordenan las abscisas de menor a mayor y se calcula a=min{xi} y b=max{xi}.' WRITE(12,'(7X,A)') ' 2) Se divide el intervalo [a,b] en 100 partes iguales.' WRITE(12,'(7X,A)') ' 3) Para cada abscisa obtenida en la division,escribe su valor en el polinomio interpolador de Lagrange.' WRITE(12,*) '==============================================================================================================' END SUBROUTINE escritura SUBROUTINE lectura(npunt,punt,nf) INTEGER,INTENT(IN):: npunt,nf DOUBLE PRECISION, INTENT(OUT)::punt(nf,*) WRITE (12,'(/,A,/)') 'Los puntos leidos del fichero datosp6 son: ' DO i=1,npunt READ(11,*) punt(1,i),punt(2,i) !Lo guarda en la columna i-esima de la matriz de dimension 2 x nmax WRITE(12,'(A,I2,A,F5.2,A,F5.2,A)') 'P',i,'=(',punt(1,i),',',punt(2,i),')' ENDDO END SUBROUTINE lectura SUBROUTINE ordenar(npunt,punt,nf) INTEGER,INTENT(IN)::npunt INTEGER j,k DOUBLE PRECISION,INTENT(OUT):: punt(nf,*) DOUBLE PRECISION aux DO j=1,npunt-1 !En cada vuelta, el menor va a parar a puntos(1,j) DO k=j+1,npunt IF (punt(1,k)<punt(1,j)) THEN aux=punt(1,j) punt(1,j)=punt(1,k) !Va comparando cada abscisa con todas las siguientes y las intercambia punt(1,k)=aux !de modo que va ordenandolas de menor a mayor aux=punt(2,j) punt(2,j)=punt(2,k) punt(2,k)=aux ENDIF

Page 114: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

114

ENDDO ENDDO END SUBROUTINE ordenar ! FUNCIONES--------------------------------------------------------------------------------------------------------- DOUBLE PRECISION FUNCTION polinomiolagrange(xx,np,p,L) !calcula el polinomio de interpolacion de Lagrange DOUBLE PRECISION auxiliar,sumando,xx DOUBLE PRECISION, EXTERNAL:: L !Se observa el argumento L que, a su vez, es una funcion INTEGER contador,np DOUBLE PRECISION p(2,*) auxiliar=0.0 DO contador=1,np sumando=L(xx,contador,np,p)*p(2,contador) auxiliar=auxiliar+sumando ENDDO polinomiolagrange=auxiliar END FUNCTION DOUBLE PRECISION FUNCTION Li(x,m,n,punt) !Esta funcion calcula los polinomios basicos de interpolacion de Lagrange DOUBLE PRECISION x,parcial INTEGER m,t,n DOUBLE PRECISION punt(2,n) parcial=1.0 DO t=1,n IF (t/=m) parcial=parcial*(x-punt(1,t))/(punt(1,m)-punt(1,t)) ENDDO Li=parcial END FUNCTION

Page 115: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

115

• • • Programa 7. Variables aleatorias

PROGRAM variablealeatoria IMPLICIT NONE DOUBLE PRECISION p(9,9),prueba(9,9),mprob(9,9),sumaexacta,sumasimulada !en p almacenamos las probabilidades de los valores que toma cada variable aleatoria (por columnas) !mprob es una matriz que almacena las probabilidades simuladas de los valores de cada variable INTEGER i,j,n(9) !n es un vector que almacena los posibles valores que puede tomar cada variable aleatoria DOUBLE PRECISION X(9:57),Xsim(9:57) !X,Xsim vectores con posiciones de 9 a 57 donde guardamos la probabilidad de que X tome cada valor !de forma exacta y de forma simulada CHARACTER(LEN=20) filesol

Page 116: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

116

!PROGRAMA PRINCIPAL ------------------------------------------------------------------------------------------------------- !Abrimos ficheros de datos y de resultados WRITE(*,'(/A)') 'Los datos se han leido desde el fichero de datos datosp7' OPEN(11, FILE='datosp7') WRITE(*,'(/A)',ADVANCE='NO') 'introduce el nombre del fichero de resultados: ' READ(*,'(A)') filesol OPEN(12, FILE=filesol) WRITE(*,'(/A)') 'Procesando ... (tarda 1 minuto aproximadamente)' WRITE(12,*) 'Número de orden: |4| Alumna: BASCUÑANA GALLEGO, Maribel' WRITE(12,*) '==============================================================================================================' WRITE(12,*) 'PRACTICA P7: VARIABLES ALEATORIAS ' !Leemos datos del fichero daposp7 DO i=1,9 READ(11,*) n(i),(p(j,i) ,j=1,n(i)) ENDDO CALL distribucionX(p,n,9,X) !hallamos la distribucion exacta de la variable aleatoria suma: X CALL simulacion(p,n,9,mprob) CALL distribucionX(mprob,n,9,Xsim) !hallamos la distribucion por simulacion (orden 10^7) de la variable aleatoria suma: X sumasimulada=0 sumaexacta=0 WRITE(12,*) '===============================================================================' WRITE(12, '(A,9X,A,7X,A,8X,A)') '| VALOR v |','P(X=v) por simulacion','|','P(X=v) valor exacto |' DO i=9,57 WRITE(12,*) '-------------------------------------------------------------------------------' WRITE(12,'(A,4X,I2,4X,A,2X,E33.27,2X,A,2X,E28.22,A)') '|',i,'|',Xsim(i),'|',X(i),'|' sumasimulada=sumasimulada+Xsim(i) sumaexacta=sumaexacta+X(i) ENDDO WRITE(12,*) '===============================================================================' WRITE(12,'(A,15X,F6.4,16X,A,12X,F6.4,12X,A)') '| SUMA P : |',sumasimulada,'|',sumaexacta,'|' WRITE(12,*) '===============================================================================' END !FIN DEL PROGRAMA PRINCIPAL ----------------------------------------------------------------------------------------------- !SUBRUTINAS --------------------------------------------------------------------------------------------------------------- !Esta subrutina obtiene la distribucion exacta (o funcion de masa) de la variable aleatoria X=Y1+Y2+...+Y9 a partir la !matriz de probabilidades leida del fichero de datos (observamos que el valor minimo de la variable aleatoria suma es 9 !y elvalor maximo es 57.

Page 117: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

117

SUBROUTINE distribucionX(pp,nn,nf,XX) IMPLICIT NONE DOUBLE PRECISION, INTENT(IN):: pp(nf,*) !matriz con tamaño asumido DOUBLE PRECISION, INTENT(OUT):: XX(9:57) INTEGER k,nn(9),nf,i1,i2,i3,i4,i5,i6,i7,i8,i9 XX=0 DO i1=1,nn(1) DO i2=1,nn(2) DO i3=1,nn(3) DO i4=1,nn(4) DO i5=1,nn(5) DO i6=1,nn(6) DO i7=1,nn(7) DO i8=1,nn(8) DO i9=1,nn(9) k=i1+i2+i3+i4+i5+i6+i7+i8+i9 XX(k)=XX(k)+pp(i1,1)*pp(i2,2)*pp(i3,3)*pp(i4,4)*pp(i5,5)*pp(i6,6)*pp(i7,7)*pp(i8,8)*pp(i9,9) ENDDO ENDDO ENDDO ENDDO ENDDO ENDDO ENDDO ENDDO ENDDO END SUBROUTINE distribucionX !Esta subrutina obtiene 10^7 numeros naturales al azar en el intervalo (0,1000] y,para cada variable Yi cuenta (en la columa ! i de la matriz prob) el numero de veces que dicha variable toma cada uno de sus posibles valores: 1,2...n(i) segun la matriz de probabilidades !leida del fichero de datos. Posteriormente dividiendo por 10^7, en prob se obtiene la matriz de probabilidades simulada. SUBROUTINE simulacion(pp,nn,nf,prob) IMPLICIT NONE DOUBLE PRECISION, INTENT(IN):: pp(nf,*) INTEGER, INTENT(IN):: nn(9) DOUBLE PRECISION, INTENT(OUT):: prob(nf,*) INTEGER i,k,nf,nvueltas,aleat DOUBLE PRECISION acumulado REAL num prob=0 !inicializacion DO nvueltas=1,10**7 CALL RANDOM_SEED() CALL RANDOM_NUMBER(num) aleat=int(num*1000)+1 DO i=1,9 !para cada variable Yi,busco en que intervalo acumulativo de probabilidad*1000 esta el numero aleatorio(aleat) acumulado=pp(1,i)*1000 DO k=1,nn(i) IF (aleat<=acumulado) THEN prob(k,i)=prob(k,i)+1 EXIT !hemos encontrado el intervalo,es decir,hemos simulado la realizacion de la variable Yi ELSE acumulado=acumulado+pp(k+1,i)*1000 ENDIF ENDDO

Page 118: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

118

ENDDO ENDDO DO i=1,9 !En prob almacenamos las probabilidades simuladas de los valores de cada variable Yi DO k=1,nn(i) prob(k,i)=prob(k,i)/(10**7) ENDDO ENDDO END SUBROUTINE simulación

• • • Programa 8. Circulo de dispersión

Page 119: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

119

Un posible código que resuelve el problema es el siguiente: !en los datos tenemos P1-P21 P2-P22 ...P20-P40 PROGRAM circulodedispersion IMPLICIT NONE DOUBLE PRECISION puntos(40,2),dist1,dist2,cent1,cent2,distancia,radio !almacenamos los 40 puntos en la matriz puntos INTEGER basepuntos(3),i,j,k,contador !basepuntos es un vector donde se guardan las posiciones de los puntos que CHARACTER(LEN=20) filesol !en cada momento van constituyendo la minima circunferencia LOGICAL CirculoPor,hayc !PROGRAMA PRINCIPAL ------------------------------------------------------------------------------------------------------- !Abrimos ficheros de datos y de resultados WRITE(*,'(/A)') 'Los datos se han leido desde el fichero de datos datosp8' OPEN(11, FILE='datosp8') WRITE(*,'(/A)',ADVANCE='NO') 'introduce el nombre del fichero de resultados: ' READ(*,'(A)') filesol OPEN(12, FILE=filesol) WRITE(12,*) '==============================================================================================================' WRITE(12,*) 'PRACTICA P8: CIRCULO DE DISPERSION' !Leemos datos del fichero daposp8 DO i=1,20 READ(11,*) puntos(i,1),puntos(i,2),puntos(i+20,1),puntos(i+20,2) ENDDO basepuntos=0 DO i=1,40 IF (CirculoPor(puntos(i,1),puntos(i,2),puntos,basepuntos)) THEN basepuntos=0 basepuntos(1)=i !esta funcion da VERDADERO si el punto considerado no DO j=1,i-1 !esta en el circulo determinado por los puntos del conjunto basepuntos IF (CirculoPor(puntos(j,1),puntos(j,2),puntos,basepuntos)) THEN basepuntos(2)=j basepuntos(3)=0 DO k=1,j-1 IF (CirculoPor(puntos(k,1),puntos(k,2),puntos,basepuntos)) basepuntos(3)=k ENDDO ENDIF ENDDO ENDIF ENDDO !AL SALIR DEL BUCLE ANTERIOR, EN BASEPUNTOS TENEMOS LOS 2 O 3 PUNTOS QUE DETERMINAN LA MINIMA CIRCUNFERENCIA contador=0 DO i=1,3 IF (basepuntos(i)==0) contador=contador+1 !contamos el nº de posiciones vacias ENDDO IF (contador==0) THEN !3 puntos en la base CALL centro(puntos(basepuntos(2),1),puntos(basepuntos(2),2),puntos(basepuntos(3),1), & & puntos(basepuntos(3),2),puntos(basepuntos(1),1),puntos(basepuntos(1),2),cent1,cent2,hayc)

Page 120: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

120

IF (hayc) radio=distancia(puntos(basepuntos(3),1),puntos(basepuntos(3),2),cent1,cent2) ELSE !2 puntos en la base cent1=(puntos(basepuntos(1),1)+puntos(basepuntos(2),1))/2 cent2=(puntos(basepuntos(1),2)+puntos(basepuntos(2),2))/2 radio=distancia(puntos(basepuntos(1),1),puntos(basepuntos(1),2),cent1,cent2) ENDIF !ESCRITURA EN FICHERO WRITE(12,*) WRITE(12,'(A,3X,A)') '================================================',' =================================================' WRITE(12,'(2(A,4X,A,3X))') '| P=(Px,Py) | Marca |',' dist (O,P) |','| P=(Px,Py) | Marca |',' dist (O,P) |' WRITE(12,'(A,3X,A)') '================================================',' =================================================' DO i=1,20 dist1=distancia(puntos(i,1),puntos(i,2),cent1,cent2) dist2=distancia(puntos(i+20,1),puntos(i+20,2),cent1,cent2) IF (dist1==radio .and. dist2==radio) THEN WRITE(12,'(A,1X,I2,A,F3.0,A,F3.0,A,1X,A,2X,A,F22.18,A)',ADVANCE='NO') '|',i,':(',puntos(i,1),',',puntos(i,2),')','|', & & ' * |',dist1,' |' WRITE(12,'(A,1X,I2,A,F3.0,A,F3.0,A,1X,A,2X,A,F22.18,A)') ' |',i+20,':(',puntos(i+20,1),',',puntos(i+20,2),')','|', & & ' * |',dist2,' |' ENDIF IF (dist1==radio .and. dist2/=radio) THEN WRITE(12,'(A,1X,I2,A,F3.0,A,F3.0,A,1X,A,2X,A,F22.18,A)',ADVANCE='NO') '|',i,':(',puntos(i,1),',',puntos(i,2),')','|', & & ' * |',dist1,' |' WRITE(12,'(A,1X,I2,A,F3.0,A,F3.0,A,1X,A,2X,A,F22.18,A)') ' |',i+20,':(',puntos(i+20,1),',',puntos(i+20,2),')','|', & & ' |',dist2,' |' ENDIF IF (dist1/=radio .and. dist2==radio) THEN WRITE(12,'(A,1X,I2,A,F3.0,A,F3.0,A,1X,A,2X,A,F22.18,A)',ADVANCE='NO') '|',i,':(',puntos(i,1),',',puntos(i,2),')','|', & & ' |',dist1,' |' WRITE(12,'(A,1X,I2,A,F3.0,A,F3.0,A,1X,A,2X,A,F22.18,A)') ' |',i+20,':(',puntos(i+20,1),',',puntos(i+20,2),')','|', & & ' * |',dist2,' |' ENDIF IF (dist1/=radio .and. dist2/=radio) THEN WRITE(12,'(A,1X,I2,A,F3.0,A,F3.0,A,1X,A,2X,A,F22.18,A)',ADVANCE='NO') '|',i,':(',puntos(i,1),',',puntos(i,2),')','|', & & ' |',dist1,' |' WRITE(12,'(A,1X,I2,A,F3.0,A,F3.0,A,1X,A,2X,A,F22.18,A)') ' |',i+20,':(',puntos(i+20,1),',',puntos(i+20,2),')','|', & &' |',dist2,' |' ENDIF ENDDO WRITE(12,*) WRITE(12,'(A,3X,A)') ' ========================================================================================' WRITE(12,'(A,3X,A,F22.18,2X,A,F22.18,2X,A,F22.18,A)') 'CIRCULO','| OX=',cent1,'|OY=',cent2,'|radio=',radio,' |' WRITE(12,'(A,3X,A)') ' ========================================================================================'

Page 121: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

121

END !FIN DEL PROGRAMA PRINCIPAL ---------------------------------------------------------------------------------------------- !SUBRUTINAS--------------------------------------------------------------------------------------------------------------- SUBROUTINE centro(p11,p12,p21,p22,p31,p32,c1,c2,haycirc) DOUBLE PRECISION,INTENT(IN)::p11,p12,p21,p22,p31,p32 !almacenamos las coordenadas de los 3 puntos DOUBLE PRECISION,INTENT(OUT)::c1,c2 !coordenadas del centro de la circunferencia que pase por los 3 puntos anteriores LOGICAL,INTENT(OUT):: haycirc !variable logica que controla la existencia de la circunferencia (ptos no alineados) !variables locales DOUBLE PRECISION m1,m2, pmedios(2,2),n1,n2,aux1,aux2,aux3,aux4 haycirc=.TRUE. !inicializacion aux1=p21-p11 aux2=p22-p12 aux3=p31-p11 aux4=p32-p12 !Distinguimos posibles casos segun la colocacion de los puntos en el plano !CALCULAMOS EL CENTRO COMO INTERSECCION DE DOS DE LAS MEDIATRICES DE LOS SEGMENTOS QUE DETERMINAN LOS PUNTOS DE ENTRADA !Los 7 casos siguientes son particulares debido al procedimiento de calculo del centro IF (aux2==0 .and. aux3==0) THEN c1=(p21+p11)/2 c2=(p32+p12)/2 RETURN ENDIF IF (aux1==0 .and. aux4==0) THEN c1=(p31+p11)/2 c2=(p22+p12)/2 RETURN ENDIF IF ((aux2==0 .and. aux4==0) .or. (aux1==0 .and. aux3==0)) THEN !los puntos estan alineados en horizontal o en vertical haycirc=.FALSE. !por tanto,no es posible hallar la circunferencia RETURN ENDIF IF (aux2==0) THEN c1=(p21+p11)/2 c2=p12+aux4*(c1-p11)/aux3 RETURN ENDIF IF (aux4==0) THEN c1=(p31+p11)/2 c2=p12+aux2*(c1-p11)/aux1 RETURN ENDIF IF (aux1==0) THEN c2=(p22+p12)/2 c1=p11+aux3*(c2-p12)/aux4 RETURN ENDIF IF (aux3==0) THEN c2=(p32+p12)/2 c1=p11+aux1*(c2-p12)/aux2

Page 122: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

122

RETURN ENDIF !Puntos en posicion general m1=aux2/aux1 !calculamos la pendiente de la recta P1P2 m1=-1/m1 !Pendiente de la mediatriz de la recta P1P2 m2=aux4/aux3 !calculamos la pendiente de la recta P1P3 m2=-1/m2 !Pendiente de la mediatriz de la recta P1P3 !El punto de interseccion de ambas mediatrices sera el centro de la circunferencia. IF (m1/=m2) THEN pmedios(1,1)=(p11+p21)/2 pmedios(1,2)=(p12+p22)/2 pmedios(2,1)=(p11+p31)/2 pmedios(2,2)=(p12+p32)/2 n1=pmedios(1,2)-m1*pmedios(1,1) !ordenadas en el origen de ambas mediatrices n2=pmedios(2,2)-m2*pmedios(2,1) !Resolvemos el sistema. Coordenadas del centro O=(c1,c2) c1=(n2-n1)/(m1-m2) c2=m1*c1+n1 ELSE !estan alineados pero no en horizontal ni en vertical haycirc=.FALSE. ENDIF END SUBROUTINE centro !FUNCIONES --------------------------------------------------------------------------------------------------------------- DOUBLE PRECISION FUNCTION distancia(r,s,x,y) !Calcula la distancia entre dos puntos. DOUBLE PRECISION r,s,x,y,aux aux=(r-x)**2 + (s-y)**2 distancia=sqrt(aux) END FUNCTION distancia !esta funcion devuelve TRUE si el punto (x,y) no pertenece a la circunferencia determinada por los puntos de la base B y !falso en caso contrario LOGICAL FUNCTION CirculoPor(x,y,punt,B) INTEGER,INTENT(IN):: B(:) !vector B en forma asumida DOUBLE PRECISION,INTENT(IN)::x,y,punt(40,*) !matriz punt en tamaño asumido INTEGER i,cont DOUBLE PRECISION centro1,centro2,d1,d2,auxd1,auxd2 LOGICAL haycirculo cont=0 DO i=1,3 IF (B(i)==0) cont=cont+1 ENDDO IF ((cont==2) .or. (cont==3)) CirculoPor=.true. !en B tenemos un unico punto o ninguno IF (cont==1) THEN !en B tenemos dos puntos, calculamos el centro de la circunferencia que pasa por ellos centro1=(punt(B(1),1)+punt(B(2),1))/2 centro2=(punt(B(1),2)+punt(B(2),2))/2 !coordenadas del centro d1=distancia(centro1,centro2,punt(B(1),1),punt(B(1),2)) !hallamos el radio usando una funcion anterior d2=distancia(centro1,centro2,x,y) !hallamos la distancia del punto (x,y) al centro IF (d2>d1) THEN

Page 123: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

123

CirculoPor=.true. ELSE CirculoPor=.false. ENDIF ENDIF IF (cont==0) THEN !tenemos 3 puntos en la base B, en este caso,hallamos el centro de la circunferencia que pasa por ellos CALL centro(punt(B(1),1),punt(B(1),2),punt(B(2),1),punt(B(2),2),punt(B(3),1),punt(B(3),2),centro1,centro2,haycirculo) IF (haycirculo) THEN d1=distancia(centro1,centro2,punt(B(1),1),punt(B(1),2)) d2=distancia(centro1,centro2,x,y) IF (d2>d1) THEN CirculoPor=.true. ELSE CirculoPor=.false. ENDIF ELSE d1=distancia(punt(B(1),1),punt(B(1),2),punt(B(3),1),punt(B(3),2)) d2=distancia(punt(B(2),1),punt(B(2),2),punt(B(3),1),punt(B(3),2)) IF (d2>d1) THEN centro1=(punt(B(2),1)+punt(B(3),1))/2 centro2=(punt(B(2),1)+punt(B(3),1))/2 auxd1=distancia(centro1,centro2,punt(B(3),1),punt(B(3),2)) !hallamos el radio auxd2= distancia(centro1,centro2,x,y) IF (auxd2>auxd1) THEN CirculoPor=.true. ELSE CirculoPor=.false. ENDIF ENDIF ENDIF ENDIF END FUNCTION CirculoPor

• • • Programa 9. Integración por aproximación CÁLCULO DE LA INTEGRAL DEFINIDA DE UNA FUNCION POLINÓMICA DE GRADO MENOR O IGUAL QUE 3 POR DISTINTOS CASOS PARTICULARES DE LAS FORMULAS DE NEWTON COTES: REGLA DE LOS TRAPECIOS Y REGLA DE SIMPSON, EN FORMA SIMPLE Y COMPUESTA CADA UNA DE ELLAS.' PROGRAM integral IMPLICIT NONE DOUBLE PRECISION,DIMENSION (3):: a,b,c,d,r,s,T,TC,SI,SC !a,b,c,d coeficientes de la funcion. r y s extremos del intervalo DOUBLE PRECISION trapeciosimple,simpsonsimple,trapeciocompuesta,simpsoncompuesta DOUBLE PRECISION Tlog,Slog,TClog,SClog,flog,trapeciocompuestalog,simpsoncompuestalog DOUBLE PRECISION exacto CHARACTER(LEN=20) filesol INTEGER i,j !Lectura de los nombres de los ficheros de datos y resultados WRITE (*,'(A)') 'Los datos se han leido desde el fichero datosp9 ' OPEN (11, FILE='datosp9')

Page 124: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

124

WRITE (*,'(/A)',ADVANCE='NO') 'Introduce el nombre de fichero de resultados: ' READ (*,'(A)') filesol OPEN (12, FILE=filesol) !PROGRAMA PRINCIPAL WRITE (12,*) '========================================================================================================' WRITE (12,*) ' Practica P9: CALCULO DE LA INTEGRAL DEFINIDA DE UNA FUNCION POLINÓMICA DE GRADO MENOR O IGUAL ' WRITE (12,*) ' QUE 3 POR DISTINTOS CASOS PARTICULARES DE LAS FORMULAS DE NEWTON COTES: REGLA DE LOS TRAPECIOS Y REGLA ' WRITE (12,*) ' DE SIMPSON, EN FORMA SIMPLE Y COMPUESTA CADA UNA DE ELLAS.' WRITE (12,*) '========================================================================================================' WRITE (12,*) WRITE (12,*) ' Dada una funcion polinomica f(x)=ax^3+bx*2+cx+d de grado menor o igual que 3, se calcula su ',& 'integral definida en el intervalo [r,s] de forma aproximada utilizando la regla del trapecio y la ',& 'regla de Simpson tanto simple como compuestapara cada una de ellas' WRITE(12,'(/,A)') ' NOTACION: trapecio simple(T), Simpson simple(S)' WRITE(12,'(11X,A)')'trapecio compuesta para 10 subintervalos(TC) y Simpson compuesta para 10 subintervalos(SC)' DO i=1,2 READ (11,*) (a(j),j=1,3) !en la primera vuelta lee los datos de los 3 primeras funciones, en la segunda los datos de la READ (11,*) (b(j),j=1,3) !cuarta a la sexta y en la tercera los datos de las tres ultimas funciones. READ (11,*) (c(j),j=1,3) READ (11,*) (d(j),j=1,3) READ (11,*) (r(j),j=1,3) READ (11,*) (s(j),j=1,3) DO j=1,3 T(j)=trapeciosimple(a(j),b(j),c(j),d(j),r(j),s(j)) SI(j)=simpsonsimple(a(j),b(j),c(j),d(j),r(j),s(j)) TC(j)=trapeciocompuesta(a(j),b(j),c(j),d(j),r(j),s(j)) SC(j)=simpsoncompuesta(a(j),b(j),c(j),d(j),r(j),s(j)) ENDDO WRITE(12,'(/,(3(A,3X)))') '=========================','========================','========================' SELECT CASE (i) CASE (1) WRITE(12,'(A,8X,A,8X,A,3X,A,8X,A,8X,A,2X,A,8X,A,7X,A)') '|',' CASO 1','|','|',' CASO 2','|','|',' CASO 3','|' CASE (2) WRITE(12,'(A,8X,A,8X,A,3X,A,8X,A,8X,A,2X,A,8X,A,7X,A)') '|',' CASO 4','|','|',' CASO 5','|','|',' CASO 6','|' END SELECT WRITE(12,'(3(A,3X))') '=========================','========================','========================' WRITE(12,'(A,F17.12,2X,A,3X,A,F17.12,2X,A,2X,A,F17.12,1X,A,)') '| a =',a(1),'|','| a =',a(2),'|','| a =',a(3),'|' WRITE(12,'(3(A,3X))') '-------------------------','------------------------','------------------------'

Page 125: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

125

WRITE(12,'(A,F17.12,2x,A,3X,A,F17.12,2X,A,2X,A,F17.12,1X,A,)') '| b =',b(1),'|','| b =',b(2),'|','| b =',b(3),'|' WRITE(12,'(3(A,3X))') '-------------------------','------------------------','------------------------' WRITE(12,'(A,F17.12,2x,A,3X,A,F17.12,2X,A,2X,A,F17.12,1X,A,)') '| c =',c(1),'|','| c =',c(2),'|','| c =',c(3),'|' WRITE(12,'(3(A,3X))') '-------------------------','------------------------','------------------------' WRITE(12,'(A,F17.12,2x,A,3X,A,F17.12,2X,A,2X,A,F17.12,1X,A,)') '| d =',d(1),'|','| d =',d(2),'|','| d =',d(3),'|' WRITE(12,'(3(A,3X))') '-------------------------','------------------------','------------------------' WRITE(12,'(A,F17.12,2x,A,3X,A,F17.12,2X,A,2X,A,F17.12,1X,A,)') '| r =',r(1),'|','| r =',r(2),'|','| r =',r(3),'|' WRITE(12,'(3(A,3X))') '-------------------------','------------------------','------------------------' WRITE(12,'(A,F17.12,2x,A,3X,A,F17.12,2X,A,2X,A,F17.12,1X,A,)') '| s =',s(1),'|','| s =',s(2),'|','| s =',s(3),'|' WRITE(12,'(3(A,3X))') '-------------------------','------------------------','------------------------' WRITE(12,'(3(A,3X))') '-------------------------','------------------------','------------------------' WRITE(12,'(A,F17.12,2X,A,3X,A,F17.12,2X,A,2X,A,F17.12,1X,A,)') '| T =',T(1),'|','| T =',T(2),'|','| T =',T(3),'|' WRITE(12,'(3(A,3X))') '-------------------------','------------------------','------------------------' WRITE(12,'(A,F17.12,2X,A,3X,A,F17.12,2X,A,2X,A,F17.12,1X,A,)') '| S =',SI(1),'|','| S =',SI(2),'|','| S =',SI(3),'|' WRITE(12,'(3(A,3X))') '-------------------------','------------------------','------------------------' WRITE(12,'(A,F16.12,2X,A,3X,A,F16.12,2X,A,2X,A,F16.12,1X,A,)') '| TC =',TC(1),'|','| TC =',TC(2),'|','| TC =',TC(3),'|' WRITE(12,'(3(A,3X))') '-------------------------','------------------------','------------------------' WRITE(12,'(A,F16.12,2X,A,3X,A,F16.12,2X,A,2X,A,F16.12,1X,A,)') '| SC =',SC(1),'|','| SC =',SC(2),'|','| SC =',SC(3),'|' WRITE(12,'((3(A,3X)))') '=========================','========================','========================' WRITE(12,*) ENDDO WRITE (12,*) WRITE (12,*) ' APLICACION AL CALCULO DE LOG(2) como la integral definida de la funcion f(x)=1/x en [1,2] con cada metodo compuesto' TClog=trapeciocompuestalog(1000) SClog=simpsoncompuestalog(1000) exacto=log(2.0) WRITE (12,'(/,21X,A)') ' ----------------------------------' WRITE (12,'(21X,A,2X,A,2X,A)') '|','Log(2) para 1000 subintervalos','|' WRITE (12,*) ' -------------------------------------------------------' WRITE (12,'(A,8X,F16.13,10X,A)') ' | trapecio compuesto|',TClog,'|' WRITE (12,*) '--------------------------------------------------------' WRITE (12,'(A,8X,F16.13,10X,A)') ' | simpson compuesto |',SClog,'|' WRITE (12,*) '--------------------------------------------------------' WRITE (12,'(A,8X,F16.13,10X,A)') ' | funcion logaritmo |',exacto,'|' WRITE (12,*) '--------------------------------------------------------' TClog=trapeciocompuestalog(10000) SClog=simpsoncompuestalog(10000) exacto=log(2.0) WRITE (12,'(/,21X,A)') ' ----------------------------------' WRITE (12,'(21X,A,2X,A,1X,A)') '|','Log(2) para 10000 subintervalos','|' WRITE (12,*) ' -------------------------------------------------------' WRITE (12,'(A,8X,F16.13,10X,A)') ' | trapecio compuesto|',TClog,'|' WRITE (12,*) '--------------------------------------------------------' WRITE (12,'(A,8X,F16.13,10X,A)') ' | simpson compuesto |',SClog,'|' WRITE (12,*) '--------------------------------------------------------' WRITE (12,'(A,8X,F16.13,10X,A)') ' | funcion logaritmo |',exacto,'|' WRITE (12,*) '--------------------------------------------------------'

Page 126: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

126

END ! FUNCIONES --------------------------------------------------------------------------------------------------- !Esta funcion evalua una funcion polinomica de grado menor o igual que 3 en un punto DOUBLE PRECISION FUNCTION f(a,b,c,d,x) DOUBLE PRECISION a,b,c,d,x f=a*x**3+b*x**2+c*x+d END FUNCTION !Esta funcion calcula la integral definida por el metodo del trapecio simple DOUBLE PRECISION FUNCTION trapeciosimple(a,b,c,d,r,s) DOUBLE PRECISION a,b,c,d,r,s trapeciosimple=(f(a,b,c,d,r)+f(a,b,c,d,s))*(s-r)/2.0 END FUNCTION !Esta funcion calcula la integral definida por el metodo simple de Simpson DOUBLE PRECISION FUNCTION simpsonsimple(a,b,c,d,r,s) DOUBLE PRECISION a,b,c,d,r,s,h,x1 h=(s-r)/2.0 !es el paso x1=(s+r)/2.0 !x1 es el pto medio del intervalo [r,s] simpsonsimple=h*(f(a,b,c,d,r)+4*f(a,b,c,d,x1)+f(a,b,c,d,s))/3.0 END FUNCTION !Esta funcion calcula la integral definida por el metodo del trapecio compuesto DOUBLE PRECISION FUNCTION trapeciocompuesta(a,b,c,d,r,s) DOUBLE PRECISION a,b,c,d,r,s,h,aux !suponemos que dividimos el intervalo en 10 partes iguales y en cada una de ellas aplicamos la regla del trapecio simple h=(s-r)/10.0 !h es el paso aux=0.0 DO i=1,9 aux=aux+f(a,b,c,d,r+i*h) ENDDO trapeciocompuesta=h*(f(a,b,c,d,r)+2*aux+f(a,b,c,d,s))/2.0 END FUNCTION !Esta funcion calcula la integral definida por el metodo de Simpson compuesto DOUBLE PRECISION FUNCTION simpsoncompuesta(a,b,c,d,r,s) DOUBLE PRECISION a,b,c,d,r,s,h,aux1,aux2 !suponemos que dividimos el intervalo en 10 partes iguales y en cada una aplicamos la regla de Simpson simple h=(s-r)/(2*10.0) aux1=0 aux2=0 DO i=1,10 aux1=aux1+f(a,b,c,d,r+h*(2*i-1)) IF (i/=10) aux2=aux2+f(a,b,c,d,r+2*i*h) ENDDO simpsoncompuesta=h*(f(a,b,c,d,r)+4*aux1+2*aux2+f(a,b,c,d,s))/3.0 END FUNCTION !funciones para la aplicacion al calculo del log(2) DOUBLE PRECISION FUNCTION flog(x) DOUBLE PRECISION x flog=1.0/x END FUNCTION

Page 127: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

127

!Esta funcion calcula la integral definida por el metodo del trapecio compuesto DOUBLE PRECISION FUNCTION trapeciocompuestalog(subint) DOUBLE PRECISION h,aux INTEGER subint !suponemos que dividimos el intervalo en 50 partes iguales y en cada una de ellas aplicamos la regla del trapecio simple h=(1.0)/subint !h es el paso aux=0.0 DO i=1,subint-1 aux=aux+flog(1.0+i*h) ENDDO trapeciocompuestalog=h*(flog(1.0)+2*aux+flog(2.0))/2.0 END FUNCTION !Esta funcion calcula la integral definida por el metodo de Simpson compuesto DOUBLE PRECISION FUNCTION simpsoncompuestalog(subint) DOUBLE PRECISION h,aux1,aux2 INTEGER subint !suponemos que dividimos el intervalo en 50 partes iguales y en cada una aplicamos la regla de Simpson simple h=(1.0)/(2*subint) aux1=0 aux2=0 DO i=1,subint aux1=aux1+flog(1.0+h*(2*i-1)) IF (i/=subint) aux2=aux2+flog(1.0+2*i*h) ENDDO simpsoncompuestalog=h*(flog(1.0)+4*aux1+2*aux2+flog(2.0))/3.0 END FUNCTION

Page 128: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

128

• • • Programa 10. Mínimo de una función en un intervalo

Un posible código que resuelve el problema es el siguiente: PROGRAM minimofuncion IMPLICIT NONE DOUBLE PRECISION,DIMENSION (3):: a,b,c,d,r,s,xm,fm !a,b,c,d,r,s vectores de tamaño 3. DOUBLE PRECISION x1,x2,fr,fs,fx1,fx2,f !x1,x2 son los posibles ceros de la funcion derivada f' !fr,fs,fx1,fx2:valor de la funcion en r,s,x1,x2 respectivamente CHARACTER(LEN=20) filesol !xm minimo de la funcion en [r,s] y fm su valor en f INTEGER i,j,indice,w,y,z !Lectura de los nombres de los ficheros de datos y resultados WRITE (*,'(A)') 'Los datos se han leido desde el fichero datosp15 ' OPEN (11, FILE='datosp15') WRITE (*,'(/A)',ADVANCE='NO') 'Introduce el nombre de fichero de resultados: ' READ (*,'(A)') filesol

Page 129: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

129

OPEN (12, FILE=filesol) !PROGRAMA PRINCIPAL WRITE (12,*) 'Número de orden: |4| Alumna: BASCUÑANA GALLEGO, Maribel' WRITE (12,*) '=================================================================================================' WRITE (12,*) ' Practica P15: MINIMO DE UNA FUNCION POLINÓMICA DE GRADO MENOR O IGUAL QUE 3 ' WRITE (12,*) '=================================================================================================' WRITE(12,*) DO i=1,3 READ (11,*) (a(j),j=1,3) !en la primera vuelta lee los datos de los 3 primeros cuadros, en la segunda los datos de los READ (11,*) (b(j),j=1,3) !casos cuarto al sexto y en la tercera los datos de los tres ultimos cuadros. READ (11,*) (c(j),j=1,3) READ (11,*) (d(j),j=1,3) READ (11,*) (r(j),j=1,3) READ (11,*) (s(j),j=1,3) DO j=1,3 CALL resolver(3*a(j),2*b(j),c(j),x1,x2,indice) fr=f(a(j),b(j),c(j),d(j),r(j)) !valor de la funcion en r fs=f(a(j),b(j),c(j),d(j),s(j)) !valor de la funcion en s IF ((indice==2) .or. (indice==3)) THEN !f' tiene una solucion doble o f' no se anula. Comparamos solo r y s fm(j)=fr !incializamos el minimo en r xm(j)=r(j) IF (fs<fm(j))THEN !comparamos con el valor alcanzado en s fm(j)=fs xm(j)=s(j) ENDIF ENDIF IF (indice==1) THEN !la funcion derivada se anula en un punto x1 fx1=f(a(j),b(j),c(j),d(j),x1) !valor de la funcion en el posible punto critico !aseguramos que el valor x1 se encuentra en el intervalo [r,s] IF ((r(j)<x1) .and. (x1<s(j))) THEN !buscamos el minimo valor entre fr,fs,fx1 fm(j)=fr !inicializamos el minimo en r y comparamos xm(j)=r(j) IF (fs<fm(j)) THEN fm(j)=fs xm(j)=s(j) ENDIF IF (fx1<fm(j))THEN !al final de los dos IF en fm guardamos el valor minimo de la funcion fm(j)=fx1 xm(j)=x1 ENDIF ELSE !x1 no esta en (r,s) , comparamos solo fr y fs fm(j)=fr !incializamos el minimo en r xm(j)=r(j) IF (fs<fm(j))THEN !comparamos con el valor alcanzado en s fm(j)=fs xm(j)=s(j) ENDIF ENDIF

Page 130: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

130

ENDIF IF (indice==4) THEN !f' se anula en dos puntos distintos x1 y x2. Comparamos esos dos valores con r y s fx1=f(a(j),b(j),c(j),d(j),x1) fx2=f(a(j),b(j),c(j),d(j),x2) IF (((x1<r(j)) .or. (s(j)<x1)) .and. ((x2<r(j)) .or. (s(j)<x2))) THEN !ni x1 ni x2 estan en [r,s] !comparamos r y s fm(j)=fr !inicializamos el minimo en r y comparamos xm(j)=r(j) IF (fs<fm(j)) THEN fm(j)=fs xm(j)=s(j) ENDIF ENDIF IF (((r(j)<x1) .and. (x1<s(j))) .and. ((x2<r(j)) .or. (s(j)<x2))) THEN !x1 esta en [r,s] ,comparamos x1,r y s !buscamos el minimo valor entre fr,fs,fx1 fm(j)=fr !inicializamos el minimo en r y comparamos xm(j)=r(j) IF (fs<fm(j)) THEN fm(j)=fs xm(j)=s(j) ENDIF IF (fx1<fm(j))THEN !al final de los dos IF en fm guardamos el valor minimo de la funcion fm(j)=fx1 xm(j)=x1 ENDIF ENDIF IF (((r(j)<x2) .and. (x2<s(j))) .and. ((x1<r(j)) .or. (s(j)<x1))) THEN !x2 esta en [r,s] ,comparamos x2,r y s !buscamos el minimo valor entre fr,fs,fx2 fm(j)=fr !inicializamos el minimo en r y comparamos xm(j)=r(j) IF (fs<fm(j)) THEN fm(j)=fs xm(j)=s(j) ENDIF IF (fx2<fm(j))THEN !al final de los dos IF en fm guardamos el valor minimo de la funcion fm(j)=fx2 xm(j)=x2 ENDIF ENDIF IF (((r(j)<x1) .and. (x1<s(j))) .and. ((r(j)<x2) .and. (x2<s(j)))) THEN !x1 y x2 estan en [r,s] !Buscamos el minimo entre fx1,fx2,fr y fs fm(j)=fr !inicializamos el minimo en r y comparamos xm(j)=r(j) IF (fx1<fm(j)) THEN fm(j)=fx1 xm(j)=x1 ENDIF IF (fx2<fm(j))THEN !al final de los dos IF en fm guardamos el valor minimo de la funcion fm(j)=fx2 xm(j)=x2 ENDIF IF (fs<fm(j)) THEN fm(j)=fs xm(j)=s(j)

Page 131: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

131

ENDIF ENDIF ENDIF !en xm(j) se encuentra el valor donde f alcanza el minimo y en fm(j) dicho valor ENDDO WRITE(12,'((3(A,3X)))') '=========================','========================','========================' SELECT CASE (i) CASE (1) WRITE(12,'(A,8X,A,8X,A,3X,A,8X,A,8X,A,2X,A,8X,A,7X,A)') '|',' CASO 1','|','|',' CASO 2','|','|',' CASO 3','|' CASE (2) WRITE(12,'(A,8X,A,8X,A,3X,A,8X,A,8X,A,2X,A,8X,A,7X,A)') '|',' CASO 4','|','|',' CASO 5','|','|',' CASO 6','|' CASE (3) WRITE(12,'(A,8X,A,8X,A,3X,A,8X,A,8X,A,2X,A,8X,A,7X,A)') '|',' CASO 7','|','|',' CASO 8','|','|',' CASO 9','|' END SELECT WRITE(12,'(3(A,3X))') '=========================','========================','========================' WRITE(12,'(A,F16.12,3X,A,3X,A,F16.12,3X,A,2X,A,F16.12,2X,A,)') '| a =',a(1),'|','| a =',a(2),'|','| a =',a(3),'|' WRITE(12,'(3(A,3X))') '-------------------------','------------------------','------------------------' WRITE(12,'(A,F16.12,3x,A,3X,A,F16.12,3X,A,2X,A,F16.12,2X,A,)') '| b =',b(1),'|','| b =',b(2),'|','| b =',b(3),'|' WRITE(12,'(3(A,3X))') '-------------------------','------------------------','------------------------' WRITE(12,'(A,F16.12,3x,A,3X,A,F16.12,3X,A,2X,A,F16.12,2X,A,)') '| c =',c(1),'|','| c =',c(2),'|','| c =',c(3),'|' WRITE(12,'(3(A,3X))') '-------------------------','------------------------','------------------------' WRITE(12,'(A,F16.12,3x,A,3X,A,F16.12,3X,A,2X,A,F16.12,2X,A,)') '| d =',d(1),'|','| d =',d(2),'|','| d =',d(3),'|' WRITE(12,'(3(A,3X))') '-------------------------','------------------------','------------------------' WRITE(12,'(A,F16.12,3x,A,3X,A,F16.12,3X,A,2X,A,F16.12,2X,A,)') '| r =',r(1),'|','| r =',r(2),'|','| r =',r(3),'|' WRITE(12,'(3(A,3X))') '-------------------------','------------------------','------------------------' WRITE(12,'(A,F16.12,3x,A,3X,A,F16.12,3X,A,2X,A,F16.12,2X,A,)') '| s =',s(1),'|','| s =',s(2),'|','| s =',s(3),'|' WRITE(12,'(3(A,3X))') '-------------------------','------------------------','------------------------' WRITE(12,'(3(A,3X))') '-------------------------','------------------------','------------------------' WRITE(12,'(A,F12.9,6X,A,3X,A,F12.9,6X,A,2X,A,F12.9,5X,A,)') '| xm =',xm(1),'|','| xm =',xm(2),'|','| xm =',xm(3),'|' WRITE(12,'(3(A,3X))') '-------------------------','------------------------','------------------------' WRITE(12,'(A,F12.9,6X,A,3X,A,F12.9,6X,A,2X,A,F12.9,5X,A,)') '| fm =',fm(1),'|','| fm =',fm(2),'|','| fm =',fm(3),'|' WRITE(12,'((3(A,3X)))') '=========================','========================','========================' WRITE(12,*) ENDDO END !SUBRUTINAS ---------------------------------------------------------------------------------------------------- !Esta subrutina resuelve una ecuacion de segundo grado SUBROUTINE resolver (m, n, l, x1, x2, indice)

Page 132: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

132

DOUBLE PRECISION m, n, l, x1, x2,disc INTEGER indice indice = 0 ! no existe ecuacion IF ((m==0) .AND. (n==0)) RETURN IF (m==0) THEN indice = 1 ! ecuacion de primer grado x1 = -l/n x2 = x1 RETURN ENDIF disc = n**2 - 4*m*l IF (disc==0) THEN indice = 2 ! raiz real doble x1 = -n /(2.*m) x2 = x1 RETURN ENDIF IF (disc<0) THEN indice = 3 ! raices complejas conjugadas x1 = -n /(2.*m) ! x1 contiene la parte real x2 = SQRT(-disc)/(2.*m) ! x2 contiene la parte imaginaria ELSE indice = 4 ! raices reales simples x1 = (-n+SQRT(disc))/(2.*m) x2 = (-n-SQRT(disc))/(2.*m) ENDIF END SUBROUTINE ! FUNCIONES --------------------------------------------------------------------------------------------------- !Esta funcion evalua una funcion polinomica de grado menor o igual que 3 en un punto DOUBLE PRECISION FUNCTION f(a,b,c,d,x) DOUBLE PRECISION a,b,c,d,x f=a*x**3+b*x**2+c*x+d END FUNCTION PROGRAMAS EN FORTRAN USANDO ALGUNAS DE SUS LIBRERÍAS

Page 133: Tecnología de la Información - jemiliobasfernandez.iescla.orgjemiliobasfernandez.iescla.org/wp-content/uploads/2012/11/APUNTES... · Los métodos más habituales para representar

133