Cátedra: Grossi
Cuatrimestre: 2.º Cuatrimestre 2008
El enunciado habría que subirlo al sitio de Apuntes. Hasta entonces, está en el grupo yahoo correspondiente.
{Sección Declarativa} program censo; uses crt; {subprogramas de manejo de pantalla} const pathitem='items.txt'; {ubicación simple del archivo que contiene la lista de items} pathloc='localidades.txt'; {ubicación simple del archivo que contiene la lista de localidades} pathcero='cerolog.txt'; {ubicación simple del archivo que contendrá el mensaje de ítems en cero} maxfil=21; {cantidad máxima de filas de la tabla} maxcol=10; {cantidad máxima de columnas de la tabla} maxitem=maxcol; {número máximo de ítems} maxloc=maxfil; {número máximo de localidades} type fila=1..maxfil; {índice de filas} columna=1..maxcol; {índice de columnas} idxitem=1..maxitem; {índice del vector de ítems} idxloc=1..maxloc; {índice del vector de localidades} idxtres=1..3; {índice del vector de tres dimensiones} idxdos=1..2; {índice del vector de dos dimensiones} vectoritem=array[idxitem] of string[15]; {definición del tipo de dato: vector de ítems} vectorloc=array[idxloc] of string[4]; {definición del tipo de dato: vector de localidades} matriz=array[fila,columna] of longint; {definición del tipo de dato: matriz} vector_rtres=array[idxtres] of longint; {definición del tipo de dato: vector de R3: se usa para guardar información sobre una celda en particular: fila, columna y contenido} vector_rdos=array[idxdos] of longint; {definición del tipo de dato: vector de R2: se usa para guardar información sobre una celda en particular: fila y contenido} vectorlocn=array[idxloc] of longint; {definición del tipo de dato: vector de localidades pero relleno de números} var ortitems: text; {localización del archivo de texto con la lista de ítems} ortlocalidades: text; {localización del archivo de texto con la lista de localidades} items: vectoritem; {vector de ítems} localidades: vectorloc; {vector de localidades} tabla: matriz; {tabla con los datos del censo} i: idxitem; {índice del vector de ítems} l: idxloc; {índice del vector de localidades} menuopt: char; {caracter para la opción del menú} salir: byte; {indica si hay que salir del bucle del menú (y por ende del programa)} otheritem: byte; {indica si el usuario quiere ingresar más ítems} otherloc: byte; {indica si el usuario quiere ingresar más localidades} entryrow: integer; {es el número de fila que corresponde a la localidad ingresada} entrycol: integer; {es el número de columna que corresponde al ítem ingresado} entry: byte; {indica si la localidad o el ítem ingresados figuran dentro de los relevados} entryitem: string[15]; {es el ítem ingresado por el usuario: está limitado por la cantidad máxima de caracteres de los números de ítems} entryloc: string[4]; {es la localidad ingresada por el usuario: está limitada por la cantidad máxima de caracteres de los números de localidades} itemincl: byte; {indica si el ítem ingresado está incluido en la lista de los relevados} locincl: byte; {indica si la localidad ingresada está incluida en la lista de las relevados} maxppl: longint; {es el número máximo de personas registradas en la tabla, sirve para barrer la tabla hasta encontrar el máximo absoluto al final del barrido} maxvec: vector_rtres; {es el vector que, al final del barrido, proporciona el número de fila, de columna y el valor de la cantidad máxima de personas registradas} sumfilas: longint; {es la suma de los ítems de una localidad. Se cerea cada vez que se empieza a barrer una nueva fila, previo almacenamiento en una celda de vecsumfilas} vecsumfilas: vectorlocn; {contiene la suma de ítems de cada localidad en sus celdas: su longitud es la del vector de localidades. Recién creado, se encuentra desordenado} localidades_ord: vectorloc; {vector de localidades, ordenado según el ordenamiento de vecsumfilas} min: vector_rdos; {vector que contiene (1) el mínimo de cada vuelta del bucle del algoritmo ordenador y (2) el número de celda del vector vecsumfilas que le corresponde} b,s: integer; {dos contadores usados en el bucle principal (b) y en el bucle secundario (s) del algoritmo ordenador} cero: byte; {indica si se ha encontrado ya un cero en la tabla, o si se ha llegado al final de ella sin encontrarlo} ortcerolog: text; {localización del archivo de texto con el mensaje de cero} procedure pathaid(nombre, simplepath: string[50];var ort: text); {subrutina que pregunta sobre la ubicación de un archivo de texto y hace las asignaciones pertinentes} {E: nombre es la denominación del elemento, p.ej. 'la lista de ítems' o 'la lista de localidades'} {E: simplepath es el nombre+extensión del archivo en cuestión, verbigracia 'ítems.txt' o 'telegrama.txt'. Es la ubicación por defecto del archivo de texto} {S: ort es la variable de tipo texto a la que se asigna el camino simplepath (u otro tipeado por el usuario) del archivo en cuestión, archivo que depende del nombre. E.g. ortlocalidades} var {variables locales de 'pathaid'} rtanew: byte; {indica si hay que volver a preguntar o no} rtasn: string[2]; {respuesta ingresada por el usuario (respuesta sí/no)} camino: string[50]; {camino del archivo ingresado por el usuario} begin rtanew:=1; repeat writeln('El archivo que contiene ',nombre,', ¨se llama "',simplepath,'" y se encuentra en la misma carpeta que este programa? (S¡/No)'); writeln; writeln; readln(rtasn); if rtasn='S¡' then {si la respuesta es afirmativa} begin rtanew:=0; {no preguntar de vuelta} assign(ort,simplepath); {asignar el string simplepath a la variable de tipo texto ort} end else begin if rtasn='No' {si la respuesta es negativa} then begin rtanew:=0; {no preguntar de nuevo} writeln; writeln('Por favor, ingrese el camino (path) del archivo de texto en cuesti¢n (si el archivo se encuentra en la misma carpeta que este programa, simplemente ingrese el nombre del archivo)'); writeln; writeln; readln(camino); assign(ort,camino); {asignar el string camino a la variable de tipo texto ort} end else writeln; {Si responde cualquier cosa, se deja una línea en blanco y se le vuelve a preguntar} end until rtanew=0; writeln; end; procedure yetanother(nombre: string[20];var otherstuff: byte); {subrutina que pregunta al usuario si quiere ingresar un nuevo ítem/localidad/etcétera} {E: nombre es el nombre de la entidad a ingresar, anexado a un sufijo que indica el género de la entidad más un espacio en blanco. Vg. 'o item' 'a localidad'} {S: otherstuff indica si hay que repetir el ingreso o no, y (por referencia) modifica el valor de otheritem/otherloc en el programa} var rtanew: byte; {indica si hay que volver a preguntar o no} rtasn: string[2]; {respuesta (Sí/No) ingresada por el usuario} begin repeat writeln('¨Quiere ingresar otr',nombre,'?'); {ejemplo: '¿Quiere ingresar otro item?', nombre='o item'} readln(rtasn); rtanew:=0; if rtasn='S¡' then otherstuff:=1 else begin if rtasn='No' then otherstuff:=0 else begin rtanew:=1; writeln; end; end until rtanew=0; end; procedure perm(var A,B: string[4]); {subrutina que permuta dos cadenas de cuatro caracteres de largo} {E/S: A y B son las cadenas a permutar} var aux: string[4]; {variable auxiliar} begin aux:=A; A:=B; B:=aux; end; procedure permz(var a,b: longint); {subrutina que permuta dos números enteros} {E/S: a y b son los números a permutar} var auz: longint; {variable auxiliar de tipo entero} begin auz:=a; a:=b; b:=auz; end; procedure numcheck(var celda: longint); {subrutina que valida el ingreso de un número (de tipo longint) por parte del usuario} {S: celda es la variable de tipo longint que en el programa principal es en efecto el contenido de una celda de la matriz 'tabla.' Es de salida pues lo que interesa es modificar su valor; no importa el valor que tenía la variable antes de ejecutar 'numcheck,' sino sólo el que se sigue de su invocación} var cantidad: string; {es la cadena de alfanuméricos ingresado por teclado} canterror: byte; {indica si ha habido un error en la conversión de cadena a número} begin repeat readln(cantidad); val(cantidad,celda,canterror); {esta función convierte la cadena 'cantidad' en un número que es asignado a la variable 'celda.' De no poder efectuar la operación, 'canterror' toma el valor 1} writeln; {dejo un espacio entre el renglón de ingreso de teclado y la siguiente oración que escriba el programa} if canterror=1 {si no se pudo convertir la cadena un número} then begin writeln('La cadena ingresada es inv lida: o bien no es un n£mero entero, o bien excede el valor 2 147 483 647. Intente con otro, por favor:'); {se solicita el ingreso nuevamente} writeln; end; until canterror=0; {se repite la solicitud hasta que la cadena pueda ser convertida} end; function quit: byte; {función que confirma la salida del programa por parte del usuario. No tiene parámetros} var rtasn: string[2]; {respuesta sí/no: es la respuesta del usuario a la pregunta} rtanew: byte; {indica si se debe repreguntar} begin repeat rtanew:=0; {en principio, no hay que volver a preguntar} writeln('¨Realmente desea salir? (S¡/No)'); writeln('(Si sale, todos los datos ingresados se perder n)'); readln(rtasn); if rtasn='S¡' then quit:=1 {si realmente se desea salir, se asigna a la función el valor 1} else begin if rtasn='No' then quit:=0 {si no se deseaba salir, se asigna a la función el valor 0} else rtanew:=1; {si la respuesta no es ni 'Sí' ni 'No', se repite la pregunta} end; until rtanew=0; {hasta que ésta sea respondida satisfactoriamente} end; {Sección Algorítmica} begin {Prólogo} Clrscr; {se borra la pantalla} writeln('Bienvenido/a al programa "censo."'); writeln('Antes de comenzar, por favor responda las siguientes preguntas:'); writeln; pathaid('la lista de ¡tems',pathitem,ortitems); {preguntas sobre la localización de los archivos de ítems, localidades y mensaje de cero} pathaid('la lista de localidades',pathloc,ortlocalidades); pathaid('el registro de ¡tems en cero',pathcero,ortcerolog); reset(ortitems); for i:=1 to maxitem do readln(ortitems,items[i]); {lee los nombres de los ítems y va llenando el vector 'items' con ellos} close(ortitems); {for i:=1 to maxitem do writeln(items[i]);} reset(ortlocalidades); for l:=1 to maxloc do readln(ortlocalidades,localidades[l]); {lee los códigos de las localidades y va llenando el vector 'localidades' con ellos} close(ortlocalidades); localidades_ord:=localidades; {inicializo el vector localidades_ord} {for l:=1 to maxloc do writeln(localidades[l]);} for l:=1 to maxloc do begin for i:=1 to maxitem do begin tabla[l,i]:=0; {lleno toda la tabla de ceros, indicando que no ha habido ingreso de datos aún: en realidad lo hago para inicializar la variable} end; end; {Resolución y Epílogo} salir:=0; {inicializo el byte salir, antes de entrar al bucle del menú} repeat {bucle del menú} Clrscr; {se borra la pantalla} writeln('Por favor, elija una de las siguientes opciones:'); {menú} writeln; writeln('a) Listar las localidades analizadas.'); writeln('b) Listar los items relevados.'); writeln('c) Tabular la cantidad de personas por ¡tem y por localidad.'); writeln('d) Mostrar la localidad que registr¢ la mayor cantidad de personas en un ¡tem.'); writeln('e) Listar la cantidad total de personas relevadas por localidad.'); writeln('f) Listar en forma creciente la cantidad total de personas relevadas por localidad.');writeln; writeln('g) Determinar si hubo un item que qued¢ en cero.'); writeln('h) Ingresar datos.'); writeln('s) Salir del programa.'); writeln; readln(menuopt); writeln; case menuopt of 'a': begin for l:=1 to maxloc do writeln(localidades[l]); {escribe el contenido de las celdas del vector de localidades y hace un retorno de carro} readln; end; 'b': begin for i:=1 to maxitem do writeln(items[i]); {escribe el contenido de las celdas del vector de ítems y hace un retorno de carro} readln; end; 'c': begin write(' '); {escribo un “tab”} for i:=1 to maxitem do {escribo el vector de ítems} write(' ',items[i]); writeln; {retorno de carro} for l:=1 to maxloc do begin write(localidades[l]); {al comienzo de cada línea va una localidad} for i:=1 to maxitem do {escribo el contenido de la tabla, fila por fila} write(' ',tabla[l,i]); writeln; {retorno de carro al final de cada fila} end; readln; end; 'd': begin maxppl:=-1; {inicializo la variable en -1 pues aún si todos los ítems son nulos, registra una celda de la tabla como máxima} for l:=1 to maxloc do {este bucle avanza filas} begin for i:=1 to maxitem do {este bucle avanza columnas} if tabla[l,i]>maxppl {si el elemento analizado es mayor que el máximo encontrado hasta el momento} then begin maxppl:=tabla[l,i]; {el nuevo máximo es el elemento en cuestión} maxvec[1]:=l; {tomo los datos del máximo: número de fila} maxvec[2]:=i; {número de celda} maxvec[3]:=tabla[l,i]; {valor del máximo} end; begin end; end; writeln('La localidad que registr¢ la mayor cantidad de personas fue ',localidades[maxvec[1]],' en el ¡tem ',items[maxvec[2]],': ',maxvec[3],'.'); readln; end; 'e': begin for l:=1 to maxloc do {calculo la sumatoria de los elementos de cada fila (localidad)}{este bucle avanza filas} begin sumfilas:=0; {cereo la sumatoria para cada fila} for i:=1 to maxitem do {este bucle avanza columnas (o sea, celdas dentro de la fila)} begin sumfilas:=sumfilas+tabla[l,i]; {voy sumando el contenido de cada celda de la fila en cuestión} end; writeln(localidades[l],' ',sumfilas); {listo cada celda del vector de localidades junto a la sumatoria de las celdas de la fila correspondiente} end; readln; end; 'f': begin for l:=1 to maxloc do {esta primera parte crea el vector vecsumfilas, que contiene la suma de cada fila de la tabla}{este bucle avanza filas} begin sumfilas:=0; {cereo la sumatoria para cada fila} for i:=1 to maxitem do {este bucle avanza columnas (o sea, celdas dentro de la fila)} begin sumfilas:=sumfilas+tabla[l,i]; {voy sumando el contenido de cada celda de la fila en cuestión} end; vecsumfilas[l]:=sumfilas; {y le asigno dicha suma a cada celda del vector vecsumfilas} end; for b:=1 to (maxloc-1) do {esta segunda parte ordena el vector vecsumfilas, y correspondientemente también el vector localidades_ord} begin min[1]:=vecsumfilas[b]; {el mínimo para cada vuelta es el valor que se encuentra en la celda b de vecsumfilas} min[2]:=b; {asigno al mínimo la coordenada (b) que le corresponde, según su posición dentro del vector vecsumfilas} for s:=b+1 to maxloc do {este loop se fija cuál es el mínimo absoluto del vector (a partir de la posición b+1) y qué hacer al encontrarlo} begin if vecsumfilas[s]<min[1] {si la posición actual del cursor es menor que el mínimo de la vuelta} then begin min[1]:=vecsumfilas[s]; {redefino el mínimo como el número de la posición actual del cursor (s)} min[2]:=s; {asigno a ese mínimo una coordenada: la posición del cursor (s)} end; end; perm(localidades_ord[b],localidades_ord[min[2]]); {permuto las localidades, correspondientemente con el vector vecsumfilas} permz(vecsumfilas[b],vecsumfilas[min[2]]); {permuto el mínimo encontrado con el elemento de la celda b} end; for l:=1 to maxloc do writeln(localidades_ord[l],' ',vecsumfilas[l]); {cada vuelta escribo el código de la localidad y a continuación el número correspondiente} readln; end; 'g': begin cero:=0; {cereo el byte, antes de entrar al loop correspondiente} b:=1; {(idem del inmediato anterior)} repeat {este bucle primario avanza filas} s:=1; {inicializo el byte, antes de entrar al bucle pertinente} repeat {este bucle secundario avanza columnas} if tabla[b,s]=0 {si el elemento en cuestión es nulo} then begin cero:=1; {salgo de ambos bucles} writeln('Por lo menos un ¡tem (',items[s],' de ',localidades[b],') qued¢ en cero.'); reset(ortcerolog); rewrite(ortcerolog); writeln(ortcerolog,'Por lo menos un ítem (',items[s],' de ',localidades[b],') quedó en cero.'); close(ortcerolog); end else {si el elemento no es nulo} begin if ((b=maxloc) AND (s=maxitem)) {si estamos en la última celda de la tabla} then begin {(No hay ningún item en cero)} writeln('Todos los items registraron valores.'); reset(ortcerolog); rewrite(ortcerolog); writeln(ortcerolog,'Todos los items registraron valores.'); close(ortcerolog); end; end; s:=s+1; {incremento el contador del bucle secundario} until ((cero=1) OR (s>maxitem)); {sale del bucle si se llega al final de la fila, o si se encontró un cero} b:=b+1; {incremento el contador del bucle primario} until ((cero=1) OR (b>maxloc)); {sale del bucle si se llega al final de la tabla, o si se encontró un cero} readln; end; 'h': begin repeat {este loop es por si quiere ingresar más localidades} entry:=0; writeln('Ingrese el c¢digo de la localidad relevada'); repeat {este loop es para ver si la localidad está dentro de la lista de las relevadas o no} readln(entryloc); writeln; locincl:=0; l:=1; repeat {acá viene la parte de ver si está incluida o no: va barriendo todas las celdas del vector hasta que encuentra o hasta el final} if entryloc=localidades[l] then begin locincl:=1; {salgo del loop de inclusión} entry:=1; {salgo del loop de entrada de localidades} entryrow:=l; {guardo el número de la fila en la que está la localidad} end else begin if l=maxloc {si ya llegué al final del vector} then begin writeln('La localidad ingresada no figura dentro de la lista de localidades relevadas. Por favor, int‚ntelo con otra:'); writeln; locincl:=1; {salgo del loop de inclusión} end end; l:=l+1; until locincl=1; until entry=1; repeat {este loop es por si quiere ingresar más ítems} entry:=0; writeln('Ingrese el c¢digo del item:'); repeat {este loop es para ver si el item está dentro de la lista de los relevados o no} readln(entryitem); writeln; itemincl:=0; i:=1; repeat {acá viene la parte de ver si está incluido o no: va barriendo todas las celdas del vector hasta que encuentra o hasta el final} if entryitem=items[i] then begin itemincl:=1; {salgo del loop de inclusión} entry:=1; {salgo del loop de entrada de ítems} entrycol:=i; {guardo el número de la columna en la que está el item} end else begin if i=maxitem then begin writeln('El ¡tem ingresado no figura dentro de los relevados. Por favor, pruebe con otro:'); itemincl:=1; {salgo del loop de inclusión} end end; i:=i+1; until itemincl=1; until entry=1; writeln('Ingrese la cantidad'); {hold on, we gotta check whether this is correct or not} numcheck(tabla[entryrow,entrycol]); {readln(tabla[entryrow,entrycol]);} {leo lo ingresado y lo escribo en la celda de la fila tanto de la columna tanto de la matriz censo} yetanother('o ¡tem',otheritem); {invoco la subrutina que pregunta si quiere ingresar otro item} writeln; until otheritem=0; {hasta que se harte de llenar ítems} yetanother('a localidad',otherloc); {invoco la subrutina que pregunta si quiere ingresar otra localidad} writeln; until otherloc=0; {hasta que se harte de llenar localidades} end; 's': salir:=quit; end; until salir=1; {vuelve siempre al menú, a menos que se seleccione la opción 's'} end.