Aritmética en Haskell Taller de Álgebra I Primer cuatrimestre de 2014
Algoritmo de división Para obtener el cociente y resto entre dos números enteros, tenemos las funciones div y mod, respectivamente.
Algoritmo de división Para obtener el cociente y resto entre dos números enteros, tenemos las funciones div y mod, respectivamente. Sin embargo, no necesitamos que estas funciones sean primitivas, sino que... podemos programarlas nosotros mismos!
Algoritmo de división Para obtener el cociente y resto entre dos números enteros, tenemos las funciones div y mod, respectivamente. Sin embargo, no necesitamos que estas funciones sean primitivas, sino que... podemos programarlas nosotros mismos! Esto corresponde a programar algún algoritmo de división...
Algoritmo de división Para obtener el cociente y resto entre dos números enteros, tenemos las funciones div y mod, respectivamente. Sin embargo, no necesitamos que estas funciones sean primitivas, sino que... podemos programarlas nosotros mismos! Esto corresponde a programar algún algoritmo de división... Alguna idea?
Algoritmo de división Para obtener el cociente y resto entre dos números enteros, tenemos las funciones div y mod, respectivamente. Sin embargo, no necesitamos que estas funciones sean primitivas, sino que... podemos programarlas nosotros mismos! Esto corresponde a programar algún algoritmo de división... Alguna idea? Idea: Para calcular div n m podemos usar la fórmula recursiva: { 0 si n < m div n m = 1 + div (n-m) m si n m
Algoritmo de división Para obtener el cociente y resto entre dos números enteros, tenemos las funciones div y mod, respectivamente. Sin embargo, no necesitamos que estas funciones sean primitivas, sino que... podemos programarlas nosotros mismos! Esto corresponde a programar algún algoritmo de división... Alguna idea? Idea: Para calcular div n m podemos usar la fórmula recursiva: { 0 si n < m div n m = 1 + div (n-m) m si n m Cómo sería el código Haskell?
Algoritmo de división Para obtener el cociente y resto entre dos números enteros, tenemos las funciones div y mod, respectivamente. Sin embargo, no necesitamos que estas funciones sean primitivas, sino que... podemos programarlas nosotros mismos! Esto corresponde a programar algún algoritmo de división... Alguna idea? Idea: Para calcular div n m podemos usar la fórmula recursiva: { 0 si n < m div n m = 1 + div (n-m) m si n m Cómo sería el código Haskell? Cómo calculamos el resto?
Algoritmo de Euclides El Algoritmo de Euclides calcula el máximo común divisor entre dos números a, b Z +.
Algoritmo de Euclides El Algoritmo de Euclides calcula el máximo común divisor entre dos números a, b Z +. Recordemos el algoritmo en su versión imperativa: 1 r 0 := a; 2 r 1 := b; 3 Mientras r i 0, hacer: 4 r i+1 := r i 1 mod r i ; 5 i := i + 1; 6 Fin 7 El resultado es r i 1 ;
Algoritmo de Euclides Cómo sería en Haskell?
Algoritmo de Euclides Cómo sería en Haskell? mcd :: Int -> Int -> Int
Algoritmo de Euclides Cómo sería en Haskell? mcd :: Int -> Int -> Int mcd a 0 = a
Algoritmo de Euclides Cómo sería en Haskell? mcd :: Int -> Int -> Int mcd a 0 = a mcd a b = mcd b (mod a b)
Algoritmo de Euclides Cómo sería en Haskell? mcd :: Int -> Int -> Int mcd a 0 = a mcd a b = mcd b (mod a b) El peor caso del algoritmo se obtiene cuando a y b son dos números consecutivos de la sucesión de Fibonacci (Lamé, 1795 1870).
Algoritmo de Euclides Cómo sería en Haskell? mcd :: Int -> Int -> Int mcd a 0 = a mcd a b = mcd b (mod a b) El peor caso del algoritmo se obtiene cuando a y b son dos números consecutivos de la sucesión de Fibonacci (Lamé, 1795 1870). En general, el número de divisiones que realiza el algoritmo nunca supera 5 veces el número de dígitos de a y b, con lo cual la cantidad de llamadas recursivas está acotada por 5 log 10 (a).
Cambio de base en Haskell Problema: Dados a, b Z + con b > 1, escribir el número a en base b.
Cambio de base en Haskell Problema: Dados a, b Z + con b > 1, escribir el número a en base b. Por ejemplo... 1 Si a = 10 y b = 2, entonces la respuesta es 1010 2. 2 Si a = 17 y b = 3, entonces la respuesta es 122 3. 3 Si a = 145 y b = 10, entonces la respuesta es 145 10.
Cambio de base en Haskell Problema: Dados a, b Z + con b > 1, escribir el número a en base b. Por ejemplo... 1 Si a = 10 y b = 2, entonces la respuesta es 1010 2. 2 Si a = 17 y b = 3, entonces la respuesta es 122 3. 3 Si a = 145 y b = 10, entonces la respuesta es 145 10. Cómo lo haríamos en Haskell si representamos la salida como una lista de enteros?
Cambio de base en Haskell Problema: Dados a, b Z + con b > 1, escribir el número a en base b. Por ejemplo... 1 Si a = 10 y b = 2, entonces la respuesta es 1010 2. 2 Si a = 17 y b = 3, entonces la respuesta es 122 3. 3 Si a = 145 y b = 10, entonces la respuesta es 145 10. Cómo lo haríamos en Haskell si representamos la salida como una lista de enteros? Cómo cambiamos el programa si queremos representar la salida como una cadena de caracteres?
Cambio de base en Haskell Problema: Dados a, b Z + con b > 1, escribir el número a en base b. Por ejemplo... 1 Si a = 10 y b = 2, entonces la respuesta es 1010 2. 2 Si a = 17 y b = 3, entonces la respuesta es 122 3. 3 Si a = 145 y b = 10, entonces la respuesta es 145 10. Cómo lo haríamos en Haskell si representamos la salida como una lista de enteros? Cómo cambiamos el programa si queremos representar la salida como una cadena de caracteres? Qué problema tiene esta representación si luego queremos usar el resultado para cálculos posteriores?
Ejercicios 1 Consideremos la sucesión t 1, t 2,..., tal que t n es la cantidad de llamadas recursivas del Algoritmo de Euclides cuando se ejecuta con a = F n y b = F n 1 (donde F n representa el n-ésimo número de Fibonacci). Escribir un programa que tome como parámetro un entero n y que retorne t n. 2 Graficar la sucesión t 1, t 2,... definida en el ejercicio anterior. 3 Escribir un programa que tome un entero b > 1 y un entero a representado en base b (expresado como una lista de enteros) y que retorne un Int con el entero a. 4 Escribir un programa que tome un entero b > 1 y un entero a representado en base b (expresado como una lista de enteros) y que retorne una lista de enteros con el entero representado en base 10.