Está en la página 1de 22

75.

554 · FP · Pract2 · 2014-02 · Estudios de Informática Multimedia y Telecomunicación

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).

Formato y fecha de entrega


Hay que entregar en el buzón de “Entrega de actividades” del aula de teoría un fichero zip
que contenga la solución de los ejercicios 1 al 4 en un fichero llamado
ApellidosNombre_FP_Pract2. La codificación de la pregunta 5 debe entregarse a través
del Corrector Automático, que encontraréis en el aula de teoría.

IMPORTANTE: Recordad que, antes de realizar el envío al Corrector Automático, es


obligatorio compilar y hacer funcionar vuestro código usando los ficheros que se han
entregado junto al enunciado de la prueba.

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

Ejercicio 1: Declaración de tipos estructurados [20%]


Objetivos: Identificar y declarar los tipos de datos (tablas, tuplas, variables y constantes)
necesarias a partir de un problema / enunciado.

Materiales: Módulo 4: Tipos estructurados de datos


M 4.1: Introducción y motivación. Estructuración de datos
M 4.2: Tablas
M 4.3: Tuplas

Tarea: Se quiere guardar la información de un hospital, teniendo en cuenta los médicos


que trabajan en él, y los pacientes que acuden al centro. Para ello, hace falta que:

NOTA: Para almacenar las cadenas de texto utilizad el tipo tString (podéis suponer que este tipo ya
está declarado).

a) [5%] Declaréis un tipo de datos tPrescription y las constantes y tipos enumerados


necesarios para almacenar la información de una receta. En concreto, se quiere
guardar si la seguridad social subvenciona el total de la receta (totalPrice), o
únicamente una parte (portionPrice), o nada (nothingPrice), la fecha de emisión de
la receta (valor numérico), la fecha de caducidad de la receta (valor numérico), la
referencia del medicamento (valor numérico), el nombre del medicamento, el
número de colegiado del médico que emite la receta (cadena de texto), el número
de seguridad social del paciente (cadena de texto), el número de toma diaria, y si
se trata o no de una receta crónica.

b) [5%] Declaréis un tipo de datos tPatient y las constantes y tipos enumerados


necesarios para almacenar la información de un paciente. En concreto, se quiere
guardar la situación laboral del paciente (si está jubilado (retired), o está en paro
(unemployed), o está trabajando (working), el DNI de la persona (valor numérico),
el nombre y apellidos de la persona, el número de seguridad social asignado a la
persona (cadena de texto), y el listado de las recetas que tiene vigentes en este
momento el paciente (como máximo puede tener 20 recetas diferentes).

c) [5%] Declaréis un tipo de datos tDoctor y las constantes y tipos enumerados


necesarios para almacenar la información de un médico. En concreto, se quiere
guardar su número de colegiado (cadena de texto), su nombre y apellidos, y el
listado de los pacientes que tiene asignados (como máximo puede tener 100
pacientes diferentes).

d) [5%] Declaréis un tipo de datos tHospital y las constantes y tipos enumerados


necesarios para almacenar la información de un hospital. En concreto, se quiere
guardar el nombre del hospital, el nombre de la población a la que cubre (cadena
de texto), y el listado con los médicos que están trabajando en el hospital (como
máximo puede tener 200 médicos en plantilla).
75.554 · FP · Pract2 · 2014-02 · Estudios de Informática Multimedia y Telecomunicación

Ejercicio 2: Llamar funciones/acciones que trabajan con tipos


estructurados [10%]

Objetivos: Especificar cómo sería una llamada a una acción / función que tiene
parámetros estructurados.

Materiales: Módulo 4: Tipos estructurados de datos


M 4.1: Introducción y motivación. Estructuración de datos
M 4.2: Tablas
M 4.3: Tuplas

Tarea: Utilizando los tipos definidos en el ejercicio anterior, declarad las acciones y
funciones pedidas a continuación. No se pide diseñarlas.

a. [2.5%] Declarad una acción/función prescriptionsExpired que dado un parámetro


de tipo tPrescription compruebe si la receta médica está o no caducada.

b. [2.5%] Declarad una acción/función writePrescriptions que dada una variable de


tipo tHospital, y el DNI de un paciente liste por el canal de salida estándar la
información de todas las recetas que tiene en este momento.

c. [2.5%] Declarad una acción/función addDoctorToHospital que dada la información


de un hospital (parámetro de tipo tHospital) y la información de un médico, añada
el médico a la lista de médicos del hospital, y devuelva la estructura tHospital
actualizada.

d. [2.5%] Declarad una acción/función existsDoctorWithoutPatients que dada la


información de un hospital devuelva si existe o no algún médico trabajando en el
hospital que en este momento no tenga ningún paciente asignado.
75.554 · FP · Pract2 · 2014-02 · Estudios de Informática Multimedia y Telecomunicación

Ejercicio 3: Acceso a tipos de datos estructurados [20%]

Objetivos: Entender el funcionamiento del acceso a los elementos de una tabla y / o los
campos de una tupla.

Materiales: Módulo 4: Tipos estructurados de datos


M 4.1: Introducción y motivación. Estructuración de datos
M 4.2: Tablas
M 4.3: Tuplas

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€

Deberemos tener en cuenta que:


• Cada sala viene identificada por un valor entero, del 1 al 30.
• Cada película se puede proyectar varias veces un mismo día, en horarios
diferentes, y en salas diferentes.
• Una sala puede aparecer más de una vez en la secuencia de entrada.

Los datos de proyección de la película en una semana se recogen en una secuencia de


entrada con el siguiente formato:

<idMovieTheatre1 typeProjection1 dayOfWeek1 numberOfViewersUnder121


numberOfViewersGreaterEqual121 ... idMovieTheatrei typeProjectioni dayOfWeeki
numberOfViewersUnder12i numberOfViewersGreaterEqual12i ... idMovieTheatren
typeProjectionn dayOfWeekn numberOfViewersUnder12n
numberOfViewersGreaterEqual12n -1>

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

• dayOfWeeki es un valor entero que indica el día de la semana en que se ha


proyectado la película en la sala i-ésima. La correspondencia de valores es 1 para
lunes, 2 para martes, 3 para miércoles, 4 para jueves, 5 para viernes, 6 para
sábado, y 7 para domingo.
• numberOfViewersUnder12i es el número de espectadores menores de 12 años que
han asistido a la proyección de la película en la sala i-ésima.
• numberOfViewersGreater12i es el número de espectadores con 12 o más años que
han asistido a la proyección de la película en la sala i-ésima.
• -1 es la marca final de la secuencia de entrada.

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:

<idMovieTheatre1 numberOfViewers1 collection1 … idMovieTheatrei numberOfViewersi


collectioni … idMovieTheatren numberOfViewersn collectionn -1>

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;

PRICE_3D_LOYALTY_DAY: real = 6.50;


PRICE_3D_LESS_12: real = 9.00;
PRICE_3D_GREATER_12: real = 11.40;

TYPE_PROJECTION_2D: caracter = ‘2’;


TYPE_PROJECTION_3D: caracter = ‘3’;

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;

NUM_MOVIE_THEATRE: entero = 30;

ENDSEQ : entero = -1;


fconst

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

{ Inicialización de la variable distributor }


initializeDistributor(distributor);

{ Leemos el primer elemento de la secuencia de entrada }


idMovieTheatre := readInteger();

{Tratamos la información de la secuencia de entrada }

typeProjection := readCharacter();
dayOfWeek := readInteger();
numViewersUnder12 := readInteger();
numViewersGreater12 := readInteger();

{ Calculamos la recaudación de la proyección leída de la secuencia de entrada }


ticketsPrice := calculateCollectionProjection(typeProjection, dayOfWeek,
numViewersUnder12, numViewersGreater12);

{ Actualizamos la información de la sala idMovieTheatee con el total calculado en


la proyección leída }
updateMovieTheatre(distributor, idMovieTheatre, (numViewersUnder12 +
numViewersGreater12), ticketsPrice);

idMovieTheatre := readInteger();
fmientras

{ Escribimos la información por el canal de salida estándar }


printResults(distributor);
falgoritmo
{ Post: En el canal estándar de salida hay una secuencia que muestra para cada sala de cine el
número de espectadores que han asistido a la proyección en esta sala durante la semana, y la
recaudación en toda la semana. Secuencia con el formato: <idMovieTheatre1 numberOfViewers1
collection1 … idMovieTheatrei numberOfViewersi collectioni … idMovieTheatren
numberOfViewersn collectionn -1>}

{ Pre: distributor = DISTRIBUTOR contiene la información de la distribuidora sin inicializar }


accion initializeDistributor (sal distributor: tDistributor)
75.554 · FP · Pract2 · 2014-02 · Estudios de Informática Multimedia y Telecomunicación

faccion
{ Post: Se ha inicializado la información de las NUM_MOVIE_THEATRE salas de cine guardadas en
DISTRIBUTOR}

{ Pre: typeProjection = TYPEPROJECTION indica si la proyección ha sido en 2D o en 3D, dayOfWeek


= DAYOFWEEK indica el día de la semana en que se realiza la proyección, numViewersUnder12 =
VIEWERSUNDER12 indica el número de espectadores menores de 12 años que han acudido a la
proyección, y numViewersGreater12 = VIEWERSGREATER12 indica el número de espectadores de
12 o más años que han acudido a la proyección}
funcion calculateCollectionProjection (typeProjection: caracter, dayOfWeek: entero,
numViewersUnder12: entero, numViewersGreater12: entero): real

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

para i := 1 hasta NUM_MOVIE_THEATRE hacer


writeInteger(distributor.moviesTheatre[i].identifier);
writeInteger(distributor.moviesTheatre[i].numViewers);
writeReal(distributor.moviesTheatre [i].collection);
fpara

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

Ejercicio 4: Diseño/modificación de algoritmos [20%]


Objetivos: Diseñar un algoritmo que pueda contener esquemas de búsqueda / recorrido,
y que trate con tablas / tuplas.

Materiales: Módulo 4: Tipos estructurados de datos


M 4.1: Introducción y motivación. Estructuración de datos
M 4.2: Tablas
M 4.3: Tuplas

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.

Para eso, hace falta que respondáis a los siguientes apartados:

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).

ii) [10%] Adaptad el algoritmo del ejercicio 3 (constantes, tipos,


funciones/acciones y algoritmo principal) para que a la salida se escriba,
después de la marca final de secuencia, el identificador de la sala que ha
recaudado más ingresos.

<idMovieTheatre1 numberOfViewers1 collection1 … idMovieTheatrei numberOfViewersi


collectioni … idMovieTheatren numberOfViewersn collectionn -1
idMovieTheatreGreaterCollection >

Donde idMovieTheatreGreaterCollection se corresponde con el identificador de la


sala que ha recaudado más ingresos.

Nota: Es obligatorio utilizar la acción creada en el apartado anterior.


75.554 · FP · Pract2 · 2014-02 · Estudios de Informática Multimedia y Telecomunicación

Ejercicio 5: Codificación en C [30%]


Objetivos: Dada una definición de tipos que presenta una combinación de tablas y tuplas,
se pide la traducción a C de un algoritmo que acceda a estas estructuras.

Materiales: Módulo 4: Tipos estructurados de datos


M 4.1: Introducción y motivación. Estructuración de datos
M 4.2: Tablas
M 4.3: Tuplas

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

• numVendingMachinesi es un entero que indica el número de máquinas


expendedoras que hay instaladas en el i-ésimo centro.
• vendingMachineij es un entero mayor que cero que identifica la máquina j-ésima
del centro i-ésimo.
• typeProductijk es un entero que identifica el tipo de producto k-ésimo vendido en la
máquina j-ésima del centro i-ésimo. La clasificación de tipos de productos utilizada
es:
o Entero 1 para bebidas.
o Entero 2 para caramelos.
o Entero 3 para chicles.
o Entero 4 para patatas.
o Entero 5 para bocadillos.
• unitsProductijk es un entero mayor que cero que indica el número de productos de
tipo k-ésimo vendido en la máquina j-ésima del centro i-ésimo.
• priceProductijk es un entero mayor que cero que indica el precio del producto de
tipo k-ésimo vendido en la máquina j-ésima del centro i-ésimo.
• -1 es el elemento que marca el final de la información de la máquina j-ésima.
• -2 es el elemento que marca el final de la secuencia.

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.

• Todos los centros pueden tener un número indeterminado y diferente de máquinas


expendedoras. Ocasionalmente puede darse el caso de que un centro no tenga
ninguna máquina disponible, cosa que no hace que el centro aparezca en la
secuencia de entrada.

• Cada máquina puede haber expendido un número indeterminado de productos, y


también puede darse el caso de que no haya expendido ningún producto.

• Un mismo producto puede tener precios diferentes dependiendo del centro, o


incluso dependiendo de la hora del día en que es expendido.

• En caso de no haber ningún centro, la secuencia de entrada contendrá únicamente


la marca de final de secuencia.

• La secuencia de entrada es correcta, y no es necesario comprobar la validez de


sus datos.

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

El formato de la secuencia de salida será el siguiente:


<typeProduct importTotalTypeProduct typeCenter importTotalTypeCenter idCenter1
importTotalCenter1 … idCenteri importTotalCenteri … idCentern importTotalCentern -1>

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.

Por ejemplo, si en la entrada tuviésemos


<5 U 3 1 1 10 1.30 2 20 1.60 5 5 3.00 – 1
4 4 8 1.00 -1
12 -1
2 E 1 1 5 2 1.30 5 10 1.60 5 8 3.00 – 1
35 H 0
20 E 2 20 1 1 1.30 2 20 0.60 3 5 1.00 4 5 1.00 5 5 2.50 – 1
120 1 1 1.00 – 1
-2>
Esta secuencia de entrada indica:
 5U3
El centro con identificador 5 que es de tipo Universidad tiene 3 máquinas:
• 1 1 10 1.30 2 20 1.60 5 5 3.00 – 1
La primera máquina tiene identificador 1 y ha vendido:
1 10 1.30  10 unidades de bebidas a 1.30€.
2 20 1.60  20 unidades de caramelos a 1.60€.
5 5 3.00  5 unidades de bocadillos a 3.00€
• 4 4 8 1.00 -1
La segunda máquina tiene identificador 4 y ha vendido:
4 8 1.00  8 unidades de patatas a 1.00€.
75.554 · FP · Pract2 · 2014-02 · Estudios de Informática Multimedia y Telecomunicación

• 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€

Y los siguientes resultados por centro / tipo de centro:


CENTRO TIPO DE CENTRO INGRESOS
5 Universidad 68,00€
75.554 · FP · Pract2 · 2014-02 · Estudios de Informática Multimedia y Telecomunicación

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();

{leemos la secuencia de centros}


mientras (idCenter ≠ ENDSEQ ) hacer
blank := readCharacter();
typeCenter := readCharacter();
numVendingMachinesCenter := 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

para i := 1 hasta MAX_TYPE_PRODUCTS hacer


typesProduct.types[i].units := 0;
typesProduct.types[i].import := 0.0;
fpara

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}

{ Pre: typesProduct = TYPESPRODUCT, contiene la información de los tipos de producto que se ha


leído hasta el momento, y en el canal de entrada estándar hay una secuencia con formato:
vendingMachine11 typeProduct111 unitsProduct111 priceProduct111 typeProduct112
unitsProduct112 priceProduct112... -1 , y importTotalCenter = IMPORTTOTALCENTER contiene el
importe hasta el momento del centro que se está leyendo }
accion readUpdateVendingMachinesCenter(entsal typesProduct: tTypesProduct, entsal
importTotalCenter: real)
var
idVendingMachine: entero;
typeProduct, unitsProduct: entero;
priceProduct: real;
importProduct: real;
fvar

idVendingMachine := readInteger();
75.554 · FP · Pract2 · 2014-02 · Estudios de Informática Multimedia y Telecomunicación

typeProduct := readInteger();

mientras typeProduct ≠ ENDSEQ_MACHINE hacer


unitsProduct := readInteger();
priceProduct := readReal();
importProduct := (unitsProduct * priceProduct);
importTotalCenter := importTotalCenter + importProduct;

updateTypeProduct(typeProduct, unitsProduct, importProduct, typesProduct);

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)

typesProduct.types[type].units := typesProduct.types [type].units + units;


typesProduct.types[type].import := typesProduct.types[type].import + import;

faccion
{ Post: Se ha acumulado al tipo TYPE de TYPESPRODUCT las unidades UNITS y el importe IMPORT }

{ Pre: idCenter = IDCENTER es un entero que indica el identificador de centro, typeCenter =


TYPECENTER es un carácter que indica el tipo de centro de IDCENTER, importCenter =
IMPORTCENTER es el importe con el que hay que actualizar el centro, y centers = CENTERS es la
estructura de centros que contiene la información leída hasta el momento }
accion addCenter(ent idCenter: entero, ent typeCenter:caracter, ent importCenter: real, entsal
centers: tCenters)
var
i, j: entero;
found: booleano;
fvar

{ añadimos en la posición de la tabla ordenado según los ingresos obtenidos }


i := 1;
found := falso;
mientras (i <= centers.numCenters y no found) hacer
found := (centers.centers[i].import < importCenter);
si (no found) entonces
i := i + 1;
75.554 · FP · Pract2 · 2014-02 · Estudios de Informática Multimedia y Telecomunicación

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

{ insertamos el nuevo centro}


centers.centers[i].idCenter := idCenter;
centers.centers[i].typeCenter := typeCenter;
centers.centers[i].import := importCenter;

centers.numCenters := centers.numCenters +1;

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 }

{ Pre: typesProduct = TYPESPRODUCT, contiene la información de los tipos de producto que se ha


leído hasta el momento }
funcion searchTypeProductMaxUnitsSold( typesProduct: tTypesProduct) : entero

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;

para i := 1 hasta centers.numCenters hacer


si centers.centers[i].typeCenter = TYPE_CENTER_UNIVERSITY entonces
importCenterU := importCenterU + centers.centers[i].import;
sino
si centers.centers[i].typeCenter = TYPE_CENTER_HOSPITAL entonces
importCenterH := importCenterH + centers.centers[i].import;
sino
si centers.centers[i].typeCenter = TYPE_CENTER_ENTERPRISE entonces
importCenterE := importCenterE + centers.centers[i].import;
fsi
fsi
fsi
fpara

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

{ Si hemos leído algún centro en la cadena de entrada }


si centers.numCenters > 0 entonces
{ tipo de producto más vendido }
i := searchTypeProductMaxUnitsSold(typesProduct);
writeInteger(i);
writeReal(typesProduct.types[i].import);

{ tipo de centro que ha generado más ingresos }


searchTypeCenterMaxImport(centers, typeCenter, importCenter);
writeCharacter(typeCenter);
writeReal(importCenter);

{ información de cada uno de los centros, ordenados por importe }


para j := 1 hasta centers.numCenters hacer
writeInteger(centers.centers[j].idCenter);
writeReal(centers.centers[j].import);
fpara
fsi
writeInteger(ENDSEQ_OUTPUT);
faccion
{ Post: 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>}

Nota: Los reales se deben escribir con dos decimales, con printf(“%.2f “, valor).

También podría gustarte