Cap02-03 - 03 04 2018
Cap02-03 - 03 04 2018
Cap02-03 - 03 04 2018
Funciones y Condicionales
2.1. General
Una vez que en el capítulo 1 hemos usado MATLAB como una calculadora potente
pero al fin y al cabo una calculadora, ha llegado el momento de aprender a programar.
En ese sentido, el capitulo 2, dedicado al concepto de función y la estructura de control
condicional, y el capitulo3, dedicado al estudio de los bucles, son los más importantes.
Constituyen la base sobre la que se cimenta el resto del curso.
En el presente capitulo se tratan principalmente las ideas de funciones, variables,
argumentos de las funciones, asignación y la primera estructura de control del libro: el
condicional. También se realiza primeramente una contextualización de este curso
desde la perspectiva de la historia de la programación y sus fundamentos.
Ejercicio 2.2 Edita manualmente la función ud2 f1 creando un archivo nuevo con el
editor abriéndolo desde la ventana de comandos (con File, New), guárdala en tu carpeta
de trabajo y ejecuta:
>>ud2 f1(2.3)
>>ud2 f1(0.1)
>>ud2 f1(0)
>>ud2 f1(-2.2)
¿Son correctos los resultados? ¿Qué errores o problemas da?
Ejercicio 2.3 Crea una función que reciba el radio de un círculo y devuelva su área.
MATLAB conoce el valor de pi, pide ayuda sobre pi para usarlo.
Ejercicio 2.4 Prueba la función que has creado con un circulo de radio la unidad.
Debería devolver3.1416, aproximación del número pi. Pruébala con 2; deberá devolver
12.5664 (aproximación de 4pi).
Ejercicio 2.6 Crea una función que reciba la base b y la altura h de un triángulo y
devuelva su área A.
Ejercicio 2.7 Crea una función que reciba la masa m y la velocidad v de un móvil y
devuelva la energía cinética Ec.
1
𝐸𝑐 = 𝑚𝑣 2
2
Ejercicio 2.8 Crea una función que reciba dos alturas, h1 y h2 y una masa m y devuelva
la energía potencial Ep perdida/ganada por dicha masa al caer/subir de h1 a h2. Se
utilizarán unidades del sistema internacional.
𝐸𝑝 = 𝑚𝑔(ℎ1 − ℎ2), 𝑔 = 9.81
Ejercicio 2.9 Consideramos la función ud2_fprueba(1,2,3) siguiente. Sin ejecutarla,
calcula qué valor devolverá si invocamos desde MATLAB ud2_fprueba(1,2,3)?.
Razónalo primero y compruébalo después editando la función y ejecutando esa orden.
¿Conmutan entre si los argumentos de entrada?
function d=ud2_fprueba(a,b,c)
b=c;
a=b;
d=a+b+c;
Ejercicio 2.10 Crea una función que reciba los tres coeficientes a, b, c, de un polinomio
de segundo grado 𝑎𝑥 2 + 𝑏𝑥 + 𝑐y devuelva la raíz
−𝑏 + √𝑏 2 − 4𝑎𝑐
𝑥1 = .
2𝑎
Cuando se invoque la función, se elegirán los coeficientes para que la ecuación tenga
raíces reales. Se recomienda usar una variable auxiliar D para definir el discriminante
𝑏 2 − 4𝑎𝑐. ¿Conmutan entre si los argumentos de entrada?. Para comprobar si tu código
es correcto, usa los coeficientes del polinomio2𝑥 2 + 5𝑥 − 3, que tiene como raíces-3 y
0:5. ¿Por qué solo aparece una de las dos raíces al invocarla función?
Hasta ahora, todas las sentencias se han ejecutado de modo secuencial, una detrás de la
otra. No disponemos todavía de herramientas que permitan controlar de algún modo la
ejecución o realizar operaciones más complejas con la información de entrada a la
función. La primera de esas herramientas y una de las más importantes es la estructura
de control condicional y nos pone en la parrilla de salida del desarrollo de estrategias y
algoritmos para resolver los problemas de los que un ordenador es capaz. Además, y no
menos importante, se convierte en el primer mecanismo de provocación de vuestra
capacidad de pensar y de articular un discurso complejo a partir de elementos mínimos,
o sea, PROGRAMAR.
La estructura condicional aparece en los lenguajes de programación normalmente
mediante la palabra reservada if. En MATLAB lo hace de ese modo, tal como se indica
en las siguientes líneas.
Function y=nombrefuncion(arg1,arg2,....)
....
If cond1 es cierta
bloque1
end
....
If cond2 es cierta
bloque2
end
....
Por cond1 nos referimos a una condición lógica o combinación de ellas. Así, cond1
puede ser que una variable sea mayor que un determinado valor, igual, mayor o igual
(>=) etc. Encaso de que la condición, en tiempo de ejecución, sea cierta, se ejecutarán
las sentencias que hemos identificado como bloque1 y que están entre la sentencia del if
y la sentencia end que cierre dicho bloque.
Dentro de una misma función puede haber varias estructuras condicionales, en principio
independientes entre si, como mostramos también en el mismo esquema.
Es importante para que los códigos sean legibles tabular o indentar las instrucciones
correspondientes a una estructura de control 3 o 4 espacios (serán 4 en nuestros
ejemplos), como hemos hecho con bloque1 y bloque2 en el esquema anterior.
Uno de los ejemplos más sencillos que se pueden poner de esta estructura es el de una
función que devuelva el mayor de dos números a, b supuestos distintos entre si. Se
puede abordar este problema de varias maneras. La más básica es mediante dos
estructuras if, una de las cuales identifica el mayor de los valores caso de que a y la
segunda identifica el mayor caso de quesea b. En este caso los dos bloques no son en
realidad independientes, y veremos más adelante que esta no es la forma más natural de
resolver este problema, aunque se considera adecuado ahora como ejemplo sencillo para
introducir la estructura de control.
% ud2_fmayorab0
% primer uso del condicional if
% Devuelve el mayor de dos números a,b
% a,b se supondrán diferentes
function mayor=ud2_fmayorab0(a,b)
if a>b
mayor=a;
end
%
if b>a
mayor=b;
end
En el ejemplo anterior, los dos valores a comparar han de ser por hipótesis distintos. Es
fácil comprobar que si los dos valores son iguales, en cuyo caso, habrá que devolver
cualquiera de ellos, la función ud2_fmayorab no va a ser capaz de tomar ninguno de
ellos como mayor. Para evitar este pequeño inconveniente, se incluye una variante de
esa función que utiliza una comprobación (>=) en uno de los casos con lo que si los dos
valores son iguales tomará uno de ellos como mayor, que es lo más recomendable.
% ud2_fmayorab1
% primer uso del operador >=
% Devuelve el mayor de dos números a,b
function mayor=ud2_fmayorab1(a,b)
if a>=b
mayor=a;
end
%
if b>a
mayor=b;
end
En la tercera posibilidad se define la variable mayor por defecto como a. Ahora se
comprueba si b es mayor que a, y si eso es cierto se define la variable mayor como b.
Esta posibilidad es mejor porque ahorra el cálculo de un condicional.
% ud2_fmayorab2
% Devuelve el mayor de dos números a,b
function mayor=ud2_fmayorab2(a,b)
mayor=a;
if b>a
mayor=b;
end
En la cuarta variante se juega con la variable a calcular, dándole primero el valor a.
Después se compara b con esa variable, y si en la comparación gana b, se actualiza el
valor de mayor. Esta es la mejor de las posibilidades porque permitirá de modo sencillo
la generalización del algoritmo para encontrar el mayor de una cantidad de números tan
grande como queramos.
% ud2_fmayorab3
% Devuelve el mayor de dos números a,b
function mayor=ud2_fmayorab3(a,b)
mayor=a;
if b>mayor
mayor=b;
end
Los ejercicios correspondientes a este ejemplo son los siguientes:
Ejercicio 2.14 Abre el editor de MATLAB y transcribe las funciones ejemplo estudiadas
en esta sección: ud2_fmayorab0, ud2_fmayorab1, ud2_fmayorab2 y ud2_fmayorab3.
Guárdalas en tu carpeta de trabajo y pruébalas.
Ejercicio 2.15 Crea una función que reciba un número r y devuelva el área del circulo
de radio r si 𝑟 ≥ 0 𝑦 − 1en caso contrario. Por tanto, se definirá en suma una
variable área como
𝜋. 𝑟 2 , 𝑟≥0
𝑎𝑟𝑒𝑎 = {
−1, 𝑟<0
Ejercicio 2.16 Crea una función que reciba un valor x y devuelva el valor y de la
función definida a trozos:
𝑥 + 1, 𝑥 < −1
𝑦={ 2
1 − 𝑥 , 𝑥 ≥ −1
Ejercicio 2.17 (Para valientes) Crea una función que reciba tres números a, b, c, que se
supondrán diferentes entre si, y devuelva el mayor de los tres. Este es un ejercicio muy
interesante, extensión de la última variante de este ejemplo, ud2_fmayorab3.
Ejercicio 2.18 Codifica una función que reciba tres valores supuestos diferentes a, b, c y
devuelva el mayor de ellos elevado al menor. Por ejemplo, si los números son a = 3, b =
4 y c = -1, la funcióndevolverá4-1= 0.25
Ejercicio 2.19 Crea una función que reciba cinco números naturales distintos entre sí y
devuelva la media geométrica del mayor y del menor. La media geométrica de a y b se
define como √𝑎 ∙ 𝑏.
Por ejemplo, si los números son 2,3,7,4 y 5 entonces la función devuelve√2 ∙ 7 =
√14 = 3.7417.
Ejercicio 2.22 Crea una función que reciba un número r y devuelva el área del circulo
de radio r si𝑟 ≥ 0 𝑦 − 1en caso contrario, utilizando la estructura if-else.
Ejercicio 2.23 Crea una función que reciba un valor x y devuelva, utilizando la
estructura if-else,
el valor y de la función definida a trozos:
𝑥 + 1, 𝑥 < −1
𝑦={
1 − 𝑥2, 𝑥 ≥ −1
Ejercicio 2.24 Codifica una función que reciba un número x y devuelva su valor
absoluto (sin usarla función abs ni sqrt, sino mediante condicionales).
Una vez que con una función hemos resuelto un determinado problema y/o hemos
agrupado una serie de tareas, es muy útil ver esa función como una caja negra que
recibe unos argumentos de entrada y devuelve unos argumentos de salida (de momento
uno sólo de salida) sin que tengamos que preocuparnos de cómo calcula/obtiene esos
resultados. Vista de ese modo, es natural que sea a su vez llamada por otra función que
eventualmente la necesita como parte de sus propios cálculos. La sintaxis de ello no
ofrece ningún problema invocándose de modo análogo a como se invoca desde la línea
de comandos. En el siguiente ejemplo codificamos una función definida a trozos,
similar a la del ejemplo 2.5, en la que el valor de uno de los trozos de la función se
obtiene llamando a una función creada previamente, la ud2_f1.
% ud2_ftrozos
% primera función q llama a otra función
% Devuelve el valor de la función:
% f(x)=x si x<1
% f(x)=x^2-ln(x) si x>=1
function y=ud2_ftrozos(x)
if x<1
y=x;
else
y=ud2_f1(x);
end
El concepto de llamar a una función desde otra es muy poderoso y es la base tanto para
resolver grandes problemas como para ser capaz de repartir la escritura de grandes
códigos entre un equipo de programadores. Haremos uso abundante de esta técnica en el
libro y si el estudiante es hábil conseguirá simplificar la resolución de muchos ejercicios
si hace buen uso de funciones ejemplo estudiadas en clase y de funciones codificadas al
resolver otros ejercicios. Los ejercicios correspondientes a este ejemplo son los
siguientes:
Ejercicio 2.28 Usando las funciones de los ejercicios 2.10 y 2.11, crea una función que
reciba los tres coeficientes A, B, C de un polinomio de segundo grado de raíces reales
(se elegirán los coeficientes para que así sean) 𝐴𝑥 2 + 𝐵𝑥 + 𝐶y devuelva el producto de
las mismas. Prueba con varios polinomios (el producto de las dos raíces ha de ser C/A).
Ejercicio 2.29 (Para los valientes) Codifica una función que reciba los tres coeficientes
a0, a1, a2 de un polinomio de grado 2, 𝑎0 + 𝑎1𝑥 + 𝑎2𝑥 2 . Internamente calculará el
discriminante 𝐷 = 𝑎12 − 4𝑎0 ∗ 𝑎2dela ecuación 𝑎0 + 𝑎1𝑥 + 𝑎2𝑥 2 = 0 para calcular
sus raíces. En función del valor de dicho discriminante, cuando el polinomio tenga
raíces positivas distintas, devolverá el producto de sus raíces calculado invocando la
función del ejercicio 2.28. Cuando las raíces tengan parte imaginaria o cuando sea una
raíz doble, la función devolverá 0 en lugar del producto de las raíces.
Ejercicio 2.30 Codifica una función que reciba tres valores x, y y z (que se supondrán
diferentes)y devuelva el mayor de ellos. Se podrá utilizar solo un bloque if-else y una
llamada a la funciónud2_fmayorab0
Ejercicio 2.32 Crea una función que reciba tres valores x, y, prec y devuelva 1 si la
diferencia en valor absoluto entre x e y es estrictamente menor que prec y 0 en caso
contrario. Por ejemplo, si x = 0.87, y = 0.83 y prec = 0.05, la función devolverá 1. Si x
= 0.87, y = 0.83 y prec = 0.01, la función devolverá 0. Para calcular el valor absoluto se
utilizará la función del ejercicio 2.24.
Ejercicio 2.33 (Para valientes) Idem con seis valores. Trata de hacerlo con un único if-
else y utilizando dos veces la función del apartado 2.30.
Ejercicio 2.34 (Para valientes) Idem con siete valores. Trata de hacerlo con el menor
número posible de if-else (ninguno).
% ud2_fsignocomp
% Variante de ud2_fsigno utilizando >=
function signo=ud2_fsignocomp(n)
if n>=0
if n>0
signo=1;
else
signo=0;
end
else
signo=-1;
end
Ejercicio 2.37 Crea una función que reciba un valor x y devuelva el valor y de la
función definida a trozos:
sin(𝑥) , 𝑥<0
𝑦={ 𝑥, 0 ≤ 𝑥<1
2
𝑥 + log(𝑥 ) , 𝑥 ≥ 1
Para comprobar el resultado, se tiene que si x = -pi/2, entonces y = -1. Si x = 0:5, y =
0:5, y si
x = 2, entonces y = 4:6931.
Ejercicio 2.39 Se trata de codificar una función que reciba una calificación y devuelva
un variable clave que ha de valer 0 si la calificación es estrictamente menor que 5, 1 si
la calificación es mayor o igual que 5 y menor que 7, 2 si la calificación es mayor o
igual que 7 y menor que 9, 3 si la calificación es mayor o igual que 9 y menor o igual
que 10 y -1 si el argumento de entrada no está entre 0 y 10.
Ejercicio 2.40 Codifica una función que devuelva el salario semanal de un trabajador en
función del coste hora, c, de las horas que ha trabajado, h, y de un fijo de productividad,
p, que se cobra si se trabajan más de 30 horas. Si se trabajan más de 40 horas, las horas
por encima de esas 40 se pagan un 50% más caras (horas extras). Por ejemplo, si c = 10,
p = 100 y h = 30, el salario es 300. Con iguales coste hora y productividad pero h = 35,
el salario es 450, y si h = 45, el salario es 575.
Una variante bastante útil del condicional es la que permite abrir el abanico de
posibilidades de ejecución a no sólo el verdadero o falso referido a una determinada
condición. La idea es que si una condición es cierta se ejecuten unas sentencias, pero si
esta es falsa, se compruebe una segunda condición y si esta es cierta, se ejecuten el
correspondiente segundo grupo de sentencias, pero si la segunda condición es falsa, se
pase a una tercera y asi sucesivamente. Finalmente, la orden terminará con una
sentencia else cuyo bloque de instrucciones posterior se ejecutará si ninguna de las
condiciones ha resultado cierta. Pretendemos reejar esto con el siguiente esquema:
function y=nombrefuncion(arg1,arg2,....)
....
....
if cond1 es cierta
bloque 1
elseif cond2 es cierta
bloque 2
elseif cond3 es cierta
bloque 3
elseif......
.....
elseif cond n-1 es cierta
bloque n-1
else
bloque n
end
....
....
Si la condición 1, cond1, es cierta, se ejecutará el bloque 1 de sentencias, y a posteriori
se pasará directamente a las sentencias posteriores a la sentencia end. Si la condición 1
fuese falsa, se evaluara la condición 2 y si está fuese cierta, se ejecutará el bloque 2,
pasando directamente a las sentencias posteriores a la sentencia end. Si ninguna de las
condiciones fuese cierta, se pasará directamente a la ejecución del bloque n.
Vemos esta estructura con el siguiente ejemplo. Se trata de construir una función que
reciba una calificación (entre 0 y 10) y devuelva 0 si es suspenso (calificación
estrictamente menor que 5), 1 si es aprobado (calificación mayor o igual que 5 y menor
que 7), 2 si es notable (calificación mayor o igual que 7 y menor que 9) y 3 si es
sobresaliente (calificación mayor o igual que 9). Si por error se introduce una
calificación que no está entre 0 y 10, la función devolverá -1. Para codificar este
ejemplo, lo primero que comprobamos es si la nota es menor que 0. Si no lo es, sólo
comprobamos si es menor que 5, por que ya sabemos que va a ser mayor o igual que 0.
Los demás casos son análogos.
% ud2_fnotas
% primera vez q usamos el elseif
function clave=ud2_fnotas(nota)
if nota<0
clave=-1;
elseif nota<5
clave=0;
elseif nota<7
clave=1;
elseif nota<9
clave=2;
elseif nota <=10
clave=3;
else
clave=-1;
end
Los ejercicios correspondientes a este ejemplo son los siguientes:
Ejercicio 2.44 Crea una función que reciba un valor x y devuelva el valor y de la
función definida
a trozos:
sin(𝑥) , 𝑥<0
𝑦 = { 𝑥, 0≤𝑥<1
𝑥 2 + log(𝑥 ) , 𝑥 ≥ 1
Se utilizará la variante elseif del condicional para realizar este ejercicio.
Ejercicio 2.45 Codifica una función que devuelva el salario semanal de un trabajador en
función del coste hora, de las horas que ha trabajado y de un fijo de productividad que
se cobra si se trabajan más de 30 horas. Si se trabajan más de 40 horas, las horas por
encima de esas 40 se pagan un 50% más caras (horas extras). Se utilizará la variante
elseif del condicional para realizar este ejercicio.
Ejercicio 2.46 Codifica una función que reciba el salario anual bruto de un trabajador y
calcule el impuesto de la renta de las personas físicas correspondiente a ese salario. Se
supondrá que los primeros 9000e están exentos. Hasta 17360e al año se aplicará una
retención del 24 %. Desde 17360 hasta 32360, la retención será del 28 %. Desde 32360,
hasta los 52360e anuales, pagaremos a Hacienda 37 %. Con ingresos anuales superiores
a 52360e, el porcentaje se sitúa en el 43 %. Para probar la función, si el salario son
7000e, el impuesto será 0. Si el salario es 11000e, el impuesto son 480e. Si son 22000e,
el impuesto es de 3305.6e. Si son 40000, el impuesto son 9033.2. Si son 100000, el
impuesto será de 34092e.
El ejemplo que acabamos de presentar es una excusa muy buena para introducir el uso
de una herramienta muy poderosa de la que disponen los entornos de programación para
corregir errores. Es habitual que una función o un programa no realice correctamente los
cálculos para los que ha sido diseñado. Para detectar los fallos se puede seguir el ujo del
mismo en tiempo de ejecución mediante el uso del depurador (debugger). Vamos a
introducir esta idea con este ejemplo.
Para ello, nos ponemos en el editor, en la line 4 de ud2_fnotas.m, y pinchamos en el
icono señalado en la figura 2.2 para activar un punto de parada o breakpoint. Una vez
hecho esto nos volvemos a la línea de comandos y ejecutamos a la función pasando 9.5
como argumento:
pag 69
Ejercicio 2.50 Codifica una función que reciba tres valores a, b y c (que se supondrán
diferentes) y devuelva una variable flag que ha de valer 1 si a es el mayor, 2 si b es el
mayor, y 3 si lo es c. Por ejemplo, si a = 2:3, b = 5:1 y c = -3:4, la función devolverá 2.
Ejercicio 2.51 Codifica una función que reciba tres valores a, b y c devuelva el mayor si
alguno de ellos es estrictamente positivo y el menor en caso contrario. Por ejemplo, si a
= 2.3, b = 5.1 y c = -3.4, la función devolverá 5.1. Sin embargo, si si a = -2:3, b = -2:1
y c = 0, la función devolverá -2.3 (solución en apéndice).
3Se puede usar también solamente &, pero hay ciertos matices que diferencian ambos
operadores. Cuando se usa &&, caso de que la primera condición sea falsa, MATLAB
ni siquiera evalúa la segunda dado que ya la sentencia lógica global va a ser falsa
independientemente del valor que tome la segunda condición
4Se puede usar también solamente |; sin embargo || es más eficiente dado que si la
primera condición es cierta, MATLAB ni siquiera evalúa la segunda dado que ya la
sentencia lógica global va a ser cierta independientemente del valor que tome la
segunda condición
Ejercicio 2.52 Crea una función que reciba la longitud de los tres lados a, b, c de un
triángulo y devuelva su área A obtenida mediante la fórmula de Herón. Caso de que los
tres lados no correspondan a un triángulo la función devolverá -1. La fórmula de Herón
es:
𝑎+𝑏+𝑐
𝐴 = √𝑝(𝑝 − 𝑎)(𝑝 − 𝑏)(𝑝 − 𝑐); 𝑝 =
2
Por ejemplo si los lados son 3/2, 5/3 y 17/6 la función devolverá que el área es 1, y si
los lados son 1, 2, 4 devolverá -1.
Ejercicio 2.53 Busca 3 valores a, b y c para los que la siguiente función no devuelva el
mayor de los 3.
function y=ud2_prueba2(a,b,c)
y=a+b+c;
if a>b || c>b
y=y-b;
if a>c
y=y-c;
else
y=y-a;
end
else
y=b;
end
Ejercicio 2.54 (Para valientes) ¿Qué errores hay en la siguiente función, la cual se
supone que deberá devolver la potencia de los dos segmentos definidos por las tres
abscisas a; b; c? La potencia es el producto de las longitudes de los dos segmentos que
determinan. No se sabe cuál es la relación de orden entre los valores pero si fuesen
crecientes, la potencia seria (b-a)(c-b). Trata de hacerlo primero en papel para encontrar
algunos errores y luego prueba con el ordenador. Prueba con (1,2,3), (3,2,1), (2,1,3), etc
y con (1,1,2), (1,2,1), (2,1,1) y (1,1,1) (en estos cuatro últimos casos deberá dar 0).
function pot=ud2_fpotencia(a,b,c)
if a>b && a>c
if b>c
pot=(a-b)*(b-c)
else
pot=(a-c)*(c-b)
end
end if b>a && b>c
if a>c
pot=(b-a)*(a-c)
else
pot=(b-c)*(c-a)
end
else
if a>b
pot=(c-a)*(a-b)
else
pot=(c-b)*(b-a)
end
end
Ejercicio 2.55 (Para valientes) Codifica una función que reciba cuatro valores x, y, z, t
supuestos todos diferentes entre si, y devuelva el menor de los estrictamente positivos.
Si no hay ningún positivo, la función devolverá 0. Por ejemplo, si x = -2, y = 3, z = 7, t
= -1, la función devolverá 3.
La operación de comparar si dos variables son iguales tiene una sintaxis especifica en
MATLAB5, colocando el símbolo = de modo duplicado, ==. En el siguiente ejemplo se
muestra su uso para construir una función que indica si dos valores son iguales o no.
% ud2_figuales
% operador de comprobación de igualdad
function flag=ud2_figuales(m,n)
if m==n
flag=1;
else
flag=0;
end
La negación lógica se escribe en MATLAB anteponiendo al operador correspondiente
el símbolo ~, el cual se obtiene pulsando las teclas AltGr y 4 (también Alt + 126 con el
teclado numérico desactivado). Por tanto, el operador para comprobar si dos valores son
distintos será ~=. Se puede reescribir la función anterior utilizando esta posibilidad
como:
5La comparación para comprobar si dos valores son iguales tiene más matices cuando
alguna de las variables no es un número entero. En realidad el concepto matemático de
igualdad entre números no enteros exige tener en cuenta un umbral para su diferencia,
lo cual es más delicado de programar y no será tenido en cuenta en este texto, en el
cual daremos por buena la comparación entre cualquier tipo de variable mediante el
operador aqui explicado.
% ud2_figualesb
% operador de comprobacion "distinto de"
function flag=ud2_figualesb(m,n)
if m˜=n
flag=0;
else
flag=1;
end
Ejercicio 2.58 Codifica una función que reciba tres números a, b y c y devuelva una
variable flag que ha de valer 1 si son iguales entre si, y 0 en caso contrario.
Ejercicio 2.59 Codifica una función que reciba tres números x, y, z y devuelva una
variable flag que ha de valer 1 si x y, 2 si x = y y y z y 3 si los tres valores son
iguales
Ejercicio 2.60 Codifica una función que reciba tres números a, b y c y devuelva una
variable flag que ha de valer 2 si los tres son iguales entre si, 1 si dos de ellos son
iguales entre si pero el otro es diferente, y 0 si los tres son distintos.
Ejercicio 2.62 Codifica una función que reciba tres valores x, y, z supuestos todos
diferentes entre si, y devuelva el del medio. Por ejemplo, si x = -2, y = 3, z = 1, la
función devolverá 1.
Ejercicio 2.63 Codifica una función que reciba cuatro valores x, y, z, t supuestos todos
diferentes entre si, y devuelva el segundo mayor. Por ejemplo, si x = -2, y = 3, z = 7, t =
1, la función devolverá 3.
Ejercicio 2.64 Codifica una función que reciba cinco valores x, y, z, t, s supuestos todos
diferentes entre si, y devuelva el del medio. Por ejemplo, si x = -2, y = 3, z = 7, t = 1, s
= 9, la función devolverá 3.
Ejercicio 2.67 Modifica la función ud2_fareafig para que también calcule el área del
rombo.
Ejercicio 2.69 Codifica una función que reciba un parámetro signo, y los coeficientes a,
b y c de un polinomio de segundo grado. Devolverá la raíz con el '+' en la fórmula si
signo es 1 y la raíz con el '-' si signo es 1. Para calcular estas raíces llamaremos a las
funciones 2.10 y 2.11. Para comprobar si tu código es correcto, usa los coeficientes del
polinomio 2.34𝑥 2 + 4.29𝑥 − 3.71, que tiene como raíces -2:4741 y 0:6408.
Ejercicio 2.70 Codifica una función que reciba los coeficientes de un polinomio de
grado 2 y devuelva la suma de sus raíces, para lo cual usará del modo que corresponda
la función del ejercicio 2.69. Para comprobar si tu código es correcto, usa los
coeficientes del polinomio 2.34𝑥 2 + 4.29𝑥 − 3.71, que tiene como raíces -2:4741 y
0:6408, cuya suma es -1.8333 que será lo que devuelva la función.
Ejercicio 2.71 (Para valientes) Sabiendo que una pulgada son 2.54 cm, que un pie son
12 pulgadas, y que una yarda son 3 pies, se pide construir una función que reciba una
cantidad, un número que indicará en qué sistema de medida está (0 para el sistema
internacional (SI) y 0 para el sistema inglés) y otro número que indicará en qué
unidades está (1,2 o 1; 2 según sea mm, cm o metros en SI y 1, 2 o 1; 2 según sea
pulgadas, pies o yardas en el sistema inglés). La función devolverá la magnitud
convertida a metros si se ha recibido en el sistema inglés y convertido a pies si se ha
recibido en el SI.
Ejercicio 2.72 Codifica una función que calcule la factura mensual de un teléfono móvil
en euros, de acuerdo con los siguientes datos:
Los argumentos de entrada serán:
_ Número de llamadas (N)
_ Minutos (min)
_ Número de mensajes (nsms)
_ Tarifa: 1, 2, 3 (idtf)
El establecimiento de llamada es de 15 céntimos.
El coste del mensaje es de 15 céntimos por mensaje.
El coste de llamada para la tarifa 1 es 8 céntimos por minuto.
El coste de llamada para la tarifa 2 es 6 céntimos por minuto.
El coste de llamada para la tarifa 3 es 3 céntimos por minuto.
la tarifa 1 tiene un consumo mínimo de 9e.
la tarifa 2 tiene un consumo mínimo de 15e.
la tarifa 3 tiene un consumo mínimo de 25e.
Por ejemplo: si las entradas son 25, 180, 16, 2, la función devolverá 16.95e. Si las
entradas son 10,
5, 3, 2 no se llega al consumo mínimo y la función devolverá por tanto 15e.
Ya vimos que el operador = en MATLAB no tiene mucho que ver con lo que ese
operador significa en Algebra. Su significado es de asignación. A la izquierda
tendremos siempre una variable y a la derecha un expresión que puede combinar
llamadas a funciones con operadores aritméticos y lógicos. El funcionamiento de la
operación es que primero se evalúa la expresión a la derecha y el valor obtenido es
asignado a la variable que está a la izquierda.
Esto abre la puerta para operaciones que no tienen sentido matemático pero si en
programación, como decir que i = i + 1. Lo que esto significa es que se evalúa la
expresión i + 1 y se asigna su valor a i, con lo cual esta variable habrá incrementado su
valor original en una unidad. Una variable como esta se llama un contador. A veces, hay
otras variables en las que se acumula un determinado valor que no tiene por qué ser el
mismo siempre. Nos referiremos a estas últimas como variables sumadoras. En el
siguiente ejemplo aplicamos estos dos conceptos para encontrar la suma de los
estrictamente positivos entre cuatro números.
%% ud2_fsumapos
%% primera variable sumadora (x=x+algo)
%% suma de los positivos entre 4 números.
function suma=ud2_fsumapos(a,b,c,d)
suma = 0;
if a>0
suma=suma+a;
end
if b>0
suma=suma+b;
end
if c>0
suma=suma+c;
end
if d>0
suma=suma+d;
end
Ejercicio 2.76 Codifica una función que reciba 5 números x, y, z, t, y s y dos números a
y b (con a b por hipótesis) y devuelva la suma de aquellos números de entre esos 5
que son mayores o iguales que el mayor de a y b, o menores o iguales que el menor de a
y b. Por ejemplo, si x = 7, y = 11, z = 3, t = -1, y s = 5, y a = 4 y b = 6, la suma en
cuestión es 7 + 11 + 3 + (-1) = 20.
Ejercicio 2.77 Codifica una función que reciba 5 números x, y, z, t, y s y dos números a
y b (con a b por hipótesis) y devuelva el producto de aquellos números de entre esos 5
que son mayores o iguales que el mayor de a y b, o menores o iguales que el menor de a
y b. Por ejemplo, si x = 7, y = 11, z = 3, t = -1, y s = 5, y a = 4 y b = 6, el producto en
cuestión es 7 11 3 (-1) = -231.
Hay una función propia de MATLAB que se usa en muchos códigos y que conviene
citar; es la función que extrae la parte entera, redondeando hacia -, de un número. Asi,
la parte entera de 3.45 es 3, y la de -4.32 es -5. En el siguiente ejemplo se usa este
operador, floor, para comprobar si un número es o no entero. El resultado es una
variable entera de nombre flag que funciona como una variable lógica al recibir
solamente valor 1 o 0 dependiendo de que x sea o no un número entero.
% ud2_fesentero
% comprueba si un numero x es entero (funcion floor)
function flag=ud2_fesentero(x)
if x==floor(x)
flag=1;
else
flag=0;
end
Los ejercicios correspondientes a este ejemplo son los siguientes:
Ejercicio 2.83 Codifica una función que reciba 4 números a, b, c, d y devuelva la suma
de los que entre ellos son enteros. Por ejemplo, si los números son 6:3, 4, 5:4, 7, la
función devolverá -4-7=-11 (solución en apéndice).
Ejercicio 2.84 Codifica una función que reciba un número natural n y devuelva una
variable flag que valga 0 si n es par y 1 si n es impar.
Ejercicio 2.85 (Para valientes) Codifica una función que reciba 4 números a, b, c, d y un
número entero n y devuelva la suma de los que entre ellos son enteros o aquellos tales
que no siendo enteros, su parte entera es múltiplo de n. Por ejemplo, si los números son
6:3, -4, 5.4, -7.2 y n = 2, la función devolverá 6.3-4-7.2=-4.9 (solución en apéndice).
3.2. Bucles
3.2.1. General
En muchos problemas abordados desde una metodología científica se requiere repetir o
iterar un mismo procedimiento. Por ejemplo, un ingeniero tendrá que ver cómo
responde un sistema físico para diversos valores de una de las variables de las que
depende. Esta es una tarea repetitiva y susceptible de ser automatizada mediante un
bucle. Es por ello que todos los lenguajes de programación contienen la posibilidad de
crear bucles que permitirán realizar una misma tarea repetidas veces. Los bucles se
utilizan para ejecutar un bloque de instrucciones, conocidas como cuerpo del bucle, de
forma reiterada sin tener que repetir varias veces el mismo código, lo cual podrá ser
imposible de codificar cuando el número de veces a repetir la tarea se conoce en el
tiempo de ejecución.
Durante este capítulo y gran parte del libro implementaremos los bucles mediante la
utilización adecuada de la sentencia while y de su sentencia de cierre correspondiente
end. Hay otra sintaxis posible para los bucles, utilizando la sentencia for, que veremos
en el capítulo 6. El cuerpo de un bucle (sentencias entre while y end) se ejecutará
mientras la condición que acompaña a la sentencia while sea cierta, de acuerdo con el
siguiente esquema.
function y=nombrefuncion(arg1,arg2,....)
....
....
while cond sea cierta
cuerpo del bucle
end
....
....
En los primeros bucles que utilizaremos se define una variable entera que controla
mediante incrementos o decrementos la evolución del bucle. A esa variable entera se la
conoce como índice del bucle e irá cambiando su valor a medida que se pasa una y otra
vez sobre el cuerpo del bucle.
La gran ventaja de los bucles escritos mediante el uso de la sentencia while frente a
otras formas de escribir un bucle (sentencia for) radica en que el índice del bucle es una
variable más del programa y su valor es controlado en todo momento por el
programador. Sin embargo, un eventual error de programación podrá llevar a que el
índice nunca llegase a cumplir la condición que pare la ejecución del bucle. Cuando en
programación nos encontramos con un bucle en la que la condición de corte o ruptura
no se llega a dar, nos referimos a él como bucle infinito. Este error conlleva que no
vuelva a aparecer el símbolo típico >>que nos indica que la anterior ejecución ha
finalizado. En estos casos MATLAB da al usuario la oportunidad de reaccionar y cortar
el proceso pulsando “CTRL+C”. Es posible que tras entrar en un bucle infinito
MATLAB pierda su estabilidad e interrumpa su funcionamiento normal, algo que
coloquialmente denominamos “cuelgue del programa”.
Ejercicio 3.1 Crea una carpeta llamada ud3 en donde consideres oportuno. Esta será tu
carpeta de
trabajo para todos los ejercicios y ejemplos del capítulo 3.
Ejercicio 3.2 Prueba la función ud3_fsuma.
Ejercicio 3.3 Codifica una función que reciba dos números naturales, m y n, con m < n
por hipótesis, y devuelva la suma de los naturales entre m y n, incluyendo en dicha
suma a m y n. Por ejemplo, si m = 3 y n = 5 el resultado será 3 + 4 + 5 = 12.
Ejercicio 3.5 Codi_ca una función que reciba un número natural, n y devuelva la media
de la función seno evaluada en los naturales entre 0 y n, ambos inclusive.
(sin(0) + sin(1) + sin(2) + ….. + sin(n -1) + sin(n))/(n+1)
Para vuestra comprobación, si n = 2, el resultado es 0.5836.
Ejercicio 3.6 (Para valientes) Codifica una función que reciba dos números, reales a, b,
con a < b, un número natural n, calcule h = (b - a)/n y devuelva
(sin(a) + sin(a + h) + sin(a + 2h) + : : : + sin(a + (n -1)h) + sin(b))/(n+1)
es decir, el valor medio aproximado del seno entre a y b, tomando n + 1 puntos para
aproximarlo. También se puede ver como la posición vertical del centro de gravedad de
la curva y = sin(x) entre a y b si la consideramos representada por esos n + 1 puntos.
Para vuestra comprobación, si a = 0, b = 2 y n = 2, el resultado deberá ser 0.5836.
Ejercicio 3.7 (Para valientes) Codifica una función que reciba dos números reales a, b,
con a < b, un número natural n, y calcule la posición vertical del centro de gravedad de
la curva y = sin(x), considerada como una poligonal que se apoya en n + 1 puntos de esa
curva cuyas abscisas están equiespaciadas entre a y b (ambos inclusive). Hay que tener
en cuenta que los diferentes tramos de la poligonal pueden tener por supuesto distinta
longitud. Por ejemplo, si a = 0, b = 1:5708 y n = 3, los puntos considerados son 0,
0.5236, 1.0472 y 1.5708, cuyas ordenadas son 0, 0.5, 0.866 y 1. La coordenada y del
centro de gravedad de estos puntos considerados de igual masa es 0.5893 (solución en
apéndice).
Ejercicio 3.8 (Para valientes) Codifica una función que reciba dos números reales a, b,
con a < b, un número natural n, y calcule el centro de gravedad del super_cie de_nida
por los rectángulos que tienen como base h = (b - a)/n y como altura sin(xi), con xi = a +
i * h, 0 <= i < n. Por ejemplo, si a = 0, b = 1.5708 y n = 3, los puntos considerados son
0, 0.5236 y 1.0472, cuyas ordenadas son 0, 0.5 y 0.866. La coordenada y del centro de
gravedad de los rectángulos que tienen como altura esos puntos es 0.3660 (solución en
apéndice). La solución analitica a este problema (0.3927) pasa por evaluar la integral
siguiente, algo que podéis intentar utilizando las herramientas simbólicas de MATLAB,
introducidas en la sección 1.10
𝜋/2
∫0 0.5 sin2 (𝑥) 𝑑𝑥
𝑦𝑐𝑔 = 𝜋/2
∫0 𝑠𝑖𝑛(𝑥) 𝑑𝑥
Ejercicio 3.11 Codifica una función que reciba un número natural, n, y devuelva la
suma de los impares entre 1 y n inclusive. Por ejemplo, si n = 7, la suma de impares
hasta n es 1+3+5+7=16
Ejercicio 3.12 Codifica una función que reciba un número natural, n, y devuelva la
suma de los múltiplos de 3 entre 1 y n inclusive. Por ejemplo, si n = 7, la suma buscada
es 9.
Ejercicio 3.13 (Para valientes) Codifica una función que reciba un número natural n y 3
números reales a, b, c. Se trata de calcular la media de los impares menores o iguales
que n. Se calculará cuál de los tres valores - a, b o c - tiene una diferencia en valor
absoluto con la media más pequeña. Se devolverá ese valor. Por ejemplo, si n = 7, la
suma de los impares es 1 + 3 + 5 + 7 = 16, y la media es 16/4 = 4. Si a = 7.1, b = 5.5, c
= 2.3, tenemos que |7.1 – 4| = 3:1, |5.5 -4| = 1.5 y |2.3 -4| = 1.7. Por tanto, el valor de
los tres que está más cerca de la media es b = 5.5 y la función devolverá este valor.
Ejercicio 3.14 (Para valientes) Codifica una función que reciba un número natural n y
devuelva una variable flag que valga 0 si n es par y 1 si n es impar. No se podrá usar la
orden floor, ni llamar a ninguna función.
Ejercicio 3.16 Prueba la función ud3_ffactorial. Compara los valores que obtienes con
ella con los que obtienes usando la función propia de MATLAB factorial.
Ejercicio 3.17 ¿Qué devuelve la siguiente función? Sin ejecutarla, trata de calcular qué
devolverá ud3_fprueba(2,15,3). Compruébalo con MATLAB.
function y=ud3_fprueba(m,n,k)
y=1;
i=m;
while i<=n
y=y*i
i=i+k;
end
Ejercicio 3.18 Codifica una función que reciba x y n con n natural y devuelva 𝑥 𝑛 , para
lo cual no se podrá usar el operador ^ sino que se ha de repetir la operación x x x
mediante un bucle el número de veces que sea necesario. Por ejemplo, si x = 3 y n = 4 el
resultado ha de ser 81.
∑ 𝑥𝑖
𝑖=1
Para calcular cada uno de los términos de la suma, se llamará a la función del ejercicio
3.18 como corresponda. Por ejemplo, si x = 3 y n = 4, el resultado es 31 + 32 + 33 + 34 =
120.
Ejercicio 3.20 (Para valientes) Codifica una función que reciba x y n, y calcule:
𝑛
∑ 𝑥𝑖
𝑖=1
No se podrá usar el operador ^ ni llamar a ninguna función y solo se podrá usar un
bucle. Por ejemplo, si x = 3 y n = 4, el resultado es 31 + 32 + 33 + 34 = 120
Ejercicio 3.21 Codifica una función que reciba 2 números naturales m y j siendo j < m,
y devuelva, utilizando un solo bucle y sin llamar a ninguna función, el resultado de la
siguiente operación:
𝑚!
(𝑚 − 𝑗)!
Por ejemplo si m = 7 y j = 3 el resultado es 210.
Ejercicio 3.22 Codifica una función que reciba 2 números naturales n y m siendo n < m,
y devuelva
la suma
𝑚
𝑚
∑( )
𝑖
𝑖=𝑛
𝑚 𝑚!
Donde ( ) = 𝑖! (𝑚−𝑖)! , 0! = 1
𝑖
Por ejemplo si n = 2 y m = 4 el resultado es 6.
Ejercicio 3.23 ¿Qué calcula la siguiente función? Sin ejecutarla, trata de deducir cuánto
vale ud3_fguess(2,5). Compruébalo con MATLAB.
function suma=ud3_fguess(x,n)
suma=0;
i=1;
pot=x;
while i<=n
suma=suma+pot;
pot=pot*x;
i=i+1;
end
Ejercicio 3.24 (Para valientes) El número pi, se puede obtener mediante la fórmula
1 1 1 1
𝜋 = 4 (1 − + − + ⋯ + (−1)𝑖 +⋯)
3 5 7 2𝑖 + 1
Codifica una función que reciba un número natural n y devuelva la aproximación de pi
mediante los n+ 1 primeros sumandos de la expresión anterior (solución en apéndice).
Por ejemplo, si n = 3, los sumandos y el resultado son:
1 1 1
4 (1 − + − ) = 2.8952
3 5 7
Ejercicio 3.25 Crea una función que dado un natural n, devuelva el error que se comete
𝑖 1
al sustituir pi/4 por la serie ∑𝑚
𝑖=𝑛(−1) 2𝑖+1, es decir
𝑚
𝜋 1
𝑒𝑟𝑟𝑜𝑟 = | − ∑(−1)𝑖 |
4 2𝑖 + 1
𝑖=𝑛
Así por ejemplo si n = 4, el error es
𝜋 1 1 1 1
𝑒𝑟𝑟𝑜𝑟 = | − 1 + − + − | = 0.0495
4 3 5 7 9
La alternancia de signo se debe conseguir sin utilizar ^. No se podrá llamar a ninguna
función.
Ejercicio 3.26 Imagina y especifica un problema susceptible de ser resuelto mediante el
ordenador y tal que el algoritmo que lo resuelva utilice las ideas utilizadas hasta ahora
en el libro, y en particular, las de esta sección.
Ejercicio 3.27 Prueba la función ud3_fnewton con algunos valores y comprueba que los
resultados son correctos.
Ejercicio 3.28 Codifica una función que reciba un número natural n y devuelva el
término n-ésimo de la sucesión
𝑥𝑖+1 = √2𝑥𝑖 , 𝑖 ∈ 𝑁, 𝑥1 = 3.57
Si por ejemplo n = 3, 𝑥2 = √2𝑥1 = 2.6721, 𝑥3 = √2𝑥2 = 2.3117 que es lo que
devolverá la función. Prueba con valores de n más grande. ¿A qué valor parece
converger la sucesión cuando n tiende a ?
Ejercicio 3.29 Codifica una función que reciba un número natural n, con 𝑛 ≥ 2 por
hipótesis, y devuelva |𝑥𝑛 − 𝑥𝑛−1 |, siendo 𝑥𝑛 𝑦 𝑥𝑛−1 los términos n y n -1 de la
sucesión del ejercicio 3.28. No se podrá llamar a ninguna función y solo se podrá usar
un bucle. Por ejemplo, si n = 5, el resultado ha de ser 0.0765 (solución en apéndice).
Ejercicio 3.30 Codifica una función que reciba un número natural n, con 𝑛 ≥ 3 por
hipótesis, y devuelva el n-ésimo término de la sucesión de Fibonacci2.
𝑥𝑛 = 𝑥𝑛−1 + 𝑥𝑛−2 , 𝑥1 = 1, 𝑥2 = 1
Por ejemplo, si n = 6, los términos de la sucesión son 1, 1, 2, 3, 5, 8, y función
devolverá 8.
Ejercicio 3.31 Modifica el ejemplo 3.30 para que reciba un número natural n, con 𝑛 ≥ 3
por hipótesis, y dos números x1 y x2 y devuelva el término n-ésimo de la sucesión de
Fibonacci iniciada por esos valores. Por ejemplo, si x1 = -0:5, x2 = 1 y n = 6, los
términos de la sucesión son -0.5, 1, 0.5, 1.5, 2, 3.5 y función devolverá 3.5.
Ejercicio 3.32 Codifica una función que reciba un número natural n (con 𝑛 ≥ 4 por
hipótesis), tres
valoresx1, x2, y x3, y devuelva el n-ésimo término de la siguiente sucesión:
𝑥𝑛 = −𝑥𝑛−1 + 𝑥𝑛−2 + 𝑥𝑛−3
Por ejemplo, si x1 = 4, x2 = -1, y x3 = -3, para n = 4 tendríamos:
𝑥4 = −𝑥3 + 𝑥2 + 𝑥1 = 3 − 1 + 4 = 6.
y para n = 5 tendríamos:
𝑥5 = −𝑥4 + 𝑥3 + 𝑥2 = −6 − 3 − 1 = −10.
Ejercicio 3.33 Imagina y especifica un problema susceptible de ser resuelto mediante el
ordenador y tal que el algoritmo que lo resuelva utilice las ideas utilizadas hasta ahora
en el libro, y en particular, las de esta sección.
Ejercicio 3.35 Codifica una función que devuelva el número de divisores impares de un
número natural n. Por ejemplo, si n = 50, la respuesta es 3, dado que 50 tiene como
divisores a 1, 2, 5, 10, 25 y 50, de los cuales 3 son impares.
Ejercicio 3.36 Codifica una función que reciba un número natural n y devuelva una
variable flag que ha de valer 0 si n es par y 1 si n es impar. Se usará la orden mod.
Ejercicio 3.37 Codifica una función que reciba un número natural n, con n >1 por
hipótesis, y devuelva el divisor máximo estrictamente menor que n. Por ejemplo, si n =
12, el resultado será 6, mientras que si n = 7, el resultado será 1.
Ejercicio 3.38 Codifica una función que reciba un número x, sume los números
naturales estrictamente menores que x que son pares y no son múltiplos de 3 entre 1 y x
y devuelva ese valor. Por ejemplo, si x = 10.47, la función devolverá 24, pues 2, 4, 8, 10
son pares, no son múltiplos de 3, y son menores que 10.47.
Ejercicio 3.39 Codifica una función que reciba dos números naturales a y b y devuelva
una variable flag que ha de valer 1 si a y b son una pareja de números amigos, y 0 en
caso contrario. Se dice que dos números a y b son una pareja de números amigos si la
suma de los divisores propios3 de a dividida por a es igual a la suma de los divisores
propios de b dividida por b.
Por ejemplo, si a = 30 y b = 140 entonces la función debería devolver 1, ya que la suma
de los divisores propios de 30 es 1 + 2 + 3 + 5 + 6 + 10 + 15 = 42 y la suma de los
divisores propios de 140 es 1 + 2 + 4 + 5 + 7 + 10 + 14 + 20 + +28 + 35 + 70 = 196.
Como se tiene que 42/30 = 1.4 es igual a 196/140, se puede ver que (30; 140) son una
pareja de números amigos. También debería devolver 1 si a = 6 y b = 28. Por otro lado,
si a = 8 y b = 12 la función debería devolver 0 ya que no son pareja de números amigos.
Ejercicio 3.40 Codifica una función que reciba un número natural n, recorra los valores
sin(1); sin(2); sin(3); . . . ; sin(n); y devuelva el número de ellos que son positivos. Por
ejemplo, si n = 5, hay 3 positivos.
Ejercicio 3.41 Codifica una función que reciba un número n, recorra los valores sin(1);
sin(2); sin(3); . . . ; sin(n); y devuelva el producto de los que son positivos. Por ejemplo,
si n = 5, el producto es 0.1080.
Ejercicio 3.43 Codifica una función que reciba dos números naturales m, n y devuelva
la cantidad de divisores comunes. Por ejemplo, m = 14 y n = 6 tienen dos divisores
comunes, el 2 y el 1.
3Los divisores propios de un números son los divisores del número sin incluir el propio
número e incluyendo el 1.
Ejercicio 3.44 Codifica una función que reciba dos números naturales m y n. La función
devolverá el resultado de dividir el factorial de su suma por el número de divisores
comunes. Por ejemplo, si m = 4 y n = 6, tienen 2 divisores comunes, el 1 y el 2. El
factorial de la suma de 4 y 6 es el factorial de 10, que es 3628800. El resultado de
dividir este valor por 2 es 1814400 que habría de ser el resultado de la función en este
caso.
Ejercicio 3.45 (Para valientes) Codifica una función que reciba dos números naturales m
y n, y devuelva su máximo común divisor mcd. Por ejemplo, si m = 12 y n = 18, mcd =
6 (solución en apéndice).
Ejercicio 3.46 (Para valientes) Codifica una función que reciba dos números naturales m
y n, y devuelva su mínimo común múltiplo mcm. Por ejemplo, si m = 12 y n = 18, mcm
= 36 (solución en apéndice).
Ejercicio 3.47 (Para valientes) Codifica una función que reciba 3 naturales m, n, p y
devuelva una variable flag tal que flag=1 si el mínimo de los máximos comunes
divisores entre dos de estos números corresponde a la pareja m, n; flag=2 si corresponde
a la pareja m, p y flag=3 si es n, p. Si por ejemplo m = 20, n = 30, p = 15, flag valdría 2.
Ejercicio 3.48 Repetir el ejercicio 3.47 pero sin llamar ahora a ninguna función, en
particular a la del ejercicio 3.45.
Ejercicio 3.49 Imagina y especifica un problema susceptible de ser resuelto mediante el
ordenador y tal que el algoritmo que lo resuelva utilice las ideas utilizadas hasta ahora
en el libro, y en particular, las de esta sección.
% ud3_fesprimo
% ud3_fesprimo(numero) devuelve 1 si numero es primo
% y 0 si no lo es
% orden break.
function primo=ud3_fesprimo(numero)
primo=1;
i=2;
while i<=sqrt(numero)
if mod(numero,i)==0
primo=0;
break;
end
i=i+1;
end
Es interesante notar que cualquier número no primo tiene divisores menores o iguales
que su raíz cuadrada. Si un número no los tiene es que es primo. Por eso el índice del
bucle solo llega hasta la raíz del número analizado. Los ejercicios correspondientes a
este ejemplo son los siguientes:
Ejercicio 3.53 Codifica una función que reciba dos enteros m, n, con m < n por
hipótesis, y devuelva el menor número entero r entre m y n (ambos inclusive) tal que
sin(r) >0 (se usará break). Si no hubiese ninguno, la función devolverá 0. Por ejemplo,
si m = 16 y n = 27 el resultado debe ser 19 ya que sin(16) = -0:2, sin(17) = -0:9, sin(18)
= -0:7, y sin(19) = 0:1.
Ejercicio 3.55 Codifica una función que reciba un natural n y devuelva el mayor número
entero positivo m < n tal que sin(m) <0. (se usará break). Se supondrá que existe
solución. Por ejemplo, si n = 29 el resultado ha de ser 25.
Ejercicio 3.57 Utilizando la función ud3_fcuentadiv, construye una función que haga lo
mismo que ud3_fesprimo.
Ejercicio 3.58 Codifica una función que calcule el número de primos menores o iguales
que un número natural n, llamando a ud3_fesprimo. Por ejemplo, si n = 10, los primos
menores o iguales que n son 2, 3, 5 y 7. La función devolvería por tanto 4.
Ejercicio 3.59 Codifica una función que calcule la suma de de los primos menores o
iguales que un número natural n. Por ejemplo, si n = 10, los primos menores o iguales
que n son 2, 3, 5 y 7, cuya suma es 17, que es lo que debe devolver la función.
Ejercicio 3.60 Codifica una función que reciba dos naturales estrictamente positivos por
hipótesis, my n, con m < n por hipótesis, y devuelva la suma de los números primos
entre m y n, ambos inclusive. Por ejemplo si m = 17 y n = 27, los primos entre ambos
son 17, 19 y 23, cuya suma es 59.
Ejercicio 3.61 Codifica una función que reciba dos naturales estrictamente positivos por
hipótesis, my n, con m < n por hipótesis, y devuelva el producto de los números primos
entre m y n. Por ejemplo si m = 17 y n = 27, los primos entre ambos son 17, 19 y 23,
cuyo producto es 7429.
Ejercicio 3.62 Codifica una función que reciba dos naturales, m y n, con m < n por
hipótesis, y devuelva el mayor número primo entre m y n, ambos inclusive. (Para
valientes) Hacerlo sin usar break. Si no hubiere ningún primo, la función devolverá 0.
Por ejemplo si m = 17 y n = 27, los primos entre ambos son 17, 19 y 23 siendo el más
grande el 23.
Ejercicio 3.63 Codifica una función que reciba dos naturales, m y n, con m < n por
hipótesis, y devuelva el menor número primo entre m y n, ambos inclusive. (Para
valientes) Hacerlo sin usar break. Si no hubiere ningún primo, la función devolverá 0.
Por ejemplo si m = 17 y n = 27, los primos entre ambos son 17, 19 y 23 siendo el más
pequeño el 17.
Ejercicio 3.64 (Para valientes) Codifica una función que reciba un número num y
devuelva una variable flag que ha de valer 1 si num descompone en producto de dos
primos y 0 si no es así. Por ejemplo, para num = 6 = 3 2 devolverá 1 y para num = 7 o
num = 12 devolverá 0.
Ejercicio 3.65 (Para los más valientes) Este ejercicio está inspirado en la estupenda
novela de Mark Haddon, The curious incident of the dog in the night-time, publicada en
el año 2003. Codifica una función que reciba un número n y devuelva el mayor primo
menor o igual que n terminado en 3 tal que el primo anterior termine en 1 y tal que la
diferencia entre ambos sea 2. Por ejemplo, si n = 55, la respuesta sería 43.
% ud3_fdigitos.m
% Cuenta los digitos de n natural mayor que 0.
% Bucle con condicion no relativa a un indice.
function cont=ud3_fdigitos(n)
cont=0;
while n>=1
n=n/10;
cont=cont+1;
end
Otro ejemplo, un poco más complicado, es contar los elementos de la sucesión de
Fibonacci menores que cierto número r. La sucesión estará iniciada por x1 y x2,
supuestos estrictamente positivos y menores que r. A priori, no se sabe cuántos términos
de la sucesión van a cumplir esa propiedad, así que no se puede crear un bucle con un
índice de 1 a un determinado n con la seguridad de que vamos a recorrer todos los
términos posibles menores que r (hay que tener en cuenta que x1 y x2 pueden ser
números tan pequeños como queramos, por ejemplo, 0.0023 y 0.0001). La manera de
resolver este problema es implementar esa condición directamente en el while del bucle.
Es decir, el bucle estará corriendo mientras que los elementos de la sucesión sean
menores que r. Concretamente:
% ud3_ffibonacci.m
% devuelve el numero de t´erminos de la sucesion de
% Fibonacci menores que r
% (iniciada por x1, x2 positivos, con x1<r, x2<r)
function cont=ud3_ffibonacci(x1,x2,r)
x3=x1+x2;
cont=2;
while x3<r
cont=cont+1;
x1=x2;
x2=x3;
x3=x1+x2;
end
Ejercicio 3.67 Prueba las funciones ud3_fdigitos y ud3_ffibonacci con algunos valores
y comprueba que los resultados son correctos.
Ejercicio 3.68 Codifica una función que reciba un número num ≥ 2, y devuelva el
primer elemento xn de la sucesión de Fibonacci 𝑥𝑥 = 𝑥𝑥−1 + 𝑥𝑥−2 , con x1 = 1 = x2 =
1, tal que xn sea mayor o igual que num. Por ejemplo, si num = 18, la función devolverá
21, pues los términos de la sucesión de Fibonacci son 1, 1, 2, 3, 5, 8, 13, 21, 34, . . . , y
el primero mayor o igual que 18 es 21.
Ejercicio 3.69 Escribe una función que reciba un número natural n, con n ≥ 2 por
hipótesis, y calcule la media aritmética de los elementos de la sucesión de Fibonacci
(con x1 = 1 y x2 = 1) que son menores o iguales que n. Por ejemplo, si n = 15, los
elementos de la sucesión de Fibonacci menores que 15 son 1, 1, 2, 3, 5, 8 y 13 y su
media es (1 + 1 + 2 + 3 + 5 + 8 + 13)/7 = 33/7 = 4.7143
Ejercicio 3.70 Crea una función que reciba un número natural n, con n ≥ 2 por
hipótesis, y devuelva el número de elementos de la sucesión de Fibonacci (con x1 = 1 y
x2 = 1) que son primos y menores que n. Por ejemplo, si n = 100 la función debería
devolver 5 ya que los elementos de la sucesión de Fibonacci menores que 100 son 1, 1,
2, 3, 5, 8, 13, 21, 34, 55 y 89 y de ellos solamente 2, 3, 5, 13 y 89 son primos. La
función devolverá por tanto 5.
Ejercicio 3.71 (Para valientes) Codifica una función que reciba tres números
estrictamente positivos p, q y r, y devuelva una variable flag que ha de valer 1 si r
pertenece a la sucesión de Fibonacci iniciada por p y q y 0 en caso contrario. O sea:
𝑥𝑥 = 𝑥𝑥−1 + 𝑥𝑥−2 , 𝑥1 = 𝑥, 𝑥2 = 𝑥
Por ejemplo, si p = 0.2, q = 0.5 y r = 1.2, la respuesta es 1, mientras que si r = 1.5, la
respuesta
ha de ser 0.
Ejercicio 3.72 Codifica una función que reciba dos números naturales m y n, con 1 < m
< n por hipótesis, y que cuente el número de veces que m divide a n. Si m no es divisor
de n la función deberá devolver 0. Por ejemplo, si m = 2 y n = 8, el resultado es 3. Si m
= 2 y n = 9, el resultado es 0.
Ejercicio 3.73 Codifica una función que reciba un número natural y devuelva el número
de ceros que hay en él (así, por ejemplo, en 304 hay un cero, en 30 hay un cero y en 115
no hay ningún cero) (solución en apéndice).
Ejercicio 3.74 Dado un número natural n escribir una función que halle la media
aritmética de los dígitos de n. Es decir, si n = 204 entonces la función ha de devolver (2
+ 0 + 4)/3 = 2.
Ejercicio 3.75 (Para valientes) Construir una función que reciba dos naturales m; n, con
m entre 0 y 9 ambos inclusive. La función devolverá el número de veces que aparece m
entre los dígitos de n. Por ejemplo, si n = 304, y m = 0 el resultado será 1, pero si m = 7,
el resultado será 0.
Ejercicio 3.76 Hay números de 5 dígitos del tipo abbbb tales que cuando los elevas al
cuadrado y les sumas o restas 1 queda un número que tiene 10 dígitos todos diferentes
entre sí. Por ejemplo
(85555)2 -1 = 7 319 658 024
(97777)2 -1 = 9 560 341 728
Codifica una función que reciba dos naturales a, b, con 0 ≤ a, b ≤ 9, y compruebe si el
número abbbb es de ese tipo, devolviendo una variable flag que valga 1 o 0
dependiendo de que lo sea o no.
Ejercicio 3.77 Considérese la serie del ejercicio 3.24 cuya suma es pi. Es decir, las
sumas parciales
1 1 (−1)𝑛
𝑆𝑛 = 4 (1 − + + ⋯ + )
3 5 2𝑛 + 1
son aproximaciones del número pi que van mejorando a medida que n es más grande.
Escribe una función que dado un valor err devuelva el número aprox que será la primera
suma parcial Sn tal que aproxime a pi con un error menor err es decir |Sn – pi |< err.
Por ejemplo, si err = 0.15, dado que los términos de la sucesión Sn son 4.0000, 2.6667,
2.8952, 3.3397, 2.9760, 3.2837, 3.0171, 3.2524, la función devolverá 3.2837, pues es el
primer término para el que |3.2837 – pi | <0.15.
Ejercicio 3.78 Codifica una función que reciba un valor real positivo prec, obtenga
términos de la
Sucesión
𝑥𝑖+1 = √2𝑥𝑖 , 𝑥1 = 8.32, 𝑖 𝑒𝑛 𝑁
|𝑥 |
y devuelva el primer 𝑥𝑖 para la que 𝑖 − 𝑥𝑖−1 < 𝑝𝑟𝑒𝑐. Por ejemplo, en la siguiente
tabla se muestran los valores de 𝑥𝑖 para i = 1, . . . . y de los correspondientes |𝑥𝑖 −
𝑥𝑖−1 |. Si la precisión es prec = 0.05 la primera vez que |𝑥𝑖 − 𝑥𝑖−1 | < 0.005 es para i =
7, así que la función ha de devolver x7 = 2.0450.
𝑖 𝑥𝑖 |𝑥𝑖 − 𝑥𝑖−1 |
1 8.3200
2 4.0792 4.2408
3 2.8563 1.2229
4 2.3901 0.4662
5 2.1864 0.2037
6 2.0911 0.0953
7 2.0450 0.0461
8 2.0224 0.0226
…. …. ….
Ejercicio 3.79 Codifica una función que reciba 3 valores reales positivos A, a, prec,
obtenga términos de la sucesión
𝑥𝑖2 − 𝐴
𝑥𝑖+1 = 𝑥𝑖 − , 𝑥1 = 𝑎, 𝑖≥1
2𝑥𝑖
y devuelva el primer 𝑥𝑖 para la que |𝑥𝑖 − 𝑥𝑖−1 | < 𝑝𝑟𝑒𝑐. Por ejemplo, si A = 225, a =
100, prec = 0.5, en la siguiente tabla se muestran los valores de 𝑥𝑖 para i = 1, . . . , y de
los correspondientes |𝑥𝑖 − 𝑥𝑖−1 |. La primera vez que |𝑥𝑖 − 𝑥𝑖−1 | < 0.5 es para i = 6,
así que la función ha de devolver 𝑥6 = 15.0019
𝑖 𝑥𝑖 |𝑥𝑖 − 𝑥𝑖−1 |
1 100
2 51.1250 48.8750
3 27.7630 23.3620
4 17.9337 9.8293
5 15.2399 2.6937
6 15.0019 0.2381
… … …
Ejercicio 3.80 Codifica una función que reciba 2 números naturales p y q y genere
términos de la sucesión de Fibonacci iniciada por p y q. O sea:
𝑥𝑖+2 = 𝑥𝑖 + 𝑥𝑖+1 , 𝑥1 = 𝑝, 𝑥2 = 𝑞, 𝑖≥1
La función devolverá el primer múltiplo de p+q (distinto de p+q). Por ejemplo, si p = 3,
q = 5, la respuesta es 144. Otro ejemplo, si p = 4, q = 15, la respuesta es 118199.
Ejercicio 3.81 Crea una función que reciba un número real x y un número natural m y
devuelva el primer valor de k para el que suceda que |sin(𝑥) − 𝑎𝑘 (𝑥)| < 10−𝑚 , con
𝑘
(−1)𝑛 2𝑛+1
𝑎𝑘 (𝑥) = ∑ 𝑥
(2𝑛 + 1)!
𝑛=0
Por ejemplo, si x = 0.05 y m = 10 la función debería devolver 3, ya que los tres
primeros términos
de la sucesión verifican:
|sin(0.05) − 𝑎1 (0.05)| = 2.08307𝑒 − 005 > 10−10
|sin(𝑥) − 𝑎2 (0.05)| = 2.60401𝑒 − 009 > 10−10
|sin(𝑥) − 𝑎3 (0.05)| = 1.55005𝑒 − 013 < 10−10
Por tanto, a3 es el primer término cuya diferencia con sin(x) es menor que 10-10.
Ejercicio 3.82 Codifica una función que reciba tres números naturales p, q y r. La
función calculará términos de la sucesión de Fibonacci iniciada por p y q y comprobará
si son múltiplos de p. En el momento en que hayamos encontrado r múltiplos de p la
función terminará, devolviendo el término en que estemos de la sucesión de Fibonacci.
No se tendrán en cuenta los valores p y q. Por ejemplo, si p = 3, q = 4 y r = 2, la
sucesión de Fibonacci estaría formada por 3; 4; 7; 11; 18; 29; 47; 76; 123; . . . . Como
18 y 123 son los dos primeros múltiplos de 3, el valor a devolver sería 123. Si p = 2, q =
1 y r = 3, la función devolvería en este caso 76, pues los tres primeros múltiplos de 2
serían 4; 18 y 76.
Ejercicio 3.83 Sea {𝑎𝑛 } la sucesión de números naturales tal que 𝑎1 > 0, 𝑎2 > 0 y
definida para 𝑛 ≥ 0 como
𝑎𝑛−1
, 𝑠𝑖 𝑎𝑛−1 𝑒𝑠 𝑝𝑎𝑟
𝑎𝑛 = { 2
𝑛 𝑎𝑛−2 , 𝑠𝑖 𝑎𝑛−1 𝑒𝑠 𝑖𝑚𝑝𝑎𝑟
Crea una función que reciba tres números naturales p, q y m (siendo p y q menores que
m) y devuelva el primer término de la sucesión {𝑎𝑛 } (con a1 = p y a2 = q) que sea
mayor que m. Por ejemplo, si p = 3, q = 5 y m = 15 entonces la función debería
devolver 20.