Introducción a la programación con MATLAB 46 ejercicios resueltos con varias soluciones, todas claramente explicadas Macario Polo Usaola Profesor Titular de Lenguajes y Sistemas Informáticos en la Universidad de Castilla-‐La Mancha © Macario Polo Usaola, 2012
[email protected] 1 . ...................................................................... Calcular el enésimo número primo ..... Contar números distintos en un vector ......... 68 Ejercicio 25............................................. Unos y ceros alternados ........................................... 33 Ejercicio 13...................................... Conversión de entero a binario ......... 57 Ejercicio 23............................................................................................................................................................ Alfil .................................................................................... 13 Ejercicio 5........................................................ 31 Ejercicio 12............................ 1 Ejercicio 2.... Vector con los n primeros números primos ordenados de mayor a menor 46 Ejercicio 16.......... Descomposición en factores primos (II) .................................................................................................. ex por Taylor ............... Traza de una matriz ...................................... Vector con los n primeros números primos ........................................................................................... Máximo común divisor ................. ÍNDICE DE EJERCICIOS Ejercicio 1................... Producto escalar .......... 9 Ejercicio 4....................... Tablero de ajedrez ....................................................... 14 Ejercicio 6........................................................................................................... Factorial recursivo ........................................ seno(x) por Taylor ............................................................. Contador de apariciones ........................................................................ 75 1 ................................. 25 Ejercicio 10................................................... 19 Ejercicio 8....................................... 61 Ejercicio 24................................ 48 Ejercicio 17........................................ 73 Ejercicio 27... 52 Ejercicio 20....................................................................................................................................................................... 20 Ejercicio 9......................................... 44 Ejercicio 15..... 49 Ejercicio 18...................................................... El caballo de ajedrez .................... 41 Ejercicio 14.................................. Distancia al primero .................... Número combinatorio ................... Matriz identidad .............. Fibonacci en un vector ...................................... Descomposición en factores primos (I) .......................................................... 54 Ejercicio 21............................................................ La divina proporción .......................................................................................................................... 70 Ejercicio 26........ 50 Ejercicio 19........... Factorial iterativo . Fibonacci ............... 16 Ejercicio 7........................................................................................................................ Números primos ............................................. 7 Ejercicio 3..................................... 56 Ejercicio 22.... 28 Ejercicio 11........ Diagonal principal ................................................... .... Detección de palíndromos ......................................................................................... 103 Ejercicio 37.............................................................................. Diagonales que se incrementan (II) ............................................. 113 Ejercicio 42..................................... 115 Ejercicio 43.................................. 137 2 ........................................... 99 Ejercicio 35..................... Triángulo equilátero ................................................................................. Búsqueda binaria ............. Buscador de cadenas ............................ Distancia en letras ..... 129 Ejercicio 45. 87 Ejercicio 32.......................... Matriz de Vandermonde .......................................................... Diagonales que se incrementan (I) ...................... El monte ........... ........................................................................ Zigzag .............. 85 Ejercicio 31...................................... Distancias ..................................................... Números ordenados ................................................................................................................ 90 Ejercicio 33.......... Matriz de Fibonacci ................................. Matriz triangular superior .............. Números ordenados descendentemente .................................... Cálculo de pi (π) ... 124 Ejercicio 44... 83 Ejercicio 30. 111 Ejercicio 41............................................................................ 102 Ejercicio 36.................................................................................................. 107 Ejercicio 40....................................................................................................................................... 81 Ejercicio 29.. Producto de matrices...................................................................................................................... Triángulo de Tartaglia ....................................... Macario Polo Usaola Ejercicio 28..................... 133 Ejercicio 46.......................... 106 Ejercicio 39........... 105 Ejercicio 38........................ La salida del laberinto ............................................................................................................................................................. 95 Ejercicio 34...................... Para computar el resultado necesitamos únicamente un bucle for que vaya desde 1 hasta n de 1 en 1 (Función 1): a la función la hemos llamado factorial1 y toma un argumento1 n. ni result ni i tienen valor. 46 ejercicios resueltos de MATLAB Ejercicio 1. sin comprobación de parámetros y con un for que incrementa El bucle for i=1:1:n inicializa la variable contador i a 1 y la va incrementando de 1 en 1 hasta n (el valor del argumento pasado). Con objeto de que result vaya almacenando correctamente los valores. result toma el valor 1 pero i sigue sin estar definida. el factorial de 0 es 1. y lo único que está definido es el parámetro n. En el cuerpo del bucle se utiliza una variable acumuladora result (puede llamarse de cualquier manera. Si n no fuera entero se deberá redondear hacia +∞. Utilizaremos ambas palabras indistintamente. result sigue valiendo 1 e i toma ya valor 1. Si no se recibiese ningún argumento de entrada se deberá devolver un -‐1 y mostrar un mensaje de aviso por pantalla. La Tabla 1 muestra una traza de ejecución de la función cuando pasamos 5 como valor del parámetro n: al entrar a la función. El factorial de un número natural n es el producto de todos los números naturales desde 1 hasta ese número n. es 1·2·3·4·5=120. devuelva el factorial de dicho número. El factorial de 5. Factorial iterativo Realizar una función que. • Solución 1. Al entrar al bucle por primera vez. es necesario inicializarla a 1 antes de empezar el bucle. recibiendo como argumento de entrada un número entero n. function result = factorial1( n ) result=1. En la asignación result=1 que hay antes del bucle. por ejemplo. 1 . Un factorial sencillo. En una primera solución supondremos que el número que se pasa como argumento a la función es natural y positivo. Si n fuera menor que cero se deberá devolver también un -‐1 y mostrar un mensaje de aviso por pantalla. pero utilizaremos habitualmente result para hacer referencia al resultado que debe devolver la función) en la que iremos guardando el resultado de calcular el valor anterior de result multiplicado por el valor de i. for i=1:1:n result=result*i. Además. end end Función 1. La función factorial se representa con una admiración: n!=n·(n-‐1)·…3·2·1. 1 argumento y parámetro significan lo mismo. que es el valor de n que pasamos como parámetro y que es la condición de parada en el bucle for: for i=1:1:n Comentarios n result i Al entrar a la función 5 Al ejecutar result=1 5 1 La primera vez que entramos al bucle 5 result=result*i 1 result=1*1=1 Segunda vuelta al bucle 5 result=result*i 2 result=1*2=2 5 result=2*3=6 3 5 result=6*4=24 4 5 result=24*5=120 5 Tabla 1 Si ejecutamos la función desde la línea de comando. Un factorial sencillo. obtenemos esto: >> factorial1(5) ans = 120 Figura 1 La palabra ans que escribe MATLAB es la answer (la respuesta) al cálculo que le hemos solicitado. de -‐1 en -‐1. y a result le asignamos el valor que tenía (1) multiplicado por el valor de i: la aparición de la palabra result en el lado derecho de la instrucción result=result*i hace referencia al valor actual de result. Macario Polo Usaola En la segunda vuelta al bucle. Otra forma de implementar exactamente lo mismo es utilizar también un bucle for. for i=n:-1:1 result=result*i. sin comprobación de parámetros y con un for que decrementa 2 . function result = factorial1( n ) • Solución 2. hasta que i alcance el valor 5. Muestra un 120 porque. Se continúa de esta manera. la aparición de result en el lado izquierdo hace referencia al valor que le vamos a asignar. en la cabecera de la función asignábamos a result el resultado de la función. i se ha incrementado en 1. y precisamente es result la variable en la que vamos. Observa (Función 2) que el bucle for ha cambiado: function result = factorial2( n ) result=1. iteración a iteración. con lo que vale 2. pero que vaya desde n hasta 1. end end Función 2. haciendo ese cómputo. almacenando el resultado que deseamos. El enunciado también nos dice que. se muestre un mensaje de error personalizado. que es bastante feo: >> factorial2() ??? Input argument "n" is undefined. el resultado de llamar a la función sin argumentos es: >> factorial2() Debes dar un argumento a la función ans = -‐1 Figura 3 • Solución 4. En el enunciado del problema nos piden que. Ahora mismo se muestra el mensaje de error por defecto de MATLAB. El factorial con comprobación del número de parámetros Ahora. se dé un mensaje de aviso y se devuelva también -‐1. la función devuelva 1 y el programa termine: en la Función 3 hemos añadido unas líneas de código en las que usamos la palabra reservada nargin (que indica el número de valores pasados a la función como parámetros) para comprobar que. disp('Debes dar un argumento a la función'). function result = factorial2( n ) if (nargin==0) result=-1. Una forma de hacerlo es añadir otro if después del if que ya añadimos a la Función 3. return. en caso de que no sea así. si no pasamos ningún argumento. de manera que el código quede como en la Función 4: 3 . Error in ==> factorial2 at 3 for i=n:-‐1:1 Figura 2 Modificaremos ligeramente la función para que se compruebe que se pasan argumentos y que. el resultado de la función sea -‐1 (nos lo pide el enunciado). si n es menor que cero. se muestre un mensaje de error (uso de la función disp de MATLAB) y el programa termine (uso de return). end result=1. end end Función 3. for i=n:-1:1 result=result*i. si es 0. 46 ejercicios resueltos de MATLAB • Solución 3. se muestre un mensaje de aviso por pantalla. de manera que si el número de argumentos es 0 o n es menor que cero. se muestre un mensaje de error y se termine el cálculo. disp('Debes dar un argumento a la función'). la barra vertical). la función devuelva -‐1. Otra forma de conseguir lo mismo que en la solución anterior es colocar las dos comprobaciones (existencia de un argumento y que éste sea positivo) en un solo if: en la Función 5 unimos ambas condiciones con un or (símbolo |. return. Macario Polo Usaola function result = factorial2( n ) if (nargin==0) result=-1. end if (n<0) result=-1. por ejemplo. se muestra la siguiente respuesta: >> factorial2(-‐5) El parámetro debe ser positivo ans = -‐1 Figura 4 • Solución 5. 4 . return. for i=n:-1:1 result=result*i. end end Función 4 Si intentamos calcular. disp('El parámetro debe ser positivo'). el factorial de -‐5. end result=1. for i=n:-1:1 result=result*i. end n=ceil(n). utilizaremos la función ceil(x) de MATLAB: si x tiene decimales. si no los tiene. end end Función 5 • Solución 6. ceil(x) redondea el valor de x hacia el entero superior más próximo. result=1.85. si queremos calcular el factorial de 7. que si n no fuera entero se redondee hacia + ∞: es decir. function result = factorial2( n ) if (nargin==0 | n<0) result=-1. return. Nos piden en el enunciado. disp('Debes dar un argumento positivo a la funciÛn'). Una vez comprobado que hay un argumento positivo. deja el valor de x como está. la función se comporta correctamente: 5 . end result=1. for i=n:-1:1 result=result*i. disp('Debes dar un argumento positivo a la función'). return. 46 ejercicios resueltos de MATLAB function result = factorial2( n ) if (nargin==0 | n<0) result=-1. devolveremos el factorial de 8. por último. end end Función 6 Ahora. Macario Polo Usaola >> factorial2(4.5) ans = 120 >> factorial(5) ans = 120 Figura 5 6 . asignamos a la variable de resultado (result) el cálculo solicitado. end if (n<m) disp('n debe ser mayor o igual que m'). 46 ejercicios resueltos de MATLAB Ejercicio 2. pero en la que se realiza todo el cálculo: en los primeros tres if (marcados en amarillo) hacemos una comprobación de los argumentos. m ) if (nargin~=2) disp('Se necesitan dos argumentos'). end factorialM=1. end factorialN=1. for i=1:1:n factorialN=factorialN*i. for i=1:1:m factorialM=factorialM*i. Número combinatorio ! Escribir una función que calcule el número combinatorio . function result = numeroCombinatorio1( n. • Solución 1. En el siguiente comprobamos si m es 0 o si n==m. end if (n<0 | m<0) disp('Los argumentos deben ser positivos'). Los valores de n y m serán ! ! ! argumentos de entrada y el resultado del cálculo se devolverá como argumento de salida. end factorialNmenosM=1. end if (n==m | m==0) result=1. factorialM y factorialNmenosM. return. con lo que debemos devolver 1 como resultado. sabiendo que ! ! ! ! !! n>=m. 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 solución a la función factorial (página 1). 7 . return. return. return. Finalmente. for i=1:1:(n-m) factorialNmenosM=factorialNmenosM*i. Escribiremos primero una solución algo larga. Estos factoriales los guardamos en tres variables llamadas factorialN. = = ! y que = !!· !!! !. En una solución menos complicada podemos utilizar cualquiera de las funciones factorial que escribimos como soluciones del ejercicio 1. Si debiéramos hacer este cálculo a mano. al calcular el de n. Macario Polo Usaola end result=factorialN/(factorialM*factorialNmenosM). factorialNmenosM=factorial1(n-m). multiplicamos el valor de factorialN por el valor de factorialM que hemos calculado antes. En la instrucción siguiente. for i=n:-1:m+1 factorialN=factorialN*i. end Función 7 • Solución 2. Supongamos que nos piden !" calcular : calculamos primero factorialN=10·9·8·7·6·5·4·3·2·1 y luego ! computamos factorialM=5·4·3·2·1. que requiere menos tiempo de cómputo: en la primera línea se calcula el factorial de m. function result = numeroCombinatorio3( n. con lo que estamos repitiendo parte del cálculo del factorialN. Esto es lo que hacemos en esta solución (Función 9). m ) result=factorial1(n)/(factorial1(m)*factorial1(n-m)) end Función 8 • Solución 3. en el bucle for resaltado en amarillo. luego. end Función 9 8 . que factorialN=10·9·8·7·6·factorialM. Basta con escribir una nueva función en la que las llamamos: function result = numeroCombinatorio2( n. probablemente calcularíamos primero el factorial de m y luego. vamos guardando en factorialN el valor de multiplicar i desde n hasta el valor de m+1. de manera que nos ahorramos unas cuantas vueltas de bucle. nos detendríamos al llegar al valor de m. Es decir. Finalmente calculamos (n-‐m)! por el método tradicional y calculamos el resultado final del número combinatorio. factorialN=1. En las dos soluciones anteriores repetimos cálculos. Se han omitido las comprobaciones de argumentos para facilitar la lectura del código. m ) factorialM=factorial1(m). end factorialN=factorialN*factorialM. result=factorialN/(factorialM*factorialNmenosM). Al programar funciones de cálculo. ∀! !! !!! • Solución 1. debemos intentar imitar nuestro propio razonamiento. La serie de Taylor de la exponencial viene dada por la expresión: ! ! !! ! = . y lo que haremos será iterar. por ejemplo. Es decir: !"" ! !! !! !! !! !! !!! !!"" ! = = + + + + ⋯+ + !! !! !! !! !! !!! !""! !!! Una forma de implementar esta solución es la siguiente: function result = exponencialPorTaylor1( x ) result=0. 100 veces. for n=0:1:100 result=result+(x^n)/factorial(n). Supongamos que deseamos calcular e5 (cuyo valor es 148. 46 ejercicios resueltos de MATLAB Ejercicio 3. en muchos casos. Antes de implementar la función es conveniente plantear un ejemplo para ver cómo podemos abordar la solución. que deberá calcularse mediante su serie de Taylor truncada en n de tal forma que el error absoluto entre la serie en el término n-‐1 y n sea menor de 10-‐7. ex por Taylor Realizar una función que recibiendo como argumento de entrada un número real x devuelva el valor de la exponencial de dicho número. Para una primera solución no tendremos en cuenta esta consideración del error absoluto.4131591025764) mediante la aproximación de Taylor: ! ! !! !! !! !! !! ! = = + + + + ⋯ !! !! !! !! !! !!! Pararemos cuando la diferencia entre el término n-‐1 y el n sea menor que 0. end end Función 10 El resultado de calcular exponencialPorTaylor1(5) es: >> exponencialPorTaylor1(5) ans = 148.0000001.4132 Figura 6 9 . n=0. utilizaremos este valor (el error absoluto) como condición de parada para devolver el resultado solicitado. el resultado que se acabe de calcular con el anterior. realice el cálculo: function result = exponencialPorTaylor2( x ) result=0. por último. Luego. Con objeto de ir acercándonos a lo que nos pide el enunciado. Macario Polo Usaola • Solución 2. en cada iteración del bucle. Más adelante. disp(error). n=n+1. en cada vuelta del bucle. pero utilizando un while en lugar de un for. En la Función 12 hemos añadido unas líneas al código anterior: ya que necesitamos comparar. while (n<=100) result=result+(x^n)/factorial(n). creamos antes del while una variable ultimoResultado a la que asignamos el valor infinito (función Inf() de MATLAB). en otra solución. Diremos entonces que mientras n (que es la variable contador del bucle) sea menor o igual a 100. ultimoResultado=Inf(). Podemos escribir una solución parecida a la anterior. end end Función 11 • Solución 3. ultimoResultado=result. asignamos a una variable error la diferencia entre el último resultado calculado (almacenado en la variable ultimoResultado que hemos creado ex profeso para esto) y el resultado que se acaba de calcular. error=ultimoResultado-result. MATLAB muestra lo siguiente: >>exponencialPorTaylor3(5) 10 . n=n+1. n=0. Mostramos el error por la consola (disp(error)) y. end end Función 12 Si ejecutamos exponencialPorTaylo3(5). function result = exponencialPorTaylor3( x ) result=0. vamos a modificar ligeramente el código anterior para que la función nos muestre la diferencia entre el valor calculado para n y para n-‐1. while (n<=24) result=result+(x^n)/factorial(n). actualizamos el valor de ultimoResultado al valor que se acaba de calcular. 5 -‐20. • Solución 4. Es decir. Como lo vamos calculando en cada vuelta del bucle.509686449899135 -‐0.413159078837 Figura 7 La larga lista de números que muestra (hemos omitido bastantes ceros al final) se corresponde con los valores de error calculados en cada iteración del bucle while.5009920634921 -‐9.000156796173996554 -‐3..0233372916620453 -‐0.. Para cumplir con el enunciado. basta con que modifiquemos la condición de parada del while para que.070011874986136 -‐0.000595825461147115 -‐0.60670547556219e-‐08 0 0 .196033249961204 -‐0.0416666666667 -‐21.8333333333333 -‐26. en lugar de dar 100 vueltas fijas.00214497166010119 -‐0.00729290364438384 -‐0.38228891093473 -‐2. esté dando vueltas mientras el valor absoluto de error sea mayor o igual a 10-‐7.91990434991385e-‐05 -‐9.7013888888889 -‐15.68812003968253 -‐5.12116034958854e-‐06 -‐4. que modificamos el código para que quede como sigue: 11 .61121828720934e-‐07 -‐9.0416666666667 -‐26.69114445546737 -‐1. 0 ans= 148. el cómputo debe detenerse en el momento en que el valor absoluto del error sea menor que 10-‐7. 46 ejercicios resueltos de MATLAB Inf -‐5 -‐12.33310559503298e-‐06 -‐2.2232474797579 -‐0. error=ultimoResultado-result. error=Inf(). n=0. ultimoResultado=result. Macario Polo Usaola function result = exponencialPorTaylor4( x ) result=0. while (abs(error)>=10e-7) result=result+(x^n)/factorial(n). ultimoResultado=Inf(). n=n+1. end end Función 13 12 . resultAnterior=result. n=0. 46 ejercicios resueltos de MATLAB Ejercicio 4. La solución a este ejercicio es muy parecida a la del anterior: ya que no sabemos exactamente cuántas iteraciones debemos hacer. while (abs(error)>=10e-7) result=result+((-1)^n/factorial(2*n+1))*(x^(2*n+1)). con un bucle while. lo haremos. La condición de parada será la misma. seno(x) por Taylor Escribir una función que recibiendo como argumento de entrada un número real x devuelva el seno de dicho número. resultAnterior=Inf(). n=n+1. que deberá calcularse mediante su serie de Taylor truncada en n de tal forma que el error absoluto entre la serie en el término n-‐1 y n sea menor de 10e-‐7. function result = senoTaylor(x) result=0. como antes. error=Inf(). end end Función 14 13 . y la forma de cálculo también muy similar. La serie de Taylor del seno viene dada por la expresión: ! (−!)! !"#$ ! = !!"!! . ∀! !" + ! ! !!! • Solución 1. sino sólo la condición de parada. Cambiará únicamente la fórmula de asignación del resultado. error=abs(result-resultAnterior). un caso base. se entra al else 4 result=4* factorialRecursivo(3) 3ª llamada. return end end Función 15 Supongamos que deseamos calcular recursivamente el factorial de 5. en caso negativo. ya que: n!=n·(n-‐1)! Es decir. n entra valiendo 3 14 . Se 5 ejecuta factorialRecursivo(5) Como n no es 0. Se ejecuta 4 factorialRecursivo(4). En el caso del factorial. ya que 4!=4·3·2·1. al menos. En efecto. asignamos a result el valor 1 y la llamada a la función termina. que haga que las sucesivas llamadas a la función se detengan. en su implementación. ya que 0!=1. contiene una llamada a sí misma. La siguiente tabla muestra una traza de lo que va sucediendo al escribir en la línea de comando de MATLAB factorialRecursivo(5): Comentarios n result 1ª llamada a la función. Una función recursiva es una función que. Factorial recursivo Escribir una función que calcule el factorial de manera recursiva. return else result=n*factorialRecursivo(n-1). tal y como hacíamos arriba al escribir n!=n·(n-‐1)! function result = factorialRecursivo( n ) if (n==0) result=1. 5!=5·4·3·2·1 o. lo que es lo mismo. se entra al else 5 result=5*factorialRecursivo(4) 2ª llamada. asignamos a result el resultado de multiplicar n por el factorial de n-‐ 1. Se ejecuta 3 factorialRecursivo(3). el caso base se alcanza cuando n=0. el factorial de n es n multiplicado por el factorial de n-‐1. En las funciones debe haber siempre. En la Función 15 preguntamos que si el argumento que se está pasando es 0: en caso afirmativo. Macario Polo Usaola Ejercicio 5. n toma ahora el valor 4 Como n no es 0. La función factorial se describe recursivamente de forma muy natural. • Solución 1. 5!=5·4!. n llega valiendo 1 Como n no es 0. se entra al else 1 result=1*factorialRecursivo(0) 6ª llamada. Ahora. n vale 0 n es ahora 0. Se ejecuta 2 factorialRecursivo(2). 4 result=4*factorialRecursivo(3)=4*6=24 Regreso a la 1ª llamada. 2 result=2*factorialRecursivo(1)=1*2=1 Regreso a la 3ª llamada. Regreso a la 5ª llamada. etcétera. que a su vez se utiliza para calcular el de la 4ª. Se ejecuta 0 factorialRecursivo(0). El valor de n es 2 Como n no es 0. por lo que es cierta 0 result=1 la condición del if (n==0) En este punto se ha alcanzado el caso base. por lo que no hay más llamadas recursivas. se entra al else 2 result=2*factorialRecursivo(1) 5ª llamada. 46 ejercicios resueltos de MATLAB Comentarios n result Como n no es 0. 3 result=3*factorialRecursivo(2)=3*2=6 Regreso a la 2ª llamada. Se ejecuta 1 factorialRecursivo(1). se entra al else 3 result=3* factorialRecursivo(2) 4ª llamada. 5 result=5*factorialRecursivo(5)=5*24=120 Tabla 2 15 . 1 result=1*factorialRecursivo(0)=1*1=1 Regreso a la 4ª llamada. el valor calculado en la 6ª llamada se utiliza para calcular el valor de la 5ª llamada. elseif (n==2) result=1. podemos agruparlos en uno solo: function result=fib2(n) if (n<=2) result=1. xi=xi-‐1+xi-‐2 • Solución 1. Realmente. En estos dos casos. por ejemplo. end end Función 17. Fibonacci recursivo con dos casos base • Solución 2. Fibonacci Escribir una función que calcule el término n de la función de Fibonacci. fib(8). Para calcular a mano. x2 = 1. Obsérvense en el código anterior los dos casos base. else result=fib(n-1)+fib(n-2). Puesto que ya sabemos un poco de recursividad. el valor de la función es 1. El código puede ser el siguiente: function result=fib(n) if (n==1) result=1. marcados en amarillo. end end Función 16. else result=fib(n-1)+fib(n-2). que viene dada por: x1=1. hacemos lo siguiente: fib(8)=fib(7)+fib(6)= 16 . Macario Polo Usaola Ejercicio 6. Cualquiera de las dos soluciones que hemos dado arriba es muy costosa en términos del número de sumas que es necesario realizar. es fácil observar que la función de Fibonacci se describe muy bien de forma recursiva: fibonacci(1)=1 fibonacci(2)=1 fibonacci(n)=fibonacci(n-‐1) + fibonacci(n-‐2). si n>2 Observamos que hay dos casos base: uno con n=0 y otro con n=1. Fibonacci recursivo con un caso base • Solución 3. que resulta complicado escribirlo en forma de ecuación. y que además no utiliza recursividad. pero con las instrucciones tic y toc. si es posible. es conveniente utilizar. Versión iterativa de la función de Fibonacci • Solución 4. En la siguiente figura reproducimos el código de la Función 17 y de la Función 18. j=0. j=t. 46 ejercicios resueltos de MATLAB = [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 cómputo. es la siguiente: function result=fib3(n) i=1. for k=1:1:n t=i+j. y obsérvese que el caso base se alcanza en total 21 veces. end Función 18. y que fibonacci(8)=21. i=j. Figura 8. se puede representar de forma arborescente: nótese que hay cálculos que se repiten varias veces. correspondientes a los 21 unos que hay en el árbol. end result=j. Una versión menos compleja computacionalmente hablando. algoritmos más rápidos. Podemos comparar el tiempo dedicado por el ordenador a realizar un determinado cómputo mediante las funciones de MATLAB tic (que pone el cronómetro a cero) y toc (que lo detiene). 17 . Árbol correspondiente al cálculo tradicional de Fibonacci(8) Por ello. mucho más rápida que cualquiera de las anteriores. end Función 20 18 . averiguaremos que el término n de la función Fibonacci se corresponde también con el siguiente valor: ! ! − (1 − !)! !"# ! = 5 …en donde: 1+ 5 != 2 Así. end j=t. La versión recursiva (izquierda) y la iterativa (derecha) para calcular Fibonacci. Si investigamos un poquito. ans = ans = 6765 6765 • Solución 5.000119 seconds. for k=1:1:n end t=i+j. else j=0. result=(fi^n-(1-fi)^n)/sqrt(5). function result=fib4(n) fi=(1+sqrt(5))/2. Macario Polo Usaola function result=fib2(n) function result=fib3(n) tic. Elapsed time is 0. y luego calculamos y devolvemos el resultado. toc. result=fib2(n-1)+fib2(n-2). es la dada en la Función 20: primero se calcula el valor de Φ. i=1. if (n<=2) result=1.000005 seconds. ya que no requiere ni recursividad ni bucles. end result=j. end Función 19. toc. otra implementación de la función. anotadas con instrucciones para calcular el tiempo El resultado de ambas funciones para calcular fibonacci(20) es: >> fib2(20) >> fib3(20) Elapsed time is 0. i=j. tic. end Función 21 19 . La divina proporción es la división del término i de la serie de Fibonacci entre el anterior. • Solución 1. Habiendo ya implementado la función de Fibonacci. la resolución de este ejercicio es muy sencilla. 46 ejercicios resueltos de MATLAB Ejercicio 7. La divina proporción Se pide realizar una función que recibiendo como argumento de entrada un número entero positivo n devuelva el valor de la aproximación de la divina proporción para el término n de la serie de Fibonacci. La fórmula de cálculo es: divinaProporción(n)=fibonacci(n)/fibonacci(n-‐1) Podemos hacer uso de cualquiera las implementaciones que hemos dado a la función de Fibonacci en el ejercicio anterior. no siendo necesario reescribirla: function result = divinaProporcion( n ) result=fib4(n)/fib4(n-1). Conversión de entero a binario Escribir una función de MATLAB que. y subiendo por todos los restos: De este modo. Antes de programar. para construir la representación en base 2. Si el número no es entero. recibiendo como argumento de entrada un número entero. utilizaremos un bucle para ir dividiendo el número que obtengamos entre 2. Además. mientras que el cociente sea mayor o igual a 2. • Solución 1. obtenemos que 152=1111. represente por pantalla su equivalente en el sistema binario. Una primera aproximación a la solución es la siguiente (Función 22): 20 . Supongamos que queremos pasar a binario el número 15: lo que hacemos es ir dividiendo sucesivamente entre 2 hasta que el cociente obtenido sea 1. se mostrará un mensaje de error. De igual manera podemos calcular el 29 en base 2: Así. n. Por tanto. deberemos ir memorizando los restos que vayamos obteniendo. 292=11101. Si el número es negativo. Luego. se deberá escribir el correspondiente signo menos antes del número. veamos cómo hacemos a mano una conversión de entero a binario. recorremos desde el último cociente obtenido (1). Macario Polo Usaola Ejercicio 8. 46 ejercicios resueltos de MATLAB function result = pasarABinario( n ) cociente=n; resto=mod(cociente, 2); result=[resto]; while (cociente>=2) cociente=floor(cociente/2); resto=mod(cociente, 2); result=[resto result]; end end Función 22. Primera aproximación para la conversión a binario El código de la Función 22 tiene una novedad respecto de las funciones que hemos escrito hasta ahora: a la variable result le asignamos, en las líneas 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]) añadimos al comienzo del vector result el valor que hemos calculado del resto en esta iteración. Usamos, además, la función mod en la primera asignación al resto: resto=mod(cociente, 2). mod(x,y) devuelve el resto de la división entera de x entre y. Igualmente, usamos la función floor, que redondea un número decimal al entero inmediatamente inferior. Hagamos una traza de la función con n=12: Comentarios n cociente resto result Llamada a la función 12 Ejecución de cociente=n 12 12 Ejecución de resto=mod(cociente, 2) 12 12 0 Ejecución 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 Macario Polo Usaola Si en la consola de MATLAB ejecutamos pasarABinario(12), se nos muestra lo siguiente: >> pasarABinario(12) ans = 1 1 0 0 Figura 9 El resultado que nos está devolviendo MATLAB no es un número entero ni natural, sino un vector con cuatro valores. • Solución 2. En el enunciado del problema se nos dice que “Si el número es negativo, se deberá escribir el correspondiente signo menos antes del número”. Como sabemos, el primer dígito del número binario es el primer resto que calculamos. Lo que haremos será preguntar, después del bucle, si el número que nos pasaron como parámetro es negativo: en caso afirmativo, modificaremos el primer elemento del vector multiplicándolo por -‐1; en caso negativo, lo dejamos como está. Inicialmente, podríamos dejar esto de la siguiente manera: function result = pasarABinario2( n ) cociente=n; resto=mod(cociente, 2); result=[resto]; while (cociente>=2) cociente=floor(cociente/2); resto=mod(cociente, 2); result=[resto result]; end if (n<0) result(1)=-1*result(1); end end Función 23. La función de paso a binario con soporte para negativos, pero con un pequeño error En las líneas 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), esperaríamos la respuesta -‐1100; sin embargo, MATLAB nos responde, sorprendentemente, de la siguiente forma: 22 46 ejercicios resueltos de MATLAB >> pasarABinario2(-‐12) ans = 0 Figura 10 El error lo encontramos en la primera sentencia de la función, que necesita ser modificada: si n=-‐12, entonces por la asignación que hay a continuación se hace cociente=-‐12 y no se entra en el while, ya que no se verifica la condición. Debemos asignar, en la primera instrucción, el valor abs(n) a cociente. Es decir: function result = pasarABinario2( n ) cociente=abs(n); resto=mod(cociente, 2); result=[resto]; while (cociente>=2) cociente=floor(cociente/2); resto=mod(cociente, 2); result=[resto result]; end if (n<0) result(1)=-1*result(1); end end Figura 11. La función de paso a binario con soporte para negativos, ahora corregida • Solución 3. En el enunciado también se nos dice que, si el número que se pasa como parámetro no es entero, se debe dar un mensaje de error. Una forma de comprobar esto es preguntar si el parámetro n es igual a la parte entera del propio n, es decir: 23 end cociente=abs(n). end end Función 24 24 . resto=mod(cociente. end if (n<0) result(1)=-1*result(1). 2). Macario Polo Usaola function result = pasarABinario3( n ) if (n~=floor(n)) error('Se esperaba un entero'). while (cociente>=2) cociente=floor(cociente/2). resto=mod(cociente. result=[resto]. return. result=[resto result]. 2). una para asignar a una variable x el vector. leeríamos el valor de la posición 1. luego. almacenamos 1 en un contador. dejamos el contador como está. Una implementación de esta solución es la siguiente (Función 25): utilizamos como contador la variable result. pasamos a la posición 3 y. en la que incrementamos el contador hasta 4. como no es 1. En el cuerpo del bucle tomamos en la variable vi el valor i-‐ésimo del vector. Una primera versión de la función para contar el número de apariciones Para ejecutar la función con el vector dado como ejemplo y para que busque el valor 1. veamos cómo haríamos esto a mano. n ) result=0. y que devuelva el número de veces que n está contenido en el vector v. for i=1:1:length(vector) vi=vector(i). luego recorremos todas las posiciones del vector con un bucle for que va desde 1 hasta su longitud (length(vector)). en la que hacemos que contador sea 3. la posición 11. que ya vale 2. y que deseamos contar las apariciones de n=1. como contiene un 1. como es 1. Supongamos que tenemos el vector v= {1 2 1 3 4 1 2 5 6 4 1}. incrementamos en uno el contador. Contador de apariciones Escribir una función de MATLAB que tome como entradas un vector de números enteros v y un número entero n. end end end Función 25. lo comparamos con n y. incrementamos el resultado. Posición 1 2 3 4 5 6 7 8 9 10 11 Valor 1 2 1 3 4 1 2 5 6 4 1 A mano. 46 ejercicios resueltos de MATLAB Ejercicio 9. y seguimos hasta el final del vector. pasamos a la posición 2 y. la llamada a la función que hemos escrito. 25 . • Solución 1. result=result+1. if (vector(i)==n). function result = problema8ContadorB( vector. llegamos sin cambiar hasta la posición 6. escribimos en el área de comandos de MATLAB dos instrucciones: primero. si es igual. Igual que en otras ocasiones. Macario Polo Usaola >> 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. la suma de los valores de x es 30: >> sum(x) ans = 30 Figura 14 Bien. Como respuesta. podemos escribir en la línea 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 cuáles no. MATLAB devuelve otro vector con unos y ceros: en aquellas posiciones en las que el vector tiene valor 2. Dado el vector anterior. y un 0 en las que no. De este modo. aparece el valor 1 en las posiciones 2 y 7. Posición 1 2 3 4 5 6 7 8 9 10 11 x= 1 2 1 3 4 1 2 5 6 4 1 ¿x==2? 0 1 0 0 0 0 1 0 0 0 0 Otra función interesante de MATLAB es la función sum: aplicada a un vector. devuelve la suma de sus elementos. ya sabremos cuántas veces aparece el número solicitado: 26 . ya que x contiene un 2 en esas dos posiciones. Por ejemplo. 1) ans = 4 Figura 12 • Solución 2. MATLAB dispone de muchas funciones muy cómodas para trabajar con vectores y matrices. MATLAB pone un 1. pues podemos combinar ambas funciones para calcular muy rápida y sencillamente el número de apariciones de un elemento en un vector: si calculamos la suma del vector de unos y ceros. Otra versión. Posición 1 2 3 4 5 6 7 8 9 10 11 x= 1 2 1 3 4 1 2 5 6 4 1 ¿x==2? 0 1 0 0 0 0 1 0 0 0 0 La suma de los elementos en amarillo es 2. n ) result=sum(vector==n). funciona: >> problema8ContadorA(x. lo que decimos en la sentencia de asignación de la Función 26 es que asigne a result el resultado de sumar los elementos del vector de unos y ceros construido a partir de la comparación del vector pasado como parámetro con el valor de n. 46 ejercicios resueltos de MATLAB function result = problema8ContadorA( vector. mucho más eficaz En efecto. end Función 26. 2) ans = 2 Figura 15 27 . Y sí. Macario Polo Usaola Ejercicio 10. Producto escalar Escribir una función que calcule el producto escalar de dos vectores v y w que se pasan como parámetros. Si no se recibiesen dos argumentos de entrada se deberá mostrar un mensaje de error por pantalla y devolver un -‐1. Si las dimensiones de los vectores fueran incoherentes para realizar el producto escalar se deberá devolver un -‐1 y mostrar también un mensaje de error. • Solución 1. El producto escalar de dos vectores se calcula de la siguiente forma: !1 ! · ! = !1, !2, … !" · !2 … = !1 · !1 + !2 ∗ !2 + ⋯ + !" · !" !" Si lo calculamos a mano, consiste en ir acumulando la suma de multiplicar el primero por el primero, más el segundo por el segundo, más el tercero por el tercero, etcétera. Para escribir la función MATLAB correspondiente, basta con un bucle for que recorra desde 1 hasta n (donde n es la longitud de los vectores) y que acumule en una variable la suma de los productos. Es decir: function result = productoEscalar(v, w) result=0; for i=1:1:length(v) result=result+v(i)*w(i); end end Función 27. Función para el cálculo del producto escalar • Solución 2. En el enunciado nos piden que hagamos varias comprobaciones de argumentos: que haya 2 y que las dimensiones de ambos vectores sean coherentes. En el primer if del siguiente código comprobamos que se pasan exactamente dos argumentos; en el segundo, que las longitudes de ambos vectores sean iguales. 28 46 ejercicios resueltos de MATLAB function result = productoEscalar2(v, w) if (nargin~=2) disp('Debe pasar dos argumentos'); return; end if (length(v)~=length(w)) disp('Los vectores deben tener el mismo número de elementos'); return; end result=0; for i=1:1:length(v) result=result+v(i)*w(i); end end Función 28. Producto escalar con comprobación de argumentos • Solución 3. Desde luego, podemos utilizar también los propios operadores de MATLAB para multiplicar matrices y vectores y hacer la cosa mucho más sencilla. En la siguiente figura mostramos el uso del operador * para multiplicar dos vectores: § En (1), mostramos el valor del vector x. § En (2), asignamos a y el mismo vector x, de manera que ya tenemos dos vectores. § En (3), utilizamos el operador ‘ para pedirle a MATLAB que nos muestre el vector y traspuesto. § En (4), intentamos multiplicar x por y. MATLAB da un error porque los vectores deben tener dimensiones compatibles: 1xn y nx1. § En (5) arreglamos el problema, multiplicando x por el traspuesto de y. >> x >> y=x x = 1 y = 2 1 2 1 3 4 1 2 5 6 4 1 1 2 1 3 4 1 2 5 6 4 1 >> y' >> x*y ??? Error using ==> mtimes ans = Inner matrix dimensions must agree. 4 1 3 2 >> x*y' 1 3 ans = 4 5 1 114 2 5 6 4 1 Figura 16. Cálculo del producto escalar, directamente en la línea de comandos de MATLAB 29 Macario Polo Usaola En realidad, no nos hace falta entonces crear ninguna función 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 número de elementos'); return; end result=v*w'; end Función 29 30 n) fib(1) = 1. la segunda en el bucle for. Luego. que construye un vector con x ceros. Por ejemplo: function fib=vectorFibonacci2(n) fib=[]. recorremos el vector desde la posición 3 hasta el final. utilizamos para devolver el resultado) un vector de tantos ceros como valor tenga el parámetro n. en este caso y por variar. Fibonacci en un vector Escribir una función de MATLAB que construya un vector que contenga los n primeros términos de la serie de Fibonacci. • Solución 1. donde n es un parámetro que se pasará como argumento de entrada. for i = 1 : n fib=[fib fib2(i)]. for i = 3 : n fib(i) = fib(i-1) + fib(i-2). Para ello usamos la función zeros(x) de MATLAB. colocamos sendos unos en la primera y segunda posiciones. A continuación. function fib=vectorFibonacci(n) fib=zeros(1. En la Función 30 damos una primera solución: primero asignamos a fib (la variable que. que construye un vector vacío. que tiene solamente los 31 . fib(2) = 1. end end Función 30 El resultado es el siguiente: >> vectorFibonacci(8) ans = 1 1 2 3 5 8 13 21 Figura 17 • Solución 2. 46 ejercicios resueltos de MATLAB Ejercicio 11. También podemos utilizar cualquiera de las funciones para el cálculo de la función de Fibonacci que vimos en ejercicios anteriores. colocando en cada una la suma de las dos posiciones anteriores. end end Función 31 En el código anterior hay dos novedades: la primera en la sentencia fib=[]. y no el incremento que debe darse a esta variable en cada vuelta del bucle. Cuando el incremento no se pone. MATLAB asume que es 1. Macario Polo Usaola valores inicial y final de i. 32 . 4. como argumento de entrada y determine cuál de todos ellos es el más cercano al primero de los elementos del vector y devuelva su posición. actualizamos p (con la posición de este elemento) y el valor de mejorDistancia. por si hubiera negativos) y. pues esto es exactamente lo que hacemos en la Función 32: en p devolveremos el resultado. if (distancia<mejorDistancia) p=i. ya que el número más cercano al primero (2) es el cuarto (1). En caso de que el vector no tenga al menos dos componentes. calcularíamos la diferencia respecto del primero (4-‐ 2=2) y. que inicializamos a infinito. end end end Función 32 33 . dentro del vector. 46 ejercicios resueltos de MATLAB Ejercicio 12. mejorDistancia=distancia. En mejorDistancia guardamos la distancia o diferencia más corta hasta el momento. que inicializamos a -‐1. Distancia al primero Escriba una función de MATLAB que reciba un vector de números reales. • Solución 1. v. ¿cómo lo haríamos a mano? Supongamos que tenemos el vector que nos proponen en el enunciado: Posición 1 2 3 4 5 v= 2 6 4 1 10 En un procedimiento manual. puesto que de momento es el más cercano (la diferencia es 4). Primero de todo. calcularíamos la diferencia (en valor absoluto. en el bucle. p. como es menor que el resultado que llevamos hasta el momento (4). Bien. 1. luego. el método devolverá un -‐1. 6. leeríamos el segundo. Si es menor que la mejorDistancia hasta el momento. for i=2:length(v) distancia=abs(v(i)-v(1)). guardaríamos su posición (2) como resultado. almacenamos la posición (3) y actualizamos el resultado. 10) . A continuación leeríamos el tercero (un 4). function p = distanciaAlPrimero(v) p=-1. Luego. mejorDistancia=Inf(). Seguiríamos así hasta la última posición del vector. recorremos el vector desde la segunda posición hasta el final. probablemente leeríamos y memorizaríamos el primer número. p = 4. Si no se proporciona un vector de entrada se generará un vector de tamaño 10 de números aleatorios reales entre 0 y 10. En cada iteración calculamos la distancia desde el elemento en el que estamos (v(i)) hasta el primero (v(1)). Ejemplo: para v = (2. 017483539523425 >> rand >> rand ans = ans = 0.918297137138448 Figura 19 Si deseamos generar un número al azar entre 0 y 10. El enunciado nos pide que.446709873639582 0. si no se proporciona un vector de entrada. debe devolverse un -‐1. el resultado es: >> x=[2 6 4 1 10] x = 2 6 4 1 10 >> distanciaAlPrimero(x) ans = 4 Figura 18 • Solución 2. generaremos un vector de 10 números aleatorios entre 0 y 10.435119497879152 0. se genere uno con 10 números aleatorios reales entre 0 y 10. a continuación generamos una matriz de 4x3: 34 . Si se pasa un vector como entrada pero no tiene al menos dos elementos. MATLAB dispone de la función rand. Por otro lado. que genera un número al azar entre 0 y 1: >> rand >> rand ans = ans = 0. Por ejemplo. m). La segunda comprobación es sencilla. pues basta utilizar la función length(v). si queremos generar una matriz de nxm números aleatorios. Macario Polo Usaola Con el vector de ejemplo. basta con escribir rand*10. Para la segunda contaremos el número de argumentos con nargin: si es 0. escribiríamos rand(n. return. que también se nos pedía.674758140355275 0. Si escribimos (por ejemplo) x-‐5. end if (length(v)<=2) p=-1. En el segundo if preguntamos por la longitud del vector.99179953529122 0. end end end Función 33 • Solución 3.17367398659238 0.379791754484912 0. mejorDistancia=Inf(). function p = distanciaAlPrimero(v) if (nargin==0) v=rand(1.673265764196007 Figura 20 Si lo que queremos es generar un vector de 10 números.561801676019808 0.446083836222534 0. Una solución más elegante pasa por utilizar las funciones de MATLAB para manipulación de vectores y matrices. Es decir: 35 . si el número de argumentos es 0. Supongamos que disponemos del siguiente vector.107561794984856 0.373326492462255 0.405999530454979 0.30283659962261 0. entonces v (el vector sobre el que vamos a trabajar) debe inicializarse como nos piden en el enunciado. 10). x. mejorDistancia=distancia. for i=2:length(v) distancia=abs(v(i)-v(1)). end p=-1. que es el que usaremos en la nueva versión de nuestra función: en amarillo indicamos que. 46 ejercicios resueltos de MATLAB >> rand(4.887620611199764 0.10)*10. sabemos que nos muestra los elementos del vector.3) ans = 0. if (distancia<mejorDistancia) p=i. el comando es rand(1. MATLAB nos muestra como resultado un vector en el que ha restado 5 a todos los elementos del vector original. en el que hay algunos elementos repetidos: posición 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 el valor de la posición que debe devolvernos la función que buscamos es un 4. entonces. pero quitándole el primer elemento. su valor absoluto: >> abs(x-‐x(1)) ans = 0 1 2 0 3 7 2 5 6 0 Figura 23 A partir del resultado mostrado en la figura anterior. le reste el valor que tenemos en la posición 1 del vector x: 36 . trabajar con el vector x. Macario Polo Usaola >> x-‐5 ans = -‐4 -‐3 -‐2 -‐4 -‐1 3 -‐6 1 2 -‐4 Figura 21 Para irnos aproximando a la solución 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 O. al vector obtenido en la Figura 24. le decimos a MATLAB que vaya al vector x. mejor aún. MATLAB permite extraer cómodamente un trozo de un vector: en la Figura 24. Afortunadamente. Nos interesa. pues se trata de un vector y no de una matriz) y que. que se fije en su fila 1 (la única que tiene. que es la ubicación del segundo cero: el que está en la primera posición no nos interesa. de ella extraiga los elementos que hay desde la posición 2 hasta la última (length(x)): >> x(1. 2:length(x)) ans = 2 3 1 4 8 -‐1 6 7 1 Figura 24 Ahora podemos medirle a MATLAB que. porque es el elemento con el que hacemos todas las comparaciones. 46 ejercicios resueltos de MATLAB >> x(1. que es realmente el cuarto del vector original. 2:length(x))-‐x(1)) ans = -‐2 Figura 27 Si seleccionamos el menor valor. 2:length(x))-‐x(1) ans = 1 2 0 3 7 -‐2 5 6 0 Figura 25 El elemento que buscamos es el que está en la tercera posición de este vector resultante. 2:length(x))-‐x(1) ans = 1 2 0 3 7 -‐2 5 6 0 >> min(x(1. en el que no estábamos considerando el primer elemento: >> x(1. que devuelve el valor mínimo del vector que se pasa como parámetro: >> x x = 1 2 3 1 4 8 -‐1 6 7 1 >> min(x) ans = -‐1 Figura 26 Realmente. pues el valor más próximo al primero es el 0. que está en la sexta posición del vector (séptima en el vector original). escogeríamos el -‐2. Modifiquemos la expresión de la Figura 27 para que considere el valor absoluto: 37 . Tendremos esto en cuenta para más adelante. nos interesa conocer el valor mínimo del vector que construimos en la Figura 25. Otra función interesante de MATLAB es min(v). Esta elección sería errónea. era este: posición 1 2 3 4 5 6 7 8 9 10 x= 1 2 3 1 4 8 -‐1 6 7 1 Las transformaciones que hemos ido haciendo para adaptarlo a nuestras necesidades han sido: posición — 1 2 3 4 5 6 7 8 9 x(1. 2:length(x))-‐x(1)= — 1 2 0 3 7 -‐2 5 6 0 abs(x(1. 2:length(x)= — 2 3 1 4 8 -‐1 6 7 1 x(1. Para encontrar valores en un vector. le estamos diciendo a MATLAB que busque. 2:length(x))-‐x(1))) ans = 0 Figura 28 Ahora sí. 4. 38 . MATLAB dispone de la función find. Macario Polo Usaola >> min(abs(x(1. El vector original. >> x x = 1 2 3 1 4 8 -‐1 6 7 1 >> find(x==1) ans = 1 4 10 Figura 29 Hasta ahora. 2:length(x))-‐x(1)). 2:length(x))-‐x(1)) las posiciones en las que aparece el valor mínimo: en la Figura 30. 2:length(x))-‐x(1)). Bien. MATLAB responde diciendo que el valor mínimo está en las posiciones 3 y 9. x. su valor mínimo. 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). pues busquemos en el vector abs(x(1. 2:length(x))-‐x(1))) y calcular el mínimo de un vector. en el vector abs(x(1. 2:length(x))-‐x(1)) — 1 2 0 3 7 2 5 6 0 Ahora necesitamos encontrar en qué posición se encuentra el menor valor del vector abs(x(1. Este resultado (1. 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. que devuelve un vector con las posiciones de los elementos que cumplen cierta condición. 10) es devuelto en forma de vector. sabemos extraer un subvector haciendo alguna transformación al vector original (como en el caso de abs(x(1. extraemos el primer elemento: primero. al ejecutar esta instrucción. 2:length(x))-‐x(1)))) z = 3 9 >> z(1) ans = 3 Figura 31 Para ir terminando. a la que llamamos z. 2) Luego mostramos el valor del vector original. 2:length(x))-‐x(1))==min(abs(x(1. recordemos que el valor que nos interesa devolver tiene que hacer referencia a la posición en el vector original. v (nótese que tenemos una instrucción compuesta simplemente de la palabra v sin punto y coma al final: la supresión del punto y coma hace que. 2:length(x))-‐x(1))==min(abs(x(1. también lo hemos quitado en las siguientes líneas. Como el resultado devuelto por find es un vector. se muestre el valor de v. 3) A continuación. en una variable a la que llamamos vectorDesdeLaPosicion2 colocamos los elementos del vector original desde la posición 2 hasta el final. 2:length(x))-‐x(1)))) ans = 3 9 Figura 30 Nos interesa realmente quedarnos sólo con el primer elemento. luego. 4) En valoresAbsolutos guardamos un nuevo vector con el valor absoluto de las diferencias respecto del primer elemento de v. >> z=find(abs(x(1. el vector que contiene las posiciones del valor mínimo. x. asignamos a una variable auxiliar. devolveremos realmente z(1)+1: >> z(1)+1 ans = 4 Figura 32 Llevemos todo esto a una función de MATLAB (Función 34): 1) Primero comprobamos la corrección de los argumentos. leemos el primer elemento de ese vector z. 39 . Por ello. para ver en la consola de MATLAB cómo va evolucionando el resultado). 46 ejercicios resueltos de MATLAB >> find(abs(x(1. 6) En posicionesDeLosMinimos guardamos un vector con las posiciones en las que se encuentra el valor mínimo. end v vectorDesdeLaPosicion2=v(1. function p = distanciaAlPrimero2(v) if (nargin==0) v=rand(1.10)*10. Macario Polo Usaola 5) En minimo guardamos el valor mínimo de los valores absolutos de las diferencias. end if (length(v)<=2) p=-1. 7) Finalmente. return. 2:length(v)) valoresAbsolutos=abs(vectorDesdeLaPosicion2-v(1)) minimo=min(valoresAbsolutos) posicionesDeLosMinimos=find(valoresAbsolutos==minimo) p=posicionesDeLosMinimos(1)+1 end Función 34 Si ejecutamos la función. devolvemos en p la posición del primer elemento de posicionesDeLosMinimos. que es el elemento más cercano a v(1). el resultado es el siguiente: >> distanciaAlPrimero2(x) v = 1 2 3 1 4 8 -‐1 6 7 1 vectorDesdeLaPosicion2 = 2 3 1 4 8 -‐1 6 7 1 valoresAbsolutos = 1 2 0 3 7 2 5 6 0 minimo = 0 posicionesDeLosMinimos = 3 9 p = 4 ans = 4 Figura 33 40 . Ya vimos que MATLAB dispone de la función mod(x. que devuelve 1 o 0 en función de que el resultado sea cierto o falso: function result = esPrimo1(n) numeroDeDivisores=0. end Función 35 41 . entonces el número es primo: function result = esPrimo1(n) numeroDeDivisores=0. hasta llegar a n. i)==0 numeroDeDivisores=numeroDeDivisores+1. end end if numeroDeDivisores==2 result=1. • Solución 1. por 3. end end result= numeroDeDivisores==2. end end Figura 34 Un pequeño cambio que podemos hacerle a la función está en el último if: en lugar de preguntar cuántos divisores hay y asignar a result. else result=0. Un número es divisible por otro cuando el resto de la división entera es 0. podemos asignar directamente el resultado de computar numeroDeDivisores==2. Un número es primo cuando sólo puede dividirse por sí mismo y por 1. for i=1:n if mod(n. 46 ejercicios resueltos de MATLAB Ejercicio 13. Números primos Escriba una función que determine si el número que se le pasa como parámetro es o no primo. Si el número de divisores encontrados es 2. que devuelve el resto de la división entera de x entre y. Una primera forma de resolver el problema es ir dividiendo el número n por 1. etcétera. y). i)==0 numeroDeDivisores=numeroDeDivisores+1. for i=1:n if mod(n. En lugar de recorrer con un for. end result= numeroDeDivisores==0. numeroDeDivisores=0. Podríamos empezar a dividir por 2 y parar a la mitad de n: si no encontramos divisores. podemos utilizar un while que se detenga o bien cuando se llegue a la mitad de n. no obstante. i)==0 numeroDeDivisores=numeroDeDivisores+1. end end result= numeroDeDivisores==0. i)==0 numeroDeDivisores=numeroDeDivisores+1. probablemente podamos averiguar si n es primo antes de llegar a la mitad de n. end i=i+1. end Función 37 • Solución 4. en lugar de hasta la mitad. entonces el número es primo. Aunque la solución anterior es más eficiente. i)==0 numeroDeDivisores=numeroDeDivisores+1. 42 . while (i<=n/2 && numeroDeDivisores==0) if mod(n. for i=2:n/2 if mod(n. Macario Polo Usaola • Solución 2. consiste en buscar hasta la raíz cuadrada de n. while (i<=sqrt(n) && numeroDeDivisores==0) if mod(n. i=2. aún más rápida. es muy ineficiente. Una variante. function result = esPrimo3(n) numeroDeDivisores=0. porque hacemos siempre n divisiones. La función de MATLAB para la raíz cuadrada es sqrt(x): function result = esPrimo5(n) tic. end Función 36 • Solución 3. La solución anterior. o bien cuando se encuentre un divisor entre 2 y n/2: function result = esPrimo4(n) numeroDeDivisores=0. i=2. end result= numeroDeDivisores==0. toc. Una última posición pasa por el uso de la función isprime(x) de MATLAB. que devuelve 1 si x es primo y 0 en caso contrario. 46 ejercicios resueltos de MATLAB end i=i+1. 43 . end Función 38 • Solución 5. Una solución incorrecta. La solución entonces es sencilla: en lugar de ir de manera fija desde 1 a n con un for. en lugar de cualquiera de las que hemos escrito antes. 44 . consiste en disponer de un bucle for desde 1 hasta n. e ir preguntando si i es primo. Macario Polo Usaola Ejercicio 14. • Solución 2. • Solución 1 (errónea). sino con los que están entre 1 y n: >> vectorNPrimerosPrimosMalo(10) ans = 2 3 5 7 Figura 35 Obsérvese que usamos (en la Función 39) la función de MATLAB isPrime. pero en la que es fácil caer. Es decir: function result = vectorNPrimerosPrimosMalo(n) result=[]. mientras (while) el número de elementos en el vector resultado sea menor que n. Una versión incorrecta del algoritmo solicitado El código anterior no funciona bien. pero no con los n primeros. porque devuelve un vector de primos. En caso afirmativo. Vector con los n primeros números primos Escriba una función que devuelva un vector con los n primeros números primos. iremos añadiendo elementos mientras que no hayamos encontrado n números: es decir. for i=1:n if (isprime(i)) result=[result i]. lo añadimos al resultado. end end end Función 39. i=1. end i=i+1. 46 ejercicios resueltos de MATLAB function result = vectorNPrimerosPrimos1(n) result=[]. De hecho. while (length(result)<n) if (isprime(i)) result=[result i]. en la figura anterior. que el vector result no contiene el valor 1. MATLAB no considera que el 1 sea primo: >> isprime(1) ans = 0 Figura 37 45 . end end Función 40 Ahora. el resultado que nos da MATLAB es: >> vectorNPrimerosPrimos1(10) ans = 2 3 5 7 11 13 17 19 23 29 Figura 36 Nótese. while (length(result)<n) if (isprime(i)) result=[result i]. end result=sort(result. end Función 41 • Solución 2. i=1. podemos añadirlo al principio. end i=i+1. 'descend'). Para resolver este ejercicio podemos añadir una sencilla línea al código de la Función 40 (página 45). si utilizamos el parámetro descend. end end Función 42 El resultado de la funciones vectorNPrimerosPrimosOrdenado1 (Función 41) y vectorNPrimerosPrimosOrdenado2 (Función 42) es exactamente el mismo: 46 . sort ordena un vector o una matriz de menor a mayor pero. while (length(result)<n) if (isprime(i)) result=[i result]. lo ordena descendentemente: function result = vectorNPrimerosPrimosOrdenado1(n) result=[]. En el código anterior. en la que llamamos a la función sort de MATLAB. Macario Polo Usaola Ejercicio 15. en la línea que hay dentro del if. escribiendo result=[i result]: function result = vectorNPrimerosPrimosOrdenado2(n) result=[]. • Solución 1. añadimos cada valor de i que vamos encontrando al final del vector (result=[result i]). i=1. Vector con los n primeros números primos ordenados de mayor a menor Escriba una función que devuelva un vector con los n primeros números primos ordenados de mayor a menor. En lugar de hacer eso. end i=i+1. 46 ejercicios resueltos de MATLAB >> vectorNPrimerosPrimosOrdenado1(10) >> vectorNPrimerosPrimosOrdenado2(10) ans = ans = 29 23 19 17 13 11 7 5 3 2 29 23 19 17 13 11 7 5 3 2 Figura 38 47 . i=2. end i=i+1. Utilizaremos la función isprime(x) para ir generando números primos hasta que un contador llegue a n: function result = enesimoPrimo( n ) contador=0. end end Función 43. Cálculo del enésimo primo 48 . siendo n el valor pasado como parámetro. end if contador==n result=i. • Solución 1. while contador<n if isprime(i)==1 contador=contador+1. Calcular el enésimo número primo Escriba una función que devuelva el n-‐ésimo número primo. Macario Polo Usaola Ejercicio 16. en cada iteración. almacenamos en un vector aparicionesDeVi las veces que aparece el número v(i) en el vector auxiliar. Al final. function result = numerosDistintos1( v ) auxiliar=[]. miramos si el valor i-‐ésimo ya se encuentra en un vector auxiliar que habremos construido previamente inicializándolo a vacío: si el valor está. si la longitud del vector aparicionesDeVi es cero). que trataremos de imitar. 46 ejercicios resueltos de MATLAB Ejercicio 17. es la siguiente: recorreremos el vector v que nos pasan como parámetro desde el principio hasta el final con un for. en el bucle. lo añadimos. Si no aparece ninguna vez (es decir. if length(aparicionesDeVi)==0 auxiliar=[auxiliar v(i)]. Una forma de hacerlo a mano. luego. end Función 44 Un par de ejemplos de la ejecución son: >> x >> z=[1 1 1 1 2 3 1] x = z = 1 2 3 1 4 8 -‐1 6 7 1 1 1 1 1 2 3 1 >> numerosDistintos1(x) >> numerosDistintos1(z) ans = ans = 8 3 Figura 39 49 . devolvemos la longitud del vector auxiliar como resultado. end end result=length(auxiliar). si no está. no lo añadimos. • Solución 1. Como resultado. Contar números distintos en un vector Escriba una función que devuelva cuántos números distintos aparecen en el vector que se pasa como parámetro. devolveremos el tamaño del vector auxiliar: posición 1 2 3 4 5 6 7 8 9 10 v= 1 2 3 1 4 8 -‐1 6 7 1 auxiliar= 1 2 3 4 8 -‐1 6 7 La solución podemos implementarla como en la Función 44: creamos el vector auxiliar vacío. for i=1:length(v) aparicionesDeVi=find(auxiliar==v(i)). entonces lo añadimos. pero que se va actualizando según vayamos encontrando factores primos) sea distinto de 1. encontrar el menor número primo por el que n es divisible: cuando lo encontramos. lo añadimos al vector result y actualizamos el cociente al valor que tenía dividido por el número primo que acabamos de encontrar. Lo que hacemos habitualmente a mano es. lo guardamos. Vamos a proceder exactamente de la misma forma. • Solución 1. enesimoPrimo(i))~=0) i=i+1. calculamos el cociente y seguimos hasta que el cociente sea 1. cociente=n. function result = factoresPrimos1( n ) result=[]. aprovechando la función enesimoPrimo que escribimos en la Función 43 (página 48): mientras el cociente (que inicialmente es n. Cálculo de los factores primos de n Los dos ejemplos manuscritos que veíamos arriba son: 50 . como se muestra a continuación. while (mod(cociente. buscamos (en el while anidado) el primer número primo que divide al cociente: cuando lo encontramos. end end Función 45. while (cociente~=1) i=1. cociente=floor(cociente/enesimoPrimo(i)). end result=[result enesimoPrimo(i)]. Descomposición en factores primos (I) Escriba una función que devuelva un vector con los factores primos del número que se pasa como parámetro. Macario Polo Usaola Ejercicio 18. 46 ejercicios resueltos de MATLAB >> factoresPrimos1(120) >> factoresPrimos1(27) ans = ans = 2 2 2 3 5 3 3 3 Figura 40 51 . 3) Recorreremos todos los valores que tengamos en el vector factores. 2) Crearemos dos vectores: uno para guardar los factores que encontremos (el 2. en la segunda. Descomposición en factores primos (II) Escriba una función que devuelva una matriz con dos filas: en la primera aparecerán los factores primos del número que se pasa como parámetro. lo añadimos al final y añadimos también un 1 al final de filaExponentes. Macario Polo Usaola Ejercicio 19. el 3 y el 5 en el ejemplo del número 120) y otro para guardar los exponentes (3. para el número 120. 4) Finalmente. Si el valor i-‐ésimo no está en filaFactores. por ejemplo. Cuando los hayamos completado. los utilizaremos para devolver la matriz resultante. Por ejemplo. respectivamente. filaFactores y filaExponentes. que es 23·3·5. Del ejercicio anterior tenemos la función que devuelve un vector con los factores primos del n que pasamos como parámetro. se devolverá la siguiente matriz: 2 3 5 3 1 1 • Solución 1. Del 120. obtenemos el siguiente vector: posición 1 2 3 4 5 result= 2 2 2 3 5 Lo que haremos será escribir una nueva función que haga lo siguiente: 1) Guardaremos los factores primos de n en un vector factores. que construiremos llamando a la Función 45 (pagina 50). Esto es lo que se hace en la función siguiente: 52 . devolveremos una matriz formada por filaFactores y FilaExponentes. 1 y 1 en el mismo ejemplo). Llamaremos a estos vectores. Si el valor ya estuviera. los exponentes de dichos factores primos. entonces basta con incrementar en uno el valor correspondiente en filaExponentes. nótese que en la variable posicionDelFactor guardamos el resultado de ejecutar la función find de MATLAB. filaExponentes]. else filaExponentes(posicionDelFactor(1))= filaExponentes(posicionDelFactor(1))+1. Si ninguno de los elementos la cumple. que devuelve un vector con las posiciones de los elementos que cumplen cierta condición. 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. filaExponentes]. Figura 41. end end result=[filaFactores. posicionDelFactor=find(filaFactores==factorI). el resultado es: >> factoresPrimos2(120) ans = 2 3 5 3 1 1 Figura 42 53 . filaExponentes=[]. for i=1:length(factores) factorI=factores(i). Devolución de los factores primos en dos vectores Nótese que la matriz resultado la construimos utilizando corchetes y el operador punto y coma para separar las filas que compondrán la matriz: result=[filaFactores. Como detalle. 46 ejercicios resueltos de MATLAB function result = factoresPrimos2( n ) factores=factoresPrimos1(n). if length(posicionDelFactor)==0 filaFactores=[filaFactores factorI]. que es la longitud del vector de entrada. filaFactores=[]. Traza de la Función 46 para n=120 Si ejecutamos la función en MATLAB. end Función 46. posicionDelFactor estará vacío. Hagamos una traza de ejemplo con el número 120. filaExponentes=[filaExponentes 1]. m) fpN=factoresPrimos2(n). :). por entendernos. :). • Solución 1. Por ejemplo. factoresM=fpM(1. tomar los factores comunes con su menor exponente. if (length(posicionEnM)>0) exponente=min(exponentesN(i). obtenemos las dos siguientes matrices a las que. añadiremos a una variable result de acumulación el factor común multiplicado por el menor exponente de los dos. hacemos: 48=24·3 60=22·3·5 Con lo que el mcd es 22·3=12. luego. result=1. exponentesM(posicionEnM(1))). :). end end end Función 47 • Solución 2. factoresN=fpN(1. function result = mcd1(n. Máximo común divisor Escriba una función que devuelva el máximo común divisor de n y m. para calcular el máximo común divisor de 48 y 60. Si aplicamos la Función 46 a los números 48 y 60. fpM=factoresPrimos2(m). :). Lo habitual es hacer la descomposición en factores primos de n y m y. exponentesN=fpN(2. for i=1:length(factoresN) posicionEnM=find(factoresM==factoresN(i)). llamaremos m48 y m60: 2 3 2 3 5 m48 m60 4 1 2 1 1 Lo que vamos a hacer es recorrer los factores (la fila 1) de m48 y ver si están en los factores de m60. result=result*factoresN(i)^exponente. En caso afirmativo. Otra solución elegante viene dada por la aplicación del algoritmo de Euclides: para calcular el mcd de n y m se hace lo siguiente: 54 . exponentesM=fpM(2. Macario Polo Usaola Ejercicio 20. 2) Si no. como se ve. entonces mcd(n. de una función recursiva pero que es muy fácil de implementar: function result = mcd2Euclides(n. r). r). mcd(n. result=mcd2Euclides(m. m) if m==0 result=n. m)=n y paramos. else r=mod(n. end end Función 48 55 . 46 ejercicios resueltos de MATLAB 1) Si m==0. m). donde r es el resto de n entre m. m)=mcd(m. Se trata. y negras las demás. a partir de ella podemos colorear todas las demás.j)='B'. 1): si nos damos cuenta. else tablero(i. Una función que dibuja el tablero es la siguiente: function tablero = tablero() tablero=char(8. Tablero de ajedrez Escribir una función que dibuje un tablero de ajedrez. Las casillas negras se indicarán con N y las blancas con B. Dicha casilla está en la posición (1. El tablero de ajedrez es un cuadrado de 8x8 casillas. Sabiendo que la casilla superior izquierda es blanca. se inicializa a una matriz de 8x8 caracteres. for i=1:1:8 for j=1:1:8 if (mod(i+j. son blancas las casillas cuya suma de fila y columna es par. • Solución 1. ya que en sus posiciones colocaremos letras. que almacena el resultado.8). Macario Polo Usaola Ejercicio 21. el resultado es: >> tablero ans = BNBNBNBN NBNBNBNB BNBNBNBN NBNBNBNB BNBNBNBN NBNBNBNB BNBNBNBN NBNBNBNB Figura 43 56 .j)='N'. 2)==0) tablero(i. Si la ejecutamos. end end end end Función 49 Obsérvese que la variable tablero. la suma de la fila y columna de las casillas de la diagonal ascendente es siempre 8 (igual que la posición en la que está situado el alfil). for i=1:1:8 for j=1:1:8 if (i+j==col+fila || i-j==col-fila) t(i. si llamamos a la función. Una solución fácil de implementar. igual que la resta de la posición original del alfil. 46 ejercicios resueltos de MATLAB Ejercicio 22. pero no muy eficiente. para los movimientos del alfil Y. 1) ans = ans = *NBNBN*N BNB*BNBN N*NBN*NB NB*BNBNB BN*N*NBN B*BNBNBN NBN*NBNB *BNBNBNB BN*N*NBN B*BNBNBN N*NBN*NB NB*BNBNB *NBNBN*N BNB*BNBN NBNBNBN* NBNB*BNB Figura 44 57 . la solución es muy sencilla: function t = alfil( col. columna 4. puede moverse a todas las casillas señaladas con el asterisco. 1 2 3 4 5 6 7 8 1 * * 2 * * 3 * * 4 A 5 * * 6 * * 7 * * 8 * Hecha esta observación. • Solución 1. fila ) t=tablero(). El alfil se mueve en diagonal: un alfil como el de la figura. 4) >> alfil(4. respecto de las que están en la descendente. obtenemos: >> alfil(4. end end end end Función 50. situado en la fila 4. Alfil Escriba una función en MATLAB que tome como parámetros la posición (fila y columna) de un alfil en el tablero de ajedrez y muestre todos sus posibles movimientos con un asterisco. sucede que la resta de sus columna y fila es cero. Si nos fijamos.j)='*'. no nos hace falta ir recorriendo todas las casillas para saber si una casilla dada es alcanzable o no por el alfil. si pasamos los valores de los parámetros intercambiados (en lugar de 4. abajo. Para marcar. abajo. en MATLAB. 3) Movernos hacia arriba y a la izquierda equivale a decrementar tanto la columna como la fila. fila). la primera columna (columna 1) es la de la izquierda y que para colocar un elemento en una matriz se pasa primero la fila y luego la columna. izquierda. Teniendo en cuenta que. Aunque funciones. las casillas alcanzables por un alfil. sobre un tablero de verdad y manualmente. 4) Movernos hacia abajo y a la izquierda implica el decremento de la columna y el incremento de la fila: mientras estemos dentro delos límites del tablero. tenemos que: 1) Movernos hacia arriba y a la derecha significa incrementar la columna y decrementar la fila. incrementamos i y j en cada vuelta del bucle mientras estemos dentro delos límites del tablero. demasiado eficiente. Si lo hacemos a mano. 4) >> alfil(1. restamos 1 a i y 1 a j en cada vuelta del bucle mientras estemos dentro delos límites del tablero. sumamos 1 a i y restamos 1 a j. el resultado de la derecha de la figura anterior cambia: >> alfil(4. El resultado derecho de la Figura 44 cambia si alteramos el orden del valor de los parámetros • Solución 2. Macario Polo Usaola Nótese que. derecha. derecha. ya que pasa por las 64 casillas del tablero. basta con que vayamos moviéndonos en cuatro direcciones y visitando muchas menos casillas: arriba.1 pasamos 1. Usamos dos variables i y j para ir marcando la casilla en la que queremos colocar el asterisco: partiendo de la posición inicial (que viene dada por los parámetros col. Ahora.4) ans = ans = *NBNBN*N BNB*BNBN N*NBN*NB NB*B*BNB BN*N*NBN B*BNB*BN NBN*NBNB *BNBNB*B BN*N*NBN BNBNBNB* N*NBN*NB NBNBNBNB *NBNBN*N BNBNBNBN NBNBNBN* NBNBNBNB Figura 45. izquierda.4). la solución anterior no es. arriba. 58 . de todos modos. uno para los movimientos en cada dirección. la primera fila (la fila 1) es la de arriba. Esto lo podemos conseguir con cuatro bucles while (Función 51). decrementamos la fila (i) e incrementamos la columna (j) mientras estemos dentro de los límites del tablero. 2) Movernos hacia abajo y a la derecha equivale a incrementar la columna e incrementar la fila. Ahora. j=col. arriba i=fila. j=j-1. j=j-1. arriba i=fila. queda mejor que la función alfil tome también los parámetros en ese orden. 59 . un pequeño detalle mejorable es que la función reciba los parámetros en el mismo orden en que se utilizan en las matrices de MATLAB: es decir. j)='*'. while (i<=8 && j>=1) t(i. Es importante que el código que escribamos sea legible. j=col. Movimientos del alfil. j)='*'. while (i>=1 && j>=1) t(i. fácil de usar por terceras personas y. abajo i=fila. columna para colocar un valor en la matriz. Esto hará más difícil que el usuario de nuestra función se equivoque. while (i>=1 && j<=8) t(i. i=i+1. abajo i=fila. while (i<=8 && j<=8) t(i. si MATLAB usa la notación fila. end end Función 51. i=i-1. en la medida de lo posible. % Derecha. i=i+1. i=i-1. j=col. j)='*'. j=col. end % Izquierda. fácil de entender. end % Izquierda. j=j+1. end % Derecha. j=j+1. j)='*'. conseguidos con menor coste • Solución 3. fila ) t=tablero(). Respecto del código de las dos soluciones que hemos dado para el movimiento del alfil. 46 ejercicios resueltos de MATLAB function t = alfil2( col. podemos modificar la cabecera de la función para que los parámetros se pasen en el orden habitual. pero con los parámetros intercambiados 60 . Es decir. col) % Todo el código de la función exactamente igual … end Función 52. dejar la cabecera como en la Función 52: function t = alfil3( fila. La misma Función 51. Macario Polo Usaola Ya que los valores de los parámetros col y fila se usan sólo para realizar asignaciones. a derecha e izquierda y hacia arriba y abajo. asignamos a j el valor del parámetro col incrementado en 1. de manera que el número de casillas de la L que puede moverse es tres: dos a la derecha/izquierda y una arriba/abajo. en este tipo de problemas (como en el anterior. si estamos dentro del tablero (es decir. habremos colocado los asteriscos en (2.5). del alfil) se trata de encontrar algún patrón que relacione la posición de origen con las posibles posiciones de destino. entonces restamos 2 a la fila (variable i).5). 2) Volvemos a la posición inicial y movemos dos casillas a la derecha. colocamos el asterisco una fila arriba y una fila abajo. De manera general. nos movemos dos columnas a la izquierda y colocamos el asterisco dos filas arriba y dos filas abajo. tenemos que controlar que no nos salgamos de los límites del tablero. 61 . si j<=8). iremos a la casilla 4. por ejemplo. Hacemos a continuación lo mismo para la casilla situada dos filas por debajo de la original (i=fila+2). Utilizamos dos variables auxiliares i y j para denotar respectivamente la fila y columna en que debemos colocar los asteriscos. 3) Otra vez desde la posición inicial.5) y (6. El caballo de ajedrez Escribir una función en MATLAB que tome como parámetros la posición (fila y columna) de un caballo en el tablero de ajedrez y muestre todos sus posibles movimientos con un asterisco. colocamos un asterisco dos filas arriba y dos filas abajo. 4) Por último. Luego. La solución que damos en la Función 53 simula estos cuatro bloques de movimientos. En el primero. Obviamente. nos movemos una a la izquierda y colocamos un asterisco dos filas arriba y dos filas abajo. Una vez aquí. moveremos una columna a la derecha (en el ejemplo de arriba. volvemos a comprobar que estamos dentro del tablero (i>=1) y. 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 solución respecto del ejercicio anterior del alfil. que vienen dados por los valores 1 a 8 para la fila y la columna. En el caso del caballo del ajedrez. 46 ejercicios resueltos de MATLAB Ejercicio 23. como se muestra en el tablero siguiente. haremos ahora lo siguiente: 1) A partir de la posición inicial (que vendrá en el orden fila. colocamos el asterisco. Así. • Solución 1. en caso afirmativo. el movimiento es en L. col). o una a la derecha/izquierda y dos arriba/abajo. Movimientos del caballo 62 . end i=fila+2. j)='*'. 2 arriba y abajo j=col+1. % 1 a la derecha. col) t=tablero(). 1 arriba y abajo j=col+2. j)='*'. 1 arriba y abajo j=col-2. if j>=1 i=fila-1. if (i<=8) t(i. end i=fila+2. if i>=1 t(i. j)='*'. j)='*'. end end % 2 a la derecha. if i>=1 t(i. end i=fila+1. end i=fila+1. if j<=8 i=fila-1. end end % 2 a la izquierda. if i>=1 t(i. if (i<=8) t(i. 2 arriba y abajo j=col-1. j)='*'. if (i<=8) t(i. Macario Polo Usaola function t = caballo1(fila. if (i<=8) t(i. j)='*'. if i>=1 t(i. end end % 1 a la izquierda. j)='*'. if j>=1 i=fila-2. end end end Función 53. if j<=8 i=fila-2. j)='*'. cuando suma=1 hay que restar/sumar 2 o 1 según suma sea. if i>=1 if i>=1 t(i. 46 ejercicios resueltos de MATLAB • Solución 2. restar 1 if i>=1 t(i. cuando se suma 2 a la columna. a la que podemos llamar suma. t(i. 1 arriba y abajo abajo j=col+1. if j<=8 if j<=8 i=fila-2. vaya desde 1 hasta 2 y que utilizaremos para sumarla a la variable j. respectivamente. t(i. end end i=fila+2. 1 o 2. Si nos fijamos en los bloques de código de la Función 53. Los movimientos a la derecha son muy parecidos en la Función 53 Podemos agrupar los dos trozos de código en uno solo. j)='*'. j)='*'. nos falta actualizar adecuadamente los valores que deben restarse y sumarse y que hemos resaltado en morado. sumar 1 if (i<=8) t(i. como en la Figura 47: % Movimientos a la derecha for suma=1:2 j=col+suma. sumamos la variable suma a j: la primera vez se le suma 1. queda de la siguiente manera: 63 . entonces. j)='*'. vemos que los dos movimientos a la derecha son casi exactamente iguales entre sí. if (i<=8) if (i<=8) t(i. El código para el movimiento a la derecha. con un bucle for cuya variable de control. j)='*'. j=col+2. En este caso. Este valor que deseamos sustituya al -‐2 y al +2 que aparecen en morado lo conseguimos con la expresión 3-‐suma. i=fila+1. if j<=8 i=fila-2. como también los dos movimientos a la izquierda. end end end Figura 47. j)='*'. j)='*'. se resta y suma 1 a la fila. Es decir. end end end end Figura 46. % Si suma=1. y la segunda 2. sumar 2. restar 2. sustituir ambos fragmentos de código por uno solo. i=fila-1. % Si suma=1. end i=fila+2. 2 arriba y % 2 a la derecha. se resta y suma 2 a la fila. Sin embargo. % 1 a la derecha. si suma=2. si suma=2. Paso 1 del agrupamiento en uno de los dos bloques de la Figura 46 En la figura anterior. En la Figura 46 resaltamos en amarillo las diferencias entre los movimientos hacia la derecha: cuando se suma 1 a la columna. j)='*'. % Movimientos a la derecha for suma=1:2 j=col+suma. if (i<=8) t(i. if i>=1 t(i. end end % 2 a la izquierda. if j>=1 i=fila-1. j)='*'. Macario Polo Usaola function t = caballo2(fila. agrupamos los movimientos a la izquierda. Movimientos del caballo. if i>=1 t(i. j)='*'. de modo que la función queda así: 64 . end end end Función 54. end i=fila+2. end i=fila+(3-suma). if i>=1 t(i. if j>=1 i=fila-2. col) t=tablero(). if j<=8 i=fila-(3-suma). if (i<=8) t(i. 2 arriba y abajo j=col-1. end i=fila+1. j)='*'. 1 arriba y abajo j=col-2. agrupando los movimientos a la derecha en un solo bloque Del mismo modo. if (i<=8) t(i. end end end % 1 a la izquierda. j)='*'. j)='*'. 8). % Movimientos a la derecha for suma=1:2 j=col+suma. con objeto de facilitar la lectura del resultado. con los movimientos a la derecha y a la izquierda en dos for Observa que. if i>=1 t(i. Dos ejemplos de ejecución son los siguientes: 65 . for i=1:1:8 for j=1:1:8 t(i. Movimientos del caballo. y que hemos añadido una instrucción (resaltada en morado) para colocar una C en el lugar en que se encuentra el caballo. if i>=1 t(i. j)='*'. if (i<=8) t(i. j)='*'. j)='*'. end end end end Función 55. end i=fila+(3-suma). if j<=8 i=fila-(3-suma). end end t(fila. if j>=1 i=fila-(3-resta). en el código anterior hemos sustituido la llamada a la función tablero() por una inicialización del tablero mediante guiones. end end end % Movimientos a la izquierda for resta=1:2 j=col-resta. if (i<=8) t(i. col) t=char(8. 46 ejercicios resueltos de MATLAB function t = caballo2(fila. j)='*'. end i=fila+(3-resta).j)='-'. col)='C'. j)='*'. i=fila-(3-resta). end end i=fila+(3-suma). Como vemos en la Figura 49. if i>=1 if i>=1 t(i. Macario Polo Usaola >> caballo2(4. end end end end end end Figura 49. j)='*'. if j<=8 if j>=1 i=fila-(3-suma). 66 . Los bucles de los movimientos a la derecha y a la izquierda son muy parecidos Bueno. 4) >> caballo2(4. esta variable signo la utilizamos (en morado) para multiplicar por factor. t(i. 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). if (i<=8) if (i<=8) t(i. otra diferencia (en morado). j)='*'. pues es sencillo agrupar ambos bucles. la última diferencia (en verde) es que en uno comparamos j<=8 y en otro j>=1. % Movimientos a la derecha % Movimientos a la izquierda for suma=1:2 for resta=1:2 j=col+suma. como se hace en la Función 56: las dos condiciones (en verde) las agrupamos en una sola (j>=1 && j<=8). vemos también semejanzas entre los dos bucles for de la Función 55. como una vez nos interesa sumar y otra restar. es que en uno sumamos y en otro restamos. En una vuelta de tuerca más. i=fila+(3-resta). que sustituye a las antiguas variables suma y resta. en uno llamamos a la variable suma y en otro resta (en amarillo). 8) ans = ans = -‐-‐-‐-‐-‐-‐-‐-‐ -‐-‐-‐-‐-‐-‐-‐-‐ -‐-‐*-‐*-‐-‐-‐ -‐-‐-‐-‐-‐-‐*-‐ -‐*-‐-‐-‐*-‐-‐ -‐-‐-‐-‐-‐*-‐-‐ -‐-‐-‐C-‐-‐-‐-‐ -‐-‐-‐-‐-‐-‐-‐C -‐*-‐-‐-‐*-‐-‐ -‐-‐-‐-‐-‐*-‐-‐ -‐-‐*-‐*-‐-‐-‐ -‐-‐-‐-‐-‐-‐*-‐ -‐-‐-‐-‐-‐-‐-‐-‐ -‐-‐-‐-‐-‐-‐-‐-‐ -‐-‐-‐-‐-‐-‐-‐-‐ -‐-‐-‐-‐-‐-‐-‐-‐ Figura 48 • Solución 3. j=col-resta. t(i. j)='*'. col) t=char(8.8). col)='C'. if j>=1 && j<=8 i=fila-(3-factor). end i=fila+(3-factor). Todos los movimientos del caballo en dos for anidados 67 . end end end end end Función 56.j)='-'. for signo=-1:+2:1 for factor=1:2 j=col+signo*factor. end end t(fila. for i=1:1:8 for j=1:1:8 t(i. if i>=1 t(i. 46 ejercicios resueltos de MATLAB function t = caballo3(fila. if (i<=8) t(i. j)='*'. j)='*'. entonces la casilla es de la diagonal principal y colocamos un 1: function result = matrizIdentidad1(n) result=zeros(n). sin usar la función eye. no es necesario recorrer todas las casillas de la matriz. for i=1:n for j=1:n if i==j result(i. Basta con recorrer desde 1 hasta n con una variable i y colocal el 1 en (i. Claramente. i): 68 . construiremos una matriz de nxn ceros y. devuelva una matriz identidad de nxn. recorreremos la diagonal principal (en sus posiciones coinciden la fila y la columna) y colocamos un 1. • Solución 1. la diagonal principal con un solo bucle for. Podemos recorrer. end end end end Función 57. luego. recorremos todas las posiciones de la matriz con dos bucles anidados controlados por i y j: si i==j. En una primera solución. La función eye(n) devuelve directamente la matriz identidad: >> eye(5) ans = 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 Figura 50 Para cumplir el enunciado. sencillamente. Macario Polo Usaola Ejercicio 24. Matriz identidad recorriendo toda la matriz • Solución 2. j)=1. Matriz identidad Escribir una función en MATLAB que. end end Función 58. i)=1. Matriz identidad. for i=1:n result(i. recorriendo solamente la diagonal principal 69 . 46 ejercicios resueltos de MATLAB function result = matrizIdentidad2(n) result=zeros(n). para devolver el resultado igual que lo devuelve la función diag (Figura 51). en forma de vector. 9 10 11 12. Diagonal principal Escribir una función en MATLAB que. La función diag(M) devuelve directamente. sin usar la función diag. Construcción de una matriz (izquierda) y extracción de su diagonal principal con diag Como el enunciado nos prohíbe usar la función diag. obtenemos esto: >> M >> diagonalPrincipal(M) M = ans = 1 2 3 4 1 6 11 16 5 6 7 8 9 10 11 12 13 14 15 16 Figura 52 Si queremos obtener el vector traspuesto. 5 6 7 8. recorreremos con un solo buce for controlado por una variable i las posiciones (i. basta con añadir la línea resaltada: 70 . Extracción de la diagonal principal Al ejecutar. los valores ubicados en la diagonal principal de la matriz M: >> M=[1 2 3 4. for i=1:length(M) diagonal=[diagonal M(i. Macario Polo Usaola Ejercicio 25. i): function diagonal = diagonalPrincipal(M) diagonal=[]. • Solución 1. devuelva los valores situados en la diagonal principal de una matriz que se pasa como parámetro. end end Función 59. 13 14 15 16] >> diag(M) M = ans = 1 2 3 4 1 5 6 7 8 6 9 10 11 12 11 13 14 15 16 16 Figura 51. i)]. 46 ejercicios resueltos de MATLAB function diagonal = diagonalPrincipal(M) diagonal=[]; for i=1:length(M) diagonal=[diagonal M(i, i)]; end diagonal=diagonal'; end Función 60. Extracción de la diagonal principal como un vector vertical • Solución 2. Supongamos que debemos comprobar que la matriz que se pasa como parámetro 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 función length(N) nos devuelve el número de filas de la matriz: >> N=[1 2 3; 4 5 6; 7 8 9; 10 11 12] >> length(N) N = ans = 1 2 3 4 4 5 6 7 8 9 10 11 12 Figura 53. Construcción de una matriz no cuadrada y cálculo de su longitud Si queremos conocer su número de columnas, debemos extraer una fila y calcular su longitud. Para extraer una fila de la matriz usamos MATRIZ(númeroDeFila, :): >> N(1, :) >> length(N(1, :)) ans = ans = 1 2 3 3 Figura 54. Extracción de la fila 1 de la matriz N (izquierda) y cálculo de la longitud de esa fila Así, añadimos a la función anterior el if que resaltamos: 71 Macario Polo Usaola function diagonal = diagonalPrincipal(M) if length(M)~=length(M(1, :)) disp('La matriz debe ser cuadrada'); return; end diagonal=[]; for i=1:length(M) diagonal=[diagonal M(i, i)]; end diagonal=diagonal'; end Función 61 El resultado con las matrices M (cuadrada) y N (no cuadrada) es: >> M >> N M = N = 1 2 3 4 1 2 3 5 6 7 8 4 5 6 9 10 11 12 7 8 9 13 14 15 16 10 11 12 >> diagonalPrincipal(M) >> diagonalPrincipal(N) La matriz debe ser cuadrada ans = 1 6 11 16 Figura 55. Resultado de diagonalPrincipal sobre una matriz cuadrada (izquierda) y una no cuadrada 72 46 ejercicios resueltos de MATLAB Ejercicio 26. Traza de una matriz Escribir una función en MATLAB que calcule la traza de una matriz. • Solución 1. La traza de una matriz es la suma de los elementos situados en su diagonal principal, por lo que esta función es casi trivial. Basta con recuperar la diagonal principal y sumar sus elementos. Un solución un poco larga es la siguiente: function result = traza1(M) if length(M)~=length(M(1, :)) disp('La matriz debe ser cuadrada'); return; end diagonal=[]; for i=1:length(M) diagonal=[diagonal M(i, i)]; end result=0; for i=1:length(diagonal) result=result+diagonal(i); end end Función 62. Cálculo de la traza de una matriz (I) • Solución 2. En una segunda aproximación, podemos recuperar la diagonal principal llamando a la función diagonalPrincipal que construimos en la Función 61 (o a la función diag de MATLAB) y sumar sus valores: function result = traza2(M) diagonal=diagonalPrincipal(M); result=0; for i=1:length(diagonal) result=result+diagonal(i); end end Función 63. Cálculo de la traza de una matriz (II) • Solución 3. Por último, en lugar de sumar los elementos con un bucle, como hacemos en la Función 62 y en la Función 63, podemos sumar mediante la función sum de MATLAB: 73 las operaciones tan sencillas las podemos escribir directamente en la línea de comandos de MATLAB: >> M M = 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 >> sum(diag(M)) ans = 34 Figura 56. Cálculo de la traza de una matriz (IV) O. end Función 65. Macario Polo Usaola function result = traza3(M) diagonal=diagonalPrincipal(M). usar diag en lugar de nuestra función diagonalPrincipal: function result = traza5(M) result=sum(diag(M)). end Función 64. Cálculo de la traza de M desde la línea de comandos 74 . result=sum(diagonal). end Función 66. Cálculo de la traza de una matriz (III) El código de la función anterior lo podemos agrupar en una sola línea: function result = traza4(M) result=sum(diagonalPrincipal(M)). como decíamos. Cálculo de la traza de una matriz (V) En general. function result = alternar1(n) if mod(n. 1). 75 . Esto lo haríamos para todas las filas impares. podemos comenzar creando una matriz de ceros (función zeros) y colocar un 1 en la posición (1. observamos que si. Si los comparamos (Figura 57). % Filas impares for fila=1:2:n-1 for columna=1:2:n-1 result(fila. 46 ejercicios resueltos de MATLAB Ejercicio 27. Para las pares. end result=zeros(n). vamos avanzando de 2 en 2 columnas hasta llegar al límite derecho (n-‐1). end end % Filas pares for fila=2:2:n for columna=2:2:n result(fila. end end end Función 67. columna)=1. Luego. en los dos bucles de la izquierda. En una primera. Por ejemplo. si n=6: 1 2 3 4 5 6 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 • Solución 1. formada por 1 y 0 alternativos. Igual que nos pasaba en el ejercicio sobre los movimientos del caballo (página 61). el resultado sigue siendo válido. Tenemos muchas formas de resolver este ejercicio. escribimos n en lugar de n-‐1. colocamos un 1 en la segunda columna y vamos avanzando de 2 en 2 hasta llegar a la columna n. Unos y ceros alternados (I) • Solución 2. 2)~=0 disp('n debe ser par'). Unos y ceros alternados Escribir una función que construya una matriz cuadrada de anchura par. columna)=1. los dos bucles son muy parecidos. columna)=1. Unos y ceros alternados (II) • Solución 3. result(fila. 2) sea 1 o 0): function result = alternar2(n) if mod(n. end end end end Función 68. cuando la fila es impar. columna)=1. se va incrementando la columna de 2 en 2 hasta llegar a n. según mod(fila. result(fila. Luego. que podemos modificar el bucle de la izquierda para que quede como se muestra: % Filas impares % Filas pares for fila=1:2:n for fila=2:2:n for columna=1:2:n for columna=2:2:n result(fila. Macario Polo Usaola % Filas impares % Filas pares for fila=1:2:n-1 for fila=2:2:n for columna=1:2:n-1 for columna=2:2:n result(fila. for fila=1:n if mod(fila. end result=zeros(n). Los bucles de las filas nones y las pares son muy parecidos Ambos bucles pueden agruparse en uno solo. end end end end Figura 58. O sea: 76 . end end end end Figura 57. sea par o impar la columna. que recorra todas las filas (desde 1 hasta n) y que actúe de diferente manera según la fila sea impar o par (es decir. end else % Si es par for columna=2:2:n result(fila. columna)=1. columna)=1. 2)~=0 disp('n debe ser par'). el primer 1 se pone en la columna 2. columna)=1. columna)=1. Los bucles de las filas nones y las pares son muy parecidos Es decir. 2)==1 % Si la fila es impar for columna=1:2:n result(fila. cuando la fila es par.´ Podemos simplificar un poco el código de la función anterior si tenemos en cuenta que. la columna en la que se coloca el primer 1 es la 1 y que. end for j=columna:2:n result(fila. 2)==1 columna=1. 2)==1 columna=1. end fila=fila+1. end result=zeros(n). Unos y ceros alternados (III) • Solución 4. 46 ejercicios resueltos de MATLAB function result = alternar3(n) if mod(n. podemos reescribir la solución anterior y utilizar un while en vez de un for: simplemente debemos inicializar la variable fila antes del bucle. for fila=1:n if mod(fila. end result=zeros(n). end for j=columna:2:n result(fila. j)=1. j)=1. 2)~=0 disp('n debe ser par'). while fila<=n if mod(fila. Simplemente por variar un poco. 2)~=0 disp('n debe ser par'). else columna=2. else columna=2. end end end Función 69. escribir adecuadamente su condición de salida (fila<=n) e incrementar al final del while para que no se forme un bucle infinito: function result = alternar4(n) if mod(n. end end Función 70. fila=1. Unos y ceros alternados (IV) 77 . nótese la necesidad de añadir un cero manualmente a las filas impares (línea resaltada en morado) para que se quede de la misma longitud que las pares. filaImpar=[]. end end end Función 71. 2)~=0 disp('n debe ser par'). ceros) y vamos sustituyendo cada fila por filaImpar o filaPar: function result = alternar5(n) if mod(n. else result(fila. for columna=1:2:n filaImpar(columna)=1. recorremos las filas de la matriz (previamente inicializada a. indicamos a MATLAB que sustituya toda la fila. al colocar dos puntos (:) después de la coma. Macario Polo Usaola • Solución 5. :)=filaImpar. Luego. sustituyendo por la que corresponda. filaPar=[]. end for fila=1:n if mod(fila. véase la forma en que se modifica una fila concreta en MATLAB: la línea resaltada en verde modifica de la variable result la fila número fila. Otra forma más de solucionar el ejercicio consiste en generar dos vectores distintos: uno para las filas impares y otro para las pares. En este caso inicializamos dos variables columnaImpar y columnaPar y. Igual que hemos rellenado por filas en la solución anterior (Función 71). también podemos rellenar por columnas. 78 . :)=filaPar. • Solución 6. Por otro lado. recorremos todas las columnas. end filaImpar=[filaImpar 0]. 2)==1 result(fila. for columna=2:2:n filaPar(columna)=1. end result=zeros(n). Unos y ceros alternados (V): sustituimos filas Como pequeño detalle. luego. por ejemplo. for columna=1:n if mod(columna. Unos y ceros alternados (VI): sustituimos columnas Obsérvese en la figura siguiente la diferencia. en los últimos bucles for de la Función 71 (en que sustituíamos filas) y de la Función 72 (sustituimos columnas). Sustitución de una fila (número. primero va el número de fila y luego dos puntos. columna) • Solución 7. para modificar una columna completa. for fila=1:2:n columnaImpar(fila)=1. dos puntos) y de una columna (dos puntos. 2)~=0 disp('n debe ser par'). colocando un 1 (o un 0 según corresponda): el 1 se pone en las casillas cuya suma de fila y columna sea par. Figura 59. result(:. 46 ejercicios resueltos de MATLAB function result = alternar6(n) if mod(n. columna)=columnaImpar. 2)==1 result(:. end columnaPar=columnaPar'. columna)=columnaPar. Una última solución consiste en inicializar la matriz a ceros (o a unos) y recorrer después las nxn casillas de la matriz. :)= filaImpar. end result=zeros(n). end columnaImpar=[columnaImpar 0]'. columnaPar=[]. for fila=2:2:n columnaPar(fila)=1. end end end Función 72. else result(:. sobre cómo sustituir una fila o una columna: para modificar una fila completa. columnaImpar=[]. columna)= columnaImpar. primero los dos puntos y después el número de columna: result(fila. 79 . end result=ones(n). end end end end Función 74. for fila=1:n for columna=1:n if mod(fila+columna. 2)==1 result(fila. columna)=1 end end end end Función 73. 2)~=0 disp('n debe ser par'). Unos y ceros alternados (VIII): colocamos un 0 en las casillas cuyas fila y columna suman impar 80 . for fila=1:n for columna=1:n if mod(fila+columna. Unos y ceros alternados (VII): colocamos un 1 en las casillas cuyas fila y columna suman par La versión en la que colocamos 0 en vez de 1 necesita dos cambios: primero. Macario Polo Usaola function result = alternar7(n) if mod(n. columna)=0. end result=zeros(n). 2)~=0 disp('n debe ser par'). 2)==0 result(fila. inicializar la matriz a 1 (marcado en amarillo) y luego colocar el 0 en las casillas cuya suma de fila y columna sea non (morado): function result = alternar8(n) if mod(n. la matriz de Vandermonde tiene los valores de v en la segunda columna. y n columnas en total: 1! !! 1! 1! 1! 2! !! 2! 2! 2! 3! !! 3! 3! 3! 4! !! 4! 4! 4! • Solución 1. Matriz de Vandermonde rellenando columna a columna El resultado para el ejemplo anterior es: 81 . añadiendo en cada iteración el vector v elevado a col-‐1: function result = vandermonde1(v. la tercera columna es la segunda con todos los elementos elevados a dos. en cada columna colocamos la segunda columna con sus elementos elevados al número columna menos 1. en la figura anterior. si v=[1 2 3 4] y n=5. Supongamos que v=[1 2 3 4]. Con un sencillo bucle for podemos iterar con un variable col desde 1 hasta n. Antes de abordar la solución. Matriz de Vandermonde Vandermonde. Si queremos obtener el vector [15 25 35 45]. n) result=[]. Por ejemplo. hacemos lo siguiente: >> v >> v.^(col-1). con todos sus valores elevados a 5 Nótese. end end Función 75. Es decir. 46 ejercicios resueltos de MATLAB Ejercicio 28. for col=1:n result(:. etcétera. En MATLAB podemos operar con todos los elementos de un vector o de una matriz de manera muy cómoda. la segunda es el vector pasado con todos sus elementos elevados a 1. Escribir una función que reciba como parámetro un vector v y un entero n y devuelva la matriz de Vandermonde de n columnas.^5 v = ans = 1 2 3 4 1 32 243 1024 Figura 60. col)=v. En el lado derecho obtenemos el vector v de la izquierda. El vector v representa los valores de la segunda columna. observamos que la primera columna es la segunda con todos sus elementos elevados a 0. el punto antes del símbolo de potencia: el símbolo punto indica que la operación afecta a todos los elementos del vector. Otra manera de conseguir el mismo resultado es rellenar la matriz por filas: estando en la fila i. Es decir: function result = vandermonde2(v. end end end Función 76. col)=v(fila)^(col-1). 5) ans = 1 1 1 1 1 1 2 4 8 16 1 3 9 27 81 1 4 16 64 256 Figura 61 • Solución 2. elevado a la columna de que se trate menos 1. el valor que corresponde a una cierta columna es el valor i-‐ ésimo del vector v. n) result=[]. Macario Polo Usaola >> v v = 1 2 3 4 >> vandermonde1(v. for fila=1:length(v) for col=1:n result(fila. Matriz de Vandermonde rellenando por filas 82 . Por cada iteración vamos incrementando un contador. que utilizamos para calcular el valor que corresponda. Matriz de Fibonacci. col)=fib(contador). en cada posición de la matriz. contador=contador+1. la suma de los dos valores anteriores. devuelva una matriz de dimensión n×n que contenga de forma ordenada los n*n primeros términos de la serie de Fibonacci. tomando como parámetro un número entero n. end end end Función 77. página 31). utilizando una función auxiliar Dos ejemplos del resultado son: >> matrizFibonacci1(3) >> matrizFibonacci1(5) ans = ans = 1 1 2 1 1 2 3 5 3 5 8 8 13 21 34 55 13 21 34 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711 28657 46368 75025 Figura 62 • Solución 2. Matriz de Fibonacci Escribir una función que. Hacerlo con una matriz tiene una pequeña dificultad adicional. por ejemplo: ! ! ! ! ! ! !" !" !" • Solución 1. contador=1. Otra forma de resolver el ejercicio es ir colocando. ya que hay que tener en cuenta los finales de fila. Podemos utilizar cualquiera de las funciones de Fibonacci que implementamos en ejercicios anteriores: function result = matrizFibonacci1(n) result=[]. Hacer esto con un vector es sencillo (ya lo resolvimos en el Ejercicio 11. Para n=3. 83 . En una primera solución. 46 ejercicios resueltos de MATLAB Ejercicio 29. recorremos todas las posiciones de la matriz con dos bucles for anidados. for fila=1:n for col=1:n result(fila. function result = matrizFibonacci2(n) result=[]. A continuación. n)+result(fila. eliminamos los dos if y. col)=result(1. col-2)+result(fila. end end end Función 79. 2)=1. inicializamos primero las dos primeras columnas de la primera fila. 1)=1. end for fila=2:n for col=1:n if col==1 result(fila. leemos los dos valores inmediatamente anteriores de la misma columna. result(fila. end for fila=2:n result(fila. col)=result(1. n). en las restantes. n)+result(fila. luego. for col=3:n result(1. 1)=result(fila-1. computada mediante la suma de las dos posiciones anteriores (I) • Solución 3. completamos la primera fila en el primer bucle for. 1). elseif col==2 result(fila. Macario Polo Usaola En el siguiente código. 2)=result(fila-1. result(1. for col=3:n result(1. for col=3:n result(fila. result(1. n). lo empezamos en col=3: function result = matrizFibonacci3(n) result=[]. 2)=result(fila-1. col-1) else result(fila. result(1. n-1)+result(fila-1. recorremos desde la fila 2 hasta la n: en las columnas 1 y 2 de estas filas tenemos la precaución de leer valores de la fila anterior. computada mediante la suma de las dos posiciones anteriores (II) 84 . 2)=1. end end end end Función 78. col-1). pero algo más sencilla. col-1). n-1)+result(fila-1. col)=result(fila. col-2)+result(1. col-1). Matriz de Fibonacci. 1)=result(fila-1. col)=result(fila. col-2)+ result(fila. col-1). result(1. Matriz de Fibonacci. 1)=1. en lugar de comenzar el bucle anidado en col=1. col-2)+result(1. En una solución parecida a la anterior. sus dos primeras posiciones son: R11=a11·b11+a12*b21+…+a1n*bn1 R12=a11·b12+a12*b22+…+a1n*bn2 En general. MATLAB ya dispone del operador * para multiplicar matrices directamente. Veamos cómo lo hacemos a mano. Obviamente. 46 ejercicios resueltos de MATLAB Ejercicio 30. j)=R(i. Escribir una función en MATLAB que calcule el producto de dos matrices. filasM=length(M(:. for i=1:filasM for j=1:columnasN for k=1:columnasM R(i. Multiplicación de dos matrices Podemos comprobar que la función está bien hecha pidiéndole 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. columnasN). • Solución 1. :)). columnasN=length(N(1. otro que recorra las columnas de N y otro más que se encargue de multiplicar los elementos de la fila y columna considera y de acumular el resultado para colocarlo en la posición i. k)*N(k. más abajo. Producto de matrices. le pedimos a MATLAB que compare los dos resultados utilizando el operador de 85 . :)). Necesitaremos tres bucles: uno que recorra las filas de M. 1)). j)+M(i. en la fila inferior. j). N) columnasM=length(M(1. R=zeros(filasM. en la posición Rij va la suma de los productos de Mij por Nji. los resultados de ejecutar nuestra función (izquierda) y de ejecutar la función de multiplicación de matrices de MATLAB (M*N). asumiendo una matriz A de nxm y otra B de mxn: !!! !!" … !!! !!! !!" … !!! !!" !!! … !!! ! !!! … !!! … … … … · !" … … … … !!! !!! … !!" !!! !!! … !!" Siendo R la matriz resultado. j: function R = productoDeMatrices(M. lo que nos piden es la escritura de una función que multiplique dos matrices sin utilizar ese operador. end end end end Función 80. por tanto. for j=1:columnasN columnaDeN=N(:. Macario Polo Usaola comparación (==): el resultado (una matriz de unos) indica que ambas matrices son iguales y que. >> M >> N M = N = 1 4 7 10 1 2 3 2 5 8 11 4 5 6 3 6 9 12 7 8 9 10 11 12 >> productoDeMatrices(M. en un vector llamado filaDeM) y la columna de N (que guardamos en columnaDeN). Multiplicación de matrices aprovechando el producto vectorial 86 . 1)). columnasN=length(N(1. N)==M*N ans = 1 1 1 1 1 1 1 1 1 Figura 63 • Solución 2. N) filasM=length(M(:. :). hemos implementado bien el código de la función. for i=1:filasM filaDeM=M(i. end end end Función 81. podemos hacer directamente el producto de ambos vectores: function R = productoDeMatrices2(M. :)). Podemos modificar un poco el código anterior: una vez que tenemos la fila de M (y que guardamos. j). R(i. R=zeros(filasM. N) >> M*N ans = ans = 166 188 210 166 188 210 188 214 240 188 214 240 210 240 270 210 240 270 >> productoDeMatrices(M. j)=filaDeM*columnaDeN. columnasN). por ejemplo. para cada columna desde 2 hasta n. Luego. 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 continuación. 46 ejercicios resueltos de MATLAB Ejercicio 31. colocamos en esa posición el valor que tiene encima más 1. Por ejemplo. Luego. construimos una matriz de nxn llena de ceros. Triángulo de Tartaglia Escribir una función que tome un parámetro n y construya una matriz con el triángulo de Tartaglia de dimensión n. En primer lugar. la matriz que se espera es: 1 2 3 4 1 1 0 0 0 2 1 1 0 0 3 1 2 1 0 4 1 3 2 1 • Solución 1. colocamos el 1 que tiene encima más 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. bajamos a la celda resaltada a continuación en amarillo y. Proseguimos de la misma manera hasta recorrer todas las columnas: 87 . 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. para n=4. Por ejemplo. pasamos a la columna 3 y a la fila 3. colocamos en cada casilla el valor que haya en la fila superior. Después. ubicados en la segunda columna y segunda fila (marcada a continuación en amarillo). en ella. colocamos 1 en la primera columna. el número de fila-‐3: en general. end end end Función 83. Podemos rellenar la matriz de otra manera. en la columna 3. ponemos valores desde la columna 2 hasta la columna 3. Podemos partir también de una matriz identidad con la primera columna a 1. Además. for fila=3:n for col=2:fila-1 result(fila. 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. result(:. desde la 2 hasta la 4. en la fila 5. El triángulo de Tartaglia. Macario Polo Usaola function result = tartaglia1( n) result=zeros(n). el siguiente. end end end Función 82. rellenando por columnas • Solución 2. podemos rellenar exactamente de la misma manera que antes: function result = tartaglia2( n) result=eye(n). col)=result(fila-1. Si nos fijamos. 1)=ones(n. por ejemplo. col)+1. 1). en la fila 5. en la columna 4. rellenando ahora por filas • Solución 3. 1)=ones(n. colocamos el número de fila menos el número de columna decrementado en 1. para completar cada fila empezaremos en la columna 2 y llegaremos hasta la columna que coincida con la fila-‐1: en la fila 4. es el número de fila-‐2. luego. col)+1. for col=2:n for fila=col:n result(fila. result(:. 1). Con esta idea. por ejemplo. el primer valor que debemos colocar en la columna 2 es el número de fila-‐1. Una solución para el triángulo de Tartaglia. 88 . col)=result(fila-1. 1)=ones(n. El triángulo de Tartaglia. col)=fila-(col-1). for fila=3:n for col=2:fila-1 result(fila. 46 ejercicios resueltos de MATLAB 1 2 3 4 5 1 1 0 0 0 0 2 1 1 0 0 0 3 1 3-‐(2-‐1) 1 0 0 4 1 4-‐(2-‐1) 4-‐(3-‐1) 1 0 5 1 5-‐(2-‐1) 5-‐(3-‐1) 5-‐(4-‐1) 1 En otras palabras: function result = tartaglia3( n) result=eye(n). 1). rellenando de otra manera 89 . end end end Función 84. result(:. escribimos blancos. n-‐3 blancos 4 * * * * * * * n-‐4 blancos. un número creciente de asteriscos y. Luego. poner los blancos que correspondan en cada fila: 90 . observamos que n representa. Cada fila está formada por un número decreciente de espacios en blanco. devuelva una matriz formada por asteriscos que formen un triángulo equilátero. 1 2 3 4 5 6 7 8 9 1 * n-‐1 blancos. 9 asteriscos. n-‐5 blancos Anchura=2·n-‐1 Es decir. Finalmente. en cada fila. otra vez. 3 asteriscos. n-‐1 blancos 2 * * * n-‐2 blancos. el número de filas de la matriz. n-‐4 blancos 5 * * * * * * * * * n-‐5 blancos. que cada fila la construimos escribiendo n-‐fila blancos desde la columna 1. Por ejemplo. luego. las figuras son: 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 1 * 1 * 2 * * * 2 * * * 3 * * * * * 3 * * * * * 4 * * * * * * * 4 * * * * * * * 5 * * * * * * * * * • Solución 1. 1 asterisco. entre ambos bloques. escribimos asteriscos desde la columna siguiente (n-‐fila+1) hasta la columna n-‐fila+1+(2n-‐1)-‐2·(n-‐fila)-‐1. un número decreciente de espacios en blanco. 5 asteriscos. además. Tenemos muchas formas de solucionar el ejercicio. la matriz tiene 2·n-‐1 columnas. vemos que. n-‐2 blancos 3 * * * * * n-‐3 blancos. con lo que el número de asteriscos es (2n-‐1)-‐2·(n-‐fila). Triángulo equilátero Escribir una función que. hay dos bloques de n-‐fila blancos y. Macario Polo Usaola Ejercicio 32. para n=4 y n=5. hay 2·(n-‐fila) blancos). por otro. dado un parámetro n. Fijándonos en las figuras anteriores. asteriscos hasta completar la anchura (si la anchura es 2n-‐1 y hay dos bloques de n-‐fila blancos. el número de la columna central. 7 asteriscos. Si observamos la siguiente figura. por un lado. Lo que haremos en primer lugar será construir una matriz de nx(2n-‐1) asteriscos y. 2*n-1). sustituyendo asteriscos por espacios en blanco. col)=' '. end for col=n-fila+1+(2*n-1)-2*(n-fila):2*n-1 result(fila. col)=' '. end end for fila=1:n for col=1:n-fila result(fila. Hagamos una traza parcial para n=4: Comentarios fila col n-‐fila n-‐fila+1+(2*n-‐1)-‐ result 2*(n-‐fila) Dimensionamos el 1 2 3 4 5 6 7 resultado como una 1 * * * * * * * matriz de nx(2n-‐1) 2 * * * * * * * caracteres y la 3 * * * * * * * rellenamos de 4 * * * * * * * asteriscos en el primer for Entramos en el bucle 1 1 3 1 2 3 4 5 6 7 resaltado en amarillo 1 * * * * * * en la Función 85 2 * * * * * * * 3 * * * * * * * 4 * * * * * * * 1 2 3 1 2 3 4 5 6 7 1 * * * * * 2 * * * * * * * 3 * * * * * * * 4 * * * * * * * 1 3 3 1 2 3 4 5 6 7 1 * * * * 2 * * * * * * * 3 * * * * * * * 4 * * * * * * * 91 . El triángulo equilátero. 46 ejercicios resueltos de MATLAB function result = trianguloEquilatero1(n) result=char(n. end end end Función 85. for fila=1:n for col=1:2*n-1 result(fila. col)='*'. partimos de una matriz de blancos y colocamos asteriscos en las posiciones que correspondan: 92 . Se 2 * * * * * * incrementa fila para 3 * * * * * * * procesar la fila 2. 4 * * * Entramos de nuevo * * * * en el bucle amarillo 2 2 2 1 2 3 4 5 6 7 1 * 2 * * * * * 3 * * * * * * * 4 * * * * * * * Y se continúa de esta manera con todas las filas Figura 64. Macario Polo Usaola Comentarios fila col n-‐fila n-‐fila+1+(2*n-‐1)-‐ result 2*(n-‐fila) Llegamos al bucle 1 5 4-‐1+1+(2*4-‐1)-‐2*(4-‐ 1 2 3 4 5 6 7 verde 1)=5 1 * * * 2 * * * * * * * 3 * * * * * * * 4 * * * * * * * 1 6 5 1 2 3 4 5 6 7 1 * * 2 * * * * * * * 3 * * * * * * * 4 * * * * * * * 1 7 5 1 2 3 4 5 6 7 1 * 2 * * * * * * * 3 * * * * * * * 4 * * * * * * * Hemos recorrido los 2 1 2 1 2 3 4 5 6 7 bucles amarillo y 1 * verde para fila=1. En otra posible solución. Traza parcial de la Función 85 • Solución 2. En la 6 hay 4. 2*n-1). en la que hay 5 asteriscos. construimos la matriz de caracteres y. y en la 9. for fila=1:n for col=n-fila+1:n-fila+1+(2*n-1)-2*(n-fila)-1 result(fila. en la 8. col)='*'. colocando asteriscos por filas • Solución 3. observamos que en la columna 1 hay 1 asterisco abajo del todo. 3. 46 ejercicios resueltos de MATLAB function result = trianguloEquilatero2(n) result=char(n. 1 2 3 4 5 6 7 8 9 * 1 * * * 2 * * * * * 3 * * * * * * * 4 * * * * * * * * * 5 En la siguiente función. end end end Función 86. en la 7. en la 2. A continuación. Por último. colocamos la hilera recién formada en la columna izquierda (col) y en su simétrica derecha (2*n-‐ col): 93 . 2 asteriscos abajo del todo. con objeto de apreciar mejor el resultado. 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). la rellenamos con guiones en lugar de con blancos. A continuación. llegamos así hasta la columna 5. El triángulo equilátero. Podemos analizar el problema por columnas en lugar de por filas. 1. construimos una variable hilera que usaremos para almacenar el contenido de cada columna. Para n=5. 2. en el bucle amarillo. for fila=1:n hilera(fila)='-'. for fila=1:n for col=1:2*n-1 result(fila. -------*****------- -*******. end end hilera=char(n). ------*******------ ********* -----*********----- ----***********---- ---*************--- --***************-- -*****************- ******************* Figura 65 94 . end result(:. colocando asteriscos por columnas Dos resultados de ejemplo son los siguientes: >> trianguloEquilatero3(5) >> trianguloEquilatero3(10) ans = ans = ----*---. ---------*--------- ---***--. 2*n-1). col)=hilera. --------***-------- --*****-. col)='-'. 2*n-col)=hilera. result(:. El triángulo equilátero. end for col=1:n for fila=n:-1:n-col+1 hilera(fila)='*'. end end Función 87. Macario Polo Usaola function result = trianguloEquilatero3(n) result=char(n. end end end Función 88. Luego. for fila=1:n for col=fila+1:n result(fila. 46 ejercicios resueltos de MATLAB Ejercicio 33. Matriz triangular superior. Podemos partir de una matriz identidad. col)=result(fila. También podemos partir de una matriz de ceros y rellenar cada fila de forma parecida: en cada fila. colocando en cada casilla el número que tenga a la izquierda incrementado en 1: function result = triangularSuperior1(n) result=eye(n). en cada fila. con la siguiente forma: ! ! ! … ! ! ! ! … !−! ! ! ! … !−! ! ! ! … … ! ! ! ! ! ! ! ! ! ! • Solución 1. col-1)+1. podría ser el siguiente: 95 . Matriz triangular superior Escribir una función tome como parámetro un número n y devuelva una matriz de nxn. recorremos desde la columna fila+1 hasta la columna n. en principio. 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 • Solución 2. El código. empezaremos en la columna fila desde 1 hasta n. Una forma de arreglar el problema es rellenar de manera separada la primera fila y. col-1)+1. Mensaje de error obtenido al ejecutar la Función 89 El error se produce la primera vez que se intenta acceder al elemento result(fila. el primer valor de cada columna es el propio número de columna. col)=result(fila. Para completar la columna. col=1 y. col-1)+1. Macario Polo Usaola function result = triangularSuperior2(n) result=zeros(n). claramente. Figura 67. index must be a positive integer or logical. 0). que está fuera de los límites de la matriz. vamos decrementando el valor hasta llegar a 0. continuar desde la fila 2 hasta la n: function result = triangularSuperior2(n) result=zeros(n). luego. col-‐1): en este momento. end end end Función 89. ahora sin el error • Solución 3. Solución incorrecta para la matriz triangular superior Al ejecutar la Función 89.0). Error in ==> triangularSuperior2 at 7 result(fila. encontramos un error: >> triangularSuperior2(5) ??? Attempted to access result(1. for col=1:n result(1. col-‐1)+1. col)=result(fila. end end end Función 90. con lo que el elemento que tratamos de recuperar es result(1. La función anterior. sin embargo. col)=col. col-‐1=0. col)=result(fila. end for fila=2:n for col=fila:n result(fila. Es decir: 96 . for fila=1:n for col=fila:n result(fila. También podemos rellenar por columnas: partiendo de una matriz de ceros. end end end Función 92. for fila=1:col result(fila. rellenando por columnas tras rellenar antes la primera fila • Solución 5. 46 ejercicios resueltos de MATLAB function result = triangularSuperior3(n) result=zeros(n). Quizá la solución más sencilla sea la siguiente: si nos fijamos. col)=result(fila-1. En cada posición. col)=col. end for col=1:n for fila=2:col result(fila. for col=1:n result(1. En una forma más de solucionarlo. end end end Función 91. el valor que aparece en cada casilla del triángulo superior es la diferencia entre el número de columna y el número de fila más 1: 1 2 3 4 5 1 2-‐1+1 2 4-‐2+1 3 3-‐3+1 4 5 Por tanto: 97 . Matriz triangular superior. colocamos el valor que haya encima menos 1: function result = triangularSuperior4(n) result=zeros(n). col)=valor. rellenando por columnas • Solución 4. valor=valor-1. for col=1:n valor=col. col)-1. completamos primero la primera fila y luego recorremos todas las columnas desde la fila 2. Matriz triangular superior. Macario Polo Usaola function r=triangularSuperior5(n) r=[]. col)=col-fila+1. Una solución sencilla para la Matriz triangular superior 98 . end end end Función 93. for fila=1:n for col=fila:n r(fila. De esta manera completamos el triángulo inferior: function r=triangularInferior1(n) r=[]. valor=valor+1. Fragmento de código para rellenar por columnas el triángulo inferior Efectivamente. Partiendo de la última solución dada al ejercicio de la matriz triangular superior. Este ejercicio es una generalización del anterior: ahora se trata de rellenar no sólo el triángulo superior. en la segunda. 46 ejercicios resueltos de MATLAB Ejercicio 34. colocamos los números desde 1 empezando en la fila 2 (el mismo número que la columna) y llegando hasta la fila n. for fila=col:n r(fila. for fila=1:n for col=1:n r(fila. col)=abs(col-fila)+1. el valor que debemos colocar en cada casilla es abs(col-‐fila)+1: function r=diagonalesQueSeIncrementan1(n) r=[]. for col=1:n valor=1. end end end Función 94 • Solución 2. y el resto de diagonales están formadas por su distancia a la diagonal principal. para n=5: ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! • Solución 1. si ejecutamos obtenemos el siguiente resultado: 99 . end end end Función 95. sino también el inferior. Diagonales que se incrementan (I) Escribir una función que construya una matriz de nxn cuya diagonal principal esté formada por unos. colocamos los números desde 1 empezando en la fila 1 y terminando en la fila n. Podemos hacerlo también más complicado: en la primera columna. Por ejemplo. col)=valor. completada para que se rellene el triángulo superior • Solución 3. end end end Función 96. col)=valor. Del ejercicio anterior tenemos varias funciones para construir la matriz triangular superior. end end for fila=1:n for col=fila+1:n r(fila. y con la Función 95 construimos la triangular inferior. for fila=col:n r(fila. nos podemos fijar en algunas de las soluciones dadas al Ejercicio 33 y completar el código: function r=diagonalesQueSeIncrementan2(n) r=[]. de cada matriz. valor=valor+1. col)=r(fila. col-1)+1. La Función 95. obtenemos el triángulo inferior Para completar el resto. for col=1:n valor=1. Macario Polo Usaola >> 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. Podemos combinar los resultados de ambas funciones en una sola matriz: lo que haremos será tomar. el máximo valor de la misma posición: 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 función siguiente mediante la función max de MATLAB: 100 . Al ejecutar el código de la Función 95. 46 ejercicios resueltos de MATLAB function r=diagonalesQueSeIncrementan3(n) r=max(triangularInferior1(n). Construcción de la matriz pedida a partir de las dos triangulares 101 . triangularSuperior1(n)). end Función 97. col)+m-1. para n=5 y m=6: ! ! ! ! !" ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! !" ! ! ! ! • Solución 1. a cada casilla. en la que llamamos a la Función 94 (página 99). Por ejemplo. Partiendo de cualquiera de las soluciones dadas al ejercicio anterior. lo único que tenemos que hacer es recorrer la matriz obtenida y sumar. Macario Polo Usaola Ejercicio 35. el valor de m-‐1. y el resto de diagonales están formadas por su distancia a la diagonal principal más m. col)=r(fila. end end end Función 98 102 . para n=5 y m=6: 1 2 3 4 5 1+6-‐1 2+6-‐1 3+6-‐1 4+6-‐1 5+6-‐1 2 1 2 3 4 2+6-‐1 1+6-‐1 2+6-‐1 3+6-‐1 4+6-‐1 3 2 1 2 3 3+6-‐1 2+6-‐1 1+6-‐1 2+6-‐1 3+6-‐1 4 3 2 1 2 4+6-‐1 3+6-‐1 2+6-‐1 1+6-‐1 2+6-‐1 5 4 3 2 1 5+6-‐1 4+6-‐1 3+6-‐1 2+6-‐1 1+6-‐1 Una posible solución. Por ejemplo. for fila=1:n for col=1:n r(fila. m) r=diagonalesQueSeIncrementan1(n). es: function r=diagonalesQueSeIncrementanB1(n. Diagonales que se incrementan (II) Escribir una función que construya una matriz de nxn cuya diagonal principal esté formada por los valores pasados en un parámetro m. for fila=1:n for col=1:n r(fila. Por ejemplo. van incrementando de n en n: 1 2 3 4 1 1 2 3 4 2 1+4 2+4 3+4 4+4 3 4 Esto es lo que hacemos en la solución siguiente: primero. hacia abajo. el primer número de cada columna es su número de columna. continuamos recorriendo cada columna a partir de la segunda fila. Otra solución algo más enrevesada es la siguiente: si nos fijamos. col)=valor. poniendo en cada posición el valor que tenga encima incrementado en n: 103 . end end end Función 99 • Solución 2. llenamos en un bucle aparte la primera fila. Por ejemplo. 46 ejercicios resueltos de MATLAB Ejercicio 36. Números ordenados Escribir una función que tome un argumento n y devuelva una matriz de nxn con todos los números desde 1 hasta n2. este ejercicio es prácticamente trivial. podemos recorrer todas las casillas con dos bucles anidados (uno para las filas y otro para las columnas). Luego. colocando en cada una un valor que vamos incrementando en cada iteración: function r = numerosOrdenados1(n) r=zeros(n). valor=valor+1. Con lo que ya sabemos. valor=1. luego. para n=4: 1 2 3 4 1 1 2 3 4 2 5 6 7 8 3 9 10 11 12 4 13 14 15 16 • Solución 1. end end end Función 100 104 . end for col=1:n for fila=2:n r(fila. Macario Polo Usaola function r = numerosOrdenados2(n) r=zeros(n). col)+n. col)=r(fila-1. for col=1:n r(1. col)=col. col)+n. en cada columna. Números ordenados descendentemente Escribir una función que tome un argumento n y devuelva una matriz de nxn con todos los números desde 1 hasta n2. 46 ejercicios resueltos de MATLAB Ejercicio 37. vamos desde la penúltima fila hasta la primera. colocando en cada posición el valor que tiene debajo más n: function r = numerosOrdenadosDescendentemente2(n) r=zeros(n). Otra forma de hacerlo. Ahora. for col=1:n r(n. parecida a la solución 2 del ejercicio anterior. valor=n^2. end end end Función 101 • Solución 2. ordenados de mayor a menor. col)=r(fila+1. col)=valor. valor=valor-1. luego. es rellenar por columnas: primero completamos la última fila en un bucle aparte. Por ejemplo. Reescribiremos la primera solución dada al ejercicio anterior. for fila=1:n for col=1:n r(fila. para n=4: 1 2 3 4 1 16 15 14 13 2 12 11 10 9 3 8 7 6 5 4 4 3 2 1 • Solución 1. el valor por el que arrancamos será n2 y lo iremos decrementando en cada iteración: function r = numerosOrdenadosDescendentemente1(n) r=zeros(n). col)=n-col+1. end for col=1:n for fila=n-1:-1:1 r(fila. end end end Función 102 105 . for fila=1:n if mod(fila. si es par. end else for col=n:-1:1 r(fila. y decrecientes en las pares. Macario Polo Usaola Ejercicio 38. valor=valor+1. colocamos un valor que inicializamos a 1 y que vamos incrementando en cada iteración. Si nos fijamos en la matriz de ejemplo. En cada casilla. para n=4: 1 2 3 4 1 1 2 3 4 2 8 7 6 5 3 9 10 11 12 4 16 15 14 13 • Solución 1. col)=valor. recorremos desde la n hasta la 1. Podemos ir recorriendo la matriz por filas: si la fila es impar. end end end end Función 103 106 . valor=valor+1. Por ejemplo. recorremos sus casillas desde la columna 1 hasta la n. 2)==1 for col=1:n r(fila. function r = zigzag(n) r=zeros(n). col)=valor. valor=1. los valores en las filas impares son crecientes. Zigzag Escribir una función en MATLAB que devuelva una matriz de nxn con los número desde el 1 hasta n2 colocados en las filas en zigzag. ambas en valor absoluto: function r = distancias1(n) r=zeros(n). con n impar. como valor. podemos movernos por las de la izquierda (desde la mitad-‐1 hasta 1) y las de la derecha (desde mitad+1 hasta n): en las de la izquierda. Podemos resolverlo de otra manera: partiendo de la columna central ya rellena. mitad=(n+1)/2. end end end Función 104 Y al ejecutar la función. para n=5: 1 2 3 4 5 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 • Solución 1. La distancia es la suma de las distancias en filas y columnas. Distancias Escribir una función que construya una matriz de nxn. obtenemos: >> distancias1(5) ans = 4 3 2 3 4 3 2 1 2 3 2 1 0 1 2 3 2 1 2 3 4 3 2 3 4 Figura 69 • Solución 2. Por ejemplo. El ejercicio es muy sencillito: conociendo la fila y columna mitad (que es (n+1)/2). recorreremos todas las casillas colocando. 46 ejercicios resueltos de MATLAB Ejercicio 39. for fila=1:n for col=1:n r(fila. en la que cada elemento es un número que representa la distancia al elemento central de la matriz. col)=abs(fila-mitad)+abs(col-mitad). la suma de su columna menos la mitad más la fila menos la mitad. colocamos el valor que 107 . end for fila=mitad+1:n r(fila. colocando valores desde 1 hasta llegar a la fila n. mitad=(n+1)/2. colocamos el valor que tengan a la izquierda más 1: 1 2 3 4 5 1 2+1 2 2+1 2 1+1 1 1+1 3 0+1 0 0+1 4 1+1 1 1+1 5 2+1 2 2+1 La primera columna la podemos completar en dos partes: para la parte superior iremos desde 1 hasta mitad-‐1. el resultado para n=5 es: >> distancias2(5) ans = 0 0 2 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 2 0 0 Figura 70 Para completar la mitad izquierda añadimos un poco de código: 108 . mitad)=mitad-fila. para la parte inferior. Macario Polo Usaola tengan a la derecha más 1. Luego. end end Función 105. en las de la derecha. Rellenamos la columna central mediante dos bucles En efecto. mitad)=fila-mitad. colocando valores desde mitad-‐1 hasta 1 (bajando de 1 en 1). for fila=1:mitad-1 r(fila. recorremos desde mitad+1 hasta n. Con el siguiente fragmento de código rellenamos la columna central: function r = distancias2(n) r=zeros(n). mitad)=mitad-fila. 46 ejercicios resueltos de MATLAB function r = distancias2(n) r=zeros(n). end for fila=mitad+1:n r(fila. end for col=mitad-1:-1:1 for fila=1:n r(fila. para completar la mitad izquierda El resultado. end end end Función 106. ya por último. mitad=(n+1)/2. col)=r(fila. es el siguiente: >> distancias2(5) ans = 4 3 2 0 0 3 2 1 0 0 2 1 0 0 0 4 3 2 0 0 3 2 1 0 0 Figura 71 Y. mitad)=fila-mitad. Completamos el código de la ¡Error! No se encuentra el origen de la referencia. col+1)+1. de momento. for fila=1:mitad-1 r(fila. completamos con otro bucle para rellenar la mitad derecha: 109 . end end for col=mitad+1:n for fila=1:n r(fila. col+1)+1. mitad)=fila-mitad. for fila=1:mitad-1 r(fila. end for fila=mitad+1:n r(fila. mitad=(n+1)/2. col)=r(fila. end end end Función 107 110 . end for col=mitad-1:-1:1 for fila=1:n r(fila. col)=r(fila. col-1)+1. Macario Polo Usaola function r = distancias2(n) r=zeros(n). mitad)=mitad-fila. El cero se corresponde con la letra a. Las minúsculas empiezan en la 97. disp(linea). que devuelve el carácter correspondiente al valor que se pasa como parámetro: así. El siguiente programa muestra los caracteres que corresponden a cada valor numérico: function caracteres() for i=1:255 linea=[int2str(i). le sumamos 97 (ya que char(97+0)=char(97)=’a’). para n=5: 1 2 3 4 5 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 • Solución 1. con n impar. las letras mayúsculas empiezan en el 65 (la A) y terminan en el 90 (la Z). como debemos empezar por la letra ‘a’ para representar el cero. por ejemplo. el 1 con la b. La distancia es la suma de las distancias en filas y columnas. y char(97)=’a’. sin embargo. Para escribir el código que solucione este ejercicio procederemos de forma muy parecida al ejercicio anterior: ahora. Para plantear la solución. char(i)]. en la que cada elemento es una letra que representa la distancia al elemento central de la matriz. El código de la función es muy parecido al de la Función 104 (página 107): la distancia de cada casilla al centro la guardamos en la variable distancia. '-> '. luego. etcétera. por ejemplo. end end Función 108. debemos saber primero que cada carácter de los que manipula MATLAB tiene un número entero asociado (lo que se llama el código ASCII). 46 ejercicios resueltos de MATLAB Ejercicio 40. Distancia en letras Escribir una función que construya una matriz de nxn. el valor que colocamos es el código ASCII correspondiente a esa distancia pero. en lugar de colocar números queremos colocar letras. char(65) es ‘A’. Programa para sacar la lista de códigos ASCII En el código de arriba hemos resaltado la función char(i). Por ejemplo. Así. 111 . col)=char(97+distancia). end end end Función 109 112 . for fila=1:n for col=1:n distancia=abs(fila-mitad)+abs(col-mitad). Macario Polo Usaola function r = distanciaEnLetras1(n) r=char(n). mitad=(n+1)/2. r(fila. desde la posición i. el problema se reduce a extraer subvectores de 6 caracteres de la cadena grande empezando en la posición 1. end i=i+1. patron)==1 r=i. Búsqueda de un patrón en una cadena Una posible traza con el ejemplo anterior es: 113 . ‘MATLAB’) debe devolver 14. que devuelve 1 si las dos cadenas que se pasan como parámetros son iguales y 0 en caso contrario. Por ejemplo: encontrar(‘Problemas de MATLAB’. si no. luego. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 P r o b l e m a s d e M A T L A B Si el patrón que buscamos (‘MATLAB’. MATLAB trata las cadenas de caracteres como vectores. El ejercicio podemos resolverlo de la siguiente forma: en posicionFinal guardamos la posición del último carácter a partir del cual no podemos seguir buscando (14. Buscador de cadenas Escribir una función en MATLAB que busque. Dentro del bucle. Para el ejemplo anterior. avanzamos hasta la 2. La comparación la hacemos con la función strcmp de MATLAB. function r = encontrar1(texto. end end Función 110. i:i+length(patron)-1). la 15). La operación debe devolver un -‐1 si no la encuentra. en el ejemplo) tiene 6 caracteres. patron) r=-1. posicionFinal=length(texto)-length(patron)+1. o la posición en la que aparece. vamos extrayendo subcadenas. la cadena que se pasa como segundo. while (r==-1 && i<=posicionFinal) subcadena=texto(1. lleguemos a la posicionFinal. 46 ejercicios resueltos de MATLAB Ejercicio 41. • Solución 1. Continuamos así hasta que lo encontremos o hasta que lleguemos a una posición desde la que no podamos leer 6 caracteres (es decir. Si lo encontramos en esa posición. sin encontrarlo. if strcmp(subcadena. de la misma longitud que el patrón. en el ejemplo). en la cadena que se pasa como primer parámetro. entramos a un while en el que permaneceremos hasta encontrar el patrón o hasta que. se trata de buscar un subvector dentro de un vector. y las comparamos con el patron. i=1. devolvemos un 1. Traza de la Función 110 114 . pues patron es 14 14 14 MATLAB MATLAB igual a subcadena Figura 72. Macario Polo Usaola Comentario r i posFinal patron subcadena Antes del while -‐1 1 14 MATLAB Entramos al while -‐1 1 14 MATLAB Proble -‐1 2 14 MATLAB roblem -‐1 3 14 MATLAB oblema -‐1 4 14 MATLAB blemas Con – denotamos el espacio en blanco -‐1 5 14 MATLAB lemas-‐ -‐1 6 14 MATLAB emas-‐d -‐1 7 14 MATLAB mas-‐de -‐1 8 14 MATLAB as-‐de-‐ -‐1 9 14 MATLAB s-‐de-‐M -‐1 10 14 MATLAB -‐de-‐MA -‐1 11 14 MATLAB de-‐MAT -‐1 12 14 MATLAB e-‐MATL -‐1 13 14 MATLAB -‐MATLA strcmp devuelve 1. Consideremos el palíndromo de siete caracteres anilina: 1 2 3 4 5 6 7 a n i l i n a La palabra es palíndromo porque el carácter 1 es igual al 7. Para un palíndromo con un número par de letras. lo añadimos a la ristra modificada. como erre. tomando una cadena de caracteres como parámetro. • Solución 1. devuelva un 1 si la cadena es un palíndromo. for i=1:length(texto) if (~isspace(texto(i))) auxiliar(pos)=texto(i). end end auxiliar end Función 111. pasamos al siguiente carácter sin añadirlo: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 original P r o b l e m a s d e M A T L A B sin 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 espacios P r o b l e m a s d e M A T L A B El siguiente trozo de código realiza la función descrita: crea la variable auxiliar como un vector de caracteres. luego. recorre el texto original y. si el carácter no es una espacio. y 0 en caso contrario. pos=pos+1. Detección de palíndromos Escribir una función que. pos=1. sin considerar los espacios en blanco. no hay carácter en el centro. lo añade a auxiliar. el 2 igual al 6 y el 3 igual al 5. function r = palindromo1(texto) auxiliar=char(). 46 ejercicios resueltos de MATLAB Ejercicio 42. El carácter 4 no hace falta compararlo porque el número de caracteres de la palabra es impar y la ele queda en medio. si sí lo es. Recorreremos la ristra original de principio a fin: si el carácter i-‐ésimo no es un espacio. El carácter 1 es igual al 4 y el 2 es igual al 3. 1 2 3 4 e r r e Lo primero que haremos será quitar todos los espacios en blanco a la ristra de caracteres que le llegue a la función. Primero eliminamos los espacios en blanco 115 . Eliminamos los espacios del texto “Problemas de MATLAB” Una vez preprocesada la cadena. obtenemos esto: 116 . for i=1:length(texto) if (~isspace(texto(i))) auxiliar(pos)=texto(i). 2)==1 dondeParar=floor(length(auxiliar)/2). recorreremos la primera mitad de la palabra e iremos comparando sus caracteres con los de la segunda mitad. desde 1 hasta la parte entera de la mitad de la longitud: entonces. pos=pos+1. calcularemos la posición de la cadena en la que termina la primera mitad. antes de comprobar si la cadena de caracteres es o no un palíndromo. else dondeParar=length(auxiliar)/2. end dondeParar end Función 112. Para una palabra de longitud par. y a la que llamamos dondeParar: function r = palindromo1(texto) auxiliar=char(). end end if mod(length(auxiliar). pos=1. en la que aparece la palabra “auxiliar” sin punto y coma al final. la primera mitad va desde 1 hasta la longitud entre 2. Macario Polo Usaola La línea resaltada en amarillo en el código anterior. sirve para que MATLAB muestre por la consola el valor de esa variable: >> texto texto = Problemas de MATLAB >> palindromo1(texto) auxiliar = ProblemasdeMATLAB Figura 73. para una de longitud impar. Al código de la Función 111 le añadimos unas líneas para conocer dónde parar la comprobación Si ejecutamos con un par de ejemplos. palíndromo. nos queda solamente completar el código para que se realice la comprobación: la función devolverá 1 o 0 según el texto pasado como parámetro sea o no. 46 ejercicios resueltos de MATLAB 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 P r o b l e m a s d e M A T L A B 8 caracteres 8 caracteres >> texto texto = Problemas de MATLAB >> palindromo1(texto) dondeParar = 8 1 2 3 4 5 6 7 8 A B C D D C B A 4 caracteres 4 caracteres >> palindromo1('ABCDDCBA') dondeParar = 4 Figura 74. respectivamente. Determinación de dondeParar en función de la longitud par o non de la cadena Ahora. El resultado lo almacenamos en la variable r. que vale inicialmente 1 (línea resaltada en amarillo) y que ponemos a 0 en el momento en que detectamos dos caracteres no coincidentes (en el if resaltado en verde): 117 . caracterDcha=auxiliar(length(auxiliar)-i+1). else dondeParar=length(auxiliar)/2. ya desde la primera comparación que 118 . pos=pos+1. end end end Función 113. Determinación de si el texto es o no palíndromo con un bucle for Hagamos una traza de la función para ilustrar su funcionamiento. if caracterIzda~=caracterDcha r=0. que es el valor que se devuelve. lo cierto es que puede modificarse para que sea más eficiente: en efecto. Si bien el código que hemos mostrado funciona. La función termina con r=0. 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 condición de parada del bucle. pos=1. for i=1:length(texto) if (~isspace(texto(i))) auxiliar(pos)=texto(i). Macario Polo Usaola function r = palindromo1(texto) auxiliar=char(). que ya ha sido preprocesado (con lo que auxiliar vale ProblemasdeMATLAB) y que dondeParar=8. for i=1:dondeParar caracterIzda=auxiliar(i). Comentarios dondeParar r i caracterIzda caracterDcha caracterIzda~=caracterDcha Estamos en 8 1 la línea r=1 Entramos al 8 1 1 P B bucle En el if 8 0 1 P B Falso marcado en verde. end end if mod(length(auxiliar). pues i=8=dondeParar. Supongamos que el texto pasado es Problemas de MATLAB. end r=1. 2)==1 dondeParar=floor(length(auxiliar)/2). pos=1. de manera que la comparación de los caracteres se ejecute mientras los que se están comparando sean iguales. en cierto modo. en cuanto MATLAB encuentra una instrucción return en la ejecución de una función. que es cero). viola los principios de la programación estructurada. termina su ejecución y retorna el valor que corresponda (el de r. desde el momento en que encontramos dos caracteres no coincidentes. end r=1. podemos evitarla pues. 46 ejercicios resueltos de MATLAB aparece en la tercera fila de la tabla se comprueba que el texto pasado no es palíndromo: es decir. return. if caracterIzda~=caracterDcha r=0. como hemos hecho en la última solución. Una forma de arreglarlo es incluyendo una sentencia return justamente después de la asignación r=0: function r = palindromo2(texto) auxiliar=char(). for i=1:length(texto) if (~isspace(texto(i))) auxiliar(pos)=texto(i). end end end Función 114. 2)==1 dondeParar=floor(length(auxiliar)/2). sustituiremos el último bucle for de la Función 113 por otra estructura de control. Adición de un return para provocar una “salida incondicional” de la función Como en otros lenguajes. • Solución 3. Para mejorar el rendimiento de la función. for i=1:dondeParar caracterIzda=auxiliar(i). en el ejemplo. • Solución 2. si lo deseamos. end end if mod(length(auxiliar). else dondeParar=length(auxiliar)/2. Eso es lo que se llama una “salida incondicional” que. caracterDcha=auxiliar(length(auxiliar)-i+1). una salida incondicional. 119 . Una forma de mejorar el rendimiento es forzar al código de la Función 113 a que termine en cuanto detecte una diferencia. pos=pos+1. ya podemos terminar la ejecución de la función devolviendo un cero. que pare en cuanto se sepa que el texto no es un palíndromo y evitar colocar. end i=i+1. if caracterIzda~=caracterDcha r=0. También podemos. y por lo que lo llamaremos delReves: 1 2 3 4 5 6 7 8 delDerecho a n i l i n a s delReves s a n i l i n a Luego. caracterDcha=auxiliar(length(auxiliar)-i+1). por ejemplo. en otro vector. Sustituimos el último for de la Función 113 (página 118) por un while • Solución 4. pos=pos+1. 2)==1 dondeParar=floor(length(auxiliar)/2). end end Función 115. Macario Polo Usaola En la siguiente función. se llame delDerecho). cambiamos el while function r = palindromo2(texto) auxiliar=char(). utilizar el operador == de MATLAB para comparar los dos vectores. ya sin espacios. pos=1. Una forma más de solucionar el problema consiste en colocar la palabra original (que tenemos guardada. sin embargo. end r=1. en una variable que. while i<=dondeParar && r==1 caracterIzda=auxiliar(i). con un for con un salto incondicional o con un while. else dondeParar=length(auxiliar)/2. for i=1:length(texto) if (~isspace(texto(i))) auxiliar(pos)=texto(i). end end if mod(length(auxiliar). i=1. que es lo que hacemos en la siguiente función: 120 . podemos ir comparando posición a posición con un for de principio a fin. como hemos hecho antes. en el que la guardamos “dada la vuelta”. sin punto y coma al final. el vector de 1 y 0 que resulta de comparar ambos vectores. los valores de los vectores delDerecho y delReves. los nombres de las variables delDerecho delDerecho y delReves para que. en el bucle for resaltado. Luego. con fines informativos. posición a posición. end Función 116. for i=1:length(delDerecho) delReves(i)=delDerecho(length(delDerecho)-i+1). pos=1. la de la derecha. no). asignamos a r el vector que resulta de comparar (con el operador ==) los dos vectores delDerecho y delReves. >> palindromo4('reconocer') >> palindromo4('dualidad') delDerecho = delDerecho = reconocer dualidad delReves = delReves = reconocer dadilaud ans = ans = 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 1 Figura 75 121 . MATLAB nos muestre su valor. Después de este for aparecen. for i=1:length(texto) if (~isspace(texto(i))) delDerecho(pos)=texto(i). 46 ejercicios resueltos de MATLAB function r = palindromo4(texto) delDerecho=char(). guardamos el texto original sin espacios en la variable delDerecho. en morado. Finalmente. colcoamos en delReves el texto al revés. En la figura siguiente aparecen dos ejemplos de uso de la función anterior: en amarillo la palabra (la de la izquierda es un palíndromo. Solución (incompleta) al problema del palíndromo mediante la comparación de dos vectores En el código anterior. pos=pos+1. end end delReves=char(). end delDerecho delReves r=delDerecho==delReves. finalmente. en verde. en la sentencia marcada en verde. 122 . end end Función 117. for i=1:length(texto) if (~isspace(texto(i))) delDerecho(pos)=texto(i). pos=pos+1. Macario Polo Usaola El texto pasado como parámetro será un palíndromo si la suma de los elementos del vector resultante (el que aparece en morado) es igual a la longitud del vector delDerecho (o delReves. hacemos un pequeño cambio en las últimas líneas del código de la Función 116 y la dejamos de este modo: function r = palindromo4(texto) delDerecho=char(). pos=pos+1. Modificación del código de la Función 116 para que se devuelva un 1 o un 0 En el trozo marcado en amarillo preguntamos si la suma de los elementos de r coincide con la longitud del vector con el texto sin espacios: en caso afirmativo. para que el código aparezca más compacto. if (sum(r)==length(delDerecho)) r=1. pos=1. for i=1:length(texto) if (~isspace(texto(i))) delDerecho(pos)=texto(i). es el que se muestra a continuación: function r = palindromo4(texto) delDerecho=char(). else r=0. for i=1:length(delDerecho) delReves(i)=delDerecho(length(delDerecho)-i+1). pos=1. modificamos el valor de r para que valga 1. Por tanto. end end delReves=char(). for i=1:length(delDerecho) delReves(i)=delDerecho(length(delDerecho)-i+1). end r=delDerecho==delReves. daría igual). end end delReves=char(). en caso negativo. Un cambio adicional. lo modificamos también (hasta ahora era un vector de unos y ceros) para que valga cero. pos=1. r=palindromoRecursivo(auxiliar). a su vez. comparar los vectores delDerecho y delReves con la longitud del vector delDerecho: básicamente. end end if length(auxiliar)<=1 r=1. else if auxiliar(1)==auxiliar(length(auxiliar)) auxiliar=auxiliar(1. pos=pos+1. Determinación recursiva de los palíndromos 123 . pero en menos espacio: 1 2 3 4 5 6 7 8 9 delDerecho r e c o n o c e r delReves r e c o n o c e r delDerecho==delReves 1 1 1 1 1 1 1 1 1 sum(delDerecho==delReves) 9 length(delDerecho) 9 r 1 • Solución 5. for i=1:length(texto) if (~isspace(texto(i))) auxiliar(pos)=texto(i). para comparar. 2:length(auxiliar)-1). else r=0. nos quede 1 o ningún carácter: function r = palindromoRecursivo(texto) auxiliar=char(). Sustituimos varias líneas del final de la Función 117 por una sola En la línea amarilla estamos asignando a r el resultado de comparar (==) la suma del vector resultante de. hacemos lo mismo que en las últimas líneas de la Función 117. un texto es un palíndromo si su primera letra es igual a la última y lo que hay entre medias es un palíndromo. end end end Figura 76. El caso se base se da cuando. 46 ejercicios resueltos de MATLAB end r= (sum(delDerecho==delReves)==length(delDerecho)). Con recursividad. end Función 118. También podemos determinar recursivamente si un texto es o no un palíndromo mediante una función recursiva: en efecto. mitad(v. El monte Un vector es un monte si su primera mitad es creciente. el segundo en el penúltimo… y el último en el primero): lo que estamos diciendo es que v es un monte si es palíndromo. implementar las funciones estaOrdenado. está también ordenada. al revés. podríamos escribir de la siguiente forma la expresión para determinar si un vector v es un monte: esPalindromo(v) y estaOrdenado(mitad(v. ‘D’) devuelve la mitad derecha de v. esPalindromo(v) devuelve 1 si el vector pasado es palíndromo y 0 en caso contrario (y puede ser cualquiera de las cuatro funciones que hemos implementado para el problema anterior). Escribir una función que determine si el vector v que se pasa como parámetro es o no un monte. alReves(v) devuelve el vector v al revés (el primer elemento en el último lugar. ‘I’) devuelve la mitad izquierda de v. además. La función para determinar si es palíndromo es la función palindromo4 (Función 118). si llegamos al final del vector. end Función 119. Macario Polo Usaola Ejercicio 43. según la definición anterior. mitad(v. Podemos traducir la expresión anterior directamente a una función MATLAB: function r = monte(v) r=palindromo4(v) && estaOrdenado(mitad(v. el vector es un palíndromo. montes: 1 2 3 4 5 6 7 8 a b c d d c b a 1 2 3 4 5 6 7 a b c d c b a Muy resumidamente. la segunda decreciente y. entonces devolvemos un cero mediante una salida incondicional (véase Función 114. 'D'))). encontramos que el valor en la posición i+1 es menor que el valor de la posición i. Determinación de si un vector es o no un monte mediante la conjunción de funciones Ahora falta. evidentemente. • Solución 1. ‘I’)) y estaOrdenado(alReves(mitad(v. número 119). ‘D’))) En la expresión anterior. La función estaOrdenado es muy sencilla: recorremos el vector desde la posición 2 hasta el final: si. mitad y alReves. estaOrdenado(v) devuelve 1 si el vector v está ordenador y 0 en caso contrario. Los dos vectores siguientes (de longitudes par e impar) son . entonces es porque el vector sí está ordenado y devolvemos un 1: 124 . si su mitad izquierda está ordenada y si su mitad derecha. 'I')) && estaOrdenado(alReves(mitad(v. en algún momento. end else for i=length(v):-1:pararEn r=[v(i) r]. Colocación. en otro vector: function r = alReves(v) r=[]. la función alReves coloca los elementos de un vector. 2)==0 pararEn=length(v)/2. al revés. for i=length(v):-1:1 r(length(v)-i+1)=v(i). for i=2:length(v) if v(i)<v(i-1) r=0. end if lado=='D' pararEn=length(v)-pararEn+1. return. de los elementos de un vector De este modo. 46 ejercicios resueltos de MATLAB function r = estaOrdenado(v) r=1. end end end Función 120. end end end Función 121. else pararEn=floor(length(v)/2). Extracción de la mitad izquierda o derecha de un vector Finalmente. la ejecución de la función da los siguientes resultados para los ejemplos que se muestran: 125 . end r=[]. if lado=='I' for i=1:pararEn r=[r v(i)]. en orden inverso. lado) if mod(length(v). Determinamos si el vector está ordenado La función mitad toma dos parámetros: el vector del que queremos extraer la mitad y un carácter que representa qué mitad queremos extraer: la izquierda (‘I’) o la derecha (‘D’): function r = mitad(v. end end Función 122. En este caso. página 124) • Solución 2. Supongamos ahora que queremos saber los motivos por los que el vector no es un monte: puede ser que no sea un palíndromo o sus dos mitades no estén ordenadas. nos damos cuenta de que. 'I')). forzosamente la mitad derecha estará ordenada de manera decreciente. deberíamos añadir alguna instrucción para que se muestren los correspondientes mensajes. Es decir. Las funciones palindromo4 (que es la que utilizamos) y estaOrdenado quedan como sigue: 126 . Algunos ejemplos de ejecución de la función monte (Función 119. end Función 123. para determinar si un vector es un monte basta con comprobar si es un palíndromo y si está ordenada su mitad izquierda pues. si ésta está ordenada y todo el vector es un palíndromo. % && estaOrdenado(alReves(mitad(v. No es necesario comprobar el orden en la mitad derecha • Solución 3. Si observamos los ejemplos anteriores. en realidad. 'D'))). Macario Polo Usaola >> v=[1 2 3 4 3 2] % No es un palíndromo >> v=[1 2 1 4 3 2] % No está ordenada la mitad izquierda v = v = 1 2 3 4 3 2 1 2 1 4 3 2 >> monte(v) >> monte(v) ans = ans = 0 0 >> v=[1 2 3 4 3 5] % No es un palíndromo y >> v=[1 2 3 4 3 2 1] % Es un monte no está ordenada la mitad derecha v = v = 1 2 3 4 3 2 1 1 2 3 4 3 5 >> monte(v) >> monte(v) ans = ans = 1 0 Figura 77. que a la conjunción de funciones que escribíamos en la Función 119 (página 124) le podemos quitar la última llamada: function r = monte(v) r=palindromo4(v) && estaOrdenado(mitad(v. 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 palíndromo ans = 0 Figura 78 127 . end end end Función 124. Sin embargo. disp('-No está ordenado'). esperamos que nos diga que no es un monte porque no es un palíndromo y además no está ordenado. end r= (sum(delDerecho==delReves)==length(delDerecho)). for i=1:length(texto) if (~isspace(texto(i))) delDerecho(pos)=texto(i). Instrucciones adicionales para mostrar mensajes Ahora. al ejecutar la función monte (Función 123) con el vector v=[1 2 1 4 3 2]. for i=1:length(delDerecho) delReves(i)=delDerecho(length(delDerecho)-i+1). disp('-No es un palíndromo'). al ejecutarla con ese ejemplo. for i=2:length(v) if v(i)<v(i-1) r=0. return. 46 ejercicios resueltos de MATLAB function r = palindromo4(texto) delDerecho=char(). end end delReves=char(). if r==0 disp('No es un monte porque:'). pos=1. pos=pos+1. end end function r = estaOrdenado(v) r=1. las llamadas a palindromo4 y a estaOrdenado están separadas con &&: al usar estos dos símbolos para enlazar dos condiciones. Los resultados pueden ser diferentes según usemos & o && 128 . ya no se evalúa la segunda función. MATLAB detiene la ejecución en el momento en que encuentra una falsa. Para que se evalúen todas las condiciones debemos usar un solo &: function r = monte(v) r=palindromo4(v) & estaOrdenado(mitad(v. end Función 125. En el ejemplo de v=[1 2 3 1 2 3]. >> v >> v v = v = 1 2 1 4 3 2 1 2 1 4 3 2 >> monte(v) >> monte(v) No es un monte porque: No es un monte porque: -‐No es un palíndromo -‐No es un palíndromo -‐No está ordenado ans = ans = 0 0 Figura 79. 'I')). se nos da sólo uno de los dos mensajes que esperábamos. puesto que el vector no es un palíndromo. 'I')). en la Función 123. 'I')). los resultados son diferentes: palindromo4(v) && estaOrdenado(mitad(v. Esto sucede porque. Con un solo ampersand. Macario Polo Usaola Como vemos. que determina el orden. palindromo4(v) & estaOrdenado(mitad(v. siempre se evalúan ambas funciones Como se ve. siendo cada valor de x y de y un número entre -‐1 y +1. Conocido el valor de n. Puesto que conocemos la superficie del cuadrado (lado x lado = 2x2 = 4) y la expresión para calcular la del círculo (π·radio2=π·12).5). y). cada dardo caerá en dos coordenadas aleatorias (x. Al finalizar el bucle. las coordenadas x e y de cada dardo se generan en las dos líneas marcadas en amarillo con la función rand(). calculamos el valor aproximado de π mediante la expresión de la Figura 80: 129 . Asumiendo que el centro del círculo (y del cuadrado) están en las coordenadas (0. a continuación comprobamos si la suma de sus cuadrados de x e y es menor o igual a 1 (if marcado en verde). Cálculo de pi (π) Mediante el algoritmo de Montecarlo es posible calcular el valor aproximado de π. La siguiente función es una posible solución: en ella. 0). Partimos de una circunferencia de radio 1 inscrita en un cuadrado de lado 2. Scírculo dardoscírculo ≈ ⇒ Scuadrado dardostotales π dardoscírculo ⇒ ≈ ⇒ 4 dardostotales dardoscírculo ⇒ π ≈ 4· dardostotales Figura 80. • Solución 1. como se observa. el dardo está dentro. Para determinar si un dardo ha caído dentro del círculo utilizaremos el teorema de pitágoras: si la suma de los cuadrados de x y de y es menor que la hipotenusa (que vale 1). y fuera en otro caso. caso en el que incrementamos la variable nd. que sirven para determinar si la coordenada respectiva es positiva o negativa (el signo se determina en función de que otro número aleatorio sea o no mayor que 0. que generan un número aleatorio entre 0 y 1. multiplicamos x por signoX e y por signoY. 46 ejercicios resueltos de MATLAB Ejercicio 44. Al terminar el proceso. mediante un bucle for i=1:n simularemos el lanzamiento de los n dardos. la proporción entre el número de dardos dentro del círculo y el número de dardos totales será aproximadamente igual a la ralción entre la superficie del círculo y la superficie del cuadrado. que representa el número de disparos que han caído dentro del círculo. Para aproximar el valor de π. podemos despejar un valor aproximado para π. lanzamos un número grande de dardos aleatoriamente dentro del cuadrado. Determinación del valor aproximado de π Se pide la escritura de una función en MATLAB que tome como parámetro el número de dardos que se desea lanzar (n) y devuelva el valor calculado para π. 14436 Figura 81. end x=rand()*signoX. el código puede simplificarse sin perder efectividad: 130 .5 signoY=-1. end if rand()<=0.000 nos dan los siguientes resultados: >> piMontecarlo(100000) >> piMontecarlo(100000) ans = ans = 3. end end result=4*nd/n. else signoX=+1. Cálculo aproximado de π mediante el método de Montecarlo Dos ejecuciones distintas de la función para n=100. end Función 126. no es preciso generar el signo. if (x^2+y^2<=1) nd=nd+1. for i=1:1:n if rand()<=0. else signoY=+1. Puesto que.5 signoX=-1. Por tanto. result=0. Macario Polo Usaola function result=piMontecarlo(n) nd=0. y=rand()*signoY. al determinar si el dardo está dentro o fuera elevamos al cuadrado las dos coordenadas del dardo (líneas en verde de la función anterior). pues en la comparación la suma no será nunca un número negativo.14316 3. Dos valores de π bastante aproximados al valor real • Solución 2. usaremos la función plot(x. end Función 127. página 130). result=4*nd/n. plot(x. y). y=rand(). y. podemos hacer que MATLAB nos dibuje el círculo de radio 1 y los puntos que representan los lugares en que han caído los dardos. result=0. plot(x. hold on. Modificamos el código de la primera solución que hemos dado a este ejercicio (Función 126. y=rand()*signoY. end end result=4*nd/n. else signoY=+1. Cálculo aproximado de π y su representación gráfica 131 . for i=1:1:n x=rand(). end Función 128. Además de calcular el valor aproximado de π.5 signoX=-1. La Función 126 puede simplificarse y no generar signos para las coordenadas • Solución 3. end end t=0:pi/30:2*pi. y). x=cos(t). que dibuja un punto en las coordenadas que se pasan como parámetro. 'red').5 signoY=-1. if (x^2+y^2<=1) nd=nd+1. if (x^2+y^2<=1) nd=nd+1. for i=1:1:n if rand()<=0. function result=piMontecarlo3(n) nd=0. y=sin(t). end x=rand()*signoX. end if rand()<=0. y una serie de instrucciones para que se dibuje el círculo. else signoX=+1. Para ello. result=0. 46 ejercicios resueltos de MATLAB function result=piMontecarlo2(n) nd=0. Macario Polo Usaola En el código anterio se marcan en amarillo las instrucciones plot y hold on. en la tercera dibujamos. El resultado por consola es: >> piMontecarlo3(100000) ans = 3.14636 Figura 82 Y el resultado en la ventana gráfica. Ésta es necesaria para que todos los puntos se pinten en la misma ventana. En azul aparecen tres líneas que utilizamos para dibujar un círculo rojo de radio 1: en la primera creamos un vector t con todos los valores desde 0 hasta 2π incrementando de π/30 en π/30. el coseno y el seno de cada valor almacenado en t. en la que se aprecian los cien mil puntos y la circunferencia en rojo es: Figura 83. En la segunda creamos dos vectores x e y con. respectivamente. Finalmente. Representación de la circunferencia goniométrica y los 100. en rojo (red) los vectores que acabamos de calcular y que tenemos almacenados en x e y.000 dardos lanzados 132 . las coordenadas de la entrada y la de la salida. la dirección es hacia arriba. que coincidirán al principio con las de la entrada y que se irán actualizando mientras no coincidan con las de la salida. En movimientos iremos guardando todos los movimientos realizados por el objeto. 10) y la salida en (1. mediante movimientos aleatorios de un objeto. Entonces. La siguiente matriz (de la que se han omitido los ceros por claridad) representa un laberinto de 10x10. calculamos la nueva coordenada (que guardamos en siguiente) sumando o restando una fila o columna a la coordenadaActual. abajo. Procederemos de esta manera para las cuatro direcciones. En la siguiente función. Tras haber calculado la nueva posición. pasamos como parámetros el laberinto (en forma de una matriz de unos y ceros) y las coordenadas de entrada y salida (como sendos vectores con dos componentes). en la variable coordenadaActual. cuya coordenada actual la guardamos. por ejemplo. si ésta no coincide con un muro (es decir. en cada momento. entonces actualizamos la coordenada actual del objeto decrementando en 1 su fila. Se pide escribir una función en MATLAB que tome como parámetros una matriz que represente el laberinto. El objeto móvil dispondrá en cada momento de unas coordenadas. el objeto no está en la fila 1 y la casilla de arriba está libre. Si. la 133 . generamos un número aleatorio entre 0 y 1 (mediante rand()) que almacenamos en la variable direccion.1): 1 2 3 4 5 6 7 8 9 10 1 S 1 1 2 1 1 1 1 1 3 1 1 1 4 1 1 1 1 1 5 1 6 1 1 1 1 1 1 7 1 1 8 1 1 1 1 1 9 1 10 1 E • Solución 1. En función de su valor. Los valores uno representan muros y los valores cero representan zonas por las que puede caminarse. Cada movimiento del móvil lo generaremos con un número aleatorio que representará la dirección en la que el objeto se pueda mover: arriba. y que permita. comprobamos si está dentro de los límites del laberinto. con la entrada en (10. llegar desde aquella hasta ésta. Al entrar a la función mostramos los valores de los parámetros y ponemos el cronómetro (función tic). La salida del laberinto Disponemos de una matriz de nxm (que representa un laberinto) en la que hay valores cero y uno. mientras la coordenada del objeto no coincida con la coordenada de la salida. derecha e izquierda. 46 ejercicios resueltos de MATLAB Ejercicio 45. entrada. siguiente(2)=coordenadaActual(2)-1. <=1: izquierda if direccion<=0. elseif direccion<=1 & coordenadaActual(2)>1 siguiente(1)=coordenadaActual(1). 1)) siguiente(1)=coordenadaActual(1)+1.5: derecha. ent. siguiente(2))==0 coordenadaActual=siguiente.25 & coordenadaActual(1)>1 siguiente(1)=coordenadaActual(1)-1. Búsqueda aleatoria del camino de salida de un laberinto Si ejecutamos la función con la siguiente línea de comando: disp(['Solución alcanzada en ' int2str(length(laberinto1(lab. siguiente(2)=coordenadaActual(2)+1. elseif direccion<=0. actualizamos la coordenadaActual. function [movimientos] = laberinto1( laberinto.75 & coordenadaActual(1)<length(laberinto(:. movimientos=[movimientos. salida ) entrada salida laberinto tic movimientos=[]. while (coordenadaActual(1)~=salida(1) || coordenadaActual(2)~=salida(2)) direccion=rand(). % <=0. siguiente(2)=coordenadaActual(2). end end toc end Función 129. almacenamos la nueva posición en el vector de movimientos y paramos el cronómetro para saber cuánto se ha tardado en encontrar la salida. % <=0.5 & coordenadaActual(2)<length(laberinto) siguiente(1)=coordenadaActual(1). movimientos=[movimientos. siguiente(2)=coordenadaActual(2). coordenadaActual]. coordenadaActual=entrada. salida))) ' movimientos']) …el resultado es: 134 . <=0. Macario Polo Usaola casilla en el laberinto es cero). elseif direccion<=0.75: abajo.25: arriba. end if laberinto(siguiente(1). coordenadaActual]. que es la variable que devuelve el resultado de la función. Finalmente. en las posiciones que indique. vamos a la posición correspondiente en el laberinto y colocamos el valor 2. para cada coordenada contenida en él. • Solución 2.021913 seconds. la segunda. debemos recorrer este vector. Supongamos que se desea que la salida de la función muestre las casillas que ha recorrido el objeto para llegar desde la entrada a la salida. la cadena movimientos. 46 ejercicios resueltos de MATLAB >> disp(['Solución alcanzada en ' int2str(length(laberinto1(lab. salida))) ' movimientos']) entrada = 10 10 salida = 1 1 laberinto = 0 1 0 0 0 0 1 0 0 0 0 1 0 1 1 1 1 0 0 0 0 1 0 1 0 0 1 0 0 0 0 1 0 1 0 0 1 1 1 0 0 1 0 0 0 0 0 0 0 0 0 1 0 1 1 1 1 0 1 0 0 0 0 1 0 0 0 0 1 0 1 1 1 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 Elapsed time is 0. Solución alcanzada en 1118 movimientos Figura 84 El comando disp que escribimos en la consola de MATLAB compone un vector de tres cadenas de caracteres: la primera es el texto Solución alcanzada en. la tercera. ent. asignamos el nuevo laberinto a la variable camino. 135 . tomar cada una de sus coordenadas y colocar. por ejemplo) sobre el laberinto. En este caso. de manera que se representen las casillas visitadas. algún valor (el 2. una vez calculados los movimientos necesarios. Esto es lo que hacemos en la Función 130 con el bucle añadido al final: recorremos el vector de movimientos (formado a su vez por vectores de dos coordenadas) y. la transformación a texto de la longitud del resultado de ejecutar la función laberinto1 con los valores que pasamos como parámetros. :). siguiente(2))==0 coordenadaActual=siguiente. % <=0. <=0. % <=0. elseif direccion<=1 & coordenadaActual(2)>1 siguiente(1)=coordenadaActual(1). coordenadaActual=entrada. movimientos=[movimientos.5: derecha. elseif direccion<=0. entrada. siguiente(2)=coordenadaActual(2)-1. siguiente(2)=coordenadaActual(2). siguiente(2)=coordenadaActual(2)+1.25: arriba. coordenadaActual]. 1)) siguiente(1)=coordenadaActual(1)+1. Modificación de la Función 129 para que se muestren las casillas visitadas Para una determinada ejecución. salida ) entrada salida laberinto tic movimientos=[]. <=1: izquierda if direccion<=0. laberinto(casilla(1). end if laberinto(siguiente(1).75: abajo. toc end Función 130. Se han marcado las casillas visitadas por la Función 130 136 .25 & coordenadaActual(1)>1 siguiente(1)=coordenadaActual(1)-1.5 & coordenadaActual(2)<length(laberinto) siguiente(1)=coordenadaActual(1).75 & coordenadaActual(1)<length(laberinto(:. el resultado final es el siguiente: ans = 2 1 2 2 2 2 1 0 0 0 2 1 2 1 1 1 1 0 2 0 2 1 2 1 0 0 1 2 2 2 2 1 2 1 2 2 1 1 1 2 2 1 2 2 2 2 2 2 2 2 2 1 2 1 1 1 1 2 1 2 2 2 2 1 2 2 2 2 1 2 1 1 1 1 2 2 2 2 1 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 0 0 1 2 Figura 85. end camino=laberinto. elseif direccion<=0. movimientos=[movimientos. coordenadaActual]. casilla(2))=2. while (coordenadaActual(1)~=salida(1) || coordenadaActual(2)~=salida(2)) direccion=rand(). Macario Polo Usaola function camino = laberinto2( laberinto. end end for i=1:length(movimientos()) casilla=movimientos(i. siguiente(2)=coordenadaActual(2). Mientras no encontremos el valor (o sea. buscamos entre el elemento 3º y el 4º. mediante una búsqueda binaria. Supongamos que tenemos el siguiente vector ordenado: 1 2 3 4 5 6 7 8 9 10 v= 2 2 4 6 7 8 8 9 15 18 Supongamos que deseamos buscar el número 4 dentro de él (o sea. o -‐1 en caso de que no esté. x=4). buscamos ahora en la mitad inferior (es decir. comparamos el elemento buscado con el que se encuentra en la mitad del vector (el 5º. • Solución 1. actualizamos el límite inferior li. que es un 2): como 2<x. mientras r=-‐1) y los límites inferior y superior no se crucen (li<=ls). que inicalizamos a -‐1. Cotinuamos así hasta que lo encontremos o hasta que lleguemos a la conclusión de que el valor x no se encuentra en el vector. pues sabemos que x no estará a la izquierda de él. En la siguiente función devolveremos el resultado en la variable r. while r==-1 && li<=ls mitad=floor((ls+li)/2). entre las posiciones 1 a 4) y comparamos con el elemento que está en la mitad (el 2º. Búsqueda binaria Disponemos de un vector ordenado de enteros de longitud n. la posición en que se encuentra el valor x dentro de v. end end end Función 131. ls=length(v). si es menor. Se pide diseñar una función que tome como parámetro el vector v y un valor x y devuelva. actualizamos el valor de r (con lo que saldremos del bucle). Búsqueda binaria iterativa Si queremos conocer en cuántas iteraciones se encuentra el valor. 46 ejercicios resueltos de MATLAB Ejercicio 46. x) r=-1. actualizamos el límite superior ls porque x no estará a la derecha. vamos comparando el elemento que encontramos en la mitad: si el valor situado en la mitad es x. si es mayor. else ls=mitad-1. function r = busquedaBinaria1(v. li=1. que es un 7): como x<5. Mediante una búsqueda binaria. if v(mitad)==x r=mitad. añadimos al código anterior las instrucciones resaltadas en amarillo: 137 . elseif v(mitad)<x li=mitad+1. En li y ls guardamos los límites inferior y superior en los que la búsqueda está acotada. if v(mitad)==x r=mitad. buscamos el 200 en el mismo rango de valores: >> z=1:100 % Inicializamos el vector z con los naturales del 1 al 100 z = Columns 1 through 24 1 2 3 4 … Columns 97 through 100 97 98 99 100 >> busquedaBinaria1(z. li=1. elseif v(mitad)<x li=mitad+1. el número 6 entre los números 1 a 100. iteraciones=0. ls=length(v). end Función 132. x) r=-1. 6) >> busquedaBinaria1(z. Búsqueda binaria iterativa con indicación del número de iteraciones En la siguiente figura buscamos. else ls=mitad-1. a diferencia de la anterior. en el derecho. Dos resultados al ejecutar la Función 132 (se encuentra en la izquierda. end iteraciones=iteraciones+1. Macario Polo Usaola function r = busquedaBinaria1(v. end disp(['Valor encontrado en ' int2str(iteraciones) ' iteraciones']). while r==-1 && li<=ls mitad=floor((ls+li)/2). no devolvemos la posición en la que se encuentra el elemento. en el lado izquierdo. sino solamente un 1 si está o un -‐1 en caso contrario: 138 . A continuación damos una versión recursiva de la función de búsqueda binaria pero. y no en la derecha) • Solución 2. 200) Valor encontrado en 4 iteraciones Valor encontrado en 7 iteraciones ans = ans = 6 -‐1 Figura 86. 46 ejercicios resueltos de MATLAB function r = busquedaBinaria2(v. li=1. devolvemos un 1. devolvemos un -‐1. se actualiza li: li=5+1=6 y auxiliar=[8 8 9 15 18]. li=1. mitad=5. x) r=-1. actualizamos el límite inferior. Supongamos que buscamos el número 20 en el siguiente vector: 1 2 3 4 5 6 7 8 9 10 v= 2 2 4 6 7 8 8 9 15 18 Al llamar a la función por primera vez. r=-‐1. return. li=1+1=2 y auxiliar=[18]. actualizamos el superior. li:ls). Si es menor (if amarillo). Entramos al segundo nivel de recursividad. Ahora. guardamos en auxiliar el subvector que hay entre las posiciones li a ls y llamamos recursivamente a la función. end auxiliar=v(1. Implementación recursiva de la búsqueda binaria En el código anterior. r=busquedaBinaria2(auxiliar. mitad=1. mitad=floor((ls+li)/2). ls=2. elseif v(mitad)<x li=mitad+1. else ls=mitad-1. Cuando no estamos en alguno de los dos casos base. v es el vector auxiliar que nos ha llegado a la función desde el primer nivel: 1 2 3 4 5 v= 8 8 9 15 18 Ahora. Como v(1)=15<20. end Función 133. y se llama a la función con este subvector y el valor x=20. if li>ls r=-1. x). li=1. Previamente hemos comprobado los dos casos base de la recursividad: si se ha encontrado el elemento en la mitad. mitad=3. y se llama nuevamente a la función: 1 2 v= 15 18 En este tercer nivel de recursividad. li=3+1=4 y auxiliar=[15 18]. si es mayor (else verde). return elseif v(mitad)==x r=1. Como v(5)=7<20. si no se ha encontrado (el límite inferior es mayor que el superior). r=-‐1. calculamos la mitad y comparamos el elemento situado en esa posición con x. llamándose nuevamente a la función: 139 . Como v(3)=9<20. ls=10. ls=length(v). r=-‐1. li=1. ls=5. 20) ans = -‐1 Figura 87. con el cual llamamos nuevamente a la función: v= En esta nueva llamada. Resultado de ejecutar una búsqueda binaria recursiva en un vector. ls=1. Se evalúa el primer caso base de la recursividad (li>ls) y. li=1. r=-‐1. como la condición es cierta. Como v(1)=18<20. se va devolviendo el -‐1 hasta llegar a la llamada original desde la línea de comando: >> v v = 2 2 4 6 7 8 8 9 15 18 >> busquedaBinaria2(v. mitad=0. ls=0. Macario Polo Usaola 1 v= 18 Ahora. obteniendo un vector vacío. r=-‐1. li=1. mitad=1. se hace li=2 y recortamos el vector desde la posición 2 hasta la 1. con resultado infructuoso 140 .