Recursión numérica. 1.- El algoritmo de Euclides para calcular el máximo común divisor de dos números naturales a y b es el siguiente: Si b = 0, entonces m.c.d.(a, b) = a. Si b > 0, entonces m.c.d.(a, b) = m.c.d.(b, c), donde c es el resto de dividir a entre b. Denir un procedimiento mcd que reciba dos números naturales, y devuelva el máximo común divisor de ambos, usando el algoritmo de Euclides para calcularlo. (mcd 2 3) (mcd 12 30) (mcd 700 300) =>1 =>6 =>100 2.- Queremos formar una escalera con bloques cuadrados, de forma que tenga un número determinado de escalones. Por ejemplo, una escalera con tres escalones tendría la siguiente forma: Denir un procedimiento numero-bloques que reciba el número de escalones de la escalera, y devuelva el número de bloques necesarios para construirla. (numero-bloques 1) (numero-bloques 3) (numero-bloques 10) =>2 =>12 =>110 3.- Denir un procedimiento suma-cuadrados-impares que reciba un número natural, n , mayor que 0, y devuelva la 1 hasta n. (suma-cuadrados-impares 1) (suma-cuadrados-impares 7) (suma-cuadrados-impares 4) suma de los cuadrados de los números impares desde =>1 =>84 =>10 4.- Denir un procedimiento suma-digitos que reciba un número natural n y devuelva la suma de sus dígitos. (suma-digitos 3) (suma-digitos 245) (suma-digitos 20045) =>3 =>11 =>11 5.- Denir un procedimiento es-digito? que reciba un dígito d y un número natural n , y devuelva #t si d es dígito de n y #f en caso contrario. (es-digito? 0 101) (es-digito? 3 101) (es-digito? 5 543210) =>#t =>#f =>#t 1 6.- Denir un procedimiento pega-digitos que reciba dos números naturales y devuelva el número resultante de pegar los dígitos. (pega-digitos 12 987) (pega-digitos 1204 7) (pega-digitos 100 100) =>12987 =>12047 =>100100 7.- Denir un procedimiento numero-capicua? que reciba un número natural n y devuelva #t si los dígitos que forman n son los mismos de izquierda a derecha que de derecha a izquierda, y #f en caso contrario. (numero-capicua? 1234) (numero-capicua? 1221) (numero-capicua? 4) =>#f =>#t =>#t 8.- Denir un procedimiento mayor-exponente que al recibir dos números naturales a y b devuelva el exponente de la mayor potencia de a que es menor o igual que b . (mayor-exponente 2 8) (mayor-exponente 2 9) (mayor-exponente 5 100) =>3 =>3 =>2 9.- En un templo hindú se encuentran tres varillas de platino. En una de ellas, hay 64 anillos de oro de distintos radios, colocados de mayor a menor. El trabajo de los monjes de ese templo consiste en pasarlos todos a la tercera varilla, usando la segunda como varilla auxiliar, con las siguientes condiciones: En cada paso sólo se puede mover un anillo. Nunca puede haber un anillo de mayor diámetro encima de uno de menor diámetro. La leyenda dice que cuando todos los anillos se encuentren en la tercera varilla, será el n del mundo. Denir un procedimiento num-pasos-hanoi que reciba el número de discos y devuelva el número de pasos necesarios para trasladarlos. (num-pasos-hanoi 2) (num-pasos-hanoi 7) (num-pasos-hanoi 64) =>3 =>127 =>18446744073709551615 2 Tipo abstracto de dato. Queremos denir un tipo abstracto de dato reloj que represente el tiempo que vemos en un reloj digital, que nos marca horas, minutos y segundos. Para ello, lo representaremos como una lista de tres elementos (horas minutos segundos ), de forma que horas ha de ser menor que 24, y minutos y segundos han de ser menores que 60. Procedimientos que forman el tipo abstracto de dato reloj. 10.- Denir un procedimiento reloj? que reciba un argumento y devuelva #t si dicho argumento representa un dato reloj representado correctamente y #f en caso contrario. (reloj? '2:5:34) (reloj? '(2 5 34)) (reloj? '(34 8 7)) =>#f =>#t =>#f 11.- Denir un procedimiento crea-reloj que reciba tres números naturales, horas , minutos y segundos , y devuelva una representación correcta del tiempo que marcan los argumentos. (crea-reloj 2 30 7) (crea-reloj 2 65 70) (crea-reloj 25 70 3680) =>(2 30 7) =>(3 6 10) =>(3 11 20) 12.- Denir un procedimiento horas , un procedimiento minutos y un procedimiento segundos que reciban un reloj y devuelvan, respectivamente, las horas, los minutos y los segundos que marca dicho reloj. (horas '(2 30 7)) (minutos '(2 30 7)) (segundos '(2 30 7)) =>2 =>30 =>7 Procedimientos independientes de la representación. 13.- Denir un procedimiento es-mas-temprano? que reciba dos relojes y devuelva #t si el primero marca un tiempo más temprano que el segundo. (es-mas-temprano? '(1 2 4) '(1 10 0)) (es-mas-temprano? '(1 2 4) (crea-reloj 1 60 52)) (es-mas-temprano? '(1 20 4) '(1 10 0)) =>#t =>#t =>#f 14.- Denir un procedimiento suma-tiempos que reciba dos relojes y devuelva otro que muestre la suma de los tiempos que marcan los argumentos. (suma-tiempos '(1 3 50) '(4 34 3)) (suma-tiempos '(1 3 50) '(4 80 90)) (suma-tiempos '(1 3 50) (crea-reloj 4 80 90)) 3 =>(5 37 53) =>suma-tiempos: argumentos incorrectos =>(6 25 20) 15.- Denir un procedimiento intervalo-de-tiempo que reciba dos relojes y devuelva el tiempo que hay entre ellos. (intervalo-de-tiempo '(2 30 10) '(5 35 40)) (intervalo-de-tiempo '(2 30 10) '(5 10 20)) (intervalo-de-tiempo '(2 30 10) '(5 10 5)) =>(3 5 30) =>(2 40 10) =>(2 39 55) 16.- Denir un procedimiento tiempo-en-medio que reciba dos relojes y devuelva el tiempo que está exactamente a mitad de camino de ambos. (tiempo-en-medio '(2 10 15) '(4 50 35)) (tiempo-en-medio '(2 10 15) '(5 50 35)) (tiempo-en-medio '(2 10 15) '(5 51 47)) =>(3 30 25) =>(4 0 25) =>(4 1 1) Cambio de representación. Ahora vamos a representar un dato reloj como una lista de tres elementos de la forma (par minutos segundos ), donde par es un par punteado de la forma (hora . am ) o de la forma (hora . pm ), siendo hora un número natural menor que 12, y minutos y segundos son números naturales menores que 60. Redenir los procedimientos que forman el tipo abstracto de dato para que se adecuen a la nueva representación. 4