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