Problemas de Programación 1

Anuncio
Problemas de Programación 1
Grado en Ingenierı́a Informática
Miguel Ángel Latre y Javier Martı́nez
Área de Lenguajes y Sistemas Informáticos
Departamento de Informática e Ingenierı́a de Sistemas
Curso 2017-18
Índice general
1. Sintaxis expresada mediante reglas BNF
1.1. Reglas sintácticas para la escritura de literales numéricos
3
. . . . . . . . . . . . .
3
1.2. Reglas sintácticas para la escritura de identificadores . . . . . . . . . . . . . . . .
4
1.3. Reglas sintácticas para la escritura de expresiones aritméticas . . . . . . . . . . .
5
1.4. Reglas sintácticas para la escritura de expresiones de relación y lógicas . . . . . .
6
1.5. Reglas sintácticas para la escritura de instrucciones . . . . . . . . . . . . . . . . .
7
1.6. Reglas sintácticas para la escritura de algunos tipos de datos . . . . . . . . . . .
8
2. Escritura de expresiones aritméticas y lógicas
10
2.1. Escritura de expresiones aritméticas . . . . . . . . . . . . . . . . . . . . . . . . .
10
2.1.1. Escritura de expresiones aritméticas cuyo resultado es un número entero .
10
2.1.2. Escritura de expresiones aritméticas cuyo resultado es un número real . .
11
2.2. Escritura de expresiones lógicas . . . . . . . . . . . . . . . . . . . . . . . . . . . .
12
3. Trabajo con datos enteros
14
3.1. Diseño de funciones para gestionar fechas del calendario . . . . . . . . . . . . . .
4. Trabajo con datos reales
14
17
4.1. Cálculo de magnitudes geométricas de polı́gonos regulares . . . . . . . . . . . . .
17
4.2. Caracterización de la caida libre de un sólido rı́gido . . . . . . . . . . . . . . . . .
18
4.3. Caracterización de un tiro parabólico . . . . . . . . . . . . . . . . . . . . . . . . .
18
4.4. Amortización de un préstamo . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
20
1
Presentación
La temática de los problemas de esta colección está centrada en las primeras lecciones del
curso. Posteriormente, en las diferentes prácticas de la asignatura, se propondrá la resolución
de un buen número de problemas de programación relacionados con las restantes lecciones del
curso.
No es un secreto que a programar se aprende programando. Quien asista a las clases
de Programación 1 y estudie las notas del curso puede llegar a comprender los conceptos en
los que se basa el trabajo de un programador, conocerá la tecnologı́a disponible y también las
metodologı́as que conviene aplicar en cada caso. No obstante, para que conceptos, tecnologı́a
y metodologı́as rindan lo esperado es esencial que cada estudiante adquiera una experiencia
suficiente en programación. Para ello deberá aplicar lo estudiado a la resolución de problemas
tales como los que se proponen en esta colección o en el programa de prácticas de la asignatura.
Saber resolver los problemas de programación de esta colección constituye la mejor garantı́a
de que el aprendizaje progresa adecuadamente. Cada estudiante ha de ser capaz de resolverlos
en primera instancia con lápiz y papel . En aquellos problemas en los que se exija el diseño
de código, que son la mayorı́a de los que se propongan a lo largo del curso, es necesario que el
alumno complete el trabajo programando su solución en un computador. Ambas tareas, el
trabajo con lápiz y papel y la programación en el computador, son complementarias y esenciales
en el estudio de un curso de programación.
En la sección de Materiales Docentes Comunes de la web de la asignatura
Programación 1 se ha dispuesto un enlace para acceder a algunos ficheros con código C++
que facilitan el trabajo de quienes resuelvan estos problemas.
Zaragoza, Septiembre de 2017
Miguel Ángel Latre y Javier Martı́nez
Departamento de Informática e Ingenierı́a de Sistemas
de la Universidad de Zaragoza
2
Capı́tulo 1
Sintaxis expresada mediante reglas
BNF
1.1.
Reglas sintácticas para la escritura de literales numéricos
En este problema se va a pedir la escritura de reglas sintácticas que determinen cómo han de
ser escritos los siguientes sı́mbolos de un lenguajes ficticio de programación:
Un dı́gito. Un dı́gito es cada uno de los diez caracteres que representan una cifra escrita
en base 10, es decir: 0, 1, 2, . . . , 8 y 9.
Un natural. Un natural se escribe como una secuencia de uno o más dı́gitos. Ejemplos de
naturales: 0, 7, 007, 11, 606, 1000, 98707 y 82672651.
Un signo. Un signo viene determinado por uno de los dos caracteres siguientes: + y -.
Un exponente. La escritura de un exponente comienza por una E o una e. Le sigue un
valor numérico natural, con o sin signo. Ejemplos: E0, e7, E-7, E07, e-07, e1075, E-23.
Un número real sin signo. Un número real sin signo se representa, en primer lugar,
escribiendo su parte entera, un número natural. Le sigue, opcionalmente, su parte decimal
(un número natural) precedida por un punto. A continuación, también opcionalmente, un
exponente. Ejemplos de números reales sin signo: 34, 0, 34.045, 0.0012, 1045.4, 34E-4,
0.1165E12. En cambio, las siguientes secuencias de caracteres no definirán números reales
sin signo válidos: 34., .045, 34.E5 y .045E12.
Un literal entero se representa como un número natural que, opcionalmente, puede venir
precedido por un signo + o -. Ejemplos: 1207, +1207 y -1207.
Un literal real se representa como un número real sin signo que, opcionalmente, puede
venir precedido por un signo + o -. Ejemplos: 13.166, +13.166, -13.166, 0.18E-6,
+0.18E-6 y -0.18E-6.
A partir de las definiciones anteriores se deben escribir reglas sintácticas para cada uno
de los sı́mbolos definidos. En la definición de cualquiera de las reglas sintácticas se puede
hacer uso de otras reglas sintácticas definidas previa o posteriormente en este documento. En
cualquier momento se pueden definir reglas sintácticas complementarias a las que se enuncian a
continuación para facilitar la escritura de éstas.
3
<dı́gito> ::=
...
<natural> ::=
...
<signo> ::= ...
<exponente> ::= ...
<real_sin_signo> ::= ...
<literal_entero> ::= ...
<literal_real> ::= ...
1.2.
Reglas sintácticas para la escritura de identificadores
Deben escribirse las reglas sintácticas que determinen cómo han de ser escritos los siguientes
elementos de un lenguaje ficticio de programación:
Una minúscula. Consideraremos minúsculas cada una de las letras minúsculas del alfabeto
inglés, es decir: a, b, c, . . . , x, y y z. No van a ser consideradas como minúsculas ni las
vocales minúsculas con tı́lde ni letras no presentes en el alfabeto inglés como la ~
n, la ç,
etc.
Una mayúscula. Consideraremos mayúsculas cada una de las letras mayúsculas del
alfabeto inglés, es decir: A, B, C, . . . , X, Y y Z. No van a ser consideradas como mayúsculas
ni las vocales mayúsculas con tı́lde ni letras no presentes en el alfabeto inglés como la ~
N,
la Ç, etc.
Una letra. Consideraremos letras cualquier carácter que sea o bien una minúscula o bien
una mayúscula.
Un identificador. La escritura de un identificador, en el lengujae que estamos definiendo,
ha de comenzar obligatoriamente por una letra pudiendo, en su caso, ir seguida por una
secuencia de letras o dı́gitos, en cualquier orden. Ejemplos de identificadores válidos:
cuenta, Cuenta, x, x027, x33nuevo, DIM, primerIndice.
A partir de las definiciones anteriores se deben escribir reglas sintácticas para cada uno de los
sı́mbolos definidos. En la definición de cualquiera de las reglas sintácticas se puede hacer uso de
otras reglas sintácticas definidas previa o posteriormente en este documento. También se pueden
definir reglas sintácticas complementarias a las que se enuncian a continuación para facilitar la
escritura de éstas.
<minúscula> ::=
<mayúscula> ::=
...
...
<letra> ::= ...
<identificador> ::=
...
4
1.3.
Reglas sintácticas
aritméticas
para
la
escritura
de
expresiones
Las reglas sintácticas que se definen a continuación contribuyen a definir la sintaxis de
cualquier expresión aritmética en el lenguaje que se está definiendo.
<literal_numérico_sin_signo> ::= <natural> | <real_sin_signo>
<término> ::= <factor>
{ <operador_de_factores>
<operador_de_factores> ::=
<factor> }
"*" | "/"
<factor> ::= [ <signo> ] ( <identificador> | <literal_numérico_sin_signo>
| ( "(" <expresión_numérica> ")" )
<operador_de_términos> ::=
"+" | "-"
<expresión_numérica> ::= <término>
{ <operador_de_términos> <término> }
Se pide, en primer lugar, rellenar esta tabla escribiendo un SI o un NO en cada una
de sus casillas. Cada fila está asociada a la secuencia de caracteres escrita en su primera
columna. las restantes columnas representan una categorı́a sintáctica: (factor, término o
expresión numérica). Se debe escribir un cada casilla un SI en el caso de que la secuencia
de caracteres defina un elemento sintácticamente válido en la categorı́a que corresponde a la
columna y un NO en el caso contrario.
Secuencia de caracteres
x
y
x + y
z
1
x
x + y - z + 1
factor
término
expresión numérica
Se pide, en segundo lugar, rellenar esta tabla escribiendo un SI o un NO en cada una de
sus casillas. Cada fila está asociada a la secuencia de caracteres escrita en su primera columna.
Cada columna representa una categorı́a sintáctica (factor, término o expresión numérica.
Escribir en cada casilla un SI en el caso de que la secuencia de caracteres defina un elemento
sintácticamente válido en la categorı́a que corresponde a la columna y un NO en el caso contrario.
Secuencia de caracteres
a
b
a + b
(a + b)
a - b
(a - b)
2.0
(a+b)*(a-b)/2.0
factor
5
término
expresión numérica
1.4.
Reglas sintácticas para la escritura de expresiones de
relación y lógicas
Las reglas sintácticas que se definen a continuación contribuyen a definir la sintáxis
de cualquier expresión de relación y de cualquier expresión lógica en el lenguaje que se
está definiendo.
<literal_cierto> ::= "cierto" | "CIERTO"
<literal_falso> ::= "falso" | "FALSO"
<literal_booleano> ::= <literal_cierto> | <literal_falso>
<operador_relación> ::= "==" | "!=" | ">" | ">=" | "<" | "<="
<expresión_relación> ::=
<expresión_numérica>
<expresión_numérica>
<operador_relación>
<operador_lógico_negación> ::= "NOT"
<operador_conjuntivo> ::=
"AND"
<operador_disyuntivo> ::=
"OR"
<operando_lógico> := [ <operador_lógico_negación> ]
( <identificador> | <literal_booleano> | <expresión_relación>
| ( "(" <expresión_lógica> ")" ) )
<operando_lógico_conjuntivo> := <operando_lógico>
{ <operador_conjuntivo> <operando_lógico>
<expresión_lógica> ::=
{
<operando_lógico_conjuntivo>
<operador_disyuntivo> <operando_lógico_conjuntivo>
}
}
Se pide, en primer lugar, rellenar la tabla que sigue escribiendo un SI o un NO en cada una
de sus casillas. Debe escribirse un SI en una casilla en el caso de que la secuencia de caracteres
defina un elemento sintácticamente válido en la categorı́a que corresponde a la fila y un NO en
caso contrario.
Categorı́a sintáctica
expresión relación
operando lógico
operando lógico conjuntivo
expresión lógica
a>=0
a<MAX
a>=0 AND a<MAX
a>=0 AND a<MAX OR a==x
Se pide, en segundo lugar, rellenar la tabla que sigue escribiendo un SI o un NO en cada una
de sus casillas. Escribir un cada casilla un SI en el caso de que la secuencia de caracteres defina
un elemento sintácticamente válido en la categorı́a que corresponde a la fila y un NO en el caso
contrario.
6
a
Categorı́a sintáctica
expresión relación
operando lógico
operando lógico conjuntivo
expresión lógica
1.5.
NOT a
x<y
NOT a AND x<y
Reglas sintácticas para la escritura de instrucciones
<instrucción> ::=
<instrucción_simple> | <instrucción_compuesta>
<instrucción_simple> ::= [ <asignación> | <invocación> | <devolución> ]
<expresión> ::= <expresión_numérica>
|
<asignación> ::= <identificador>
":="
<invocación> ::= <identificador>
"(" [
<devolución> ::= "devuelve"
<instrucción_compuesta> ::=
";"
<expresión_lógica>
<expresión>
<argumento>
{ ","
<argumento>
} ]
")"
<expresión>
<bloque_secuencial> | <instrucción_condicional>
| <instrucción_iterativa>
<bloque_secuencial> := "principio" { <instrucción> } "fin"
<instrucción_condicional> := "si" <expresión_lógica> "entonces" <instrucción>
{ "sino si" <expresión_lógica> "entonces" <instrucción> }
[ "sino" <instrucción> ]
"finSi"
<instrucción_iterativa> := "mientrasQue" <expresión_lógica> "hacer"
<instrucción> "finMQ"
Se pide escribir tres secuencias de sı́mbolos diferentes que respondan a la sintaxis de cada
una de las categorı́as sintácticas que se enumeran a continuación. Debe procurarse escribir tres
secuencias con las máximas diferencias sintácticas entre sı́.
instrucción: escribir tres instrucciones
instrucción simple: escribir tres instrucciones simples
asignación: escribir tres instrucciones de asignación
invocación: escribir tres instrucciones de invocación
devolución: escribir tres instrucciones de devolución
bloque secuencial: escribir tres bloques secuenciales de instrucciones
instrucción condicional: escribir tres instrucciones condicionales
instrucción iterativa: escribir tres instrucciones iterativas
7
1.6.
Reglas sintácticas para la escritura de algunos tipos de
datos
En este problema se va a pedir la escritura de reglas sintácticas que determinen cómo han de
ser presentados determinados datos.
Un número dni. El número de un DNI (documento nacional de identidad) puede ser, en
principio, cualquier número natural.
Un letra dni. La letra de un DNI ha de ser una letra mayúscula del alfabeto inglés.
Un dni. Un dato de tipo dni se define como una secuencia de un número dni seguido de
una letra dni.
Un dı́a, un mes y un año se van a representar, cada uno de ellos, mediante un número
natural.
Una fecha se representa por una secuencia de tres datos, el primero representa el dı́a, el
segundo el mes y el tercero el año de la fecha.
Una hora, un minuto y un segundo se van a representar, cada uno de ellos, mediante
un número natural.
Un tiempo es un dato que corresponde a uno de los 84.400 segundos de un dı́a. Se va a
representar mediante una secuencia de tres datos, el primero define la hora, el segundo
el minuto y el tercero el segundo que determinan un tiempo comprendido entre las
00:00:00 horas y las 23:59:59 horas del dı́a.
Un dato del tipo sexo hombre ha de venir representado por un literal booleano, por el
literal cierto (si se trata de un hombre) o por el literal falso (si se trata de una mujer).
Un dato del tipo estado civil soltero ha de venir representado por un literal booleano,
por el literal cierto (si se trata de una persona soltera) o por el literal falso (si se trata
de una persona casada).
Un nombrePropio es una secuencia de caracteres que comienza por una mayúscula
pudiendo, en su caso, estar seguida por una secuencia de minúsculas.
Un nombre persona se representa mediante un único nombre propio.
Un apellido persona se representa mediante un único nombre propio.
Un ciudadano se representa mediante una secuencia integrada por los siguientes datos.
Un dato dni, seguido por un dato fecha, que representa su fecha de nacimiento, al que
siguen, en este oreden, un dato sexo hombre, un dato estado civil soltero y un dato
nombre persona. Concluye la secuencia por uno o dos datos apellido persona.
A partir de las definiciones anteriores se deben escribir reglas sintácticas para cada uno de
los tipos de datos definidos previamente. En la definición de cualquiera de las reglas sintácticas
se puede hacer uso de otras reglas sintácticas definidas previamente en este documento. En
cualquier momento se pueden definir reglas sintácticas complementarias a las que se enuncian a
continuación para facilitar la escritura de éstas.
8
<número_dni> ::= ...
<letra_dni> ::= ...
<dni> ::= ...
<dia> ::=
<mes> ::=
<a~
no> ::=
...
...
...
<fecha> ::=
...
<hora> ::= ...
<minuto> ::= ...
<segundo> ::= ...
<tiempo> ::=
...
<sexo_hombre> ::= ...
<estado_civil_soltero> ::= ...
<nombrePropio> ::= ...
<nombre_persona> ::= ...
<apellido_persona> ::= ...
<ciudadano> ::=
...
9
Capı́tulo 2
Escritura de expresiones aritméticas
y lógicas
En este capı́tulo se propone una colección de ejercicios para el ejercicio en la escritura
de expresiones aritméticas, tanto aquellas cuyos resultados son números enteros como si son
números reales, y de expresiones lógicas.
2.1.
Escritura de expresiones aritméticas
2.1.1.
Escritura de expresiones aritméticas cuyo resultado es un número
entero
Para escribir las siguientes expresiones se dispone únicamente del siguiente conjunto de
operadores aritméticos: + (suma de enteros), - (resta de enteros), * (producto de enteros), /
(cociente de la división entera), % (resto de la división entera).
Escribir una expresión que determine el número de enteros comprendidos entre los enteros
x e y, siendo x ≤ y.
Escribir una expresión que determine la cifra menos significativa del número natural n, es
decir, la cifra de las unidades cuando n se escribe en base 10.
Escribir una expresión que determine la cifra de las decenas de n, cuando n se escribe en
base 10.
Escribir una expresión que determine la cifra de las centenas de n, cuando n se escribe en
base 10.
Escribir una expresión que determine el número de baldosas cuadradas de lado 25 cm.
necesarias para cubrir una superficie rectangular de dimensiones a y b, donde los valores
de a y b son medidas enteras expresadas en metros.
Escribir una expresión que determine cuántos cubos de arista 5 cm pueden almacenarse
en una caja con forma de ortoedro (paralelepı́pedo ortogonal) cuyas dimensiones son x, y,
z, todas ellas enteros múltiplos de 10 cm.
Escribir una expresión que determine cuántas bolas esféricas de radio 1 cm pueden
almacenarse en una caja con forma de ortoedro (paralelepı́pedo ortogonal) cuyas
dimensiones son a, b, c, todas ellas enteros múltiplos de 10 cm.
10
Escribir una expresión que determine el número de semanas completas hay en d dı́as.
Se dispone de n bolsas de caramelos, cada una de las cuales contiene m caramelos. Se han
de repartir equitativamente todos los caramelos entre los p niños asistentes a una fiesta.
Escribir una primera expresión que determine el número de caramelos que recibirá cada
niño y escribir una segundo expresión que determine el número de caramelos que no habrán
podido ser repartidos para no generar agravios.
Una fecha la podemos representar mediante un entero de ocho dı́gitos de la forma
aaaammdd, donde aaaa denota el año, mm el mes y dd el dı́a. Ejemplos: 20160101 (primer
dı́a del año 2016), 20161231 (últmo dı́a del año 2016) y 14921012 (fecha de la llegada de
Cristóbal Colón a América). Dada una fecha descrita del modo anterior por el valor entero
f, escribir tres expresiones que determinen el año, el mes y el dı́a que corresponden a la
fecha f.
Una instante del dı́a lo podemos representar mediante un entero de seis dı́gitos de la forma
hhmmss, donde hh denota la hora, mm el minuto y ss el segundo. Ejemplos: 0 (medianoche),
310 (las 3 y 10 de la madrugada), 605 (las 6 y 5 de la madrugada), 120000 (mediodı́a),
183000 (las seis y media de la tarde)y 235959 (un segundo antes de la medianoche). Dado
un instante del dı́a descrito del modo anterior por el valor entero momento, escribir tres
expresiones que determinen la hora, el minuto y el segundo que corresponden al instante
del dı́a momento.
Una instante del dı́a también lo podemos representar mediante los segundos transcurridos
desde el comienzo del dı́a. Ejemplos: 0 (medianoche), 3600 (la una de la madrugada, es
decir, las 00:00:00), 3663 (la 01:01:03), 43200 (mediodı́a, es decir, las 12:00:00), 86399 (un
segundo antes de la medianoche). Dado un instante del dı́a descrito del modo anterior
por un valor entero segs, escribir tres expresiones que determinen la hora, el minuto y el
segundo que corresponden al instante del dı́a segs.
Escribir una expresión que determine el valor de la suma de los enteros comprendidos en
el intervalo [x,y], siendo x ≤ y.
2.1.2.
Escritura de expresiones aritméticas cuyo resultado es un número real
Para escribir las expresiones cuyo resultado es un número real se dispone de los siguientes
operadores:
De los operadores aritméticos enumerados en el apartado anterior para trabajar con datos
numéricos enteros.
De los siguientes operadores aritméticos: + (suma de reales), - (resta de reales), * (producto
de reales), / (división de reales).
√
La funcion sqrt(x) que proporciona como resultado x y las funciones sin(x), cos(x)
y tan(x) que devuelven los valores de las funciones trigonométricas sen x, cos x y tg x,
con el ángulo x expresado en radianes.
Se pide escribir las expresiones que se proponen a continuación.
Escribir una expresión que determine el área de un rectángulo cuyos lados miden x e y y
una segunda expresión que determine la longitud de su diagonal.
11
Escribir una expresión que determine la distancia entre dos puntos cuyas coordenadas
cartesianas son (a,b) y (c,d), respectivamente.
Dada un circunferencia de radio r, se pide escribir una expresión para calcular su longitud
y otra expresión que calcule el área del cı́culo que determina.
Dado un polı́gono regular con n lados de longitud lado, se pide escribir una expresión para
calcular su área y otra expresión para calcular el valor, en grados sexagesimales, de los
ángulos determinados por dos lados consecutivos.
Dado un exaedro regular o cubo de arista a, escribir una primera expresión que calcule
el área total de sus caras, una segunda expresión que calcule su volumen y una tercera
expresión que calcule la longitud de su diagonal.
2.2.
Escritura de expresiones lógicas
Una expresión lógica es aquella cuya evaluación proporciona como resultado es un valor
booleano, es decir, cierto o falso.
Para escribir las expresiones lógicas vamos a disponer de los siguientes operadores:
Todos los operadores y funciones descritos en los apartados anteriores para la escritura de
expresiones aritmética cuyo resultado es un número entero o un número real.
Seis operadores de relación: ==, !=, <, <=, > y >=.
Tres operadores lógicos: AND (conjunción lógica), OR (negación lógica y NOT (negación
lógica).
Se pide escribir las expresiones lógicas que se proponen a continuación.
Escribir una expresión lógica cuyo valor sea cierto si y sólo si el valor de x es mayor o
igual que el valor de y.
Escribir una expresión lógica cuyo valor sea cierto si y sólo si los valores de a y de b son
diferentes.
Escribir una expresión lógica cuyo valor sea cierto si y sólo si el valor de x
está comprendido entre los valores de a y de b, es decir, pertenece al intervalo [a,b].
Escribir una expresión lógica cuyo valor sea cierto si y sólo si el valor de x no
está comprendido entre los valores de a y de b, es decir, está fuera del intervalo [a,b].
Escribir una expresión lógica cuyo valor sea cierto si y sólo si los valores de a, de b y de
c son todos ellos diferentes.
Escribir una expresión lógica cuyo valor sea cierto si y sólo si el valor de a el menor de
los tres valores a, b y c.
Escribir una expresión lógica cuyo valor sea cierto si y sólo si el valor de x es igual que
el menor de los tres valores a, b y c.
Escribir una expresión lógica cuyo valor sea cierto si y sólo si los valor de a, b, c y d,
dichos en este orden, están ordenados de menor a mayor valor.
12
Escribir una expresión lógica cuyo valor sea cierto si y sólo si el valor el entero n no tiene
ningún divisor de una cifra, si se exceptúa la unidad.
Escribir una expresión lógica cuyo valor sea cierto si y sólo si el valor el entero n tiene
algún divisor de una cifra que sea diferente de la unidad.
Escribir una expresión lógica cuyo valor sea cierto si y sólo si el punto de coordenadas
cartesianas (a,b) está situado en la circunferencia o dentro de un cı́culo con centro en el
origen y radio r.
Escribir una expresión lógica cuyo valor sea cierto si y sólo si el punto de coordenadas
cartesianas (a,b) está situado fuera de un cı́culo con centro en el origen y radio r.
Escribir una expresión lógica cuyo valor sea cierto si y sólo si el punto de coordenadas
cartesianas (a,b) está situado en el perı́metro o dentro de un cuadrado con centro en el
origen y lado h.
Escribir una expresión lógica cuyo valor sea cierto si y sólo si el punto de coordenadas
cartesianas (a,b) está situado fuera de un cuadrado con centro en el origen y lado h.
13
Capı́tulo 3
Trabajo con datos enteros
3.1.
Diseño de funciones para gestionar fechas del calendario
Se pide desarrollar un módulo de biblioteca denominado calendario que ofrezca al resto de
módulos las funciones que se especifican a continuación. El desarrollo de este módulo requiere
escribir sus ficheros de interfaz y de implementación.
/∗
∗ Fichero calendario.h de interfaz del módulo calendario
∗/
/∗
∗ Pre: anyo >= 1600
∗ Post: Devuelve [true] si y solo si [anyo] es un año bisieto
∗/
bool esBisiesto (int anyo);
/∗
∗ Pre: anyo >= 1600
∗ Post: Devuelve el número de dı́as del año [anyo]
∗/
int diasDelAnyo (int anyo);
/∗
∗ Pre: mes >= 1 y mes <= 12 y anyo >= 1600
∗ Post: Devuelve el número de dı́as del mes [mes] del año [anyo]
∗/
int diasDelMes (int mes, int anyo);
/∗
∗ Pre: fecha escrito en base 10 tiene la forma aaaammdd donde los dı́gitos
∗
aaaa representan el año, los dı́gitos mm el mes y los digitos dd el
∗
dı́a de una fecha
∗ Post: Devuelve el valor del dı́a correspondiente a la fecha del calendario
∗
representada por el entero [fecha]
∗/
int dia (int fecha );
/∗
∗ Pre: fecha escrito en base 10 tiene la forma aaaammdd donde los dı́gitos
∗
aaaa representan el año, los dı́gitos mm el mes y los digitos dd el
14
∗
dı́a de una fecha
∗ Post: Devuelve el valor del mes correspondiente a la fecha del calendario
∗
representada por el entero [fecha]
∗/
int mes (int fecha );
/∗
∗ Pre: fecha escrito en base 10 tiene la forma aaaammdd donde los dı́gitos
∗
aaaa representan el año, los dı́gitos mm el mes y los digitos dd el
∗
dı́a de una fecha
∗ Post: Devuelve el valor del año correspondiente a la fecha del calendario
∗
representada por el entero [fecha]
∗/
int anyo (int fecha );
/∗
∗ Pre: El trı́o de datos (dia,mes,anyo) definen una fecha válida del calendario,
∗
la fecha dia/mes/anyo
∗ Post: Devuelve un entero que, al ser escrito en base 10, tiene la forma aaaammdd
∗
que representa la fecha dia/mes/anyo donde los dı́gitos aaaa representan el ,
∗
año los dı́gitos mm el mes y los digitos dd el dı́a
∗/
int fecha (int dia, int mes, int anyo);
/∗
∗ Pre: f escrito en base 10 tiene la forma aaaammdd donde los dı́gitos aaaa
∗
representan el año, los dı́gitos mm el mes y los digitos dd el dı́a de una
∗
fecha. La fecha [ f ] es igual o posterior al 1/1/1600
∗ Post: Devuelve el número de dı́a en el año de la fecha [ f ]
∗/
int diaDelAnyo (int f);
/∗
∗ Pre: f escrito en base 10 tiene la forma aaaammdd donde los dı́gitos aaaa
∗
representan el año, los dı́gitos mm el mes y los digitos dd el dı́a de una
∗
fecha. La fecha [ f ] es igual o posterior al 1/1/1600
∗ Post: Devuelve el número de dı́a de la semana de la fecha [f ], con la convención de
∗
que el lunes es el primer dı́a de la semana y el domingo el séptimo y último.
∗
Devolverá, por lo tanto, un valor entre el 1 (lunes) y el 7 (domingo).
∗/
int diaDeLaSemana (int f);
/∗
∗ Pre: d >= 1 y d <= 7
∗ Post: Escribe por pantalla , en castellano , el nombre del dı́a de la semana número [d].
∗
Si d=1 escribe ”lunes”, si d=2 escribe ”martes”, etc.
∗/
void escribeDia (int d);
/∗
∗ Pre: m>=1 y m<=12
∗ Post: Escribe por pantalla , en castellano , el nombre del mes número [m].
∗
Si m=1 escribe ”enero”, si m=2 escribe ”febrero”, etc.
∗/
void escribeMes (int m);
/∗
∗ Pre: mes >= 1, mes <= 12 y año >= 1600
∗ Post: Presenta por pantalla el calendario del mes [mes] del año [año] con
15
∗
un formato similar el mostrado en el siguiente ejemplo:
∗
∗
septiembre 2015
∗
1
2
3
4
5
6
∗
7
8
9 10 11 12 13
∗
14 15 16 17 18 19 20
∗
21 22 23 24 25 26 27
∗
28 29 30
∗/
void calendario (int mes, int anyo);
16
Capı́tulo 4
Trabajo con datos reales
En cada uno de los problemas que se plantean a continuación se pide el desarrollo de un
módulo de biblioteca. Por cada módulo, habrá que programar sus ficheros de interfaz y de
implementación.
En cada uno de los problemas conviene desarrollar también uno o más programas de prueba
para verificar el correcto comportamiento de las funciones definidas en el módulo de biblioteca
pedido.
Cada alumno tiene libertad para definir sus programas de prueba.
4.1.
Cálculo de magnitudes geométricas de polı́gonos regulares
Se pide desarrollar un módulo de biblioteca denominado poligonos que ofrezca al resto de
módulos las funciones que se especifican a continuación.
/∗
∗ Fichero de interfaz poligonos .h
∗/
/∗
∗ Pre: n>=3 y lado>=0.0
∗ Post: devuelve la longitud del área encerrada por un polı́gono regular de [n] lados
∗
de longitud [lado]
∗/
double area (int n, double lado);
/∗
∗ Pre: n>=3 y lado>=0.0
∗ Post: devuelve la longitud del perı́metro de un polı́gono regular de [n] lados
∗
de longitud [lado]
∗/
double perimetro (int n, double lado);
/∗∗
∗ Pre: n>=3 y lado>=0.0
∗ Post: devuelve la longitud del apotema de un polı́gono regular de [n] lados
∗
de longitud [lado]
∗/
double apotema (int n, double lado);
17
/∗
∗ Pre: n>=3 y lado>=0.0
∗ Post: devuelve la longitud del radio de la circunferencia circunscrita de un polı́gono
∗
regular de [n] lados de longitud [lado]
∗/
double radio (int n, double lado):
/∗
∗ Pre: n>=3 y lado>=0.0
∗ Post: devuelve el valor , en grados sexagesimales, de los ángulos interiores de un polı́gono
∗
regular de [n] lados de longitud [lado]
∗/
double anguloInterior (int n, double lado);
4.2.
Caracterización de la caida libre de un sólido rı́gido
Se pide desarrollar el módulo de biblioteca caida que ofrecerá al resto de módulos dos
funciones que permiten calcular la duración del movimiento en caida libre de un cuerpo y la
velocidad máxima alcanzada al llegar al suelo. Asumimos que la caida libre se produce al soltar
el cuerpo desde una altura h y que el rozamiento del aire es despreciable. El cuerpo sufre una
aceleración por acción de la gravedad, g, igual a 9,81 sm2 , hasta llegar al suelo con una velocidad
máxima v después de un tiempo t. Las siguientes relaciones son fácilmente deducibles (en caso
de duda se puede consultar algún libro de fı́sica elemental o acudir a páginas especializadas de
internet):
v =g×t
h = 12 g × t2
/∗
∗ Fichero de interfaz caida.h
∗/
/∗
∗ Pre: [h] es la altura , en metros, desde la que inicia la caida libre y sin rozamiento
∗
un objeto
∗ Post: Devuelve el tiempo, en segundos, que tarda el objeto en llegar al suelo
∗/
double tiempo (double h);
/∗
∗ Pre: [h] es la altura , en metros, desde la que inicia la caida libre y sin rozamiento
∗
un objeto
∗ Post: Devuelve la velocidad , en metros/segundo, a la que impacta el objeto en el suelo
∗/
double velocidad (double h);
4.3.
Caracterización de un tiro parabólico
La trayectoria que describe una pelota de tenis al ser lanzada sin efecto es una parábola. Las
trayectorias descritas por un proyectil disparado por un arma de fuego o por una flecha lanzada
18
desde un arco también son parábolas. Cualquiera de nosotros puede lanzar una piedra con un
determinado ángulo de inclinación y ella decribirá una parábola. El lanzamiento de cualquiera
de estos objetos se denomina tiro parabólico o tiro oblicuo.
Imaginemos que estamos situados sobre una superficie horizontal y que lanzamos un objeto
con una velocidad v, expresada en m/s, en una direción que forma un ángulo α con relación a la
superficie horizontal sobre la que estamos ubicados. El objeto lanzado irá elevándose y alejándose
de nosotros hasta alcanzar una altura máxima. A partir de ese momento continuará alejándose
de nosotros e irá perdiendo altura hasta caer sobre la superficie horizontal.
Si denominamos y al valor de la altura alcanzada en cada instante t por el objeto lanzado
y denominamos x al valor de su distancia en cada instante, medida en horizontal, respecto del
punto de lanzamiento, podemos escribir las relaciones que describen la trayectoria parabólica
del objeto en función del tiempo t:
x = v × cos α × t
y = v × sen α × t − 12 g × t2
En este problema se pide diseñar un módulo de biblioteca, denominado tiro, que
ofertará cuatro funciones que permiten calcular cuatro datos referidos a la trayectoria descrita
por un objeto lanzado mediante tiro parabólico:
Función alturaMaxima(v, angulo) que devuelve la máxima altura alcanzada por el
objeto.
Función tiempoMaximo(v, angulo) que devuelve el tiempo que tarda el objeto en alcanzar
esa altura máxima, medido desde el instante en que fue lanzado.
Función distanciaCaida(v, angulo) que devuelve el alejamiento horizontal del objeto
respecto del punto de lanzamiento, que corresponde a la distancia entre el punto de
lanzamiento y el punto de caida.
Función tiempoCaida(v, angulo) que devuelve el tiempo que ha tardado el objeto en
caer, medido desde el instante en que fue lanzado.
/∗
∗ Fichero de interfaz tiro .h
∗/
/∗
∗ Pre: [v] es la velocidad , expresada en m/s, a la que es lanzado un objeto y [angulo] es
∗
el ángulo, expresado en grados sexagesimales, que forma la dirección de lanzamiento
∗
del objeto con la superficie horizontal . Debe satisfacerse que angulo>=0o y que
∗
angulo<=90o
∗ Post: Devuelve la altura máxima, en metros, que llega a alcanzar el objeto en su trayectoria
∗
parabólica sin rozamiento, medida respecto de la superficie horizontal
∗/
double alturaMaxima (double v, double angulo);
/∗
∗ Pre: [v] es la velocidad , expresada en m/s, a la que es lanzado un objeto y [angulo] es
∗
el ángulo, expresado en grados sexagesimales, que forma la dirección de lanzamiento
∗
del objeto con la superficie horizontal . Debe satisfacerse que angulo>=0o y que
∗
angulo<=90o
19
∗ Post: Devuelve el tiempo, en segundos, que tarda el objeto en alcanzar la máxima altura
∗
de su trayectoria parabólica sin rozamiento respecto de la superficie horizontal .
∗/
double tiempoMaximo (double v, double angulo);
/∗
∗ Pre: [v] es la velocidad , expresada en m/s, a la que es lanzado un objeto y [angulo] es
∗
el ángulo, expresado en grados sexagesimales, que forma la dirección de lanzamiento
∗
del objeto con la superficie horizontal . Debe satisfacerse que angulo>=0o y que
∗
angulo<=90o
∗ Post: Devuelve la distancia , en metros, que hay entre el punto de lanzamiento y el punto
∗
de caida sobre la misma la superficie horizontal , tras describir una trayectoria
∗
parabólica sin rozamiento
∗/
double distanciaCaida (double v, double angulo);
/∗
∗ Pre: [v] es la velocidad , expresada en m/s, a la que es lanzado un objeto y [angulo] es
∗
el ángulo, expresado en grados sexagesimales, que forma la dirección de lanzamiento
∗
del objeto con la superficie horizontal . Debe satisfacerse que angulo>=0o y que
∗
angulo<=90o
∗ Post: Devuelve el tiempo, en segundos, que tarda el objeto en caer de nuevo sobre la
∗
superficie horizontal , tras describir una trayectoria parabólica sin rozamiento
∗/
double tiempoCaida (double v, double angulo); }
En caso necesario, se recomienda consultar algún libro de fı́sica elemental o acudir a páginas
especializadas de internet para recordar las ecuaciones del tiro parabólico y las fórmulas que de
ellas se deducen.
4.4.
Amortización de un préstamo
En este problema se debe diseñar un módulo de biblioteca, denominado prestamo, que
ofrezca a otros módulos las funciones tae, nominal y tablaAmortizacion tal como se especifican
a continuación.
/∗
∗ Fichero de interfaz prestamo.h
∗/
/∗
∗ Pre: [r] es una tasa anual nominal de interés de un préstamo
∗ Post: devuelve la tasa anual equivalente (TAE) del mismo préstamo
∗/
double tae (double r);
/∗
∗ Pre: [tae] es la tasa anual equivalente (TAE) de un préstamo
∗ Post: devuelve la tasa anual nominal del mismo préstamo
∗/
double nominal (double tae);
/∗
∗ Pre: capital >=0.0, numMeses>0, r>0.0
∗ Post: Presenta por pantalla la tabla de amortización de un préstamo de [capital]
20
∗
euros a amortizar en [numMeses] meses con una tasa anual de interés nominal
∗
del [r] por ciento
∗/
void tablaAmortizacion (double capital, int numMeses, double r);
El modo en que la función tablaAmortizacion debe presentar los datos de una tabla de
amortización se ilustran a continuación mediante el siguiente ejemplo de aplicación. Una
invocación tablaAmortizacion(100000.0, 18, 4.8) presenta por pantalla la tabla de amortización
de un préstamo de 100000 euros a un interés nominal del 4.8% con un periodo de amortización
de 18 meses durante los cuales se paga una cuota constante. A continuación se muestran los
resultados que dicha invocación presenta por pantalla. Comienzan con los datos del capital
prestado, el periodo de amortización, la tasa de interés nominal y su TAE equivalente y la cuota
mensual constante a pagar. A continuación presenta la tabla de amotozación propiamento dicha
con cinco columnas: número de mes, cantidad pagada ese mes, parte de la cantidad anterior
dedicada a amortizar capital, parte de la cantidad anterior dedicada al pago de intereses y
capital pendiente de amortizar. La última lı́nea de la tabla presenta los totales de las cantidades
pagadas, amortizadas y abonadas como interés.
Capital prestado: 100000,00 euros
Periodo de amortización: 18 meses
Interés anual nominal: 4,80 (TAE: 4,91)
Cuota constante: 5769,05 euros/mes
MES
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
PAGADO
0,00
5769,05
5769,05
5769,05
5769,05
5769,05
5769,05
5769,05
5769,05
5769,05
5769,05
5769,05
5769,05
5769,05
5769,05
5769,05
5769,05
5769,05
5769,05
TOTAL
103842,98
AMORTIZADO
0,00
5369,05
5390,53
5412,09
5433,74
5455,48
5477,30
5499,21
5521,20
5543,29
5565,46
5587,72
5610,07
5632,51
5655,04
5677,67
5700,38
5723,18
5746,07
100000,00
INTERESES
0,00
400,00
378,52
356,96
335,31
313,58
291,76
269,85
247,85
225,77
203,59
181,33
158,98
136,54
114,01
91,39
68,68
45,88
22,98
PENDIENTE
100000,00
94630,95
89240,42
83828,32
78394,58
72939,11
67461,81
61962,60
56441,40
50898,11
45332,65
39744,92
34134,85
28502,33
22847,29
17169,62
11469,25
5746,07
0,00
3842,98
0,00
En caso necesario, se recomienda consultar algún libro introductorio de Economı́a o acudir
a páginas especializadas de internet para documentarse sobre cómo calcular el TAE de un
préstamo, los intereses mensuales a satisfacer o la cuota mensual constante a pagar.
21
Descargar