Desafío
Escriba el programa o función más corto para calcular el algoritmo de Luhn para verificar los números (tarjeta de crédito).
Algoritmo de Luhn explicado
Desde RosettaCode , este algoritmo para los propósitos de este desafío se especifica como tal, con la entrada de ejemplo de 49927398716
:
Reverse the digits, make an array:
6, 1, 7, 8, 9, 3, 7, 2, 9, 9, 4
Double the numbers in odd indexes:
6, 2, 7, 16, 9, 6, 7, 4, 9, 18, 4
Sum the digits in each number:
6, 2, 7, 7, 9, 6, 7, 4, 9, 9, 4
Sum all of the numbers:
6 + 2 + 7 + 7 + 9 + 6 + 7 + 4 + 9 + 9 + 4 = 70
If the sum modulo 10 is 0, then the number is valid:
70 % 10 = 0 => valid
Reglas IO
Entrada : una cadena o número (su elección), en el formato de entrada / salida de su idioma de elección
Salida : Un valor verdadero o falso , respectivamente, que indica si la entrada es válida o no de acuerdo con la prueba anterior.
Notas / Consejos
Intente no publicar accidentalmente su propia tarjeta de crédito o números de cuenta, si los usa para probar :)
Si la entrada es inválida e imposible de procesar con el algoritmo especificado (es decir, demasiado corto para trabajar), puede hacer lo que quiera, incluso hacer estallar mi computadora.
Sin embargo , la viñeta anterior no significa que su idioma pueda hacer lo que quiera con Números que son demasiado grandes para manejarlos. Si su idioma no es capaz de manejar un caso de prueba, considere tomar una cadena como entrada.
Ejemplos
Los siguientes ejemplos fueron validados con este script Python ; Si cree que uno está equivocado o tiene una pregunta, simplemente haga ping a @cat.
49927398716 True
49927398717 False
1234567812345670 True
1234567812345678 False
79927398710 False
79927398711 False
79927398712 False
79927398713 True
79927398714 False
79927398715 False
79927398716 False
79927398717 False
79927398718 False
79927398719 False
374652346956782346957823694857692364857368475368 True
374652346956782346957823694857692364857387456834 False
8 False **
0 True **
** según la implementación de Python, pero puede hacer cualquier cosa porque estos son demasiado cortos para ser elegibles por un estricto cumplimiento de la especificación.
Si alguno de los anteriores invalida las respuestas existentes (aunque creo que eso no debería ser posible), esas respuestas aún son válidas. Sin embargo, las nuevas respuestas, para ser válidas, deben seguir la especificación anterior.
Tabla de clasificación
fuente
echo -n
-1% 2/
se puede combinar en-2/
.1,
se puede reemplazar con0
(0 se coacciona a una matriz, luego+
se concatena).9>9*-
se puede reemplazar con9>+
(ya que solo nos preocupa el último dígito). Además, la comprobación de longitudes impares es un poco larga, el uso.,2%,\+
es más corto. Después de hacer esto, también podemos cambiar{16%}%
y(\0=
entrar{16}/
(dentro del bucle). Una vez hecho todo esto, que se verá algo como esto:.,2%,\+-2/0\+{{16%}/2*.9>+++}*10%!
.Python,
7369 caracteresfuente
D[-2::-2]
->D[1::2]
ya que el orden de una suma no es importante :)==0
se puede acortar a<1
Python 3, 77 bytes
fuente
C # 119 caracteres:
No es demasiado malo para un n00b código de golf en un lenguaje de tipos estáticos, espero.
Esto se puede reducir a 100 :
fuente
i%2<1?1:2
revés. Gracias.Golfscript - 34 caracteres
Número de ejemplo de la página de wikipedia 4992739871
fuente
.+(9%)
es muy innovador (para mí, de todos modos). ¡Me gusta! +10(9%)
es 9 y no 0).PHP, 108 bytes
fuente
Ruby - 85 caracteres
fuente
Haskell, 96 bytes
Debe haber una forma mejor / más corta, pero aquí está mi solución de Haskell en 96 caracteres :
Lamentablemente, la
digitToInt
función solo se puede usar si ustedimport Data.Char
primero. De lo contrario, podría bajar a 88 caracteres reemplazando((+(-48)).fromEnum)
condigitToInt
.fuente
Windows PowerShell, 82
Historia:
+1 + +3
Todavía se puede evaluar.fuente
Q, 63
uso
fuente
{0=mod[sum"J"$raze($)($)x*#:[x]#1 2]10}"I"$'(|)
una forma diferente de duplicar los índices impares.D, 144 bytes
Más legible:
fuente
APL, 28 bytes
Vista en despiece ordenado
Ejemplos
fuente
{0=10|+/⍎¨∊⍕¨⍵×⌽2-2|⍳⍴⍵}⍎¨
PowerShell 123
fuente
Perl,
464241 bytesIncluye +1 para
-p
Dar entrada en STDIN:
luhn.pl
:fuente
$=-=-$&-$&*/\G(..)+$/
?0..4
* 2 da0, 2, 4, 6, 8
pero5..9
da a10,12,14,16,18
qué suma1 3 5 7 9
tienen los mismos últimos dígitos11 13 15 17 19
que los mismos valores que0..9 * 2.2
si truncara a entero. El primero$&
ya aporta un factor1
, por1.2
lo que aún se necesita una corrección por .$=
solo puede contener enteros y comienza con un valor que termina en 0, por lo que se encarga del truncamiento. Los valores negativos son necesarios ya que la/\G/
expresión regular cambia cualquier$&
todavía en la pila de evaluación, por lo que deben cambiarseJavaScript (ES6), 61 bytes
No competidor, ya que JavaScript fue muy diferente en 2011.
Suma de dígitos de
2*n
es2*n
ifn in 0..4
,2*n-9
ifn in 5..9
. Dicho esto, toda la suma se puede calcular en un solo paso.fuente
Jalea ,
1211 bytesPruébalo en línea!(con todos los casos de prueba)
Cómo funciona
Alternativamente, para 12 bytes:
fuente
x86-16 ASM , IBM PC DOS, 23 bytes
Utiliza (abusa) la instrucción BCD a binario del x86
AAM
para manejar la división ymodulo 10
verificación de dígitos individuales .Tarjeta de entrada número puntero cadena
SI
, longitud enCX
. Salida:ZF
si es válida.Ejemplo de salida del programa de prueba:
Descargue el programa de prueba LUHN.COM IBM PC DOS.
fuente
Scala: 132
invocación:
fuente
JavaScript 1.8: 106 caracteres
Esta es una solución original que se me ocurrió antes de encontrar esta publicación:
Forma legible:
fuente
K4, 35 bytes
fuente
Retina ,
4342 bytesLa retina es (mucho) más nueva que este desafío.
La línea vacía principal es significativa.
Impresiones
0
para falsedad y1
verdaderos.Pruébalo en línea!(Ligeramente modificado para ejecutar todos los casos de prueba a la vez).
Explicación
Insertar
;
en cada posición para separar los dígitos.Desde el
r
ight, repetidamente emparejamos dos dígitos y duplicamos el izquierdo. De esta manera evitamos una inversión costosa de la lista.Emparejamos cada dígito y lo convertimos a esa cantidad de
1
s (es decir, convertimos cada dígito a unario).Esto coincide con cada número unario y lo convierte de nuevo a decimal reemplazándolo por su longitud. Junto con la etapa anterior, esto agrega los dígitos duplicados.
Una vez más, combinamos cada personaje y lo convertimos en tantos
1
s. Es decir, convertimos cada dígito individualmente de nuevo a unario. Esto también coincide con el;
separadores, que se tratan como ceros en la conversión, lo que significa que simplemente se eliminan. Dado que todos los números unarios están ahora juntos, hemos agregado automáticamente las representaciones unarias de todos los dígitos juntos.Al final, insertamos la longitud de toda la cadena, es decir, la representación decimal de la suma de comprobación unaria.
Finalmente contamos el número de coincidencias de esta expresión regular, es decir, verificamos si la representación decimal termina
0
, imprimiendo0
o en1
consecuencia.fuente
Powershell, 74 bytes
Explicación
Script de prueba
Salida
fuente
05AB1E ,
1210 bytesPruébalo en línea! o como un conjunto de pruebas
Explicación
fuente
Haskell: 97
Por alguna razón, esto no funciona para mí , así que aquí está mi versión
fuente
GNU sed, 140 bytes
(incluido +1 para la
-r
bandera)Sed casi nunca es el lenguaje más natural para la aritmética, pero aquí vamos:
fuente
APL, 38 bytes
espera el número como un número, no como una cadena, pero eso es solo porque tryAPL (comprensiblemente) no se implementa
⍎
más reducible, estoy seguro ...
fuente
PHP - 136 caracteres
fuente
MATL ,
2320 bytes (no competidor)Pruébalo en línea!
Salidas 1 para un número válido, 0 de lo contrario.
Ahorré tres bytes gracias a las sugerencias de Luis Mendo.
Explicación
fuente
Jalea , 14 bytes
Pruébalo en línea!
Explicación:
fuente