Ir al contenido principal

El algoritmo de Luhn

El objetivo de este ejercicio es estudiar un algoritmo para validar algunos identificadores numéricos como los números de algunas tarjetas de crédito; por ejemplo, las de tipo Visa o Master Card.

El algoritmo que vamos a estudiar es el algoritmo de Luhn consistente en aplicar los siguientes pasos a los dígitos del número de la tarjeta.

  1. Se invierten los dígitos del número; por ejemplo, [9,4,5,5] se transforma en [5,5,4,9].
  2. Se duplican los dígitos que se encuentra en posiciones impares (empezando a contar en 0); por ejemplo, [5,5,4,9] se transforma en [5,10,4,18].
  3. Se suman los dígitos de cada número; por ejemplo, [5,10,4,18] se transforma en 5 + (1 + 0) + 4 + (1 + 8) = 19.
  4. Si el último dígito de la suma es 0, el número es válido; y no lo es, en caso contrario.

A los números válidos, se les llama números de Luhn.

Definir las siguientes funciones:

   digitosInv    :: Integer -> [Integer]
   doblePosImpar :: [Integer] -> [Integer]
   sumaDigitos   :: [Integer] -> Integer
   ultimoDigito  :: Integer -> Integer
   luhn          :: Integer -> Bool

tales que

  • digitosInv n es la lista de los dígitos del número n, en orden inverso. Por ejemplo,
     digitosInv 320274  ==  [4,7,2,0,2,3]
  • doblePosImpar ns es la lista obtenida doblando los elementos de ns en las posiciones impares (empezando a contar en cero y dejando igual a los que están en posiciones pares. Por ejemplo,
     doblePosImpar [4,9,5,5]    ==  [4,18,5,10]
     doblePosImpar [4,9,5,5,7]  ==  [4,18,5,10,7]
  • sumaDigitos ns es la suma de los dígitos de ns. Por ejemplo,
     sumaDigitos [10,5,18,4] = 1 + 0 + 5 + 1 + 8 + 4 =
                             = 19
  • ultimoDigito n es el último dígito de n. Por ejemplo,
     ultimoDigito 123 == 3
     ultimoDigito   0 == 0
  • luhn n se verifica si n es un número de Luhn. Por ejemplo,
     luhn 5594589764218858  ==  True
     luhn 1234567898765432  ==  False

Leer más…

Subconjuntos de un conjunto

Definir la función

   subconjuntos :: [a] -> [[a]]

tal que subconjuntos xs es la lista de las subconjuntos de la lista xs. Por ejemplo,

   λ> subconjuntos [2,3,4]
   [[2,3,4],[2,3],[2,4],[2],[3,4],[3],[4],[]]
   λ> subconjuntos [1,2,3,4]
   [[1,2,3,4],[1,2,3],[1,2,4],[1,2],[1,3,4],[1,3],[1,4],[1],
      [2,3,4],  [2,3],  [2,4],  [2],  [3,4],  [3],  [4], []]

Comprobar con QuickChek que el número de elementos de subconjuntos xs es 2 elevado al número de elementos de xs.

Leer más…

Producto cartesiano de dos conjuntos

Definir la función

   producto :: [a] -> [b] -> [(a,b)]

tal que producto xs ys es el producto cartesiano de xs e ys. Por ejemplo,

   producto [1,3] [2,4] == [(1,2),(1,4),(3,2),(3,4)]

Comprobar con QuickCheck que el número de elementos de producto xs y es el producto del número de elementos de xs y de ys.

Leer más…

Exponente de la mayor potencia de x que divide a y

Definir la función

   mayorExponente :: Integer -> Integer -> Integer

tal que mayorExponente a b es el exponente de la mayor potencia de a que divide a b. Por ejemplo,

   mayorExponente 2 8    ==  3
   mayorExponente 2 9    ==  0
   mayorExponente 5 100  ==  2
   mayorExponente 2 60   ==  2

Nota: Se supone que a > 1 y b > 0.

Leer más…

Número a partir de sus dígitos

Definir la función

   listaNumero :: [Integer] -> Integer

tal que listaNumero xs es el número formado por los dígitos xs. Por ejemplo,

   listaNumero [5]        == 5
   listaNumero [1,3,4,7]  == 1347
   listaNumero [0,0,1]    == 1

Leer más…

Suma de los digitos de un número

Definir la función

   sumaDigitos :: Integer -> Integer

tal que sumaDigitos n es la suma de los dígitos de n. Por ejemplo,

   sumaDigitos 3     ==  3
   sumaDigitos 2454  == 15
   sumaDigitos 20045 == 11

Leer más…

Dígitos de un número

Definir la función

   digitos :: Integer -> [Int]

tal que digitos n es la lista de los dígitos del número n. Por ejemplo,

   digitos 320274  ==  [3,2,0,2,7,4]

Leer más…

Algoritmo de Euclides del mcd

Dados dos números naturales, a y b, es posible calcular su máximo común divisor mediante el Algoritmo de Euclides. Este algoritmo se puede resumir en la siguiente fórmula:

   mcd(a,b) = a,                   si b = 0
            = mcd (b, a módulo b), si b > 0

Definir la función

   mcd :: Integer -> Integer -> Integer

tal que mcd a b es el máximo común divisor de a y b calculado mediante el algoritmo de Euclides. Por ejemplo,

   mcd 30 45  ==  15
   mcd 45 30  ==  15

Comprobar con QuickCheck que el máximo común divisor de dos números a y b (ambos mayores que 0) es siempre mayor o igual que 1 y además es menor o igual que el menor de los números a y b.

Leer más…

Potencia entera

Definir la función

   potencia :: Integer -> Integer -> Integer

tal que potencia x n es x elevado al número natural n. Por ejemplo,

   potencia 2 3  ==  8

Leer más…

Base de dato de actividades

Las bases de datos sobre actividades de personas pueden representarse mediante listas de elementos de la forma (a,b,c,d), donde a es el nombre de la persona, b su actividad, c su fecha de nacimiento y d la de su fallecimiento. Un ejemplo es la siguiente que usaremos a lo largo de este ejercicio,

   personas :: [(String,String,Int,Int)]
   personas = [("Cervantes","Literatura",1547,1616),
               ("Velazquez","Pintura",1599,1660),
               ("Picasso","Pintura",1881,1973),
               ("Beethoven","Musica",1770,1823),
               ("Poincare","Ciencia",1854,1912),
               ("Quevedo","Literatura",1580,1654),
               ("Goya","Pintura",1746,1828),
               ("Einstein","Ciencia",1879,1955),
               ("Mozart","Musica",1756,1791),
               ("Botticelli","Pintura",1445,1510),
               ("Borromini","Arquitectura",1599,1667),
               ("Bach","Musica",1685,1750)]

Definir las funciones

   nombres   :: [(String,String,Int,Int)] -> [String]
   musicos   :: [(String,String,Int,Int)] -> [String]
   seleccion :: [(String,String,Int,Int)] -> String -> [String]
   musicos'  :: [(String,String,Int,Int)] -> [String]
   vivas     :: [(String,String,Int,Int)] -> Int -> [String]

tales que

  • nombres bd es la lista de los nombres de las personas de la base de datos bd. Por ejemplo,
     λ> nombres personas
     ["Cervantes","Velazquez","Picasso","Beethoven","Poincare",
      "Quevedo","Goya","Einstein","Mozart","Botticelli","Borromini",
      "Bach"]
  • musicos bd es la lista de los nombres de los músicos de la base de datos bd. Por ejemplo,
     musicos personas  ==  ["Beethoven","Mozart","Bach"]
  • seleccion bd m es la lista de los nombres de las personas de la base de datos bd cuya actividad es m. Por ejemplo,
     λ> seleccion personas "Pintura"
     ["Velazquez","Picasso","Goya","Botticelli"]
     λ> seleccion personas "Musica"
     ["Beethoven","Mozart","Bach"]
  • musicos' bd es la lista de los nombres de los músicos de la base de datos bd. Por ejemplo,
     musicos' personas  ==  ["Beethoven","Mozart","Bach"]
  • vivas bd a es la lista de los nombres de las personas de la base de datos bd que estaban vivas en el año a. Por ejemplo,
     λ> vivas personas 1600
     ["Cervantes","Velazquez","Quevedo","Borromini"]

Leer más…