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 = | 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 = | 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 = | 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 = | 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 = | 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