LENGUAJES DE PROGRAMACIÓN Trabajo Práctico - Junio de 2015 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 2015 EJERCICIO 1 Uno de los primeros generadores combinados de números pseudoaleatorios fue el propuesto por Wichmann y Hill en 1982. El generador de Wichmann-Hill emplea los siguientes tres generadores lineales congruenciales para obtener tres números enteros {xi , yi , zi }: xi = (171 · xi−1 ) mód 30269 yi = (172 · yi−1 ) mód 30307 zi = (170 · zi−1 ) mód 30323 de los cuales se obtiene un número pseudoaleatorio ui en el intervalo (0, 1): ui = x yi zi i + + 30269 30307 30323 mód 1 donde i = 1, 2, . . . La semilla de este generador son tres números enteros, {x0 , y0 , z0 }, que deben estar comprendidos entre 1 y 30000. Escriba un programa en C++ que realice las acciones siguientes: 1. Solicitar al usuario que introduzca por consola la semilla del generador. 2. Comprobar que estos tres números están comprendidos entre 1 y 30000. Si no lo están, el programa vuelve a solicitar por consola los números al usuario. 3. Empleando el algoritmo de Wichmann-Hill, obtener 100 números pseudoaleatorios e ir almacenándolos en un array de 100 componentes. 4. Mostrar en la consola el contenido del array. Los números deberán mostrarse en formato fijo, con 5 dígitos detrás del punto decimal. 5. Almacenar los números, en el formato anteriormente indicado y formando una única columna (es decir, un número por fila), en un fichero de texto llamado random.txt. 6. Terminar. Dpto. de Informática y Automática, UNED 3 LENGUAJES DE PROGRAMACIÓN EJERCICIO 2 Escriba un programa en C++ que, a partir de una secuencia de 2 · N números pseudoaleatorios, obtenga N = 45 posiciones aleatorias uniformemente distribuidas sobre una superficie plana rectangular de longitud L = 30 mm y altura A = 2 mm. Para ello, el programa debe realizar las acciones siguientes: 1. El número de posiciones N, así como la longitud (L) y altura (A) de la superficie, son constantes del programa: N = 45, L = 30, A = 2. 2. Abrir para lectura un fichero de texto llamado random.txt, en el cual hay escrita una columna de números pseudoaleatorios. Estos números pueden ser los obtenidos de ejecutar el programa del ejercicio anterior o cualquier otra secuencia de números pseudoaleatorios. 3. Almacenar el contenido completo del fichero en un vector de double llamado randomNums. 4. Si el vector contiene menos de 2 · N componentes, mostrar un mensaje de error y terminar. 5. Operar de la forma siguiente los primeros 2·N números del vector. Por cada pareja de números, {u2i , u2i+1 }, calcular una posición aleatoria {xi , yi } de la forma siguiente: xi = L · u2i yi = A · u2i+1 donde i = 0, . . . , N − 1. 6. Almacenar las posiciones en un fichero de texto llamado posiciones.txt. Deberán almacenarse en dos columnas: en la primera las posiciones xi y en la segunda las correspondientes posiciones yi . Deberán expresarse en formato fijo, con 3 dígitos detrás del punto decimal. 7. Terminar. 4 Dpto. de Informática y Automática, UNED TRABAJO PRÁCTICO - JUNIO DE 2015 EJERCICIO 3 Considérense N = 45 círculos de radio r = 0.5 mm distribuidos aleatoriamente sobre una superficie rectangular de L = 30 mm de longitud y A = 2 mm de altura. Los círculos que se encuentran sobre la superficie se agrupan en conjuntos de la manera siguiente: – Cada círculo debe pertenecer a un único conjunto. – Dos círculos entre los cuales existe solapamiento deben estar en el mismo conjunto. Se considera que existe solapamiento entre dos círculos si la distancia entre sus centros es menor o igual que 2 · r. Escriba un programa en C++ que cumpla las especificaciones siguientes: – El número de círculos (N) y su diámetro (2 · r) deben ser constantes del programa. – El programa debe leer las posiciones de los centros de los N círculos de un fichero de texto llamado posiciones.txt, que contiene dos columnas de números reales expresados en formato fijo, con 3 dígitos detrás del punto decimal. Los números de la primera columna son la coordenada x del centro del círculo y los de la segunda columna la correspondiente coordenada y. Este fichero podría ser, por ejemplo, el obtenido al ejecutar el programa escrito en el ejercicio anterior. – Si el fichero posiciones.txt contiene menos de 2 · N números, el programa debe mostrar un mensaje de error y terminar. – El programa debe agrupar los círculos en conjuntos. – Cada conjunto está compuesto por uno o más círculos. El programa debe escribir en un fichero de texto llamado nElemConj.txt el número de círculos de que consta cada conjunto. Los números se escribirán formando una columna. El orden de escritura de los números es irrelevante. Puede usar en el programa las estructuras de datos que estime convenientes. La figura mostrada a continuación es un ejemplo que pretende ilustrar la clasificación de los círculos en conjuntos. Por simplicidad en este ejemplo se consideran Dpto. de Informática y Automática, UNED 5 LENGUAJES DE PROGRAMACIÓN C7 C6 C3 C1 C13 C2 C11 C12 C4 C9 C10 C15 C8 C14 C5 Figura 1.1: Los círculos mostrados en esta figura se clasifican en 5 conjuntos: {C7 }, {C2 , C11 , C9 , C15 }, {C6 , C1 , C13 , C4 , C10 }, {C3 , C12 }, {C8 , C14 , C5 } sólo N = 15 círculos. Los círculos se han etiquetado C1 , . . . , C15 con el propósito de facilitar referirse a ellos al indicar los círculos pertenecientes a cada conjunto. Dados los conjuntos del ejemplo mostrado en la Figura 1.1, la salida del programa debería ser los números siguientes escritos en cualquier orden en una columna: 1, 4, 5, 2, 3. 6 Dpto. de Informática y Automática, UNED TRABAJO PRÁCTICO - JUNIO DE 2015 EJERCICIO 4 Escriba un programa en C++ que calcule la frecuencia con la que aparece cada número de un determinado conjunto de números naturales. Por ejemplo, dado el conjunto {2, 1, 1, 2, 4, 1, 1, 1}, el programa debe obtener que la frecuencia del número 1 es 5/8 (cinco de los ocho números tienen valor 1), la frecuencia del número 2 es 2/8 (dos de los ocho números tienen valor 2) y la frecuencia del número 4 es 1/8 (uno de los ocho números tiene valor 4). El conjunto de números naturales se encuentra almacenado en un fichero de texto llamado nElemConj.txt. Los números están escritos formando una única columna. El programa debe leer el contenido del fichero, calcular la frecuencia de cada número natural, mostrar el resultado en la consola y terminar. El resultado debe mostrarse en dos columnas: en la primera los números, ordenados crecientemente, y en la segunda su frecuencia, expresada como fracción. En el ejemplo anterior, la salida del programa debería ser: 1 2 4 5/8 2/8 1/8 Dpto. de Informática y Automática, UNED 7