Acciones

Diferencia entre revisiones de «Relación 7»

De Informática de 1º de Matemáticas [Curso 2021-22, Grupo 3]

(Página creada con «<source lang='haskell'> -- I1M 2021-22: -- El algoritmo de Luhn -- Departamento de Ciencias de la Computación e I.A. -- Universidad de Sevilla -- =========================…»)
 
 
Línea 1: Línea 1:
<source lang='haskell'>
<source lang='haskell'>
-- I1M 2021-22:
-- I1M 2021-22: Rel_7.hs
-- El algoritmo de Luhn
-- El algoritmo de Luhn
-- Departamento de Ciencias de la Computación e I.A.
-- Departamento de Ciencias de la Computación e I.A.
Línea 12: Línea 12:
-- El objetivo de esta relación es estudiar un algoritmo para validar
-- El objetivo de esta relación es estudiar un algoritmo para validar
-- algunos identificadores numéricos como los números de algunas tarjetas
-- algunos identificadores numéricos como los números de algunas tarjetas
-- de crédito; por ejemplo, las de tipo Visa o Master Card.
-- de crédito; por ejemplo, las de tipo Visa o Master Card.
--
--
-- El algoritmo que vamos a estudiar es el algoritmo de Luhn consistente
-- 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
-- en aplicar los siguientes pasos a los dígitos del número de la
-- tarjeta.  
-- tarjeta.
--    1. Se invierten los dígitos del número; por ejemplo, [9,4,5,5] se
--    1. Se invierten los dígitos del número; por ejemplo, [9,4,5,5] se
--      transdforma en [5,5,4,9].
--      transdforma en [5,5,4,9].
Línea 25: Línea 25:
--      se transforma en 5 + (1 + 0) + 4 + (1 + 8) = 19.
--      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
--    4. Si el último dígito de la suma es 0, el número es válido; y no
--      lo es, en caso contrario.  
--      lo es, en caso contrario.
--
--
-- A los números válidos, los llamaremos números de Luhn.  
-- A los números válidos, los llamaremos números de Luhn.


-- ---------------------------------------------------------------------
-- ---------------------------------------------------------------------
Línea 33: Línea 33:
--    digitosInv :: Integer -> [Integer]
--    digitosInv :: Integer -> [Integer]
-- tal que (digitosInv n) es la lista de los dígitos del número n. en
-- tal que (digitosInv n) es la lista de los dígitos del número n. en
-- orden inverso. Por ejemplo,  
-- orden inverso. Por ejemplo,
--    digitosInv 320274  ==  [4,7,2,0,2,3]
--    digitosInv 320274  ==  [4,7,2,0,2,3]
-- ---------------------------------------------------------------------
-- ---------------------------------------------------------------------
-- Álvaro Galisteo:


digitosInv :: Integer -> [Integer]
digitosInv :: Integer -> [Integer]
digitosInv n = undefined
digitosInv n = reverse [read [x] :: Integer | x <- show n ]


-- ---------------------------------------------------------------------
-- ---------------------------------------------------------------------
Línea 46: Línea 48:
-- elementos en las posiciones impares (empezando a contar en cero y
-- elementos en las posiciones impares (empezando a contar en cero y
-- dejando igual a los que están en posiciones pares. Por ejemplo,
-- 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]    ==  [4,18,5,10]
--    doblePosImpar [4,9,5,5,7]  ==  [4,18,5,10,7]
--    doblePosImpar [4,9,5,5,7]  ==  [4,18,5,10,7]
-- ---------------------------------------------------------------------
-- ---------------------------------------------------------------------
-- Álvaro Galisteo:


doblePosImpar :: [Integer] -> [Integer]
doblePosImpar :: [Integer] -> [Integer]
doblePosImpar = undefined
doblePosImpar [] = []
doblePosImpar [x] = [x]
doblePosImpar (x:y:xs) = [x,2*y] ++ doblePosImpar xs


-- ---------------------------------------------------------------------
-- ---------------------------------------------------------------------
Línea 57: Línea 63:
--    sumaDigitos :: [Integer] -> Integer
--    sumaDigitos :: [Integer] -> Integer
-- tal que (sumaDigitos ns) es la suma de los dígitos de ns. Por
-- tal que (sumaDigitos ns) es la suma de los dígitos de ns. Por
-- ejemplo,  
-- ejemplo,
--    sumaDigitos [10,5,18,4] = 1 + 0 + 5 + 1 + 8 + 4 =
--    sumaDigitos [10,5,18,4] = 1 + 0 + 5 + 1 + 8 + 4 =
--                            = 19
--                            = 19
-- ---------------------------------------------------------------------
-- ---------------------------------------------------------------------
-- Álvaro Galisteo:


sumaDigitos :: [Integer] -> Integer
sumaDigitos :: [Integer] -> Integer
sumaDigitos ns = undefined
sumaDigitos ns = sum [sumaDigitos' x | x <- ns]
 
sumaDigitos' :: Integer -> Integer
sumaDigitos' n = sum [read [x] :: Integer | x <- show n ]


-- ---------------------------------------------------------------------
-- ---------------------------------------------------------------------
-- Ejercicio 4. Definir la función
-- Ejercicio 4. Definir la función
--    ultimoDigito :: Integer -> Integer
--    ultimoDigito :: Integer -> Integer
-- tal que (ultimoDigito n) es el último dígito de n. Por ejemplo,
-- tal que (ultimoDigito n) es el último dígito de n. Por ejemplo,
Línea 72: Línea 83:
--    ultimoDigito  0 == 0
--    ultimoDigito  0 == 0
-- ---------------------------------------------------------------------
-- ---------------------------------------------------------------------
-- Álvaro Galisteo:


ultimoDigito :: Integer -> Integer
ultimoDigito :: Integer -> Integer
ultimoDigito n = undefined
ultimoDigito n = mod n 10


-- ---------------------------------------------------------------------
-- ---------------------------------------------------------------------
-- Ejercicio 5. Definir la función  
-- Ejercicio 5. Definir la función
--    luhn :: Integer -> Bool
--    luhn :: Integer -> Bool
-- tal que (luhn n) se verifica si n es un número de Luhn. Por ejemplo,
-- tal que (luhn n) se verifica si n es un número de Luhn. Por ejemplo,
Línea 83: Línea 96:
--    luhn 1234567898765432  ==  False
--    luhn 1234567898765432  ==  False
-- ---------------------------------------------------------------------
-- ---------------------------------------------------------------------
-- Álvaro Galisteo:


luhn :: Integer -> Bool
luhn :: Integer -> Bool
luhn n = undefined
luhn n = ultimoDigito (sumaDigitos (doblePosImpar (digitosInv n))) == 0


</source>
</source>

Revisión actual del 12:50 15 ene 2022

-- I1M 2021-22: Rel_7.hs
-- El algoritmo de Luhn
-- Departamento de Ciencias de la Computación e I.A.
-- Universidad de Sevilla
-- =====================================================================

-- ---------------------------------------------------------------------
-- § Introducción                                                     --
-- ---------------------------------------------------------------------

-- El objetivo de esta relación 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
--       transdforma 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, los llamaremos números de Luhn.

-- ---------------------------------------------------------------------
-- Ejercicio 1. Definir la función
--    digitosInv :: Integer -> [Integer]
-- tal 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]
-- ---------------------------------------------------------------------

-- Álvaro Galisteo:

digitosInv :: Integer -> [Integer]
digitosInv n = reverse [read [x] :: Integer | x <- show n ]

-- ---------------------------------------------------------------------
-- Ejercicio 2. Definir la función
--    doblePosImpar :: [Integer] -> [Integer]
-- tal que (doblePosImpar ns) es la lista obtenida doblando los
-- elementos 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]
-- ---------------------------------------------------------------------

-- Álvaro Galisteo:

doblePosImpar :: [Integer] -> [Integer]
doblePosImpar [] = []
doblePosImpar [x] = [x]
doblePosImpar (x:y:xs) = [x,2*y] ++ doblePosImpar xs

-- ---------------------------------------------------------------------
-- Ejercicio 3. Definir la función
--    sumaDigitos :: [Integer] -> Integer
-- tal que (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
-- ---------------------------------------------------------------------

-- Álvaro Galisteo:

sumaDigitos :: [Integer] -> Integer
sumaDigitos ns = sum [sumaDigitos' x | x <- ns] 

sumaDigitos' :: Integer -> Integer
sumaDigitos' n = sum [read [x] :: Integer | x <- show n ]

-- ---------------------------------------------------------------------
-- Ejercicio 4. Definir la función
--    ultimoDigito :: Integer -> Integer
-- tal que (ultimoDigito n) es el último dígito de n. Por ejemplo,
--    ultimoDigito 123 == 3
--    ultimoDigito   0 == 0
-- ---------------------------------------------------------------------

-- Álvaro Galisteo:

ultimoDigito :: Integer -> Integer
ultimoDigito n = mod n 10 

-- ---------------------------------------------------------------------
-- Ejercicio 5. Definir la función
--    luhn :: Integer -> Bool
-- tal que (luhn n) se verifica si n es un número de Luhn. Por ejemplo,
--    luhn 5594589764218858  ==  True
--    luhn 1234567898765432  ==  False
-- ---------------------------------------------------------------------

-- Álvaro Galisteo:

luhn :: Integer -> Bool
luhn n = ultimoDigito (sumaDigitos (doblePosImpar (digitosInv n))) == 0