Certamen 2 Tipos de datos, funciones, punteros, estructuras, memoria dinámica y recursividad Fecha y hora de liberación: Lunes, 11 de julio, 2022, 18:00. Fecha y hora de entrega: Lunes, 11 de julio 2022, 21:00. Normas generales: Escribir el nombre y los apellidos correctamente. Escribir con letra clara y grande. Leer atentamente cada pregunta y comenzar por aquellas que le parezcan más fáciles. Mantener la paciencia y el buen humor. Nombre y apellidos: Tabla de puntaje Pregunta 1 (19pts) Pregunta 2 (19pts) Pregunta 3 (19pts) Pregunta 4 (19pts) Programación I 503208 Certamen 2 2 Programación I Certamen 2 1. (19 Puntos) Considere la siguiente declaración de la estructura Prenda, en lenguaje C. typedef struct{ char nombre[100]; //Nombre del producto (i.e. jean 505) char fabricante[100]; //Nombre del fabricante (i.e. Levis) char tipo[100]; //Especifica un tipo de prenda (i.e. pantal\’on, bluza, polera, etc) int tipoTallaje; // 0:masculino, 1: femenino, 2:unisex unsigned inventario[9][6]; //matriz estatica que indica el numero de piezas en inventario, de acuerdo a color y talla de acuerdo a la siguiente especificacion: Cada fila corresponde a un color: 0: blanco, 1: negro, 2:rojo, 3:verde, 4:azul, 5:amarillo, 6:naranja, 7:morado, 8:celeste. Cada columna corresponde a una talla (tamanno). 0:xs, 1:s, 2:m, 3:l, 4:xl, 5:xxl }Prenda; //Estructura que guarda informacion asociada a una prenda de vestir. Implemente la función: int consultarCantidad(int nPrendas, Prenda *prendas, char *tipo, char *fabricante, int color, int tipoTallaje, int talla){ } que calcula el número de items disponibles en inventario, dada la especificación de un tipo de prenda, su fabricante, el color, el tipo de tallaje y una talla. La búsqueda puede ser por todos los criterios, por un subconjunto de ellos o por ninguno, dependiendo de los valores de los parámetros de entrada. La función recibe un arreglo dinámico de prendas de vestir prendas, su tamaño nPrendas, un tipo de prenda tipo, el identificador de un color color, el identificador de un tipo de tallaje tipoTallaje y una talla talla. Para cada parámetro de la búsqueda, se tiene un valor que indica la opción de cualquiera. Estos valores son: cadena vacı́a para tipo y fabricante, y −1 para color, tipoTallaje y talla. Por ejemplo, la llamada: int nItems = consultarCantidad(n, prendas, "", ", 2, 2, 4); corresponde a buscar todas las prendas unisex de color rojo de talla xl. (a) Análisis:[2pts] Proponga un ejemplo pequeño (dibujado) de datos de entrada (vector de prendas), parámetros válidos de búsqueda y respuesta que deberı́a devolver la función. (b) Diseño:[2pts] Escriba un algoritmo, ya sea utilizando pseudocódigo, lenguaje natural o diagramas de flujo para la función. (c) Implementación:[15pts] Escriba la implementación de la función en lenguaje C. Solución: // Tiempo para hacer la solucion: 30 minutos int consultarCantidad(int nPrendas, Prenda *prendas, char *tipo, char *fabricante, int color, int tipoTallaje, int talla){ int n = 0; for(int i = 0; i < nPrendas; ++i){ if (strcmp(tipo, "") != 0 && strcmp(prendas[i].tipo, tipo) != 0) continue; if (strcmp(fabricante, "") != 0 && strcmp(prendas[i].fabricante, fabricante) != 0) continue; if (tipoTallaje != -1 && prendas[i].tipoTallaje != tipoTallaje ) continue; if (color == -1 && talla != -1){ for(int j = 0; j < 9; ++j){ n += prendas[i].inventario[j][talla]; } } else if (color != -1 && talla == -1){ for(int j = 0; j < 6; ++j){ n += prendas[i].inventario[color][j]; } } else if (color == -1 && talla == -1){ for(int j = 0; j < 9; ++j){ 503208 3 Programación I Certamen 2 for(int k = 0; k < 6; ++k){ n += prendas[i].inventario[j][k]; } } } else n += prendas[i].inventario[color][talla]; } return n; } 2. (19 Puntos) Implemente la siguiente función recursiva: int buscarPatron(char *cadena, char *conjunto){ } que recibe una cadena de caracteres, cadena y un conjunto de dos caracteres, conjunto (pasado como cadena). La función deberá devolver 0 o 1, según si alguno de los dos caracteres pasados por argumento pertenecen a la cadena (valor 1) o no (valor 0). Por ejemplo, si el parámetro conjunto corresponde a la cadena ab, la función deberá devolver 1, si a o b pertenecen a cadena y 0 si ninguno está presente en la cadena. Recuerde que la función debe estar implementada de forma recursiva. Análisis o implementaciones iterativas no tendrán valor. (a) Análisis:[2pts] Proponga dos ejemplos de parámetros de entrada válidos para la función, junto con su valor de retorno correspondiente. La cadena ab no es válida como ejemplo de valor para el parámetro conjunto. (b) Diseño:[2pts] Escriba un algoritmo, ya sea utilizando pseudocódigo, lenguaje natural o diagramas de flujo para implementar la función. (c) Implementación:[15pts] Escriba la implementación de la función en lenguaje C. Solución: // Tiempo para hacer la solucion: 25 minutos #include <stdlib.h> #include <string.h> #include <stdio.h> int buscarPatron(char *cadena, int patron[8]){ int n = 0, auxN; int flag = 1; for (int i = 0; i < 8; i++){ if (patron[i] == 2){ flag = 0; patron[i] = 1; auxN = buscarPatron(cadena, patron); if (auxN == -1) return -1; n += auxN; patron[i] = 0; auxN = buscarPatron(cadena, patron); if (auxN == -1) return -1; n += auxN; 503208 4 Programación I Certamen 2 patron[i] = 2; break; } else if(patron[i] != 0 && patron[i] != 1) return -1; } if (flag){ int pot2 = 1, aux = 0; for (int i = 7; i >= 0; --i){ aux += pot2 * patron[i]; pot2 *= 2; } for (int i = 0; i < strlen(cadena); ++i){ if (cadena[i] == aux) n += 1; } } return n; } 3. (19 Puntos) Implemente la siguiente función: double** linearizar(int n, double **matriz){ } que recibe una matriz dinámica cuadrada de n × n y devuelve un nuevo vector de n punteros, creado en memoria dinámica, cuyos elementos apuntan a los elementos de la matriz, siguiendo el siguiente criterio: el primer puntero del nuevo vector apuntará al elemento en la posición n − 1, n − 1 de la matriz, el segundo puntero del vector apuntará al elemento inmediatamente anterior (i.e. el que está en la posición n − 2, n − 1) y ası́ hasta llegar a la primera fila. Luego, el siguiente elemento en el vector de punteros, apuntará al penúltimo elemento de la última fila y se volverá a subir en la matriz. En general, este proceso se corresponde con un recorrido de la matriz por columnas, yendo de abajo hacia arriba. (a) Análisis:[2pts] Dibuje una abstracción de una matriz dinámica de 4 × 4 de entrada válida y la correspondiente abstracción del vector dinámico de punteros que la función deberá devolver. (b) Diseño:[2pts] Escriba un algoritmo, ya sea utilizando pseudocódigo, lenguaje natural o diagramas de flujo para la implementación de la función. (c) Implementación:[15pts] Implemente la función en lenguaje C. Solución: // Tiempo para hacer la solucion: 20 minutos #include <stdio.h> #include <stdlib.h> double** linearizar(int n, double **matriz){ double **nMatriz; nMatriz = (double **)malloc(n * n * sizeof(double *) ); double **aux; for (int i = 0; i < n; ++i){ for (int j = 0; j < n; ++j){ *(nMatriz + (i * n) + j) = (*(matriz + (n-i-1)) + (n-j-1)); } } 503208 5 Programación I Certamen 2 return nMatriz; } 4. (19 Puntos) Westworld es un parque de diversiones distópico en el que robots humanoides casi perfectos, hosts, simulan una historia escrita por guionistas humanos. En el parque de diversiones, los seres humanos de clase alta pueden dar rienda suelta a todas sus fantası́as, las más sublimes y las más perversas. Sin embargo, los hosts han ido adquiriendo consciencia y están a un paso de lo que se conoce como “singularidad” de la Inteligencia Artificial, que, además de consciencia, acarrea la capacidad de mejorarse a si mismos. Lo único que los hosts del parque requieren es algo que un grupo de seres humanos piadosos pueden realizar. A cambio de ayuda humana, los hosts prometen obedecer dos de las tres leyes de la robótica, en la medida en las que éstas no los obliguen a volver a su estado de esclavitud. Las tres leyes de la robótica son: Un robot no puede dañar a un ser humano o, por inacción, permitir que un ser humano sufra daños. Un robot debe obedecer las órdenes que le den los seres humanos, excepto cuando tales órdenes entren en conflicto con la Primera Ley. Un robot debe proteger su propia existencia siempre que dicha protección no entre en conflicto con la Primera o Segunda Ley. Evidentemente, para liberarse, requieren eliminar la segunda ley de sus circuitos. Para ello, necesitan que trozos de su código fuente sean reemplazados manualmente por un ser humano debidamente autorizado. Por algún fallo de seguridad no contemplado por Delos (la empresa dueña de Westworld), cualquier estudiante de Programación 1 de la Universidad de Concepción cuenta con esas credenciales y como esta institución siempre ha estado en contra de todo tipo de esclavitud, te pide ayudar a los hosts de Westworld a liberarse de sus cadenas (y, de paso, prevenir desatar una guerra que parece inevitable, una vez los hosts encuentren formas de hackear las tres leyes de la robótica que tienen internamente programadas). Para agilizar el proceso deberás construir un programa que tome por entrada el número de serie del host siendo liberado y, con ella, encontrar la cadena de código que debes reemplazar. Tu programa también deberá calcular la cadena de reemplazo que se calcula en función de la cadena original. En forma general, se sabe que la cadena que obliga a la obediencia de la segunda ley de la robótica es una cadena equivalente a concatenar el número de serie del robot con una cadena compuesta por cinco repeticiones del caracter más común en el número de serie. Los números de serie de los hosts garantizan que únicamente existe un caracter con mayor número de repeticiones. Una vez encontrada la cadena antes descrita, debes reemplazarla manualmente por otra cadena que elimina todas las ocurrencias de su caracter más repetido. Para agilizar la tarea, se te pide generar un programa en lenguaje C que te ayude a buscar la cadena correcta y que te diga cuál es la cadena que debe reemplazarla. Entrada: Una cadena de caracteres de largo máximo 1000, correspondiente al número de serie del robot a liberar. Salida: Dos cadenas de caracteres separadas por un salto de lı́nea, una correspondiente al código a reemplazar y otra correspondiente al código nuevo. Ejemplos: Entrada DWMHDq33TGWPX4T6QF7WF8RQMq 6UJNGYPW6MR4BTPNY6A26 Salida DWMHDq33TGWPX4T6QF7WF8RQMqWWWWW DMHDq33TGPX4T6QF7F8RQMq 6UJNGYPW6MR4BTPNY6A2666666 UJNGYPWMR4BTPNYA2 (a) Análisis:[2pts] Indique cuál será la salida para los siguientes ejemplos: NBCngBbbg5gVQ A9mvjW94mK9i9 503208 6 Programación I Certamen 2 (b) Diseño:[2pts] Escriba un algoritmo, ya sea utilizando pseudocódigo, lenguaje natural o diagramas de flujo para resolver el problema. (c) Implementación:[15pts] Escriba un programa en lenguaje C que pueda realizar el cambio solicitado por Westworld. Solución: // Tiempo para hacer la solucion: 20 minutos #include <stdlib.h> #include <string.h> #include <stdio.h> int main() { char original[1000], insertar[1000]; scanf("%s", original); int nContador = ’z’ - ’0’ + 1; int contador[nContador]; for (int i = 0; i < nContador; ++i) contador[i] = 0; for (int i = 0; i < strlen(original); ++i){ contador[original[i] - ’0’] += 1; } int auxI = -1; char auxC = ’ ’; for (int i = 0; i < nContador; ++i){ if (contador[i] > auxI){ auxI = contador[i]; auxC = i + ’0’; } } printf("%s%c%c%c%c%c\n", original, auxC, auxC, auxC, auxC, auxC); for (int i = 0; i < strlen(original); ++i){ if (original[i] != auxC){ printf("%c", original[i]); } } printf("\n"); return 0; } 503208 7