Documente Academic
Documente Profesional
Documente Cultură
a
la
programacin
con
MATLAB
46
ejercicios
resueltos
con
varias
soluciones,
todas
claramente
explicadas
Macario
Polo
Usaola,
2012
macario.polo@gmail.com
NDICE
DE
EJERCICIOS
Ejercicio
1.
Factorial
iterativo
........................................................................................................
1
Ejercicio
2.
Nmero
combinatorio
...............................................................................................
7
Ejercicio
3.
ex
por
Taylor
..................................................................................................................
9
Ejercicio
4.
seno(x)
por
Taylor
....................................................................................................
13
Ejercicio
5.
Factorial
recursivo
...................................................................................................
14
Ejercicio
6.
Fibonacci
......................................................................................................................
16
Ejercicio
7.
La
divina
proporcin
...............................................................................................
19
Ejercicio
8.
Conversin
de
entero
a
binario
..........................................................................
20
Ejercicio
9.
Contador
de
apariciones
.......................................................................................
25
Ejercicio
10.
Producto
escalar
....................................................................................................
28
Ejercicio
11.
Fibonacci
en
un
vector
........................................................................................
31
Ejercicio
12.
Distancia
al
primero
.............................................................................................
33
Ejercicio
13.
Nmeros
primos
....................................................................................................
41
Ejercicio
14.
Vector
con
los
n
primeros
nmeros
primos
...............................................
44
Ejercicio
15.
Vector
con
los
n
primeros
nmeros
primos
ordenados
de
mayor
a
menor
46
Ejercicio
16.
Calcular
el
ensimo
nmero
primo
................................................................
48
Ejercicio
17.
Contar
nmeros
distintos
en
un
vector
.......................................................
49
Ejercicio
18.
Descomposicin
en
factores
primos
(I)
.......................................................
50
Ejercicio
19.
Descomposicin
en
factores
primos
(II)
......................................................
52
Ejercicio
20.
Mximo
comn
divisor
........................................................................................
54
Ejercicio
21.
Tablero
de
ajedrez
.................................................................................................
56
Ejercicio
22.
Alfil
...............................................................................................................................
57
Ejercicio
23.
El
caballo
de
ajedrez
.............................................................................................
61
Ejercicio
24.
Matriz
identidad
.....................................................................................................
68
Ejercicio
25.
Diagonal
principal
.................................................................................................
70
Ejercicio
26.
Traza
de
una
matriz
..............................................................................................
73
Ejercicio
27.
Unos
y
ceros
alternados
......................................................................................
75
Solucin 1.
1
argumento
y
parmetro
significan
lo
mismo.
Utilizaremos
ambas
palabras
indistintamente.
n
5
5
5
5
5
5
result
1
result=result*i
result=1*1=1
result=result*i
result=1*2=2
result=2*3=6
result=6*4=24
result=24*5=120
i
1
2
3
4
5
Tabla 1
La
palabra
ans
que
escribe
MATLAB
es
la
answer
(la
respuesta)
al
clculo
que
le
hemos
solicitado.
Muestra
un
120
porque,
en
la
cabecera
de
la
funcin
asignbamos
a
result
el
resultado
de
la
funcin,
y
precisamente
es
result
la
variable
en
la
que
vamos,
iteracin
a
iteracin,
almacenando
el
resultado
que
deseamos.
function result = factorial1( n )
Solucin 2.
Solucin 3.
Solucin 4.
Solucin 5.
Otra
forma
de
conseguir
lo
mismo
que
en
la
solucin
anterior
es
colocar
las
dos
comprobaciones
(existencia
de
un
argumento
y
que
ste
sea
positivo)
en
un
solo
if:
en
la
Funcin
5
unimos
ambas
condiciones
con
un
or
(smbolo
|,
la
barra
vertical),
de
manera
que
si
el
nmero
de
argumentos
es
0
o
n
es
menor
que
cero,
la
funcin
devuelva
-1,
se
muestre
un
mensaje
de
error
y
se
termine
el
clculo.
Solucin 6.
Nos
piden
en
el
enunciado,
por
ltimo,
que
si
n
no
fuera
entero
se
redondee
hacia
+
:
es
decir,
si
queremos
calcular
el
factorial
de
7.85,
devolveremos
el
factorial
de
8.
Una
vez
comprobado
que
hay
un
argumento
positivo,
utilizaremos
la
funcin
ceil(x)
de
MATLAB:
si
x
tiene
decimales,
ceil(x)
redondea
el
valor
de
x
hacia
el
entero
superior
ms
prximo;
si
no
los
tiene,
deja
el
valor
de
x
como
est.
function result = factorial2( n )
if (nargin==0 | n<0)
result=-1;
disp('Debes dar un argumento positivo a la funcin');
return;
end
n=ceil(n);
result=1;
for i=n:-1:1
result=result*i;
end
end
Funcin
6
>>
factorial2(4.5)
ans
=
120
>>
factorial(5)
ans
=
120
Figura
5
Solucin 1.
Escribiremos
primero
una
solucin
algo
larga,
pero
en
la
que
se
realiza
todo
el
clculo:
en
los
primeros
tres
if
(marcados
en
amarillo)
hacemos
una
comprobacin
de
los
argumentos.
En
el
siguiente
comprobamos
si
m
es
0
o
si
n==m,
con
lo
que
debemos
devolver
1
como
resultado.
En
los
siguientes
tres
bloques
calculamos
los
factoriales
de
n,
m
y
de
n-m
usando
tres
bucles
for
como
los
que
ya
utilizamos
en
la
primera
solucin
a
la
funcin
factorial
(pgina
1).
Estos
factoriales
los
guardamos
en
tres
variables
llamadas
factorialN,
factorialM
y
factorialNmenosM.
Finalmente,
asignamos
a
la
variable
de
resultado
(result)
el
clculo
solicitado.
function result = numeroCombinatorio1( n, m )
if (nargin~=2)
disp('Se necesitan dos argumentos');
return;
end
if (n<0 | m<0)
disp('Los argumentos deben ser positivos');
return;
end
if (n<m)
disp('n debe ser mayor o igual que m');
return;
end
if (n==m | m==0)
result=1;
return;
end
factorialN=1;
for i=1:1:n
factorialN=factorialN*i;
end
factorialM=1;
for i=1:1:m
factorialM=factorialM*i;
end
factorialNmenosM=1;
for i=1:1:(n-m)
factorialNmenosM=factorialNmenosM*i;
end
result=factorialN/(factorialM*factorialNmenosM);
end
Funcin
7
Solucin 2.
Solucin 3.
En
las
dos
soluciones
anteriores
repetimos
clculos.
Supongamos
que
nos
piden
!"
calcular
:
calculamos
primero
factorialN=10987654321
y
luego
!
computamos
factorialM=54321,
con
lo
que
estamos
repitiendo
parte
del
clculo
del
factorialN.
Si
debiramos
hacer
este
clculo
a
mano,
probablemente
calcularamos
primero
el
factorial
de
m
y
luego,
al
calcular
el
de
n,
nos
detendramos
al
llegar
al
valor
de
m.
Es
decir,
que
factorialN=109876factorialM.
Esto
es
lo
que
hacemos
en
esta
solucin
(Funcin
9),
que
requiere
menos
tiempo
de
cmputo:
en
la
primera
lnea
se
calcula
el
factorial
de
m;
luego,
en
el
bucle
for
resaltado
en
amarillo,
vamos
guardando
en
factorialN
el
valor
de
multiplicar
i
desde
n
hasta
el
valor
de
m+1.
En
la
instruccin
siguiente,
multiplicamos
el
valor
de
factorialN
por
el
valor
de
factorialM
que
hemos
calculado
antes,
de
manera
que
nos
ahorramos
unas
cuantas
vueltas
de
bucle.
Finalmente
calculamos
(n-m)!
por
el
mtodo
tradicional
y
calculamos
el
resultado
final
del
nmero
combinatorio.
Se
han
omitido
las
comprobaciones
de
argumentos
para
facilitar
la
lectura
del
cdigo.
function result = numeroCombinatorio3( n, m )
factorialM=factorial1(m);
factorialN=1;
for i=n:-1:m+1
factorialN=factorialN*i;
end
factorialN=factorialN*factorialM;
factorialNmenosM=factorial1(n-m);
result=factorialN/(factorialM*factorialNmenosM);
end
Funcin
9
! =
!!!
!!
, !
!!
Solucin 1.
! =
!!!
!! !! !! !! !!
=
+ +
+
+
!! !! !! !! !!
! =
!!!
!! !! !! !! !!
!!! !!""
=
+ +
+
+ +
+
!! !! !! !! !!
!!! !""!
Solucin 2.
Solucin 3.
10
Inf
-5
-12.5
-20.8333333333333
-26.0416666666667
-26.0416666666667
-21.7013888888889
-15.5009920634921
-9.68812003968253
-5.38228891093473
-2.69114445546737
-1.2232474797579
-0.509686449899135
-0.196033249961204
-0.070011874986136
-0.0233372916620453
-0.00729290364438384
-0.00214497166010119
-0.000595825461147115
-0.000156796173996554
-3.91990434991385e-05
-9.33310559503298e-06
-2.12116034958854e-06
-4.61121828720934e-07
-9.60670547556219e-08
0
0
...
0
ans=
148.413159078837
Figura
7
La
larga
lista
de
nmeros
que
muestra
(hemos
omitido
bastantes
ceros
al
final)
se
corresponde
con
los
valores
de
error
calculados
en
cada
iteracin
del
bucle
while.
Solucin 4.
11
12
!"#$ ! =
!!!
(!)!
!!"!! , !
!" + ! !
Solucin 1.
13
Solucin 1.
n
5
result
5
4
result=5*factorialRecursivo(4)
4
3
result=4*
factorialRecursivo(3)
14
Comentarios
n
result
Como
n
no
es
0,
se
entra
al
else
3
result=3*
factorialRecursivo(2)
4
llamada.
Se
ejecuta
2
factorialRecursivo(2).
El
valor
de
n
es
2
Como
n
no
es
0,
se
entra
al
else
2
result=2*factorialRecursivo(1)
5
llamada.
Se
ejecuta
1
factorialRecursivo(1).
n
llega
valiendo
1
Como
n
no
es
0,
se
entra
al
else
1
result=1*factorialRecursivo(0)
6
llamada.
Se
ejecuta
0
factorialRecursivo(0).
n
vale
0
n
es
ahora
0,
por
lo
que
es
cierta
0
result=1
la
condicin
del
if
(n==0)
En
este
punto
se
ha
alcanzado
el
caso
base,
por
lo
que
no
hay
ms
llamadas
recursivas.
Ahora,
el
valor
calculado
en
la
6
llamada
se
utiliza
para
calcular
el
valor
de
la
5
llamada,
que
a
su
vez
se
utiliza
para
calcular
el
de
la
4,
etctera.
Regreso
a
la
5
llamada.
1
result=1*factorialRecursivo(0)=1*1=1
Regreso
a
la
4
llamada.
2
result=2*factorialRecursivo(1)=1*2=1
Regreso
a
la
3
llamada.
3
result=3*factorialRecursivo(2)=3*2=6
Regreso
a
la
2
llamada.
4
result=4*factorialRecursivo(3)=4*6=24
Regreso
a
la
1
llamada.
5
result=5*factorialRecursivo(5)=5*24=120
Tabla
2
15
Ejercicio
6. Fibonacci
Escribir
una
funcin
que
calcule
el
trmino
n
de
la
funcin
de
Fibonacci,
que
viene
dada
por:
x1=1;
x2
=
1;
xi=xi-1+xi-2
Solucin 1.
fibonacci(1)=1
fibonacci(2)=1
Observamos
que
hay
dos
casos
base:
uno
con
n=0
y
otro
con
n=1.
En
estos
dos
casos,
el
valor
de
la
funcin
es
1.
El
cdigo
puede
ser
el
siguiente:
function result=fib(n)
if (n==1)
result=1;
elseif (n==2)
result=1;
else
result=fib(n-1)+fib(n-2);
end
end
Funcin
16.
Fibonacci
recursivo
con
dos
casos
base
Solucin 2.
Solucin 3.
Cualquiera
de
las
dos
soluciones
que
hemos
dado
arriba
es
muy
costosa
en
trminos
del
nmero
de
sumas
que
es
necesario
realizar.
Para
calcular
a
mano,
por
ejemplo,
fib(8),
hacemos
lo
siguiente:
fib(8)=fib(7)+fib(6)=
16
=
[fib(6)+fib(5)]
+
[fib(5)+fib(4)]
=
=
{
[fib(5)+fib(4)]
+
[fib(4)+fib(3)]
}
+
{
[fib(4)+fib(3)]
+
[fib(2)+fib(1)]
}
=
El
mismo
cmputo,
que
resulta
complicado
escribirlo
en
forma
de
ecuacin,
se
puede
representar
de
forma
arborescente:
ntese
que
hay
clculos
que
se
repiten
varias
veces,
y
obsrvese
que
el
caso
base
se
alcanza
en
total
21
veces,
correspondientes
a
los
21
unos
que
hay
en
el
rbol,
y
que
fibonacci(8)=21.
Figura
8.
rbol
correspondiente
al
clculo
tradicional
de
Fibonacci(8)
Solucin 4.
17
function result=fib2(n)
tic;
if (n<=2)
result=1;
else
result=fib2(n-1)+fib2(n-2);
end
toc;
end
function result=fib3(n)
tic;
i=1;
j=0;
for k=1:1:n
t=i+j;
i=j;
j=t;
end
result=j;
toc;
end
Funcin
19.
La
versin
recursiva
(izquierda)
y
la
iterativa
(derecha)
para
calcular
Fibonacci,
anotadas
con
instrucciones
para
calcular
el
tiempo
>>
fib3(20)
Elapsed
time
is
0.000005
seconds.
ans
=
6765
Solucin 5.
! ! (1 !)!
5
en
donde:
!=
1+ 5
2
18
Solucin 1.
divinaProporcin(n)=fibonacci(n)/fibonacci(n-1)
19
Solucin 1.
De
este
modo,
obtenemos
que
152=1111.
De
igual
manera
podemos
calcular
el
29
en
base
2:
As,
292=11101.
Por
tanto,
utilizaremos
un
bucle
para
ir
dividiendo
el
nmero
que
obtengamos
entre
2,
mientras
que
el
cociente
sea
mayor
o
igual
a
2.
Adems,
deberemos
ir
memorizando
los
restos
que
vayamos
obteniendo.
Una
primera
aproximacin
a
la
solucin
es
la
siguiente
(Funcin
22):
20
El
cdigo
de
la
Funcin
22
tiene
una
novedad
respecto
de
las
funciones
que
hemos
escrito
hasta
ahora:
a
la
variable
result
le
asignamos,
en
las
lneas
resaltadas,
valores
entre
corchetes.
Con
los
corchetes
indicamos
que
la
variable
es
un
vector.
En
la
primera
sentencia
(result=[resto]),
guardamos
en
result
un
vector
con
un
solo
elemento,
el
resto
que
se
ha
calculado.
En
la
segunda
(result=[resto
result])
aadimos
al
comienzo
del
vector
result
el
valor
que
hemos
calculado
del
resto
en
esta
iteracin.
Usamos,
adems,
la
funcin
mod
en
la
primera
asignacin
al
resto:
resto=mod(cociente,
2).
mod(x,y)
devuelve
el
resto
de
la
divisin
entera
de
x
entre
y.
Igualmente,
usamos
la
funcin
floor,
que
redondea
un
nmero
decimal
al
entero
inmediatamente
inferior.
Hagamos
una
traza
de
la
funcin
con
n=12:
Comentarios
n
cociente
resto
result
Llamada
a
la
funcin
12
Ejecucin
de
cociente=n
12
12
Ejecucin
de
resto=mod(cociente,
2)
12
12
0
Ejecucin
de
result=[resto]
12
12
0
[
0
]
Entramos
al
bucle,
ya
que
12
12
0
[
0
]
cociente>=2
cociente=floor(cociente/2)
12
6
0
[
0
]
resto=mod(cociente,
2)
12
6
0
[
0
]
result=[resto
result]
12
6
0
[
0
0
]
Segunda
vuelta
al
bucle
12
6
0
[
0
0]
cociente=floor(cociente/2)
12
3
0
[
0
]
resto=mod(cociente,
2)
12
3
1
[
0
]
result=[resto
result]
12
3
1
[
1
0
0
]
Tercera
vuelta
al
bucle
12
3
1
[
1
0
0
]
cociente=floor(cociente/2)
12
1
1
[
0
]
resto=mod(cociente,
2)
12
1
1
[
0
]
result=[resto
result]
12
1
1
[
1
1
0
0
]
Y
en
este
momento
se
sale
del
bucle,
ya
que
cociente=1,
que
es
menor
que
2
Tabla
3.
Traza
de
pasarABinario(12)
21
Solucin 2.
En
las
lneas
en
amarillo
preguntamos
que,
si
n<0,
entonces
el
primer
elemento
del
vector
sea
sustituido
por
su
valor
multiplicado
por
-1.
Al
ejecutar,
como
ejemplo,
pasarABinario(-12),
esperaramos
la
respuesta
-1100;
sin
embargo,
MATLAB
nos
responde,
sorprendentemente,
de
la
siguiente
forma:
22
>>
pasarABinario2(-12)
ans
=
0
Figura
10
Solucin 3.
En
el
enunciado
tambin
se
nos
dice
que,
si
el
nmero
que
se
pasa
como
parmetro
no
es
entero,
se
debe
dar
un
mensaje
de
error.
Una
forma
de
comprobar
esto
es
preguntar
si
el
parmetro
n
es
igual
a
la
parte
entera
del
propio
n,
es
decir:
23
24
Solucin 1.
Igual
que
en
otras
ocasiones,
veamos
cmo
haramos
esto
a
mano.
Supongamos
que
tenemos
el
vector
v=
{1
2
1
3
4
1
2
5
6
4
1},
y
que
deseamos
contar
las
apariciones
de
n=1.
Posicin
Valor
1
1
2
2
3
1
4
3
5
4
6
1
7
2
8
5
9
6
10
4
11
1
Para
ejecutar
la
funcin
con
el
vector
dado
como
ejemplo
y
para
que
busque
el
valor
1,
escribimos
en
el
rea
de
comandos
de
MATLAB
dos
instrucciones:
primero,
una
para
asignar
a
una
variable
x
el
vector;
luego,
la
llamada
a
la
funcin
que
hemos
escrito.
25
>>
x=[
1
2
1
3
4
1
2
5
6
4
1]
x
=
1
2
1
3
4
1
2
5
6
4
1
>>
problema8ContadorB(x,
1)
ans
=
4
Figura
12
Solucin 2.
MATLAB
dispone
de
muchas
funciones
muy
cmodas
para
trabajar
con
vectores
y
matrices.
Dado
el
vector
anterior,
podemos
escribir
en
la
lnea
de
comandos
lo
siguiente:
>>
x==2
ans
=
0
1
0
0
0
0
1
0
0
0
0
Figura
13
Lo
que
le
estamos
diciendo
a
MATLAB
con
x==2
es
que
me
muestre
qu
valores
del
vector
x
son
iguales
a
2
y
cules
no.
Como
respuesta,
MATLAB
devuelve
otro
vector
con
unos
y
ceros:
en
aquellas
posiciones
en
las
que
el
vector
tiene
valor
2,
MATLAB
pone
un
1,
y
un
0
en
las
que
no.
De
este
modo,
aparece
el
valor
1
en
las
posiciones
2
y
7,
ya
que
x
contiene
un
2
en
esas
dos
posiciones.
Posicin
x=
x==2?
1
1
0
2
2
1
3
1
0
4
3
0
5
4
0
6
1
0
7
2
1
8
5
0
9
6
0
10
4
0
11
1
0
Bien,
pues
podemos
combinar
ambas
funciones
para
calcular
muy
rpida
y
sencillamente
el
nmero
de
apariciones
de
un
elemento
en
un
vector:
si
calculamos
la
suma
del
vector
de
unos
y
ceros,
ya
sabremos
cuntas
veces
aparece
el
nmero
solicitado:
26
1
1
0
2
2
1
3
4
5
6
7
8
9
1
3
4
1
2
5
6
0
0
0
0
1
0
0
La
suma
de
los
elementos
en
amarillo
es
2.
Y
s,
funciona:
>>
problema8ContadorA(x,
2)
ans
=
2
Figura
15
27
10
4
0
11
1
0
Solucin 1.
Solucin 2.
28
Solucin 3.
Desde
luego,
podemos
utilizar
tambin
los
propios
operadores
de
MATLAB
para
multiplicar
matrices
y
vectores
y
hacer
la
cosa
mucho
ms
sencilla.
En
la
siguiente
figura
mostramos
el
uso
del
operador
*
para
multiplicar
dos
vectores:
>>
x
1
x
=
1
2
1
3
4
1
2
5
6
4
1
>>
y'
ans
=
3
1
2
1
3
4
1
2
5
6
4
1
>>
y=x
2
y
=
1
2
1
3
4
1
2
5
6
4
1
>>
x*y
???
Error
using
==>
mtimes
Inner
matrix
dimensions
must
agree.
4
>>
x*y'
ans
=
114
Figura 16. Clculo del producto escalar, directamente en la lnea de comandos de MATLAB
29
En
realidad,
no
nos
hace
falta
entonces
crear
ninguna
funcin
en
MATLAB
para
calcular
el
producto
escalar
de
dos
vectores.
No
obstante,
si
deseamos
hacerlo:
function result = productoEscalar3(v, w)
if (nargin~=2)
disp('Debe pasar dos argumentos');
return;
end
if (length(v)~=length(w))
disp('Los vectores deben tener el mismo nmero de elementos');
return;
end
result=v*w';
end
Funcin
29
30
Solucin 1.
En
la
Funcin
30
damos
una
primera
solucin:
primero
asignamos
a
fib
(la
variable
que,
en
este
caso
y
por
variar,
utilizamos
para
devolver
el
resultado)
un
vector
de
tantos
ceros
como
valor
tenga
el
parmetro
n.
Para
ello
usamos
la
funcin
zeros(x)
de
MATLAB,
que
construye
un
vector
con
x
ceros.
Luego,
colocamos
sendos
unos
en
la
primera
y
segunda
posiciones.
A
continuacin,
recorremos
el
vector
desde
la
posicin
3
hasta
el
final,
colocando
en
cada
una
la
suma
de
las
dos
posiciones
anteriores.
function fib=vectorFibonacci(n)
fib=zeros(1, n)
fib(1) = 1;
fib(2) = 1;
for i = 3 : n
fib(i) = fib(i-1) + fib(i-2);
end
end
Funcin
30
El
resultado
es
el
siguiente:
>>
vectorFibonacci(8)
ans
=
1
1
2
3
5
8
13
21
Figura
17
Solucin 2.
31
32
Solucin 1.
33
Solucin 2.
>>
rand
ans
=
0.017483539523425
>>
rand
ans
=
0.918297137138448
Figura 19
Si
deseamos
generar
un
nmero
al
azar
entre
0
y
10,
basta
con
escribir
rand*10.
Por
otro
lado,
si
queremos
generar
una
matriz
de
nxm
nmeros
aleatorios,
escribiramos
rand(n,
m).
Por
ejemplo,
a
continuacin
generamos
una
matriz
de
4x3:
34
>>
rand(4,3)
ans
=
0.887620611199764
0.561801676019808
0.674758140355275
0.17367398659238
0.107561794984856
0.373326492462255
0.379791754484912
0.446083836222534
0.30283659962261
0.405999530454979
0.99179953529122
0.673265764196007
Figura
20
Solucin 3.
Una
solucin
ms
elegante
pasa
por
utilizar
las
funciones
de
MATLAB
para
manipulacin
de
vectores
y
matrices.
Supongamos
que
disponemos
del
siguiente
vector,
en
el
que
hay
algunos
elementos
repetidos:
posicin
1
2
3
4
5
6
7
8
9
10
x=
1
2
3
1
4
8
-1
6
7
1
Si
escribimos
x
en
la
consola
de
MATLAB,
sabemos
que
nos
muestra
los
elementos
del
vector.
Si
escribimos
(por
ejemplo)
x-5,
MATLAB
nos
muestra
como
resultado
un
vector
en
el
que
ha
restado
5
a
todos
los
elementos
del
vector
original,
x.
Es
decir:
35
>>
x-5
ans
=
-4
-3
-2
-4
-1
3
-6
1
2
-4
Figura
21
Para
irnos
aproximando
a
la
solucin
del
ejercicio,
podemos
pedirle
a
MATLAB
que
nos
muestre
el
resultado
de
restar
a
todos
los
elementos
de
x
el
primer
elemento
del
vector:
>>
x-x(1)
ans
=
0
1
2
0
3
7
-2
5
6
0
Figura
22
Ahora
podemos
medirle
a
MATLAB
que,
al
vector
obtenido
en
la
Figura
24,
le
reste
el
valor
que
tenemos
en
la
posicin
1
del
vector
x:
36
Realmente,
nos
interesa
conocer
el
valor
mnimo
del
vector
que
construimos
en
la
Figura
25,
en
el
que
no
estbamos
considerando
el
primer
elemento:
>>
x(1,
2:length(x))-x(1)
ans
=
1
2
0
3
7
-2
5
6
0
>>
min(x(1,
2:length(x))-x(1))
ans
=
-2
Figura
27
37
Ahora
s,
en
la
figura
anterior
tenemos
localizado
el
menor
valor
del
vector
que
procede
de
calcular
el
valor
absoluto
de
restar
a
los
elementos
2
a
ltimo
de
x
el
valor
x(1).
El
vector
original,
x,
era
este:
posicin
x=
1
1
2
2
3
3
4
1
5
4
6
8
7
-1
8
6
9
7
10
1
Las
transformaciones
que
hemos
ido
haciendo
para
adaptarlo
a
nuestras
necesidades
han
sido:
posicin
x(1,
2:length(x)=
x(1,
2:length(x))-x(1)=
abs(x(1,
2:length(x))-x(1))
1
2
1
1
2
3
2
2
3
1
0
0
4
4
3
3
5
8
7
7
6
-1
-2
2
7
6
5
5
8
7
6
6
9
1
0
0
Ahora
necesitamos
encontrar
en
qu
posicin
se
encuentra
el
menor
valor
del
vector
abs(x(1,
2:length(x))-x(1)).
Para
encontrar
valores
en
un
vector,
MATLAB
dispone
de
la
funcin
find,
que
devuelve
un
vector
con
las
posiciones
de
los
elementos
que
cumplen
cierta
condicin.
En
la
figura
siguiente
buscamos
todas
las
apariciones
del
valor
1
en
el
vector
x:
nos
dice
que
el
valor
1
aparece
en
las
posiciones
1,
4
y
10.
Este
resultado
(1,
4,
10)
es
devuelto
en
forma
de
vector.
>>
x
x
=
1
2
3
1
4
8
-1
6
7
1
>>
find(x==1)
ans
=
1
4
10
Figura
29
38
>>
find(abs(x(1,
2:length(x))-x(1))==min(abs(x(1,
2:length(x))-x(1))))
ans
=
3
9
Figura
30
Nos
interesa
realmente
quedarnos
slo
con
el
primer
elemento.
Como
el
resultado
devuelto
por
find
es
un
vector,
extraemos
el
primer
elemento:
primero,
asignamos
a
una
variable
auxiliar,
a
la
que
llamamos
z,
el
vector
que
contiene
las
posiciones
del
valor
mnimo;
luego,
leemos
el
primer
elemento
de
ese
vector
z.
>>
z=find(abs(x(1,
2:length(x))-x(1))==min(abs(x(1,
2:length(x))-x(1))))
z
=
3
9
>>
z(1)
ans
=
3
Figura
31
Para
ir
terminando,
recordemos
que
el
valor
que
nos
interesa
devolver
tiene
que
hacer
referencia
a
la
posicin
en
el
vector
original,
x.
Por
ello,
devolveremos
realmente
z(1)+1:
>>
z(1)+1
ans
=
4
Figura
32
39
40
Solucin 1.
Un
nmero
es
primo
cuando
slo
puede
dividirse
por
s
mismo
y
por
1.
Un
nmero
es
divisible
por
otro
cuando
el
resto
de
la
divisin
entera
es
0.
Ya
vimos
que
MATLAB
dispone
de
la
funcin
mod(x,
y),
que
devuelve
el
resto
de
la
divisin
entera
de
x
entre
y.
Una
primera
forma
de
resolver
el
problema
es
ir
dividiendo
el
nmero
n
por
1,
por
3,
etctera,
hasta
llegar
a
n.
Si
el
nmero
de
divisores
encontrados
es
2,
entonces
el
nmero
es
primo:
function result = esPrimo1(n)
numeroDeDivisores=0;
for i=1:n
if mod(n, i)==0
numeroDeDivisores=numeroDeDivisores+1;
end
end
if numeroDeDivisores==2
result=1;
else
result=0;
end
end
Figura
34
Un
pequeo
cambio
que
podemos
hacerle
a
la
funcin
est
en
el
ltimo
if:
en
lugar
de
preguntar
cuntos
divisores
hay
y
asignar
a
result,
podemos
asignar
directamente
el
resultado
de
computar
numeroDeDivisores==2,
que
devuelve
1
o
0
en
funcin
de
que
el
resultado
sea
cierto
o
falso:
function result = esPrimo1(n)
numeroDeDivisores=0;
for i=1:n
if mod(n, i)==0
numeroDeDivisores=numeroDeDivisores+1;
end
end
result= numeroDeDivisores==2;
end
Funcin
35
41
Solucin 2.
Solucin 3.
Solucin 4.
42
end
i=i+1;
end
result= numeroDeDivisores==0;
toc;
end
Funcin
38
Solucin 5.
Una
ltima
posicin
pasa
por
el
uso
de
la
funcin
isprime(x)
de
MATLAB,
que
devuelve
1
si
x
es
primo
y
0
en
caso
contrario.
43
Solucin 1 (errnea).
Obsrvese
que
usamos
(en
la
Funcin
39)
la
funcin
de
MATLAB
isPrime,
en
lugar
de
cualquiera
de
las
que
hemos
escrito
antes.
Solucin 2.
44
45
Ejercicio
15. Vector
con
los
n
primeros
nmeros
primos
ordenados
de
mayor
a
menor
Escriba
una
funcin
que
devuelva
un
vector
con
los
n
primeros
nmeros
primos
ordenados
de
mayor
a
menor.
Solucin 1.
Para
resolver
este
ejercicio
podemos
aadir
una
sencilla
lnea
al
cdigo
de
la
Funcin
40
(pgina
45),
en
la
que
llamamos
a
la
funcin
sort
de
MATLAB.
sort
ordena
un
vector
o
una
matriz
de
menor
a
mayor
pero,
si
utilizamos
el
parmetro
descend,
lo
ordena
descendentemente:
function result = vectorNPrimerosPrimosOrdenado1(n)
result=[];
i=1;
while (length(result)<n)
if (isprime(i))
result=[result i];
end
i=i+1;
end
result=sort(result, 'descend');
end
Funcin
41
Solucin 2.
En
el
cdigo
anterior,
en
la
lnea
que
hay
dentro
del
if,
aadimos
cada
valor
de
i
que
vamos
encontrando
al
final
del
vector
(result=[result
i]).
En
lugar
de
hacer
eso,
podemos
aadirlo
al
principio,
escribiendo
result=[i
result]:
function result = vectorNPrimerosPrimosOrdenado2(n)
result=[];
i=1;
while (length(result)<n)
if (isprime(i))
result=[i result];
end
i=i+1;
end
end
Funcin
42
46
>>
vectorNPrimerosPrimosOrdenado2(10)
ans
=
29
23
19
17
13
11
7
5
3
2
Figura 38
47
Solucin 1.
48
Solucin 1.
1
1
1
2
2
2
3
3
3
4
1
4
5
4
8
6
8
-1
7
-1
6
8
6
7
9
7
10
1
La
solucin
podemos
implementarla
como
en
la
Funcin
44:
creamos
el
vector
auxiliar
vaco;
luego,
en
el
bucle,
almacenamos
en
un
vector
aparicionesDeVi
las
veces
que
aparece
el
nmero
v(i)
en
el
vector
auxiliar.
Si
no
aparece
ninguna
vez
(es
decir,
si
la
longitud
del
vector
aparicionesDeVi
es
cero),
entonces
lo
aadimos.
Al
final,
devolvemos
la
longitud
del
vector
auxiliar
como
resultado.
function result = numerosDistintos1( v )
auxiliar=[];
for i=1:length(v)
aparicionesDeVi=find(auxiliar==v(i));
if length(aparicionesDeVi)==0
auxiliar=[auxiliar v(i)];
end
end
result=length(auxiliar);
end
Funcin
44
>>
z=[1
1
1
1
2
3
1]
z
=
1
1
1
1
2
3
1
>>
numerosDistintos1(z)
ans
=
3
49
Solucin 1.
Vamos
a
proceder
exactamente
de
la
misma
forma,
aprovechando
la
funcin
enesimoPrimo
que
escribimos
en
la
Funcin
43
(pgina
48):
mientras
el
cociente
(que
inicialmente
es
n,
pero
que
se
va
actualizando
segn
vayamos
encontrando
factores
primos)
sea
distinto
de
1,
buscamos
(en
el
while
anidado)
el
primer
nmero
primo
que
divide
al
cociente:
cuando
lo
encontramos,
lo
aadimos
al
vector
result
y
actualizamos
el
cociente
al
valor
que
tena
dividido
por
el
nmero
primo
que
acabamos
de
encontrar.
function result = factoresPrimos1( n )
result=[];
cociente=n;
while (cociente~=1)
i=1;
while (mod(cociente, enesimoPrimo(i))~=0)
i=i+1;
end
result=[result enesimoPrimo(i)];
cociente=floor(cociente/enesimoPrimo(i));
end
end
Funcin
45.
Clculo
de
los
factores
primos
de
n
50
>>
factoresPrimos1(120)
ans
=
2
2
2
3
5
>>
factoresPrimos1(27)
ans
=
3
3
3
Figura 40
51
3
1
5
1
Solucin 1.
Del
ejercicio
anterior
tenemos
la
funcin
que
devuelve
un
vector
con
los
factores
primos
del
n
que
pasamos
como
parmetro.
Del
120,
por
ejemplo,
obtenemos
el
siguiente
vector:
posicin
1
2
3
4
5
result=
2
2
2
3
5
Lo
que
haremos
ser
escribir
una
nueva
funcin
que
haga
lo
siguiente:
1) Guardaremos
los
factores
primos
de
n
en
un
vector
factores,
que
construiremos
llamando
a
la
Funcin
45
(pagina
50).
2) Crearemos
dos
vectores:
uno
para
guardar
los
factores
que
encontremos
(el
2,
el
3
y
el
5
en
el
ejemplo
del
nmero
120)
y
otro
para
guardar
los
exponentes
(3,
1
y
1
en
el
mismo
ejemplo).
Llamaremos
a
estos
vectores,
respectivamente,
filaFactores
y
filaExponentes.
Cuando
los
hayamos
completado,
los
utilizaremos
para
devolver
la
matriz
resultante.
3) Recorreremos
todos
los
valores
que
tengamos
en
el
vector
factores.
Si
el
valor
i-simo
no
est
en
filaFactores,
lo
aadimos
al
final
y
aadimos
tambin
un
1
al
final
de
filaExponentes.
Si
el
valor
ya
estuviera,
entonces
basta
con
incrementar
en
uno
el
valor
correspondiente
en
filaExponentes.
4) Finalmente,
devolveremos
una
matriz
formada
por
filaFactores
y
FilaExponentes.
Esto
es
lo
que
se
hace
en
la
funcin
siguiente:
52
Hagamos
una
traza
de
ejemplo
con
el
nmero
120.
Como
detalle,
ntese
que
en
la
variable
posicionDelFactor
guardamos
el
resultado
de
ejecutar
la
funcin
find
de
MATLAB,
que
devuelve
un
vector
con
las
posiciones
de
los
elementos
que
cumplen
cierta
condicin.
Si
ninguno
de
los
elementos
la
cumple,
posicionDelFactor
estar
vaco.
Comentarios
factores
i
factorI
posicionDelFactor
filaFactores
filaExponentes
[2
2
2
3
5]
[
]
[
]
1
2
[
]
El
if
es
cierto
1
2
[
]
[
2
]
[
1
]
2
2
[
1
]
[
2
]
[
1
]
El
if
es
falso
2
2
[
1
]
[
2
]
[
2
]
3
2
[
1
]
[
2
]
[
2]
El
if
es
falso
3
2
[
1
]
[
2
]
[
3
]
4
3
[
]
[
2
]
[
3
]
El
if
es
cierto
4
3
[
]
[
2
3
]
[
3
1
]
5
5
[
]
[
2
3
]
[
3
1
]
El
if
es
cierto
5
5
[
]
[
2
3
5]
[
3
1
1
]
Y
aqu
se
termina
el
bucle
porque
se
ha
llegado
a
i=5,
que
es
la
longitud
del
vector
de
entrada.
Figura
41.
Traza
de
la
Funcin
46
para
n=120
53
Solucin 1.
48=243
60=2235
2
4
3
1
m60
2
2
3
1
5
1
Lo
que
vamos
a
hacer
es
recorrer
los
factores
(la
fila
1)
de
m48
y
ver
si
estn
en
los
factores
de
m60.
En
caso
afirmativo,
aadiremos
a
una
variable
result
de
acumulacin
el
factor
comn
multiplicado
por
el
menor
exponente
de
los
dos.
function result = mcd1(n, m)
fpN=factoresPrimos2(n);
fpM=factoresPrimos2(m);
factoresN=fpN(1, :);
exponentesN=fpN(2, :);
factoresM=fpM(1, :);
exponentesM=fpM(2, :);
result=1;
for i=1:length(factoresN)
posicionEnM=find(factoresM==factoresN(i));
if (length(posicionEnM)>0)
exponente=min(exponentesN(i),
exponentesM(posicionEnM(1)));
result=result*factoresN(i)^exponente;
end
end
end
Funcin
47
Solucin 2.
Otra
solucin
elegante
viene
dada
por
la
aplicacin
del
algoritmo
de
Euclides:
para
calcular
el
mcd
de
n
y
m
se
hace
lo
siguiente:
54
55
Solucin 1.
56
Solucin 1.
1
2
3
4
5
6
1
*
2
*
*
3
*
*
4
A
5
*
*
6
*
*
7
*
8
Hecha
esta
observacin,
la
solucin
es
muy
sencilla:
7
*
*
8
*
>>
alfil(4,
1)
ans
=
BNB*BNBN
NB*BNBNB
B*BNBNBN
*BNBNBNB
B*BNBNBN
NB*BNBNB
BNB*BNBN
NBNB*BNB
Figura 44
57
Ntese
que,
si
pasamos
los
valores
de
los
parmetros
intercambiados
(en
lugar
de
4,1
pasamos
1,4),
el
resultado
de
la
derecha
de
la
figura
anterior
cambia:
>>
alfil(4,
4)
ans
=
*NBNBN*N
N*NBN*NB
BN*N*NBN
NBN*NBNB
BN*N*NBN
N*NBN*NB
*NBNBN*N
NBNBNBN*
>>
alfil(1,4)
ans
=
BNB*BNBN
NB*B*BNB
B*BNB*BN
*BNBNB*B
BNBNBNB*
NBNBNBNB
BNBNBNBN
NBNBNBNB
Figura
45.
El
resultado
derecho
de
la
Figura
44
cambia
si
alteramos
el
orden
del
valor
de
los
parmetros
Solucin 2.
58
Solucin 3.
Es
importante
que
el
cdigo
que
escribamos
sea
legible,
fcil
de
usar
por
terceras
personas
y,
en
la
medida
de
lo
posible,
fcil
de
entender.
Respecto
del
cdigo
de
las
dos
soluciones
que
hemos
dado
para
el
movimiento
del
alfil,
un
pequeo
detalle
mejorable
es
que
la
funcin
reciba
los
parmetros
en
el
mismo
orden
en
que
se
utilizan
en
las
matrices
de
MATLAB:
es
decir,
si
MATLAB
usa
la
notacin
fila,
columna
para
colocar
un
valor
en
la
matriz,
queda
mejor
que
la
funcin
alfil
tome
tambin
los
parmetros
en
ese
orden.
Esto
har
ms
difcil
que
el
usuario
de
nuestra
funcin
se
equivoque.
59
Ya
que
los
valores
de
los
parmetros
col
y
fila
se
usan
slo
para
realizar
asignaciones,
podemos
modificar
la
cabecera
de
la
funcin
para
que
los
parmetros
se
pasen
en
el
orden
habitual.
Es
decir,
dejar
la
cabecera
como
en
la
Funcin
52:
function t = alfil3( fila, col)
% Todo el cdigo de la funcin exactamente igual
end
Funcin
52.
La
misma
Funcin
51,
pero
con
los
parmetros
intercambiados
60
Solucin 1.
1
2
3
4
5
6
7
8
1
2
*
*
3
*
*
4
C
5
*
*
6
*
*
7
8
Por
cambiar
un
poco
el
punto
de
vista
de
la
solucin
respecto
del
ejercicio
anterior
del
alfil,
haremos
ahora
lo
siguiente:
1) A
partir
de
la
posicin
inicial
(que
vendr
en
el
orden
fila,
col),
moveremos
una
columna
a
la
derecha
(en
el
ejemplo
de
arriba,
iremos
a
la
casilla
4,5).
Una
vez
aqu,
colocamos
un
asterisco
dos
filas
arriba
y
dos
filas
abajo.
As,
habremos
colocado
los
asteriscos
en
(2,5)
y
(6,5).
2) Volvemos
a
la
posicin
inicial
y
movemos
dos
casillas
a
la
derecha.
Luego,
colocamos
el
asterisco
una
fila
arriba
y
una
fila
abajo.
3) Otra
vez
desde
la
posicin
inicial,
nos
movemos
una
a
la
izquierda
y
colocamos
un
asterisco
dos
filas
arriba
y
dos
filas
abajo.
4) Por
ltimo,
nos
movemos
dos
columnas
a
la
izquierda
y
colocamos
el
asterisco
dos
filas
arriba
y
dos
filas
abajo.
Obviamente,
tenemos
que
controlar
que
no
nos
salgamos
de
los
lmites
del
tablero,
que
vienen
dados
por
los
valores
1
a
8
para
la
fila
y
la
columna.
La
solucin
que
damos
en
la
Funcin
53
simula
estos
cuatro
bloques
de
movimientos.
Utilizamos
dos
variables
auxiliares
i
y
j
para
denotar
respectivamente
la
fila
y
columna
en
que
debemos
colocar
los
asteriscos.
En
el
primero,
por
ejemplo,
asignamos
a
j
el
valor
del
parmetro
col
incrementado
en
1;
si
estamos
dentro
del
tablero
(es
decir,
si
j<=8),
entonces
restamos
2
a
la
fila
(variable
i),
volvemos
a
comprobar
que
estamos
dentro
del
tablero
(i>=1)
y,
en
caso
afirmativo,
colocamos
el
asterisco.
Hacemos
a
continuacin
lo
mismo
para
la
casilla
situada
dos
filas
por
debajo
de
la
original
(i=fila+2).
61
62
Solucin 2.
Si
nos
fijamos
en
los
bloques
de
cdigo
de
la
Funcin
53,
vemos
que
los
dos
movimientos
a
la
derecha
son
casi
exactamente
iguales
entre
s,
como
tambin
los
dos
movimientos
a
la
izquierda.
En
la
Figura
46
resaltamos
en
amarillo
las
diferencias
entre
los
movimientos
hacia
la
derecha:
cuando
se
suma
1
a
la
columna,
se
resta
y
suma
2
a
la
fila;
cuando
se
suma
2
a
la
columna,
se
resta
y
suma
1
a
la
fila.
% 1 a la derecha, 2 arriba y
abajo
j=col+1;
if j<=8
i=fila-2;
if i>=1
t(i, j)='*';
end
i=fila+2;
if (i<=8)
t(i, j)='*';
end
end
% 2 a la derecha, 1 arriba y
abajo
j=col+2;
if j<=8
i=fila-1;
if i>=1
t(i, j)='*';
end
i=fila+1;
if (i<=8)
t(i, j)='*';
end
end
Podemos
agrupar
los
dos
trozos
de
cdigo
en
uno
solo,
con
un
bucle
for
cuya
variable
de
control,
a
la
que
podemos
llamar
suma,
vaya
desde
1
hasta
2
y
que
utilizaremos
para
sumarla
a
la
variable
j.
Es
decir,
sustituir
ambos
fragmentos
de
cdigo
por
uno
solo,
como
en
la
Figura
47:
% Movimientos a la derecha
for suma=1:2
j=col+suma;
if j<=8
i=fila-2; % Si suma=1, restar 2; si suma=2, restar 1
if i>=1
t(i, j)='*';
end
i=fila+2; % Si suma=1, sumar 2; si suma=2, sumar 1
if (i<=8)
t(i, j)='*';
end
end
end
Figura
47.
Paso
1
del
agrupamiento
en
uno
de
los
dos
bloques
de
la
Figura
46
63
64
Observa
que,
con
objeto
de
facilitar
la
lectura
del
resultado,
en
el
cdigo
anterior
hemos
sustituido
la
llamada
a
la
funcin
tablero()
por
una
inicializacin
del
tablero
mediante
guiones,
y
que
hemos
aadido
una
instruccin
(resaltada
en
morado)
para
colocar
una
C
en
el
lugar
en
que
se
encuentra
el
caballo.
Dos
ejemplos
de
ejecucin
son
los
siguientes:
65
>>
caballo2(4,
4)
ans
=
--------
--*-*---
-*---*--
---C----
-*---*--
--*-*---
--------
--------
>>
caballo2(4,
8)
ans
=
--------
------*-
-----*--
-------C
-----*--
------*-
--------
--------
Figura 48
Solucin 3.
En
una
vuelta
de
tuerca
ms,
vemos
tambin
semejanzas
entre
los
dos
bucles
for
de
la
Funcin
55.
Como
vemos
en
la
Figura
49,
en
uno
llamamos
a
la
variable
suma
y
en
otro
resta
(en
amarillo);
otra
diferencia
(en
morado),
es
que
en
uno
sumamos
y
en
otro
restamos;
la
ltima
diferencia
(en
verde)
es
que
en
uno
comparamos
j<=8
y
en
otro
j>=1.
% Movimientos a la derecha
for suma=1:2
j=col+suma;
if j<=8
i=fila-(3-suma);
if i>=1
t(i, j)='*';
end
i=fila+(3-suma);
if (i<=8)
t(i, j)='*';
end
end
end
% Movimientos a la izquierda
for resta=1:2
j=col-resta;
if j>=1
i=fila-(3-resta);
if i>=1
t(i, j)='*';
end
i=fila+(3-resta);
if (i<=8)
t(i, j)='*';
end
end
end
Figura 49. Los bucles de los movimientos a la derecha y a la izquierda son muy parecidos
Bueno,
pues
es
sencillo
agrupar
ambos
bucles,
como
se
hace
en
la
Funcin
56:
las
dos
condiciones
(en
verde)
las
agrupamos
en
una
sola
(j>=1
&&
j<=8);
como
una
vez
nos
interesa
sumar
y
otra
restar,
nos
inventamos
una
variable
nueva
signo
que
tome
valor
-1
y
+1
y
que
usamos
como
variable
de
control
de
un
nuevo
bucle
for
(en
amarillo);
esta
variable
signo
la
utilizamos
(en
morado)
para
multiplicar
por
factor,
que
sustituye
a
las
antiguas
variables
suma
y
resta.
66
67
Solucin 1.
Solucin 2.
68
69
Solucin 1.
>>
diag(M)
ans
=
1
6
11
16
Figura 51. Construccin de una matriz (izquierda) y extraccin de su diagonal principal con diag
Como
el
enunciado
nos
prohbe
usar
la
funcin
diag,
recorreremos
con
un
solo
buce
for
controlado
por
una
variable
i
las
posiciones
(i,
i):
function diagonal = diagonalPrincipal(M)
diagonal=[];
for i=1:length(M)
diagonal=[diagonal M(i, i)];
end
end
Funcin
59.
Extraccin
de
la
diagonal
principal
>>
diagonalPrincipal(M)
ans
=
1
6
11
16
Figura 52
70
Solucin 2.
Supongamos
que
debemos
comprobar
que
la
matriz
que
se
pasa
como
parmetro
sea
cuadrada.
Si
tenemos
la
siguiente
matriz
no
cuadrada
N:
1
2
3
1
1
2
3
2
4
5
6
3
7
8
9
4
10
11
12
La
funcin
length(N)
nos
devuelve
el
nmero
de
filas
de
la
matriz:
>>
N=[1
2
3;
4
5
6;
7
8
9;
10
11
12]
N
=
1
2
3
4
5
6
7
8
9
10
11
12
>>
length(N)
ans
=
4
Figura 54. Extraccin de la fila 1 de la matriz N (izquierda) y clculo de la longitud de esa fila
71
>>
N
N
=
1
2
3
4
5
6
7
8
9
10
11
12
>>
diagonalPrincipal(N)
La
matriz
debe
ser
cuadrada
Figura 55. Resultado de diagonalPrincipal sobre una matriz cuadrada (izquierda) y una no cuadrada
72
Solucin 1.
Solucin 2.
Solucin 3.
Por
ltimo,
en
lugar
de
sumar
los
elementos
con
un
bucle,
como
hacemos
en
la
Funcin
62
y
en
la
Funcin
63,
podemos
sumar
mediante
la
funcin
sum
de
MATLAB:
73
74
1
1
0
1
0
1
0
2
0
1
0
1
0
1
3
1
0
1
0
1
0
4
0
1
0
1
0
1
5
1
0
1
0
1
0
6
0
1
0
1
0
1
Solucin 1.
Solucin 2.
Igual
que
nos
pasaba
en
el
ejercicio
sobre
los
movimientos
del
caballo
(pgina
61),
los
dos
bucles
son
muy
parecidos.
Si
los
comparamos
(Figura
57),
observamos
que
si,
en
los
dos
bucles
de
la
izquierda,
escribimos
n
en
lugar
de
n-1,
el
resultado
sigue
siendo
vlido.
75
% Filas impares
for fila=1:2:n-1
for columna=1:2:n-1
result(fila, columna)=1;
end
end
% Filas pares
for fila=2:2:n
for columna=2:2:n
result(fila, columna)=1;
end
end
Figura 57. Los bucles de las filas nones y las pares son muy parecidos
Es
decir,
que
podemos
modificar
el
bucle
de
la
izquierda
para
que
quede
como
se
muestra:
% Filas impares
for fila=1:2:n
for columna=1:2:n
result(fila, columna)=1;
end
end
% Filas pares
for fila=2:2:n
for columna=2:2:n
result(fila, columna)=1;
end
end
Figura 58. Los bucles de las filas nones y las pares son muy parecidos
Ambos
bucles
pueden
agruparse
en
uno
solo,
que
recorra
todas
las
filas
(desde
1
hasta
n)
y
que
acte
de
diferente
manera
segn
la
fila
sea
impar
o
par
(es
decir,
segn
mod(fila,
2)
sea
1
o
0):
function result = alternar2(n)
if mod(n, 2)~=0
disp('n debe ser par');
end
result=zeros(n);
for fila=1:n
if mod(fila, 2)==1 % Si la fila es impar
for columna=1:2:n
result(fila, columna)=1;
end
else
% Si es par
for columna=2:2:n
result(fila, columna)=1;
end
end
end
end
Funcin
68.
Unos
y
ceros
alternados
(II)
Solucin 3.
76
Solucin 4.
77
Solucin 5.
Solucin 6.
Igual
que
hemos
rellenado
por
filas
en
la
solucin
anterior
(Funcin
71),
tambin
podemos
rellenar
por
columnas.
En
este
caso
inicializamos
dos
variables
columnaImpar
y
columnaPar
y,
luego,
recorremos
todas
las
columnas,
sustituyendo
por
la
que
corresponda.
78
Figura 59. Sustitucin de una fila (nmero, dos puntos) y de una columna (dos puntos, columna)
Solucin 7.
79
80
!!
!!
!!
!!
1!
2!
3!
4!
1!
2!
3!
4!
1!
2!
3!
4!
Solucin 1.
>>
v.^5
ans
=
1
32
243
1024
Figura 60. En el lado derecho obtenemos el vector v de la izquierda, con todos sus valores elevados a 5
81
>>
v
v
=
1
2
3
4
>>
vandermonde1(v,
5)
ans
=
1
1
1
1
1
1
2
4
8
16
1
3
9
27
81
1
4
16
64
256
Figura
61
Solucin 2.
82
!
!
!"
!
!
!"
Solucin 1.
En
una
primera
solucin,
recorremos
todas
las
posiciones
de
la
matriz
con
dos
bucles
for
anidados.
Por
cada
iteracin
vamos
incrementando
un
contador,
que
utilizamos
para
calcular
el
valor
que
corresponda.
Podemos
utilizar
cualquiera
de
las
funciones
de
Fibonacci
que
implementamos
en
ejercicios
anteriores:
function result = matrizFibonacci1(n)
result=[];
contador=1;
for fila=1:n
for col=1:n
result(fila, col)=fib(contador);
contador=contador+1;
end
end
end
Funcin
77.
Matriz
de
Fibonacci,
utilizando
una
funcin
auxiliar
>>
matrizFibonacci1(5)
ans
=
1
1
2
3
5
8
13
21
34
55
89
144
233
377
610
987
1597
2584
4181
6765
10946
17711
28657
46368
75025
Figura 62
Solucin 2.
83
Solucin 3.
En
una
solucin
parecida
a
la
anterior,
pero
algo
ms
sencilla,
eliminamos
los
dos
if
y,
en
lugar
de
comenzar
el
bucle
anidado
en
col=1,
lo
empezamos
en
col=3:
function result = matrizFibonacci3(n)
result=[];
result(1, 1)=1;
result(1, 2)=1;
for col=3:n
result(1, col)=result(1, col-2)+result(1, col-1);
end
for fila=2:n
result(fila, 1)=result(fila-1, n-1)+result(fila-1, n);
result(fila, 2)=result(fila-1, n)+result(fila, 1);
for col=3:n
result(fila, col)=result(fila, col-2)+
result(fila, col-1);
end
end
end
Funcin
79.
Matriz
de
Fibonacci,
computada
mediante
la
suma
de
las
dos
posiciones
anteriores
(II)
84
Solucin 1.
!!!
!!"
!!!
!!!
!!!
!!!
!!"
!!!
!
!"
!!!
!!"
!!!
!!!
!!!
!!!
!!"
Podemos
comprobar
que
la
funcin
est
bien
hecha
pidindole
a
MATLAB
que
nos
diga
si
todos
los
elementos
de
la
matriz
R
coinciden
con
todos
los
elementos
que
MATLAB
calcula
para
M*N:
en
la
figura
siguiente
mostramos
dos
matrices
M
y
N;
ms
abajo,
los
resultados
de
ejecutar
nuestra
funcin
(izquierda)
y
de
ejecutar
la
funcin
de
multiplicacin
de
matrices
de
MATLAB
(M*N);
en
la
fila
inferior,
le
pedimos
a
MATLAB
que
compare
los
dos
resultados
utilizando
el
operador
de
85
comparacin
(==):
el
resultado
(una
matriz
de
unos)
indica
que
ambas
matrices
son
iguales
y
que,
por
tanto,
hemos
implementado
bien
el
cdigo
de
la
funcin.
>>
M
M
=
1
4
7
10
2
5
8
11
3
6
9
12
>>
productoDeMatrices(M,
N)
ans
=
166
188
210
188
214
240
210
240
270
>>
productoDeMatrices(M,
N)==M*N
ans
=
1
1
1
1
1
1
1
1
1
>>
N
N
=
1
2
3
4
5
6
7
8
9
10
11
12
>>
M*N
ans
=
166
188
210
188
214
240
210
240
270
Figura 63
Solucin 2.
Podemos
modificar
un
poco
el
cdigo
anterior:
una
vez
que
tenemos
la
fila
de
M
(y
que
guardamos,
por
ejemplo,
en
un
vector
llamado
filaDeM)
y
la
columna
de
N
(que
guardamos
en
columnaDeN),
podemos
hacer
directamente
el
producto
de
ambos
vectores:
function R = productoDeMatrices2(M, N)
filasM=length(M(:, 1));
columnasN=length(N(1, :));
R=zeros(filasM, columnasN);
for i=1:filasM
filaDeM=M(i, :);
for j=1:columnasN
columnaDeN=N(:, j);
R(i, j)=filaDeM*columnaDeN;
end
end
end
Funcin
81.
Multiplicacin
de
matrices
aprovechando
el
producto
vectorial
86
1
1
1
1
1
2
0
1
2
3
3
0
0
1
2
4
0
0
0
1
Solucin 1.
En
primer
lugar,
construimos
una
matriz
de
nxn
llena
de
ceros.
Luego,
colocamos
1
en
la
primera
columna.
Despus,
para
cada
columna
desde
2
hasta
n,
colocamos
en
cada
casilla
el
valor
que
haya
en
la
fila
superior.
Por
ejemplo,
ubicados
en
la
segunda
columna
y
segunda
fila
(marcada
a
continuacin
en
amarillo),
colocamos
en
esa
posicin
el
valor
que
tiene
encima
ms
1.
1
2
3
4
1
1
0
0
0
2
1
0
0
0
3
1
0
0
0
4
1
0
0
0
De
este
modo,
la
matriz
quedar
de
la
siguiente
manera:
1
2
3
4
1
1
0
0
0
2
1
1
0
0
3
1
0
0
0
4
1
0
0
0
A
continuacin,
bajamos
a
la
celda
resaltada
a
continuacin
en
amarillo
y,
en
ella,
colocamos
el
1
que
tiene
encima
ms
1:
1
2
3
4
1
1
0
0
0
2
1
1
0
0
3
1
2
0
0
4
1
0
0
0
Continuamos
de
esa
manera
hasta
llegar
a
la
ltima
fila.
Luego,
pasamos
a
la
columna
3
y
a
la
fila
3.
Proseguimos
de
la
misma
manera
hasta
recorrer
todas
las
columnas:
87
Solucin 2.
Podemos
partir
tambin
de
una
matriz
identidad
con
la
primera
columna
a
1.
Por
ejemplo:
1
2
3
4
5
1
1
0
0
0
0
2
1
1
0
0
0
3
1
0
1
0
0
4
1
0
0
1
0
5
1
0
0
0
1
Para
completar
esta
matriz
basta
con
comenzar
por
la
fila
3.
Adems,
para
completar
cada
fila
empezaremos
en
la
columna
2
y
llegaremos
hasta
la
columna
que
coincida
con
la
fila-1:
en
la
fila
4,
por
ejemplo,
ponemos
valores
desde
la
columna
2
hasta
la
columna
3;
en
la
fila
5,
desde
la
2
hasta
la
4.
Con
esta
idea,
podemos
rellenar
exactamente
de
la
misma
manera
que
antes:
function result = tartaglia2( n)
result=eye(n);
result(:, 1)=ones(n, 1);
for fila=3:n
for col=2:fila-1
result(fila, col)=result(fila-1, col)+1;
end
end
end
Funcin
83.
El
tringulo
de
Tartaglia,
rellenando
ahora
por
filas
Solucin 3.
Podemos
rellenar
la
matriz
de
otra
manera.
Si
nos
fijamos,
por
ejemplo,
en
la
fila
5,
el
primer
valor
que
debemos
colocar
en
la
columna
2
es
el
nmero
de
fila-1;
el
siguiente,
en
la
columna
3,
es
el
nmero
de
fila-2;
luego,
en
la
columna
4,
el
nmero
de
fila-3:
en
general,
colocamos
el
nmero
de
fila
menos
el
nmero
de
columna
decrementado
en
1.
88
1
2
3
4
5
1
1
1
1
1
1
2
0
1
3-(2-1)
4-(2-1)
5-(2-1)
3
0
0
1
4-(3-1)
5-(3-1)
4
0
0
0
1
5-(4-1)
5
0
0
0
0
1
En
otras
palabras:
function result = tartaglia3( n)
result=eye(n);
result(:, 1)=ones(n, 1);
for fila=3:n
for col=2:fila-1
result(fila, col)=fila-(col-1);
end
end
end
Funcin
84.
El
tringulo
de
Tartaglia,
rellenando
de
otra
manera
89
1
2
3
4
5
1 2 3 4 5 6 7
*
*
*
*
*
*
*
*
*
*
*
*
*
*
1 2 3 4 5 6 7 8 9
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
Solucin 1.
1 2 3 4 5 6 7 8 9
*
*
90
n-fila+1+(2*n-1)-
2*(n-fila)
result
1
2
3
4
5
6
7
1
*
*
*
*
*
*
*
2
*
*
*
*
*
*
*
3
*
*
*
*
*
*
*
4
*
*
*
*
*
*
*
1
2
3
4
5
6
7
1
*
*
*
*
*
*
2
*
*
*
*
*
*
*
3
*
*
*
*
*
*
*
4
*
*
*
*
*
*
*
1
2
3
4
5
6
7
1
*
*
*
*
*
2
*
*
*
*
*
*
*
3
*
*
*
*
*
*
*
4
*
*
*
*
*
*
*
1
2
3
4
5
6
7
1
*
*
*
*
2
*
*
*
*
*
*
*
3
*
*
*
*
*
*
*
4
*
*
*
*
*
*
*
91
Comentarios
Llegamos
al
bucle
verde
n-fila+1+(2*n-1)-
2*(n-fila)
result
4-1+1+(2*4-1)-2*(4-
1)=5
1
2
3
1
2
*
*
*
3
*
*
*
4
*
*
*
1
2
3
1
2
*
*
*
3
*
*
*
4
*
*
*
1
2
3
1
2
*
*
*
3
*
*
*
4
*
*
*
1
2
3
1
2
*
*
3
*
*
*
4
*
*
*
4 5 6 7
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
4 5 6 7
*
*
*
*
*
*
*
*
*
*
*
*
*
*
4 5 6 7
*
*
*
*
*
*
*
*
*
*
*
*
*
4 5 6 7
*
*
*
*
*
*
*
*
*
*
*
*
*
1
2
3
4
5
6
7
1
*
2
*
*
*
*
*
3
*
*
*
*
*
*
*
4
*
*
*
*
*
*
*
Solucin 2.
92
Solucin 3.
Podemos
analizar
el
problema
por
columnas
en
lugar
de
por
filas.
Para
n=5,
observamos
que
en
la
columna
1
hay
1
asterisco
abajo
del
todo;
en
la
2,
2
asteriscos
abajo
del
todo;
llegamos
as
hasta
la
columna
5,
en
la
que
hay
5
asteriscos.
En
la
6
hay
4;
en
la
7,
3;
en
la
8,
2;
y
en
la
9,
1.
1
2
3
4
5
1 2 3 4 5 6 7 8 9
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
En
la
siguiente
funcin,
construimos
la
matriz
de
caracteres
y,
con
objeto
de
apreciar
mejor
el
resultado,
la
rellenamos
con
guiones
en
lugar
de
con
blancos.
A
continuacin,
en
el
bucle
amarillo,
construimos
una
variable
hilera
que
usaremos
para
almacenar
el
contenido
de
cada
columna.
A
continuacin,
recorremos
la
matriz
desde
las
columnas
1
a
n
y
colocamos
en
hilera
los
asteriscos
que
hagan
falta
para
la
columna
que
corresponda
(bucle
verde).
Por
ltimo,
colocamos
la
hilera
recin
formada
en
la
columna
izquierda
(col)
y
en
su
simtrica
derecha
(2*n-
col):
93
>>
trianguloEquilatero3(10)
ans
=
---------*----------------***--------------*****------------*******----------*********--------***********------*************----***************--************************************
Figura 65
94
!
!
!
!
!
!
!
!
!
!
!
!
!
!!
!!
!
!
!
!
Solucin 1.
Podemos
partir
de
una
matriz
identidad.
Luego,
en
cada
fila,
recorremos
desde
la
columna
fila+1
hasta
la
columna
n,
colocando
en
cada
casilla
el
nmero
que
tenga
a
la
izquierda
incrementado
en
1:
function result = triangularSuperior1(n)
result=eye(n);
for fila=1:n
for col=fila+1:n
result(fila, col)=result(fila, col-1)+1;
end
end
end
Funcin
88.
Matriz
triangular
superior,
rellenando
por
filas
y
empezando
con
una
matriz
identidad
Y
el
resultado
es:
>>
triangularSuperior1(5)
ans
=
1
2
3
4
5
0
1
2
3
4
0
0
1
2
3
0
0
0
1
2
0
0
0
0
1
Figura
66
Solucin 2.
Tambin
podemos
partir
de
una
matriz
de
ceros
y
rellenar
cada
fila
de
forma
parecida:
en
cada
fila,
empezaremos
en
la
columna
fila
desde
1
hasta
n.
El
cdigo,
en
principio,
podra
ser
el
siguiente:
95
Solucin 3.
96
Solucin 4.
Solucin 5.
Quiz
la
solucin
ms
sencilla
sea
la
siguiente:
si
nos
fijamos,
el
valor
que
aparece
en
cada
casilla
del
tringulo
superior
es
la
diferencia
entre
el
nmero
de
columna
y
el
nmero
de
fila
ms
1:
1
2
3
4
5
2-1+1
3-3+1
4-2+1
Por tanto:
97
function r=triangularSuperior5(n)
r=[];
for fila=1:n
for col=fila:n
r(fila, col)=col-fila+1;
end
end
end
Funcin
93.
Una
solucin
sencilla
para
la
Matriz
triangular
superior
98
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
Solucin 1.
Este
ejercicio
es
una
generalizacin
del
anterior:
ahora
se
trata
de
rellenar
no
slo
el
tringulo
superior,
sino
tambin
el
inferior.
Partiendo
de
la
ltima
solucin
dada
al
ejercicio
de
la
matriz
triangular
superior,
el
valor
que
debemos
colocar
en
cada
casilla
es
abs(col-fila)+1:
function r=diagonalesQueSeIncrementan1(n)
r=[];
for fila=1:n
for col=1:n
r(fila, col)=abs(col-fila)+1;
end
end
end
Funcin
94
Solucin 2.
99
>>
diagonalesQueSeIncrementan2(8)
ans
=
1
0
0
0
0
0
0
0
2
1
0
0
0
0
0
0
3
2
1
0
0
0
0
0
4
3
2
1
0
0
0
0
5
4
3
2
1
0
0
0
6
5
4
3
2
1
0
0
7
6
5
4
3
2
1
0
8
7
6
5
4
3
2
1
Figura
68.
Al
ejecutar
el
cdigo
de
la
Funcin
95,
obtenemos
el
tringulo
inferior
Para
completar
el
resto,
nos
podemos
fijar
en
algunas
de
las
soluciones
dadas
al
Ejercicio
33
y
completar
el
cdigo:
function r=diagonalesQueSeIncrementan2(n)
r=[];
for col=1:n
valor=1;
for fila=col:n
r(fila, col)=valor;
valor=valor+1;
end
end
for fila=1:n
for col=fila+1:n
r(fila, col)=r(fila, col-1)+1;
end
end
end
Funcin
96.
La
Funcin
95,
completada
para
que
se
rellene
el
tringulo
superior
Solucin 3.
Del
ejercicio
anterior
tenemos
varias
funciones
para
construir
la
matriz
triangular
superior,
y
con
la
Funcin
95
construimos
la
triangular
inferior.
Podemos
combinar
los
resultados
de
ambas
funciones
en
una
sola
matriz:
lo
que
haremos
ser
tomar,
de
cada
matriz,
el
mximo
valor
de
la
misma
posicin:
Triangular
superior
Triangular
inferior
1
2
3
4
5
1
0
0
0
0
0
1
2
3
4
2
1
0
0
0
0
0
1
2
3
3
2
1
0
0
0
0
0
1
2
4
3
2
1
0
0
0
0
0
1
5
4
3
2
1
Esto
es
lo
que
hacemos
en
la
funcin
siguiente
mediante
la
funcin
max
de
MATLAB:
100
function r=diagonalesQueSeIncrementan3(n)
r=max(triangularInferior1(n), triangularSuperior1(n));
end
Funcin
97.
Construccin
de
la
matriz
pedida
a
partir
de
las
dos
triangulares
101
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!"
!
!
!
!
Solucin 1.
function r=diagonalesQueSeIncrementanB1(n, m)
r=diagonalesQueSeIncrementan1(n);
for fila=1:n
for col=1:n
r(fila, col)=r(fila, col)+m-1;
end
end
end
Funcin
98
102
1
1
5
9
13
2
2
6
10
14
3
3
7
11
15
4
4
8
12
16
Solucin 1.
Solucin 2.
103
function r = numerosOrdenados2(n)
r=zeros(n);
for col=1:n
r(1, col)=col;
end
for col=1:n
for fila=2:n
r(fila, col)=r(fila-1, col)+n;
end
end
end
Funcin
100
104
1
16
12
8
4
2
15
11
7
3
3
14
10
6
2
4
13
9
5
1
Solucin 1.
Solucin 2.
105
1
1
8
9
16
2
2
7
10
15
3
3
6
11
14
4
4
5
12
13
Solucin 1.
Si
nos
fijamos
en
la
matriz
de
ejemplo,
los
valores
en
las
filas
impares
son
crecientes,
y
decrecientes
en
las
pares.
Podemos
ir
recorriendo
la
matriz
por
filas:
si
la
fila
es
impar,
recorremos
sus
casillas
desde
la
columna
1
hasta
la
n;
si
es
par,
recorremos
desde
la
n
hasta
la
1.
En
cada
casilla,
colocamos
un
valor
que
inicializamos
a
1
y
que
vamos
incrementando
en
cada
iteracin.
function r = zigzag(n)
r=zeros(n);
valor=1;
for fila=1:n
if mod(fila, 2)==1
for col=1:n
r(fila, col)=valor;
valor=valor+1;
end
else
for col=n:-1:1
r(fila, col)=valor;
valor=valor+1;
end
end
end
end
Funcin
103
106
1
4
3
2
3
4
2
3
2
1
2
3
3
2
1
0
1
2
4
3
2
1
2
3
5
4
3
2
3
4
Solucin 1.
Solucin 2.
107
108
function r = distancias2(n)
r=zeros(n);
mitad=(n+1)/2;
for fila=1:mitad-1
r(fila, mitad)=mitad-fila;
end
for fila=mitad+1:n
r(fila, mitad)=fila-mitad;
end
for col=mitad-1:-1:1
for fila=1:n
r(fila, col)=r(fila, col+1)+1;
end
end
end
Funcin
106.
Completamos
el
cdigo
de
la
Error!
No
se
encuentra
el
origen
de
la
referencia.
para
completar
la
mitad
izquierda
Y, ya por ltimo, completamos con otro bucle para rellenar la mitad derecha:
109
function r = distancias2(n)
r=zeros(n);
mitad=(n+1)/2;
for fila=1:mitad-1
r(fila, mitad)=mitad-fila;
end
for fila=mitad+1:n
r(fila, mitad)=fila-mitad;
end
for col=mitad-1:-1:1
for fila=1:n
r(fila, col)=r(fila, col+1)+1;
end
end
for col=mitad+1:n
for fila=1:n
r(fila, col)=r(fila, col-1)+1;
end
end
end
Funcin
107
110
1
e
d
c
d
e
2
d
c
b
c
d
3
c
b
a
b
c
4
d
c
b
c
d
5
e
d
c
d
e
Solucin 1.
Para
plantear
la
solucin,
debemos
saber
primero
que
cada
carcter
de
los
que
manipula
MATLAB
tiene
un
nmero
entero
asociado
(lo
que
se
llama
el
cdigo
ASCII).
As,
por
ejemplo,
las
letras
maysculas
empiezan
en
el
65
(la
A)
y
terminan
en
el
90
(la
Z).
Las
minsculas
empiezan
en
la
97.
El
siguiente
programa
muestra
los
caracteres
que
corresponden
a
cada
valor
numrico:
function caracteres()
for i=1:255
linea=[int2str(i), '-> ', char(i)];
disp(linea);
end
end
Funcin
108.
Programa
para
sacar
la
lista
de
cdigos
ASCII
111
function r = distanciaEnLetras1(n)
r=char(n);
mitad=(n+1)/2;
for fila=1:n
for col=1:n
distancia=abs(fila-mitad)+abs(col-mitad);
r(fila, col)=char(97+distancia);
end
end
end
Funcin
109
112
Solucin 1.
MATLAB
trata
las
cadenas
de
caracteres
como
vectores.
Para
el
ejemplo
anterior,
se
trata
de
buscar
un
subvector
dentro
de
un
vector.
1
2
3
4
5
6
7
P r o b l
8 9 10 11 12 13 14 15 16 17 18 19
e m a s
Si
el
patrn
que
buscamos
(MATLAB,
en
el
ejemplo)
tiene
6
caracteres,
el
problema
se
reduce
a
extraer
subvectores
de
6
caracteres
de
la
cadena
grande
empezando
en
la
posicin
1.
Si
lo
encontramos
en
esa
posicin,
devolvemos
un
1;
si
no,
avanzamos
hasta
la
2.
Continuamos
as
hasta
que
lo
encontremos
o
hasta
que
lleguemos
a
una
posicin
desde
la
que
no
podamos
leer
6
caracteres
(es
decir,
la
15).
El
ejercicio
podemos
resolverlo
de
la
siguiente
forma:
en
posicionFinal
guardamos
la
posicin
del
ltimo
carcter
a
partir
del
cual
no
podemos
seguir
buscando
(14,
en
el
ejemplo);
luego,
entramos
a
un
while
en
el
que
permaneceremos
hasta
encontrar
el
patrn
o
hasta
que,
sin
encontrarlo,
lleguemos
a
la
posicionFinal.
Dentro
del
bucle,
vamos
extrayendo
subcadenas,
desde
la
posicin
i,
de
la
misma
longitud
que
el
patrn,
y
las
comparamos
con
el
patron.
La
comparacin
la
hacemos
con
la
funcin
strcmp
de
MATLAB,
que
devuelve
1
si
las
dos
cadenas
que
se
pasan
como
parmetros
son
iguales
y
0
en
caso
contrario.
function r = encontrar1(texto, patron)
r=-1;
i=1;
posicionFinal=length(texto)-length(patron)+1;
while (r==-1 && i<=posicionFinal)
subcadena=texto(1, i:i+length(patron)-1);
if strcmp(subcadena, patron)==1
r=i;
end
i=i+1;
end
end
Funcin
110.
Bsqueda
de
un
patrn
en
una
cadena
113
Comentario
Antes
del
while
Entramos
al
while
r
-1
-1
-1
-1
-1
i
1
1
2
3
4
posFinal
14
14
14
14
14
patron
MATLAB
MATLAB
MATLAB
MATLAB
MATLAB
subcadena
Proble
roblem
oblema
blemas
Con
denotamos
el
espacio
en
blanco
-1
14
MATLAB
lemas-
-1
-1
-1
-1
-1
-1
-1
-1
6
7
8
9
10
11
12
13
14
14
14
14
14
14
14
14
MATLAB
MATLAB
MATLAB
MATLAB
MATLAB
MATLAB
MATLAB
MATLAB
emas-d
mas-de
as-de-
s-de-M
-de-MA
de-MAT
e-MATL
-MATLA
14
14
14
MATLAB
MATLAB
strcmp
devuelve
1,
pues
patron
es
igual
a
subcadena
114
1 2 3 4 5 6 7
P r o b l
8 9 10 11 12 13 14 15 16 17 18 19
e m a s
sin
espacios
1 2 3 4 5 6 7
P r o b l
8 9 10 11 12 13 14 15 16 17
e m a s d
El
siguiente
trozo
de
cdigo
realiza
la
funcin
descrita:
crea
la
variable
auxiliar
como
un
vector
de
caracteres;
luego,
recorre
el
texto
original
y,
si
el
carcter
no
es
una
espacio,
lo
aade
a
auxiliar.
function r = palindromo1(texto)
auxiliar=char();
pos=1;
for i=1:length(texto)
if (~isspace(texto(i)))
auxiliar(pos)=texto(i);
pos=pos+1;
end
end
auxiliar
end
Funcin
111.
Primero
eliminamos
los
espacios
en
blanco
115
116
8 9 10 11 12 13 14 15 16 17
P
r
o
b
l
e
m
a
s
d
8
caracteres
>>
texto
texto
=
Problemas
de
MATLAB
>>
palindromo1(texto)
dondeParar
=
8
1
A
2
3
4
B
C
D
4
caracteres
5
D
A
T
L
8
caracteres
6
7
8
C
B
A
4
caracteres
>>
palindromo1('ABCDDCBA')
dondeParar
=
4
Figura
74.
Determinacin
de
dondeParar
en
funcin
de
la
longitud
par
o
non
de
la
cadena
117
function r = palindromo1(texto)
auxiliar=char();
pos=1;
for i=1:length(texto)
if (~isspace(texto(i)))
auxiliar(pos)=texto(i);
pos=pos+1;
end
end
if mod(length(auxiliar), 2)==1
dondeParar=floor(length(auxiliar)/2);
else
dondeParar=length(auxiliar)/2;
end
r=1;
for i=1:dondeParar
caracterIzda=auxiliar(i);
caracterDcha=auxiliar(length(auxiliar)-i+1);
if caracterIzda~=caracterDcha
r=0;
end
end
end
Funcin
113.
Determinacin
de
si
el
texto
es
o
no
palndromo
con
un
bucle
for
dondeParar r
Estamos
en
8
1
la
lnea
r=1
Entramos
al
8
1
1
P
B
bucle
En
el
if
8
0
1
P
B
Falso
marcado
en
verde.
r
se
pone
a
0
Reentramos
8
0
2
r
A
Falso
en
el
bucle
y
comparamos
en
el
if
verde
8
0
3
o
L
Falso
8
0
4
b
T
Falso
8
0
5
l
A
Falso
8
0
6
e
M
Falso
8
0
7
m
e
Falso
8
0
8
a
d
Falso
En
este
punto
se
alcanza
la
condicin
de
parada
del
bucle,
pues
i=8=dondeParar.
La
funcin
termina
con
r=0,
que
es
el
valor
que
se
devuelve.
Si
bien
el
cdigo
que
hemos
mostrado
funciona,
lo
cierto
es
que
puede
modificarse
para
que
sea
ms
eficiente:
en
efecto,
ya
desde
la
primera
comparacin
que
118
Solucin 2.
Solucin 3.
Para
mejorar
el
rendimiento
de
la
funcin,
que
pare
en
cuanto
se
sepa
que
el
texto
no
es
un
palndromo
y
evitar
colocar,
como
hemos
hecho
en
la
ltima
solucin,
una
salida
incondicional,
sustituiremos
el
ltimo
bucle
for
de
la
Funcin
113
por
otra
estructura
de
control,
de
manera
que
la
comparacin
de
los
caracteres
se
ejecute
mientras
los
que
se
estn
comparando
sean
iguales.
119
Solucin 4.
120
function r = palindromo4(texto)
delDerecho=char();
pos=1;
for i=1:length(texto)
if (~isspace(texto(i)))
delDerecho(pos)=texto(i);
pos=pos+1;
end
end
delReves=char();
for i=1:length(delDerecho)
delReves(i)=delDerecho(length(delDerecho)-i+1);
end
delDerecho
delReves
r=delDerecho==delReves;
end
Funcin
116.
Solucin
(incompleta)
al
problema
del
palndromo
mediante
la
comparacin
de
dos
vectores
>>
palindromo4('dualidad')
delDerecho
=
dualidad
delReves
=
dadilaud
ans
=
1
0
0
0
0
0
0
1
Figura 75
121
122
end
r= (sum(delDerecho==delReves)==length(delDerecho));
end
Funcin
118.
Sustituimos
varias
lneas
del
final
de
la
Funcin
117
por
una
sola
6
o
o
1
7
c
c
1
8
e
e
1
9
r
r
1
123
Solucin 1.
Los
dos
vectores
siguientes
(de
longitudes
par
e
impar)
son
,
segn
la
definicin
anterior,
montes:
1
a
2
b
3
c
4
d
5
d
6
c
7
b
8
a
1
a
2
b
3
c
4
d
5
c
6
b
7
a
Muy
resumidamente,
podramos
escribir
de
la
siguiente
forma
la
expresin
para
determinar
si
un
vector
v
es
un
monte:
esPalindromo(v)
y
estaOrdenado(mitad(v,
I))
y
estaOrdenado(alReves(mitad(v,
D)))
124
function r = estaOrdenado(v)
r=1;
for i=2:length(v)
if v(i)<v(i-1)
r=0;
return;
end
end
end
Funcin
120.
Determinamos
si
el
vector
est
ordenado
La
funcin
mitad
toma
dos
parmetros:
el
vector
del
que
queremos
extraer
la
mitad
y
un
carcter
que
representa
qu
mitad
queremos
extraer:
la
izquierda
(I)
o
la
derecha
(D):
function r = mitad(v, lado)
if mod(length(v), 2)==0
pararEn=length(v)/2;
else
pararEn=floor(length(v)/2);
end
if lado=='D'
pararEn=length(v)-pararEn+1;
end
r=[];
if lado=='I'
for i=1:pararEn
r=[r v(i)];
end
else
for i=length(v):-1:pararEn
r=[v(i) r];
end
end
end
Funcin
121.
Extraccin
de
la
mitad
izquierda
o
derecha
de
un
vector
125
Solucin 2.
Si
observamos
los
ejemplos
anteriores,
nos
damos
cuenta
de
que,
en
realidad,
para
determinar
si
un
vector
es
un
monte
basta
con
comprobar
si
es
un
palndromo
y
si
est
ordenada
su
mitad
izquierda
pues,
si
sta
est
ordenada
y
todo
el
vector
es
un
palndromo,
forzosamente
la
mitad
derecha
estar
ordenada
de
manera
decreciente.
Es
decir,
que
a
la
conjuncin
de
funciones
que
escribamos
en
la
Funcin
119
(pgina
124)
le
podemos
quitar
la
ltima
llamada:
function r = monte(v)
r=palindromo4(v) && estaOrdenado(mitad(v, 'I'));
% && estaOrdenado(alReves(mitad(v, 'D')));
end
Funcin
123.
No
es
necesario
comprobar
el
orden
en
la
mitad
derecha
Solucin 3.
Supongamos
ahora
que
queremos
saber
los
motivos
por
los
que
el
vector
no
es
un
monte:
puede
ser
que
no
sea
un
palndromo
o
sus
dos
mitades
no
estn
ordenadas.
En
este
caso,
deberamos
aadir
alguna
instruccin
para
que
se
muestren
los
correspondientes
mensajes.
Las
funciones
palindromo4
(que
es
la
que
utilizamos)
y
estaOrdenado
quedan
como
sigue:
126
function r = palindromo4(texto)
delDerecho=char();
pos=1;
for i=1:length(texto)
if (~isspace(texto(i)))
delDerecho(pos)=texto(i);
pos=pos+1;
end
end
delReves=char();
for i=1:length(delDerecho)
delReves(i)=delDerecho(length(delDerecho)-i+1);
end
r= (sum(delDerecho==delReves)==length(delDerecho));
if r==0
disp('No es un monte porque:');
disp('-No es un palndromo');
end
end
function r = estaOrdenado(v)
r=1;
for i=2:length(v)
if v(i)<v(i-1)
r=0;
disp('-No est ordenado');
return;
end
end
end
Funcin
124.
Instrucciones
adicionales
para
mostrar
mensajes
Ahora,
al
ejecutar
la
funcin
monte
(Funcin
123)
con
el
vector
v=[1
2
1
4
3
2],
esperamos
que
nos
diga
que
no
es
un
monte
porque
no
es
un
palndromo
y
adems
no
est
ordenado.
Sin
embargo,
al
ejecutarla
con
ese
ejemplo,
el
resultado
es:
>>
v=[1
2
1
4
3
2]
v
=
1
2
1
4
3
2
>>
monte(v)
No
es
un
monte
porque:
-No
es
un
palndromo
ans
=
0
Figura
78
127
Como
vemos,
se
nos
da
slo
uno
de
los
dos
mensajes
que
esperbamos.
Esto
sucede
porque,
en
la
Funcin
123,
las
llamadas
a
palindromo4
y
a
estaOrdenado
estn
separadas
con
&&:
al
usar
estos
dos
smbolos
para
enlazar
dos
condiciones,
MATLAB
detiene
la
ejecucin
en
el
momento
en
que
encuentra
una
falsa.
En
el
ejemplo
de
v=[1
2
3
1
2
3],
puesto
que
el
vector
no
es
un
palndromo,
ya
no
se
evala
la
segunda
funcin,
que
determina
el
orden.
Para
que
se
evalen
todas
las
condiciones
debemos
usar
un
solo
&:
function r = monte(v)
r=palindromo4(v) & estaOrdenado(mitad(v, 'I'));
end
Funcin
125.
Con
un
solo
ampersand,
siempre
se
evalan
ambas
funciones
>>
v
v
=
1
2
1
4
3
2
>>
monte(v)
No
es
un
monte
porque:
-No
es
un
palndromo
ans
=
0
>>
v
v
=
1
2
1
4
3
2
>>
monte(v)
No
es
un
monte
porque:
-No
es
un
palndromo
-No
est
ordenado
ans
=
0
Figura 79. Los resultados pueden ser diferentes segn usemos & o &&
128
Scrculo
dardoscrculo
Scuadrado
dardostotales
dardoscrculo
dardostotales
dardoscrculo
dardostotales
Solucin 1.
129
function result=piMontecarlo(n)
nd=0;
result=0;
for i=1:1:n
if rand()<=0.5
signoX=-1;
else
signoX=+1;
end
if rand()<=0.5
signoY=-1;
else
signoY=+1;
end
x=rand()*signoX;
y=rand()*signoY;
if (x^2+y^2<=1)
nd=nd+1;
end
end
result=4*nd/n;
end
Funcin
126.
Clculo
aproximado
de
mediante
el
mtodo
de
Montecarlo
Dos
ejecuciones
distintas
de
la
funcin
para
n=100.000
nos
dan
los
siguientes
resultados:
>>
piMontecarlo(100000)
ans
=
3.14316
>>
piMontecarlo(100000)
ans
=
3.14436
Solucin 2.
Puesto
que,
al
determinar
si
el
dardo
est
dentro
o
fuera
elevamos
al
cuadrado
las
dos
coordenadas
del
dardo
(lneas
en
verde
de
la
funcin
anterior),
no
es
preciso
generar
el
signo,
pues
en
la
comparacin
la
suma
no
ser
nunca
un
nmero
negativo.
Por
tanto,
el
cdigo
puede
simplificarse
sin
perder
efectividad:
130
function result=piMontecarlo2(n)
nd=0;
result=0;
for i=1:1:n
x=rand();
y=rand();
if (x^2+y^2<=1)
nd=nd+1;
end
end
result=4*nd/n;
end
Funcin
127.
La
Funcin
126
puede
simplificarse
y
no
generar
signos
para
las
coordenadas
Solucin 3.
131
En
el
cdigo
anterio
se
marcan
en
amarillo
las
instrucciones
plot
y
hold
on.
sta
es
necesaria
para
que
todos
los
puntos
se
pinten
en
la
misma
ventana.
En
azul
aparecen
tres
lneas
que
utilizamos
para
dibujar
un
crculo
rojo
de
radio
1:
en
la
primera
creamos
un
vector
t
con
todos
los
valores
desde
0
hasta
2
incrementando
de
/30
en
/30.
En
la
segunda
creamos
dos
vectores
x
e
y
con,
respectivamente,
el
coseno
y
el
seno
de
cada
valor
almacenado
en
t.
Finalmente,
en
la
tercera
dibujamos,
en
rojo
(red)
los
vectores
que
acabamos
de
calcular
y
que
tenemos
almacenados
en
x
e
y.
El
resultado
por
consola
es:
>>
piMontecarlo3(100000)
ans
=
3.14636
Figura
82
Figura
83.
Representacin
de
la
circunferencia
goniomtrica
y
los
100.000
dardos
lanzados
132
S
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
E
Solucin 1.
133
el resultado es:
134
Solucin 2.
Supongamos
que
se
desea
que
la
salida
de
la
funcin
muestre
las
casillas
que
ha
recorrido
el
objeto
para
llegar
desde
la
entrada
a
la
salida.
En
este
caso,
una
vez
calculados
los
movimientos
necesarios,
debemos
recorrer
este
vector,
tomar
cada
una
de
sus
coordenadas
y
colocar,
en
las
posiciones
que
indique,
algn
valor
(el
2,
por
ejemplo)
sobre
el
laberinto,
de
manera
que
se
representen
las
casillas
visitadas.
Esto
es
lo
que
hacemos
en
la
Funcin
130
con
el
bucle
aadido
al
final:
recorremos
el
vector
de
movimientos
(formado
a
su
vez
por
vectores
de
dos
coordenadas)
y,
para
cada
coordenada
contenida
en
l,
vamos
a
la
posicin
correspondiente
en
el
laberinto
y
colocamos
el
valor
2.
Finalmente,
asignamos
el
nuevo
laberinto
a
la
variable
camino,
que
es
la
variable
que
devuelve
el
resultado
de
la
funcin.
135
136
Solucin 1.
137
function r = busquedaBinaria1(v, x)
r=-1;
li=1;
ls=length(v);
iteraciones=0;
while r==-1 && li<=ls
mitad=floor((ls+li)/2);
if v(mitad)==x
r=mitad;
elseif v(mitad)<x
li=mitad+1;
else
ls=mitad-1;
end
iteraciones=iteraciones+1;
end
disp(['Valor encontrado en ' int2str(iteraciones)
' iteraciones']);
end
Funcin
132.
Bsqueda
binaria
iterativa
con
indicacin
del
nmero
de
iteraciones
Solucin 2.
138
function r = busquedaBinaria2(v, x)
r=-1;
li=1;
ls=length(v);
mitad=floor((ls+li)/2);
if li>ls
r=-1;
return
elseif v(mitad)==x
r=1;
return;
elseif v(mitad)<x
li=mitad+1;
else
ls=mitad-1;
end
auxiliar=v(1, li:ls);
r=busquedaBinaria2(auxiliar, x);
end
Funcin
133.
Implementacin
recursiva
de
la
bsqueda
binaria
1
2
15
18
En
este
tercer
nivel
de
recursividad,
r=-1,
li=1,
ls=2,
mitad=1.
Como
v(1)=15<20,
li=1+1=2
y
auxiliar=[18],
llamndose
nuevamente
a
la
funcin:
v=
139
1
18
Ahora,
r=-1,
li=1,
ls=1,
mitad=1.
Como
v(1)=18<20,
se
hace
li=2
y
recortamos
el
vector
desde
la
posicin
2
hasta
la
1,
obteniendo
un
vector
vaco,
con
el
cual
llamamos
nuevamente
a
la
funcin:
v=
v=
En
esta
nueva
llamada,
r=-1,
li=1,
ls=0,
mitad=0.
Se
evala
el
primer
caso
base
de
la
recursividad
(li>ls)
y,
como
la
condicin
es
cierta,
se
va
devolviendo
el
-1
hasta
llegar
a
la
llamada
original
desde
la
lnea
de
comando:
>>
v
v
=
2
2
4
6
7
8
8
9
15
18
>>
busquedaBinaria2(v,
20)
ans
=
-1
Figura
87.
Resultado
de
ejecutar
una
bsqueda
binaria
recursiva
en
un
vector,
con
resultado
infructuoso
140