Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Fundamentos de Programación
Práctica 2 - Segunda Práctica
Presentación
En este documento se presenta la segunda práctica. Esta prueba constituye un 50% de
la nota final de prácticas.
Competencias
La principal competencia del grado que se trabaja en esta práctica es la capacidad de
diseñar y construir aplicaciones informáticas mediante técnicas de desarrollo, integración
y reutilización. Para trabajar esta competencia, la Práctica plantea varios ejercicios en
torno al uso de estructuras de datos como tablas y tuplas, así como las combinaciones
entre ellas.
Objetivos
• Identificar y declarar los tipos de datos (tablas, tuplas, variables y constantes)
necesarias a partir de un problema / enunciado.
• Especificar cómo sería una llamada a una acción / función que tiene parámetros
estructurados.
• Entender el funcionamiento del acceso a los elementos de una tabla y / o los campos
de una tupla.
• Diseñar un algoritmo que pueda contener esquemas de búsqueda / recorrido, y que
trate con tablas / tuplas.
• Dada una definición de tipo que presenta una combinación de tablas y tuplas, se pide
la traducción a C de un algoritmo que acceda a estas estructuras.
Descripción de la práctica
La práctica consta de 5 ejercicios, que trabajan los diferentes objetivos que se han
enumerado como claves en esta prueba. Cada ejercicio consta de un enunciado y un
peso que indica el porcentaje que representa respecto a la nota global.
Recursos
Será necesario leer previamente los capítulos del temario relativos al uso de tablas y
tuplas, tanto de los apuntes de la asignatura como de las TS que encontraréis en las
citas del calendario de vuestra aula.
75.554 · FP · Pract2 · 2014-02 · Estudios de Informática Multimedia y Telecomunicación
Adicionalmente, para resolver los ejercicios de codificación, será necesario que reviséis
las tablas de traducción y todo el material relacionado con la codificación en C que se
encuentra en el apartado de "recursos" de vuestra aula.
Criterios de valoración
Se evaluará cada ejercicio de acuerdo con su peso, que aparece indicado antes de su
enunciado. Los ejercicios que consten de varios apartados se valorarán como
completamente correctos o incorrectos. Las respuestas incorrectas no disminuyen la nota.
Razonad y justificad todas las respuestas, especialmente si así lo indica el enunciado (si,
aun pedirlo el enunciado, no justificáis la respuesta, se contabilizará como incorrecta).
Fecha límite para entregar la solución: miércoles, 20 de mayo de 2015 (a las 23:59
horas).
75.554 · FP · Pract2 · 2014-02 · Estudios de Informática Multimedia y Telecomunicación
NOTA: Para almacenar las cadenas de texto utilizad el tipo tString (podéis suponer que este tipo ya
está declarado).
Objetivos: Especificar cómo sería una llamada a una acción / función que tiene
parámetros estructurados.
Tarea: Utilizando los tipos definidos en el ejercicio anterior, declarad las acciones y
funciones pedidas a continuación. No se pide diseñarlas.
Objetivos: Entender el funcionamiento del acceso a los elementos de una tabla y / o los
campos de una tupla.
Tarea: Una distribuidora de cine tiene 30 salas de cine repartidas por una provincia, y
quiere recoger información sobre la recaudación y el aforo que una determinada película
tiene durante su proyección en una semana en concreto. Para obtener la información
tendremos en cuenta que el precio de la entrada para ver la película varía dependiendo de
si la película se proyecta en 2D o en 3D, dependiendo de la edad del espectador, y
dependiendo del día de la semana que se proyecta, tal y como se indica a continuación:
• Película 2D:
o Días fidelidad (lunes a jueves): 4,60€
o Viernes, sábado y domingo para menores de 12 años: 7,20€
o Viernes, sábado y domingo para 12 años y mayores: 9,60€
• Película 3D:
o Días fidelidad (lunes a jueves): 6,50€
o Viernes, sábado y domingo para menores de 12 años: 9,00€
o Viernes, sábado y domingo para 12 años y mayores: 11,40€
Donde:
• idMovieTheatrei es un entero comprendido entre 1 y 30 que identifica la sala.
• typeProjectioni es un carácter que indica si la proyección de la película de la sala i-
ésima es en 2D (carácter ‘2’) o en 3D (carácter ‘3’).
75.554 · FP · Pract2 · 2014-02 · Estudios de Informática Multimedia y Telecomunicación
Podemos suponer que los datos de entrada son correctos, y coherentes con las
estructuras de datos definidas y que no es necesario comprobarlo.
El algoritmo siguiente lee del canal de entrada estándar una secuencia con éste formado
y genera una secuencia de salida por el canal de salida estándar donde aparece para cada
una de las 30 salas el número de espectadores y la recaudación de la semana, tal y como
se muestra a continuación:
En concreto:
• idMovieTheatrei es el identificador de la sala de cine i-ésima.
• numberOfViewersi es el número de espectadores que han visto la proyección de la
película en la sala i-ésima durante la semana.
• collectioni es la recaudación de la sala i-ésima durante la semana de proyección
• -1 es la marca de final de secuencia.
75.554 · FP · Pract2 · 2014-02 · Estudios de Informática Multimedia y Telecomunicación
Se pide que completéis los recuadros (En cada recuadro puede haber una o más
instrucciones).
const
PRICE_2D_LOYALTY_DAY: real = 4.60;
PRICE_2D_LESS_12: real = 7.20;
PRICE_2D_GREATER_12: real = 9.60;
DAY_OF_WEEK_MONDAY: entero = 1;
DAY_OF_WEEK_TUESDAY: entero = 2;
DAY_OF_WEEK_WEDNESDAY: entero = 3;
DAY_OF_WEEK_THURSDAY: entero = 4;
DAY_OF_WEEK_FRIDAY: entero = 5;
DAY_OF_WEEK_SATURDAY: entero = 6;
DAY_OF_WEEK_SUNDAY: entero = 7;
tipo
tMovieTheatre = tupla
identifier: entero;
numViewers: entero;
collection: real;
ftupla
tDistributor = tupla
moviesTheatre: tabla[NUM_MOVIE_THEATRE] de tMovieTheatre;
ftupla
ftipo
{ Pre: En el canal estándar de entrada tenemos una secuencia con el formato <idMovieTheatre1
typeProjection1 dayOfWeek1 numberOfViewersUnder121 numberOfViewersGreaterEqual121 ...
idMovieTheatrei typeProjectioni dayOfWeeki numberOfViewersUnder12i
numberOfViewersGreaterEqual12i ... idMovieTheatren typeProjectionn dayOfWeekn
numberOfViewersUnder12n numberOfViewersGreaterEqual12n -1> }
algoritmo movies
var
distributor: tDistributor;
idMovieTheatre: entero;
75.554 · FP · Pract2 · 2014-02 · Estudios de Informática Multimedia y Telecomunicación
typeProjection: caracter;
dayOfWeek: entero;
numViewersUnder12, numViewersGreater12: entero;
ticketsPrice: real;
fvar
typeProjection := readCharacter();
dayOfWeek := readInteger();
numViewersUnder12 := readInteger();
numViewersGreater12 := readInteger();
idMovieTheatre := readInteger();
fmientras
faccion
{ Post: Se ha inicializado la información de las NUM_MOVIE_THEATRE salas de cine guardadas en
DISTRIBUTOR}
ffuncion
{ Post: Calcula y retorna la recaudación de una proyección en concreto, según el tipo de proyección
indicado(TYPEPROJECTION), el día de la semana (DAYOFWEEK), y el número de espectadores
menores de 12 años (VIEWERSUNDER12) y mayores o igual a 12 años (VIEWERSGREATER12) }
75.554 · FP · Pract2 · 2014-02 · Estudios de Informática Multimedia y Telecomunicación
{ Pre: distributor = DISTRIBUTOR, donde cada una de las salas de cine está actualizada con la
información (de recaudación y número de espectadores) leída hasta el momento, idMovieTheatre
= ID, numViewers = NUMVIEWERS y collection = COLLECTION }
accion updateMovieTheatre(entsal distributor: tDistributor, ent idMovieTheatre: entero,
ent numViewers: entero, ent collection: real)
faccion
{ Post: La sala de DISTRIBUTOR con identificador ID, se ha actualizado con el número de
espectadores NUMVIEWERS, y la recaudación COLLECTION }
{ Pre: distributor = DISTRIBUTOR, donde cada una de las salas de cine está actualizada con la
información (de recaudación y número de espectadores) leída de la secuencia de entrada estándar
}
accion printResults(ent distributor: tDistributor)
var
i: entero;
fvar
writeInteger(ENDSEQ);
faccion
{ Post: Se ha escrito por el canal de salida estándar una secuencia con el siguiente formato:
<idMovieTheatre1 numberOfViewers1 collection1 … idMovieTheatrei numberOfViewersi collectioni
… idMovieTheatren numberOfViewersn collectionn -1>}
75.554 · FP · Pract2 · 2014-02 · Estudios de Informática Multimedia y Telecomunicación
Tarea: Partiendo del algoritmo del ejercicio 3, haced las modificaciones adecuadas a fin
de que el algoritmo muestre también la sala que ha generado más ingresos.
i) [10%] Crear una acción que reciba como parámetro una variable de tipo
tDistributor y que lo devuelva ordenado por recaudación (de más a menos
ingresos).
Tarea: El siguiente algoritmo es utilizado por una empresa que dispone de una red de
máquinas expendedoras de productos repartidas por diversos centros, en concreto,
universidades, hospitales y empresas. Cada centro puede tener varias máquinas, y las
máquinas pueden suministrar productos diferentes dependiendo del tipo de centro en que
se encuentren: bebidas, caramelos, chicles, patatas o bocadillos.
El algoritmo tiene que leer la secuencia de entrada y devolver información relacionada con
las ventas de las máquinas.
Para ello, se dispone de la información de las ventas que ha realizado cada una de las
máquinas expendedoras durante un día, organizada en una secuencia de entrada con el
siguiente formato:
<idCenter1 typeCenter1 numVendingMachines1 vendingMachine11 typeProduct111
unitsProduct111 priceProduct111 typeProduct112 unitsProduct112 priceProduct112... -1
vendingMachine12 typeProduct121 unitsProduct121 priceProduct121 typeProduct122
unitsProduct122 priceProduct122... -1
idCenter2 typeCenter2 numVendingMachines2 vendingMachine21 typeProduct211
unitsProduct211 priceProduct211 typeProduct212 unitsProduct212 priceProduct212... -1
vendingMachine22 typeProduct221 unitsProduct221 priceProduct221 typeProduct222
unitsProduct222 priceProduct222... -1
...
-2>
Para cada centro se muestra la información del centro (identificador, tipo, y número de
máquinas instaladas), y a continuación los datos del conjunto de máquinas que tiene. Para
cada máquina tenemos la información de los productos que ha expedido: tipo de producto,
unidades de producto vendidas, y precio del producto. La información de cada una de las
máquinas está delimitada por el código -1, y el código -2 indica el final de la secuencia.
Donde:
• idCenteri es un entero mayor que cero que identifica de manera única el i-ésimo
centro.
• typeCenteri es un entero que indica el tipo del i-ésimo centro. La clasificación de
centros utilizada es:
o Carácter ‘U’ para universidades.
o Carácter ‘H’ para hospitales.
o Carácter ‘E’ para empresas.
75.554 · FP · Pract2 · 2014-02 · Estudios de Informática Multimedia y Telecomunicación
Consideraremos que:
• Como máximo habrá 20 centros. Sin embargo, los identificadores de centro no
tienen por qué ser números del 1 al 20, ni tampoco ser números consecutivos. Cada
código de centro aparecerá una única vez en la secuencia de entrada.
El algoritmo tiene que generar una secuencia de salida con la siguiente información:
• Tipo de producto que ha sido el más vendido, y los ingresos que ha generado.
• Tipo de centro que ha generado más ingresos, y el total de estos ingresos.
• Para cada uno de los centros, su identificador seguido de los ingresos totales. Los
centros se escribirán ordenados por el importe de los ingresos (de mayor a menor).
75.554 · FP · Pract2 · 2014-02 · Estudios de Informática Multimedia y Telecomunicación
Donde:
• typeProduct es un entero (1 para bebidas, 2 para caramelos, 3 para chicles, 4 para
patatas y 5 para bocadillos) que indica el tipo de producto que ha sido el más
vendido.
• importTotalTypeProduct es un real que contiene los ingresos que ha generado el
tipo de producto más vendido (tipo typeProduct).
• typeCenter es un carácter (‘U’ para universidades, ‘H’ para hospitales y ‘E’ para
empresas) que indica el tipo de centro que ha generado más ingresos.
• importTotalTypeCenter son los ingresos generados por el tipo de centro que ha
obtenido más ingresos (typeCenter).
• idCenteri es el identificador del centro i-ésimo. (La secuencia de centros está
ordenada por los ingresos obtenidos, de más a menos).
• importTotalCenteri son los ingresos totales obtenidos por el centro i-ésimo.
• -1 es la marca de final de secuencia.
• 12 -1
La tercera máquina tiene identificador 12 y no ha vendido ningún producto.
2E1
El centro con identificador 2 que es de tipo Empresa tiene 1 máquina:
• 1 5 2 1.30 5 10 1.60 5 8 3.00 – 1
La primera máquina tiene identificador 1 y ha vendido:
5 2 1.30 2 unidades de bocadillos a 1.30€.
5 10 1.60 10 unidades de bocadillos a 1.60€.
5 8 3.00 8 unidades de bocadillos a 3.00€
20 E 2
El centro con identificador 20 que es de tipo Empresa tiene 2 máquinas:
• 20 1 1 1.30 2 20 0.60 3 5 1.00 4 5 1.00 5 5 2.50 – 1
La primera máquina tiene identificador 20 y ha vendido:
1 1 1.30 1 unidad de bebidas a 1.30€.
2 20 0.60 20 unidades de caramelos a 0.60€.
3 5 1.00 5 unidades de chicles a 1.00€.
4 5 1.00 5 unidades de patatas a 1.00€.
5 5 2.50 5 unidades de bocadillos a 2.50€.
• 120 1 1 1.00 – 1
La segunda máquina tiene identificador 120 y ha vendido:
1 1 1.00 1 unidad de bebidas a 1.00€.
35 H 0
El centro con identificador 35 que es de tipo Hospital no tiene ninguna máquina.
Con esta secuencia de entrada tendremos los siguientes resultados por tipo de producto:
TIPO UNIDADES INGRESOS
Bebidas 12 15,30€
Caramelos 40 44,00€
Chicles 5 5,00€
Patatas 13 13,00€
Bocadillos 30 70,10€
2 Empresa 42,60€
35 Hospital 0,00€
20 Empresa 36,80€
Y por lo tanto la secuencia de salida indicaría que el producto más vendido sería el de tipo
2 (caramelos), y que el tipo de centro con más ingresos ha sido el de tipo empresa.
Tendríamos la siguiente información a la salida estándar:
< 2 44.00 E 79.40 5 68.00 2 42.60 20 36.80 35 0.00 -1>
const
MAX_CENTERS: entero = 20;
MAX_TYPE_PRODUCTS: entero = 5;
TYPE_CENTER_UNIVERSITY: caracter = ‘U’;
TYPE_CENTER_HOSPITAL: caracter = ‘H’;
TYPE_CENTER_ENTERPRISE: caracter = ‘E’;
TYPE_PRODUCT_DRINK: entero = 1;
TYPE_PRODUCT_CANDY: entero = 2;
TYPE_PRODUCT_GUM: entero = 3;
TYPE_PRODUCT_CHIPS: entero = 4;
TYPE_PRODUCT_SNACK: entero = 5;
ENDSEQ_MACHINE: entero = -1;
ENDSEQ: entero = -2;
ENDSEQ_OUTPUT: entero = -1;
fconst
tipo
tTypeProductInfo = tupla
units: entero;
import: real;
ftupla
tTypesProduct = tupla
types: tabla[MAX_TYPE_PRODUCTS] de tTypeProductInfo;
ftupla
tCenterInfo = tupla
idCenter: entero;
typeCenter: caracter;
import: real;
ftupla
tCenters = tupla
centers: tabla [MAX_CENTERS] de tCenterInfo;
numCenters: entero;
ftupla
ftipo
75.554 · FP · Pract2 · 2014-02 · Estudios de Informática Multimedia y Telecomunicación
{ Pre: En el canal estándar de entrada tenemos una secuencia con la información de las máquinas
espendedoras de diferentes centros, con el formato <idCenter1 typeCenter1
numVendingMachines1 vendingMachine11 typeProduct111 unitsProduct111 priceProduct111
typeProduct112 unitsProduct112 priceProduct112... -1 vendingMachine12 typeProduct121
unitsProduct121 priceProduct121 typeProduct122 unitsProduct122 priceProduct122... -1
idCenter2 typeCenter2 numVendingMachines2 vendingMachine21 typeProduct211
unitsProduct211 priceProduct211 typeProduct212 unitsProduct212 priceProduct212... -1
vendingMachine22 typeProduct221 unitsProduct221 priceProduct221 typeProduct222
unitsProduct222 priceProduct222... -1
...
-2> }
algoritmo vendingMachines
var
i: entero;
typesProduct : tTypesProduct;
centers: tCenters;
idCenter, numVendingMachinesCenter: entero;
typeCenter: caracter;
importTotalCenter: real;
blank: caracter;
fvar
initializeTypesProducts(typesProduct);
initializeCenters(centers);
idCenter := readInteger();
importTotalCenter := 0;
para i := 1 hasta numVendingMachinesCenter hacer
readUpdateVendingMachinesCenter(typesProduct, importTotalCenter);
fpara
addCenter(idCenter, typeCenter, importTotalCenter, centers);
idCenter := readInteger();
fmientras
writeResults(centers, typesProduct);
falgoritmo
{ Pre: En el canal estándar de salida se ha escrito una secuencia con formato: <typeProduct
importTotalTypeProduct typeCenter importTotalTypeCenter idCenter1 importTotalCenter1 …
idCenteri importTotalCenteri … idCentern importTotalCentern -1> }
75.554 · FP · Pract2 · 2014-02 · Estudios de Informática Multimedia y Telecomunicación
{ Pre: typesProduct = TYPESPRODUCT, estructura que contiene la información relacionada con cada
uno de los tipos de productos: estructura sin inicializar }
accion initializeTypesProducts(sal typesProduct: tTypesProduct)
var
i : entero;
fvar
faccion
{ Post: La estructura TYPESPRODUCT está inicializada}
{ Pre: centers = CENTERS, estructura que contiene la información relacionada con cada uno de los
centros: estructura sin inicializar }
accion initializeCenters(sal centers: tCenters)
var
i : entero;
fvar
centers.numCenters := 0;
para i := 1 hasta MAX_CENTERS hacer
centers.centers[i].idCenter := -1;
centers.centers[i].import := 0.0;
fpara
faccion
{ Post: La estructura CENTERS está inicializada}
idVendingMachine := readInteger();
75.554 · FP · Pract2 · 2014-02 · Estudios de Informática Multimedia y Telecomunicación
typeProduct := readInteger();
typeProduct := readInteger();
fmientras
faccion
{ Post: Se ha leído la información relacionada con una máquina, y se ha actualizado con esta
información TYPESPRODUCT, y IMPORTTOTALCENTER. }
{ Pre: type = TYPE es un entero que indica el tipo de producto, units = UNITS son las unidades de
producto de tipo TYPE, import = IMPORT es el importe pagado por las UNITS unidades de tipo TYPE,
typesProduct = TYPESPRODUCT, estructura que contiene la información relacionada con cada uno
de los tipos de productos, actualizada con la información leída hasta el momento }
accion updateTypeProduct(ent type: entero, ent units: entero, ent import: real, entsal
typesProduct: tTypesProduct)
faccion
{ Post: Se ha acumulado al tipo TYPE de TYPESPRODUCT las unidades UNITS y el importe IMPORT }
fsi
fmientras
{ la variable i contiene la posición en que insertar el centro. Si found = cierto tenemos que
desplazar los elementos de la tabla }
si found entonces
para j := centers.numCenters hasta i paso -1
centers.centers[j+1].idCenter := centers.centers[j].idCenter;
centers.centers[j+1].typeCenter := centers.centers[j].typeCenter;
centers.centers[j+1].import := centers.centers[j].import;
fpara
fsi
faccion
{ Post: Se ha añadido el centro IDCENTER (con la información de TYPECENTER y IMPORT) a la
estructura CENTERS en la posición adecuada para mantener la estructura CENTERS ordenada de
mayor a menor por ingresos de centro }
var
maxUnits, maxIndex: entero;
i: entero;
fvar
maxIndex := -1;
maxUnits := -1;
para i := 1 hasta MAX_TYPE_PRODUCTS hacer
si typesProduct.types[i].units > maxUnits entonces
maxUnits= typesProduct.types[i].units;
maxIndex := i;
fsi
fpara
retorna maxIndex;
ffuncion
{ Post: Devuelve la posición de la tabla de la estructura TYPESPRODUCT donde se encuentra el tipo
de producto del que se han vendido más unidades }
75.554 · FP · Pract2 · 2014-02 · Estudios de Informática Multimedia y Telecomunicación
{ Pre: centers = CENTERS es la estructura de centros que contiene la información leída hasta el
momento y ordenada según los ingresos generados por cada centro (de más a menos)}
accion searchTypeCenterMaxImport(ent centers: tCenters, sal typeCenter: caracter, sal
importTypeCenter: real)
var
importCenterU, importCenterH, importCenterE: real;
i : entero;
fvar
importCenterU := 0.0;
importCenterH := 0.0;
importCenterE := 0.0;
importTypeCenter:= -1.0;
si importCenterU > importTypeCenter entonces
importTypeCenter := importCenterU;
typeCenter := TYPE_CENTER_UNIVERSITY;
fsi
si importCenterH > importTypeCenter entonces
importTypeCenter:= importCenterH;
typeCenter := TYPE_CENTER_HOSPITAL;
fsi
si importCenterE > importTypeCenter entonces
importTypeCenter:= importCenterE;
typeCenter := TYPE_CENTER_ENTERPRISE;
fsi
faccion
{ Post: Devuelve el tipo del centro, y los ingresos generados, que se corresponden con el tipo de
centro que ha generado más ingresos }
75.554 · FP · Pract2 · 2014-02 · Estudios de Informática Multimedia y Telecomunicación
{ Pre: centers = CENTERS es la estructura de centros que contiene la información leída hasta el
momento y ordenada según los ingresos generados por cada centro (de más a menos), y
typesProduct = TYPESPRODUCT es la estructura de tipos de producto que contiene la información
leída hasta el momento }
accion writeResults(ent centers: tCenters, ent typesProduct: tTypesProduct)
var
i, j: entero;
typeCenter: caracter,
importCenter: real;
fvar
Nota: Los reales se deben escribir con dos decimales, con printf(“%.2f “, valor).