LENGUAJES DE PROGRAMACIÓN Trabajo Práctico - Junio de 2016 INSTRUCCIONES – El trabajo práctico debe realizarse de manera individual. No debe realizarse en grupo. Se penalizará cualquier uso compartido de las soluciones propuestas y de los códigos programados. – El trabajo debe entregarse a través del curso virtual de la asignatura en la plataforma Alf. – La fecha límite de entrega es el día 16 de abril. – El alumno debe entregar un fichero comprimido, en formato zip o tar, que contenga: ◦ Una memoria en la cual explique la solución a los ejercicios, incluyendo los listados documentados del código C++ desarrollado. Este documento deberá estar en formato pdf. ◦ Los ficheros del código fuente C++ solución a los ejercicios. No deben entregarse ficheros ejecutables. El nombre del fichero comprimido debe ser la concatenación del nombre y apellidos del alumno. Por ejemplo, LuisaGomezMartin.zip LENGUAJES DE PROGRAMACIÓN CRITERIOS DE EVALUACIÓN – Para que el trabajo pueda ser corregido, es imprescindible que el alumno entregue dentro del plazo establecido un fichero comprimido que contenga la memoria en formato pdf y el código fuente C++ de los ejercicios que haya realizado. – El trabajo se compone de 4 ejercicios, cada uno de los cuales se valorará sobre 2.5 puntos. – Para aprobar el trabajo es necesario que la suma de las puntuaciones obtenidas en los ejercicios sea mayor o igual que 5. – Si el código solución de un ejercicio tiene errores de compilación o no tiene la funcionalidad pedida, dicho ejercicio se valorará con cero puntos. – Si el código solución de un ejercicio compila sin errores y tiene la funcionalidad pedida, la puntuación en dicho ejercicio será al menos de 2 puntos. – Se valorará positivamente la eficiencia y la adecuada documentación del código, así como la presentación y calidad de las explicaciones proporcionadas en la memoria. 2 Dpto. de Informática y Automática, UNED TRABAJO PRÁCTICO - JUNIO DE 2016 EJERCICIO 1 La distancia entre dos puntos en el plano, pi = {xi , yi } y pj = {xj , yj }, se calcula de la forma siguiente: di,j = q (xi − xj )2 + (yi − yj )2 donde las coordenadas xi , yi , xj e yj son números reales. Escriba un programa en C++ que realice las acciones siguientes: 1. Solicitar al usuario que éste introduzca por consola los valores de las coordenadas x1 , y1 , . . . , x5 , y5 de 5 puntos, y leer de la consola dichos valores. 2. Sean p1 = {x1 , y1 }, . . . , p5 = {x5 , y5} los cinco puntos leídos de la consola. Calcular la suma de la distancia entre puntos consecutivos, es decir; D= 4 X di,i+1 i=1 y mostrar dicho valor en la consola. Esta distancia es la longitud del camino p1 → p2 → p3 → p4 → p5 . 3. Para los cinco puntos leídos de la consola, calcular qué camino o caminos tienen la longitud mínima, satisfaciendo que comienzan en p1 , finalizan en p5 , y pasan una única vez, en cualquier orden, por los puntos p2 , p3 y p4 . Mostrar el valor de dicha distancia mínima en la consola, así como el correspondiente camino o caminos. 4. Terminar. Dpto. de Informática y Automática, UNED 3 LENGUAJES DE PROGRAMACIÓN EJERCICIO 2 En la Figura 1.1 se muestra un objeto de masa M que puede deslizar con rozamiento sobre el suelo y que se encuentra unido a una pared inmóvil mediante un muelle. Muelle Objeto de masa M Pared Suelo Figura 1.1: Sistema mecánico. La evolución en el tiempo de la velocidad v y la posición x del objeto viene descrita por las ecuaciones siguientes: M· dv = −K · (x − L0 ) − b · v dt dx = v dt donde K es la constante de proporcionalidad del muelle, L0 es su elongación natural, y b es la constante de rozamiento entre el objeto y el suelo. Se supone que el valor de cada una de estas magnitudes, así como la masa del objeto, permanecen constantes en el tiempo. Aplicando el método de integración de Euler explícito a las dos ecuaciones anteriores se obtiene: M· vi+1 − vi = −K · (xi − L0 ) − b · vi h xi+1 − xi = vi h donde xi , vi representan la posición y la velocidad del objeto en el instante de tiempo t = i · h, y donde h es el tamaño del paso de integración. 4 Dpto. de Informática y Automática, UNED TRABAJO PRÁCTICO - JUNIO DE 2016 Manipulando las expresiones anteriores puede obtenerse la posición xi+1 y la velocidad vi+1 en el instante (i + 1) · h, a partir de la posición xi y la velocidad vi en el instante i · h, conocidas las magnitudes constantes K, L0 , M y b, y el valor del paso de integración h. b·h K·h · (xi − L0 ) − · vi M M = xi + h · vi vi+1 = vi − (1.1) xi+1 (1.2) para i = 0, . . . , N − 1. Escriba un programa en C++ que realice las acciones siguientes: 1. Declarar dos constantes, una int llamada N y otra double llamada h, y asignarles respectivamente los valores 1000 y 0.01. 2. Solicitar al usuario que éste introduzca por consola los valores de las magnitudes K, L0 , M y b, las cuales deben ser números reales mayores que cero. Si no se satisface esta condición, el programa debe mostrar un mensaje de error y terminar. 3. Solicitar al usuario que éste introduzca por consola el valor inicial de la posición, x0 . El valor de x0 debe ser un número real en el intervalo [0.8 · L0 , 1.2 · L0 ]. Si no se satisface esta condición, el programa debe mostrar un mensaje de error y terminar. 4. Calcular xi y vi , para i = 1, . . . , N, empleando para ello las Ecs. (1.1) y (1.2). Se considera que la velocidad inicial siempre vale cero, es decir, v0 = 0. Los valores xi y vi , con i = 0, . . . , N, deben almacenarse en sendos arrays de N + 1 componentes de tipo double. 5. Grabar en un fichero de texto llamado sistMecanico.txt los valores ti , xi , vi con i = 0, . . . , N. El fichero deberá tener tres columnas (tiempo, posición y velocidad) y N + 1 filas. Los valores de la posición y la velocidad se mostrarán en formato fijo, con 5 dígitos detrás del punto decimal. El tiempo se mostrará en formato fijo, con 2 dígitos detrás del punto decimal. 6. Terminar. Dpto. de Informática y Automática, UNED 5 LENGUAJES DE PROGRAMACIÓN EJERCICIO 3 El método descrito a continuación es uno de los más sencillos y rápidos para generar observaciones de una variable aleatoria discreta X. 1. Obtener una observación independiente u de una distribución U(0, 1). 2. Calcular: (1.3) i = ⌈u · n⌉ La función ⌈x⌉, denominada ceil, devuelve el menor número entero que es mayor o igual que x. Por ejemplo, ⌈3.1⌉ y ⌈3.8⌉ valen 4. El valor entero n es el número de componentes de un array predeterminado (a1 , . . . , an ), que se calcula a partir de la función de probabilidad de la variable aleatoria X. 3. Devolver ai . Esto es, el componente i-ésimo del array (a1 , . . . , an ). A continuación se muestra un ejemplo. Supongamos que se desea generar observaciones de una variable aleatoria discreta X, cuyo conjunto de valores posibles es {1, 2, . . . , 10}, y cuya función de probabilidad es: fX (x) = x 55 con x = 1, . . . , 10 Es decir, la probabilidad de que la variable valga 1 es 3 la de que valga 3 es 55 y así sucesivamente. 1 , 55 (1.4) la de que valga 2 es 2 , 55 Las observaciones pueden generarse aplicando el algoritmo anterior, empleando el siguiente array de n = 55 elementos: 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, . . . , 10, . . . , 10 (1.5) Obsérvese que el primer componente del array tiene valor 1, los dos siguientes valor 2, los tres siguientes valor 3, y así sucesivamente. Los 10 últimos componentes del array tienen valor 10. 6 Dpto. de Informática y Automática, UNED TRABAJO PRÁCTICO - JUNIO DE 2016 Escriba un programa en C++ que genere 10000 observaciones independientes de la variable aleatoria X, cuya función de probabilidad se muestra en (1.4). A continuación, el programa debe calcular la probabilidad empírica a partir de esos datos y compararla con la teórica. El programa debe realizar las acciones siguientes: 1. Declarar dos constantes int llamadas N y n, y asignarles los valores 10000 y 55 respectivamente. 2. Declarar un array llamado a con n componentes int. Empleando bucles for, asignar valor a los componentes del array tal como se muestra en (1.5). 3. En un fichero de texto llamado obsX.txt, escribir N = 10000 observaciones aleatorias independientes de la variable aleatoria discreta X, cuya probabilidad fX (x) es (1.4), empleando para ello el algoritmo descrito anteriormente. Para obtener u1, . . . , uN puede emplear el generador de números pseudoaleatorios que desee. Por ejemplo, la función rand(). 4. Leer los datos del fichero obsX.txt y calcular la probabilidad con la que aparece cada uno de los diez posibles valores de X: {1, 2, . . . , 10}. 5. Mostrar en la consola, para cada uno de los 10 posibles valores de X: – la probabilidad empírica calculada de los datos del fichero, – la correspondiente probabilidad teórica (véase (1.4)) y – la diferencia entre ambas. Las probabilidades y sus diferencias se mostrarán en formato fijo, con 4 dígitos detrás del punto decimal. 6. Terminar. Dpto. de Informática y Automática, UNED 7 LENGUAJES DE PROGRAMACIÓN EJERCICIO 4 Se propone realizar un programa en C++ que obtenga el trazo dibujado por una tiza en su movimiento sobre una pizarra. Las acciones a realizar por la tiza se leerán de un fichero de texto. Éstas pueden ser: apoyarse sobre la pizarra, levantarse de la pizarra y avanzar en la dirección indicada. A continuación se explica todo ello con detalle. La pizarra es una región plana cuadrada, recubierta por un mallado de N × N celdas cuadradas, donde N = 41. La celda (0, 0) se encuentra en el extremo inferior izquierdo de la pizarra y la celda (40, 40) en el extremo superior derecho. La tiza se encuentra inicialmente apoyada sobre la pizarra y situada en la celda (Ix , Iy ), donde Ix = Iy = 21. La tiza puede moverse en cuatro direcciones: hacia arriba, hacia abajo, hacia la izquierda y hacia la derecha. Si la tiza se mueve estando apoyada sobre la pizarra, entonces dibuja en la pizarra. Si por el contrario el movimiento se produce mientras la tiza no está apoyada sobre la pizarra, entonces ese movimiento no produce dibujo alguno. El movimiento de la tiza se describe mediante una secuencia arbitraria de los seis comandos siguientes: APOYA_TIZA LEVANTA_TIZA AVANCE_N AVANCE_S AVANCE_E AVANCE_O Apoya la tiza sobre la pizarra Levanta la tiza de la pizarra La tiza se desplaza una celda hacia arriba La tiza se desplaza una celda hacia abajo La tiza se desplaza una celda hacia la derecha La tiza se desplaza una celda hacia la izquierda La secuencia de comandos está escrita en un fichero de texto llamado comand.txt. Los comandos pueden estar separados entre sí por espacios en blanco y saltos de línea. El programa debe abrir dicho fichero e ir leyéndolo palabra a palabra. Si la palabra leída coincide con uno de los comandos, el programa debe realizar la acción indicada por el comando. Si no coincide, el programa debe mostrar en la consola un mensaje y terminar. El mensaje debe ser lo más descriptivo posible, indicando qué texto produce el error. La estructura de datos empleada en el programa para representar la pizarra y los trazos dibujados en ella deberá ser un array bidimensional N × N de bool. Cada componente está asociado con una de las celdas. Un componente del array vale 8 Dpto. de Informática y Automática, UNED TRABAJO PRÁCTICO - JUNIO DE 2016 true cuando la celda asociada ha sido visitada por la tiza, estando ésta apoyada sobre la pizarra. En caso contrario vale false. Una vez ejecutados los comandos escritos en comand.txt, el programa debe escribir en un fichero de texto llamado result.txt información relativa al valor del array bidimensional y a continuación debe terminar. La escritura en el fichero result.txt debe hacerse de la manera siguiente: – Cada fila del array debe escribirse en una línea del fichero. Las filas deben escribirse en orden decreciente, de manera que la última fila en ser escrita sea la cero. – Cada componente del array bidimensional dará lugar a la escritura de un punto o un asterisco: • Si vale false, se escribirá un punto. • Si vale true, se escribirá un asterisco. De esta forma, los trazos dibujados por la tiza quedarán representados mediante asteriscos. Las celdas que no han sido dibujadas por la tiza se representarán mediante puntos. El programa debe ir vigilando que la tiza no salga de la pizarra. Cuando se ejecute un comando que haga que la tiza salga de la pizarra (ya sea estando la tiza levantada o apoyada), el programa debe escribir en la consola un aviso indicándolo, escribir el fichero result.txt a partir del valor actual del array y terminar. A fin de ilustrar cuál debe ser el funcionamiento del programa, se muestran a continuación dos ejemplos. En cada caso se indica el contenido del fichero comand.txt, que es proporcionado por el usuario y leído por el programa, y del fichero result.txt, que es generado por el programa. Dpto. de Informática y Automática, UNED 9 LENGUAJES DE PROGRAMACIÓN Ejemplo 1 Contenido del fichero comand.txt: AVANCE_N AVANCE_E AVANCE_E AVANCE_E AVANCE_E AVANCE_E AVANCE_N AVANCE_E AVANCE_E AVANCE_E AVANCE_E AVANCE_E AVANCE_N AVANCE_E AVANCE_E AVANCE_E AVANCE_E AVANCE_E AVANCE_N AVANCE_E AVANCE_E AVANCE_E AVANCE_E AVANCE_E AVANCE_N AVANCE_E AVANCE_E AVANCE_E AVANCE_E AVANCE_E Contenido del fichero result.txt: ......................................... ......................................... ......................................... ......................................... ......................................... ......................................... ......................................... ......................................... ......................................... ......................................... ......................................... ......................................... ......................................... ......................................... .....................******************** .....................*................... .....................* ................... .....................*................... .....................*................... .....................* ................... ......................................... ......................................... ......................................... ......................................... ......................................... ......................................... ......................................... ......................................... ......................................... ......................................... ......................................... ......................................... ......................................... ......................................... ......................................... ......................................... ......................................... ......................................... ......................................... ......................................... ......................................... El programa debe escribir un mensaje en la consola indicando que la tiza ha salido de la pizarra. 10 Dpto. de Informática y Automática, UNED TRABAJO PRÁCTICO - JUNIO DE 2016 Ejemplo 2 Contenido del fichero comand.txt: AVANCE_E AVANCE_E AVANCE_E AVANCE_E AVANCE_E AVANCE_N AVANCE_N AVANCE_N AVANCE_N AVANCE_N LEVANTA_TIZA AVANCE_N AVANCE_N AVANCE_N AVANCE_N AVANCE_N AVANCE_O AVANCE_O AVANCE_O AVANCE_O AVANCE_O APOYA_TIZA AVANCE_N AVANCE_N AVANCE_N AVANCE_N AVANCE_N AVANCE_E AVANCE_E AVANCE_E AVANCE_E AVANCE_E AVANCE_E AVANCE_E AVANCE_E AVANCE_E AVANCE_E AVANCE_S AVANCE_S AVANCE_S AVANCE_S AVANCE_S LEVANTA_TIZA AVANCE_E AVANCE_E AVANCE_N APOYA_TIZA LEVANTA_TIZA AVANCE_E AVANCE_E AVANCE_N APOYA_TIZA LEVANTA_TIZA AVANCE_E AVANCE_E AVANCE_N APOYA_TIZA AVANCE_S AVANCE_S AVANCE_S AVANCE_S AVANCE_S Contenido del fichero result.txt: ......................................... ......................................... ......................................... ......................................... .....................***********......... .....................* .........*......... .....................*.........* .....*... .....................*.........*...*.* ... .....................* .........*.*...*... .....................*.........*.....*... .....................................*... .....................................*... ......................................... ......................................... .......................... .............. ..........................* *.............. ..........................* .............. ..........................*.............. ..........................*.............. .....................****** .............. ......................................... ......................................... ......................................... ......................................... ......................................... ......................................... ......................................... ......................................... ......................................... ......................................... ......................................... ......................................... ......................................... ......................................... ......................................... ......................................... ......................................... ......................................... ......................................... ......................................... ......................................... En este caso el programa no debe mostrar ningún mensaje de error o aviso en la consola. Dpto. de Informática y Automática, UNED 11