/* */

24 de agosto de 2007

Problema 4.2

.
Enunciado
En una facultad se tiene la información de los alumnos que se inscribieron en las diferentes materias. Por cada inscripción se tiene los siguientes datos:

  • Legajo
  • Código de Materia
  • Día de Preferencia
Día de Preferencia puede ser alguna de estas opciones: { 'lu', 'ma', 'mi', 'ju', 'vi' }. Los datos están ordenados por legajo y luego por código de materia.

Se pide:

1 - Por cada alumno, a cuantas materias se pretende inscribir y cuantas inscripciones resultaron anuladas (según la superposición)

2- Al finalizar el proceso indicar el total de alumnos que cursarán en la facultad cada día de la semana.

Nota: si un alumno se inscribe en más de una materia un mismo día, se anularán todas las inscripciones que realizó para ese día. Por ejemplo un alumno se inscribe en "Algebra" los lunes, en "Algoritmos" los martes y en "Análisis" los lunes entonces la única inscripción válida será la de "Algoritmos" porque "Algebra" y "Análisis" las pidió el mismo día entonces se deben anular las dos.


Análisis
Este es un problema de corte de control por una variable: legajo. Veamos un ejemplo de los datos:



Como podemos ver el conjunto de datos (registros) se puede dividir en varios subconjuntos. Cada subconjunto corresponde a un alumno (legajo) y se compone de todas las inscripciones que dicho alumno realizó.

Según el enunciado, del total de inscripciones que realizó el alumno cuyo legajo es 1 la única válida es la inscripción a la materia código 15 (día martes) ya que como se inscribió en más de una materia para los días lunes todas ellas deben ser rechazadas.

Los alumnos con legajo 2 y 3 se inscribieron perfectamente en todas sus materias ya que (según los datos) no existe ninguna superposición entre las materias que van a cursar.


Como tenemos un problema de corte de control sabemos que la estructura correcta para "barrer los datos" (leerlos desde el primero hasta el último y detectar cada vez que se comienza a procesar los datos del próximo alumno) será dos ciclos iterativos anidados. Uno para controlar el fin de datos y otro para controlar el cambio de la variable de control.


Ahora, teniendo resuelta la "barrida" de los datos analizaremos lo que nos pide enunciado para encontrar la mejor manera de resolverlo.

1 - Para cada alumno, a cuantas materias se pretende inscribir y cuantas de sus inscripciones resultaron rechazadas.

Esta es una pregunta "por alumno". Es decir: por cada subconjunto de datos. Por lo tanto tendremos que procesar en proceso, mostrar el resultado en finLegajo e inicializar las variables en cabLegajo.

Basicamente lo que necesitamos son cinco contadores, uno para cada día de la semana. Utilizaremos las variables contLu, contMa, contMi, contJu y contVi. Por cada inscripción (cada fila o registro que leemos) verificamos a que día de la semana corresponde (según la preferencia pref) e incrementamos el contador asociado con ese día.

Al finalizar el proceso cada contador tendrá la cantidad de materias que el alumno prentende cursar ese día. Así, por ejemplo, si contMa está en cero significa que el alumno no se inscribió en ninguna materia los días martes. Pero si contMa vale 1 entonces el alumno se inscribió en una única materia ese día. En este caso la inscripción será válida. Por último, si contMa es mayor que 1 entonces el alumno se inscribió en más de una materia los días martes y por lo tanto todas serán rechazadas.

Para saber a cuantas materias se pretende inscribir el alumno simplemente sumamos los cinco contadores. Para saber cuantas de las inscripciones del alumno resultaron rechazadas simplemente tenemos que sumar los contadores que valen más que uno.


Para evaluar el día de preferencia de la materia que estamos procesando en esta iteración necesitamos comparar el valor de pref con cada una de las cadenas que representan los días de la semana (según el enunciado): 'lu',...,'vi'. Para esto, en lugar de hacer los 5 "ifes" (anidados o no) preferí utilizar un procedimiento llamado evaluarPreferencia. Este procedimiento recibe el día de la semana (por ejemplo 'lu'), la preferncia de inscripción y (por referencia) el contador que corresponde incrementar si dia es igual a pref. Luego, llamamos 5 veces a este procedimiento pasándole cada uno de los días de la semana, la preferencia y el contador que corresponde a ese día.

Los cinco contadores y la variable de contro legAnt deben inicializarce en cabLegajo.



Veamos ahora el procedimiento finLegajo en el que mostramos los resultados del punto 1 y procesamos los datos para el punto 2.



En finLegajo sumamos los contadores que corresponden a las inscripciones de cada día del alumno que acabamos de procesar para luego mostrar la "cantidad de inscripciones solicitadas" (cantInscr). Luego en un acumulador cantRech acumulamos la cantidad de inscripciones rechazadas. Para esto utilizamos la función evalDia. La función evalDia recibe el contador del día que se quiere evaluar y retorna la cantidad de inscripciones rechazadas para ese día. Es decir: si (por ejemplo) contJu vale 3 entonces las tres inscripciones del día jueves serán rechazadas. La función devolverá 3. Pero si contJu es cero o 1 entonces retorna 0 ya que si es cero resulta que el día jueves, este alumno no se inscribió en ninguna materia y si es 1 el alumno se inscribió en una sola materia y (entonces) esta no será rechazada.



Vemos que la función modifica el valor del contador en el caso de que este sea mayor que 1, es decir: si este día fué necesario anular las inscripciones. Esto se debe a que en finLegajo tenemos que "reacumular" los contadores para obtener los totales generales de inscriptos aceptados de cada día. Así, como la función asigna cero al contador en el caso de que a este alumno se le rechacen las inscripciones de este día, al reacumular estaremos sumando cero al total general.

Por último tenemos que ver los procedimientos resultados e inicializar.






.

No hay comentarios: