L'algoritmo Luhn per la verifica dei numeri di carta di credito, ecc


50

Sfida

Scrivi il programma o la funzione più breve per calcolare l' algoritmo Luhn per la verifica dei numeri (carta di credito).

Spiegazione dell'algoritmo Luhn

Da RosettaCode , questo algoritmo ai fini di questa sfida è specificato come tale, con l'input di esempio di 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

Regole IO

Input : una stringa o un numero (a tua scelta), nel formato di input / output della tua lingua preferito

Output : un valore di verità o falsa , rispettivamente, che indica se l'input è valido o meno secondo il test sopra.

Note / Suggerimenti

  • Cerca di non pubblicare accidentalmente la tua carta di credito o i tuoi numeri di conto, se li usi per testare :)

  • Se l'input non è valido e impossibile da elaborare con l'algoritmo specificato (ovvero, troppo corto per funzionare), puoi fare quello che vuoi, incluso far esplodere il mio computer.

  • Tuttavia , il proiettile precedente non significa che la tua lingua possa fare quello che vuole con numeri troppo grandi per essere gestiti. Se la tua lingua non è in grado di gestire un caso di prova, considera di prendere una stringa come input.

Esempi

I seguenti esempi sono stati validati con questo script Python ; se ritieni che uno abbia torto o hai una domanda, esegui semplicemente il ping su @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  **

** secondo l'implementazione di Python, ma puoi fare qualsiasi cosa perché questi sono troppo corti per essere idonei da una stretta aderenza alle specifiche.


Se una qualsiasi delle risposte precedenti invalida le risposte esistenti (anche se credo che ciò non dovrebbe essere possibile), tali risposte sono ancora valide. Tuttavia, le nuove risposte, per essere valide, devono seguire le specifiche di cui sopra.

Classifica

Risposte:


21

Golfscript - 24 caratteri

-1%{2+0!:0)*109%+}*10%8=

Spiegazione:

  1. -1% inverte la stringa
  2. {inizia un blocco (che usiamo come un ciclo). Ogni carattere nelle stringhe viene spinto in quanto è valore ASCII.
    1. 2+ aggiunge 2. (il valore ascii di una cifra è 48 + n, quindi ora abbiamo 50 + n e l'ultima cifra è n)
    2. 0!:0 inverte il valore di 0 e lo memorizza (tutto è una variabile), quindi abbiamo 1 sulla prima iterazione, 0 sulla seconda, ecc.
    3. )* aggiunge uno a questo valore e lo moltiplica, quindi moltiplichiamo per 2, quindi 1, quindi 2, ecc.
    4. 109% è resto modulo 109. Ciò riguarda solo i valori 5-9 che sono stati raddoppiati e li riduce al valore corretto.
    5. + aggiunge questo valore alla somma corrente
  3. }*termina il blocco e esegue un'operazione di "piegatura". Innanzitutto, viene premuto il primo carattere (poiché abbiamo invertito, questa è la cifra di controllo). Quindi, alternare spingendo ed eseguendo il blocco. Pertanto, stiamo usando il valore ASCII del primo carattere come valore iniziale per la somma corrente.
  4. 10% prende il resto modulo 10.
  5. 8= restituirà 1 se il valore è 8. Lo usiamo perché non abbiamo normalizzato il primo carattere premuto (la cifra di controllo).

Si potrebbe pensare che potremmo usare 8-invece di 2+salvare un personaggio cambiando 109%in 89%, tranne che avremmo bisogno di aggiungere uno spazio in modo che -sia la sottrazione (invece di -0).


11

GolfScript, 44 caratteri

-1%{16%}%2/1,\+{(\.{0=2*.9>9*-+}{;}if+}*10%!

Commento selezionato

È interessante notare che i primi due elementi seguenti mostrano tre usi completamente diversi %dell'operatore: selezione dell'array, mappa e mod. La maggior parte degli operatori GolfScript è "sensibile al contesto", offrendo loro comportamenti estremamente divergenti a seconda del tipo di argomenti.

  1. -1%inverte la stringa. Questo è importante poiché le coppie di cifre vengono contate da destra.
  2. {16%}% converte tutte le cifre ASCII in numeri, modificandole con 16.
  3. 2/ divide l'array in gruppi di 2.
  4. 1,è un modo economico per farlo [0].
  5. \+antepone efficacemente lo 0 alla matrice di cifre. Lo fa scambiando e concatenando.

Lo 0 viene anteposto in preparazione per la piega che verrà dopo. Anziché assumere un valore iniziale esplicito, la piega di GolfScript utilizza il primo elemento dell'array come valore iniziale.

Ora diamo un'occhiata alla funzione di piegatura effettiva. Questa funzione accetta due argomenti: il valore piegato e l'elemento corrente sull'array (che in questo caso sarà un array di 2 o (raramente) 1, a causa del 2/precedente). Supponiamo che gli argomenti siano 1 [2 3].

  1. (\.divide l'elemento dell'array più a sinistra, sposta l'array rimanente in primo piano, quindi lo copia. Stack ora assomiglia: 1 2 [3] [3].
  2. I ifcontrolla se la matrice è vuota (che è il caso per l'ultimo gruppo quando si tratta di un numero di conto dispari dimensioni). In tal caso, quindi non si verifica alcuna elaborazione speciale (basta estrarre l'array vuoto).
  3. Per un gruppo pari:
    1. 0= prende il primo (solo, in questo caso) elemento dell'array. 1 2 3
    2. 2* raddoppia il numero. 1 2 6
    3. .9>9*- sottrae 9 dal numero se è maggiore di 9. Implementato come: copia il numero, confronta con 9, moltiplica il risultato (che è 0 o 1) per 9, quindi sottrai. 1 2 6
    4. + aggiunge infine quello al primo numero. 1 8
  4. +(dopo il if) aggiunge il risultato del ifvalore originale, risultando nel nuovo valore piegato.

Dopo il completamento della piegatura, modiamo semplicemente con 10 ( 10%) e neghiamo il risultato ( !), in modo da restituire 1 se la somma è un multiplo di 10.


Questo sembra restituire 0 per il numero di esempio su wikipedia (49927398716)
gnibbler

nm. Ho dimenticato di usareecho -n
gnibbler,

1
@gnibbler: Haha, fallisci. :-P (Scherzi a parte, anche io sono stato colpito da quello, nei miei test iniziali.)
Chris Jester-Young,

1
Qui puoi salvare alcuni personaggi facili. -1% 2/può essere combinato in -2/. 1,può essere sostituito con 0(0 è forzato in un array, quindi +è concatenato). 9>9*-può essere sostituito con 9>+(poiché ci occupiamo solo dell'ultima cifra). Inoltre, il controllo per le lunghezze dispari è un po 'lungo, usando .,2%,\+è più breve. Dopo averlo fatto, possiamo anche cambiare {16%}%e (\0=in {16}/(all'interno del loop). Una volta fatto tutto questo, sembrerà qualcosa di simile a questo: .,2%,\+-2/0\+{{16%}/2*.9>+++}*10%!.
Nabb,

@Nabb: grazie! Li incorporerò nella mia soluzione, anche se sembra che tu ne abbia già uno che ti prende a calci in culo. :-)
Chris Jester-Young,

11

Python, 73 69 caratteri

def P(x):D=map(int,x);return sum(D+[d-d/5*9for d in D[-2::-2]])%10==0

4
Puoi salvare altri due caratteri non eseguendo il ciclo indietro: D[-2::-2]-> D[1::2]poiché l'ordine di una somma non è importante :)
ThinkChaos

==0può essere abbreviato in<1
Black Owl Kai il

10

Python 3, 77 byte

c=lambda a:sum(sum(divmod(int(a[-e-1])<<e%2,10))for e in range(len(a)))%10==0

9

Caratteri C # 119:

bool l(string n){return(String.Join("",n.Reverse().Select((x,i)=>(x-48)*(i%2<1?1:2)+"").ToArray()).Sum(x=>x-48))%10<1;}

Non troppo male per un n00b codice di golf in un linguaggio a tipizzazione statica, spero.

Questo può essere ridotto a 100 :

bool l(string n){return String.Join("",n.Reverse().Select((x,i)=>(x-48)*(i%2+1))).Sum(x=>x+2)%10<1;}

È una buona idea e un approccio interessante, ma non sembra funzionare. Almeno non con i miei pochi test. Sembra che la "i" nella tua prima lambda dovrebbe essere l'indice del personaggio nella stringa. Funziona come dovrebbe? In tal caso, perché invertire la stringa solo per modificarla in base alla posizione dell'indice? Sembra un po 'ridondante, no?
Nellius,

Ho testato solo una delle mie carte di credito e alcuni errori di uno da esso TBH. (Utilizzo del debugger VS 2008) L'algoritmo dovrebbe raddoppiare ogni seconda cifra a partire dalla LAST. Se non invertissi la stringa, sarebbe errata per stringhe con lunghezze dispari.
Mootinator

Si scopre che ho avuto il risultato di i%2<1?1:2tornare indietro. Grazie.
Mootinator

8

Golfscript - 34 caratteri

{15&}%.-2%\);-2%{.+(9%)}%+{+}*10%!

Numero di esempio da pagina Wikipedia 4992739871

{15&}%  does a bitwise and of each ascii digit with 00001111
        now I have a list of digits 
        [4 9 9 2 7 3 9 8 7 1 6]
.       makes a copy of the list, now I have two identical lists
        [4 9 9 2 7 3 9 8 7 1 6] [4 9 9 2 7 3 9 8 7 1 6]
-2%     like [::-2] in python takes every second element in reverse
        [4 9 9 2 7 3 9 8 7 1 6] [6 7 9 7 9 4]
\       swap the two lists around
        [6 7 9 7 9 4] [4 9 9 2 7 3 9 8 7 1 6]
);      drop the last digit off the list
        [6 7 9 7 9 4] [4 9 9 2 7 3 9 8 7 1]
-2%     same as before
        [6 7 9 7 9 4] [1 8 3 2 9]
{       for each item in the list ...
.+      ... double it ...
(       ... subtract 1 ...
9%      ... mod 9 ...
)}%     ... add 1 ...
        [6 7 9 7 9 4] [2 7 6 4 9]
+       join the two lists
        [6 7 9 7 9 4 2 7 6 4 9]
{+}*    add the elements up
        70
10%     mod 10
        0
!       invert the result
        1

Il .+(9%)è molto innovativo (per me, comunque). Mi piace! +1
Chris Jester-Young,

Tuttavia, GolfScript ha bisogno di un operatore di partizionamento, quindi non è necessario eseguire queste sciocchezze "elimina l'elemento finale e ripeti". :-)
Chris Jester-Young,

1
@ Chris, ne ho sentito parlare molti anni fa chiamato "scacciare nove". È un modo pulito per ricontrollare le aggiunte e le moltiplicazioni longhand
gnibbler

3
Questo non funzionerà per un valore pari a 0 raddoppiato (0(9%) è 9 e non 0).
Nabb,

8

PHP, 108 byte

<?function v($s,$t=0){for($i=strlen($s);$i>=0;$i--,$c=$s[$i])$t+=$c+$i%2*(($c>4)*-4+$c%5);return!($t % 10);}

7

Rubino - 85 caratteri

def f s
l=s.size
s.chars.map{|k|(i=k.to_i*((l-=1)%2+1))%10+i/10}.inject(:+)%10==0
end

Probabilmente lo sai, ma potresti fare .sum invece di .inject (: +) per salvare 7 byte
Håvard Nygård

7

Haskell, 96 byte

Deve esserci un modo migliore / più breve, ma ecco la mia soluzione Haskell in 96 caratteri :

l=(==0).(`mod`10).sum.zipWith($)(cycle[id,\x->x`mod`5*2+x`div`5]).reverse.map((+(-48)).fromEnum)

Purtroppo la digitToIntfunzione può essere utilizzata solo se import Data.Charprima. Altrimenti potrei arrivare a 88 caratteri sostituendoli ((+(-48)).fromEnum)con digitToInt.


6

Windows PowerShell, 82

filter f{!((''+($_[($_.length)..0]|%{+"$_"*($i++%2+1)})-replace'.','+$&'|iex)%10)}

Storia:

  • 13/02/2011 03:08 (84) Primo tentativo.
  • 13/02/2011 12:13 (82) Non ho bisogno di unirmi, poiché gli spazi non fanno male. +1 + +3può ancora essere valutato.

5

Q, 63

{0=mod[(+/)"I"$(,/)($)($)@["I"$'x;1+2*'(!)(_)((#)x)%2;*;2];10]}

uso

q){0=mod[(+/)"I"$(,/)($)($)@["I"$'x;1+2*'(!)(_)((#)x)%2;*;2];10]}"79927398711"
0b
q){0=mod[(+/)"I"$(,/)($)($)@["I"$'x;1+2*'(!)(_)((#)x)%2;*;2];10]}"79927398712"
0b
q){0=mod[(+/)"I"$(,/)($)($)@["I"$'x;1+2*'(!)(_)((#)x)%2;*;2];10]}"79927398713"
1b

47 byte con {0=mod[sum"J"$raze($)($)x*#:[x]#1 2]10}"I"$'(|)un modo diverso di raddoppiare gli indici dispari.
streetster,

5

D, 144 byte

bool f(S)(S s){int t(C)(C c){return to!int(c)-'0';}int n,v;foreach(i,c;array(retro(s))){v=i&1?t(c)*2:t(c);n+=v>=10?v%10+v/10:v;}return n%10==0;}

Più leggibilmente:

bool f(S)(S s)
{
    int t(C)(C c)
    {
        return to!int(c) - '0';
    }

    int n, v;

    foreach(i, c; array(retro(s)))
    {
        v = i & 1 ? t(c) * 2 : t(c);

        n += v >= 10 ? v % 10 + v / 10 : v;
    }

    return n % 10 == 0;
}

5

APL, 28 byte

{0=10|+/⍎¨∊⍕¨v×⌽2-2|⍳⍴v←⍎¨⍵}

Vista esplosa

{                     v←⍎¨⍵}  ⍝ turn the string into a numeric vector of its digits, v
                2-2|⍳⍴v       ⍝ make a vector of the same length, with 2 in every 2nd place
             v×⌽              ⍝ multiply it with v, starting from the right
          ∊⍕¨                 ⍝ turn each component into a string and collect all the digits
      +/⍎¨                    ⍝ turn each digit again into a number and sum them
 0=10|                        ⍝ check whether the sum is a multiple of 10

Esempi

      {0=10|+/⍎¨∊⍕¨v×⌽2-2|⍳⍴v←⍎¨⍵} '79927398713'
1
      {0=10|+/⍎¨∊⍕¨v×⌽2-2|⍳⍴v←⍎¨⍵} '123456789'
0

1
-2:{0=10|+/⍎¨∊⍕¨⍵×⌽2-2|⍳⍴⍵}⍎¨
Adám

4

PowerShell 123

filter L($x){$l=$x.Length-1;$l..0|%{$d=$x[$_]-48;if($_%2-eq$l%2){$s+=$d}elseif($d-le4){$s+=$d*2}else{$s+=$d*2-9}};!($s%10)}

4

Perl, 46 42 41 byte

Include +1 per -p

Dare input su STDIN:

luhn.pl <<< 79927398713

luhn.pl:

#!/usr/bin/perl -p
s%.%$=-=-$&-$&*1.2*/\G(..)+$/%eg;$_=/0$/

Puoi spiegare come funziona? Sembra che tu stia diminuendo per la partita e poi anche per i tempi della partita 1.2 ma solo nelle posizioni corrette. Perché 1.2? Non dovrebbe essere $=-=-$&-$&*/\G(..)+$/?
msh210,

3
@ msh210: codifica l'effetto della moltiplicazione per 2. 0..4* 2, 0, 2, 4, 6, 8ma 5..9fornisce la 10,12,14,16,18somma a 1 3 5 7 9cui hanno le stesse ultime cifre 11 13 15 17 19degli stessi valori degli stessi valori che 0..9 * 2.2se si troncano a numeri interi. Il primo $&contribuisce già a un fattore 1, quindi 1.2è ancora necessaria una correzione . $=può contenere solo numeri interi e inizia con un valore che termina con 0, quindi si occupa del troncamento. I valori negativi sono necessari poiché la /\G/regex cambia qualsiasi $&ancora nello stack di valutazione, quindi devono essere cambiati
Ton Hospel

Oh. Brillante! E grazie per la spiegazione.
msh210,

3

JavaScript (ES6), 61 byte

Non competitiva, poiché JavaScript era molto diverso nel 2011.

La somma delle cifre di 2*nè 2*nif n in 0..4, 2*n-9if n in 5..9. Detto questo, tutta la somma può essere calcolata in un solo passaggio.

s=>!([...s].reduceRight((t,d)=>t-d-i++%2*(d>4?d-9:d),i=0)%10)

3

Gelatina , 12 11 byte

ṚḤJḤ$¦DFS⁵ḍ

Provalo online!(con tutti i casi di test)

Come funziona

ṚḤJḤ$¦DFSḍ⁵  - Main link. Argument: n (integer) e.g. 49927398716
Ṛ            - Reverse. Casts a number to digits     [6, 1, 7, 8, 9, 3, 7, 2, 9, 9, 4]
     ¦       - Sparse application. Apply the next command to the given indicies
 Ḥ           -   Command: Double
    $        -   Indicies:
  J          -     range(length)...                  [1, 2 , 3, 4, 5, 6, 7, 8, 9, 10, 11]
   Ḥ         -     doubled.                          [2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22]
             - Doubles elements at odd indicies      [6, 2, 7, 16, 9, 6, 7, 4, 9, 18, 4]
      D      - Split each into digits                [6, 2, 7, [1, 6], 9, 6, 7, 4, 9, [1, 8], 4]
       F     - Flatten                               [6, 2, 7, 1, 6, 9, 6, 7, 4, 9, 1, 8, 4]
        S    - Sum                                   70
          ḍ  - Divisible by... 
         ⁵   -   10?                                 1

In alternativa, per 12 byte:

ṚḤJḤ$¦DFSḍ@⁵

3

x86-16 ASM , IBM PC DOS, 23 byte

03 F1       ADD  SI, CX         ; start at end of input string 
FD          STD                 ; set LODSB direction to decrement 
    DIGIT_LOOP:
AC          LODSB               ; load next digit into AL, decrement SI
2C 30       SUB  AL, '0'        ; convert ASCII char to binary value 
F7 DA       NEG  DX             ; flip DX to alternate odd/even index
78 06       JS   EVEN           ; if even index, do not double and sum digits 
D0 E0       SHL  AL, 1          ; double the value 
D4 0A       AAM                 ; BCD convert to split digits (ex: 18 = 12H --> 0108H) 
02 DC       ADD  BL, AH         ; add tens digit to running sum 
    EVEN:
02 D8       ADD  BL, AL         ; add ones digit to running sum 
E2 ED       LOOP DIGIT_LOOP 
93          XCHG BX, AX         ; sum is in BL, move to AL for conversion
D4 0A       AAM                 ; BCD convert AL, set ZF=1 if low digit is 0

Utilizza (abusa) le istruzioni da BCD a binario dell'86 AAMper gestire la divisione delle singole cifre emodulo 10 controllo .

Inserire il puntatore stringa numerica della scheda in SI, lunghezza in CX. Uscita: ZFse valida.

Esempio di output del programma di test:

inserisci qui la descrizione dell'immagine

Scarica il programma di test DOS PC PC LUHN.COM .


2

Scala: 132

def q(x:Int)=x%10+x/10
def c(i:String)={val s=i.reverse
(s(0)-48)==10-(s.tail.sliding(2,2).map(n=>(q((n(0)-48)*2)+n(1)-48)).sum%10)}

invocazione:

c("79927398713")
  • reverse ("79927398713") = 31789372997
  • s (0), coda s: (3) (1789372997)
  • scorrevole (2,2) = (17 89 37 29 97)
  • mappa (q ((n (0) -48 * 2 + n (1) -48)) => q (('1' - '0') * 2) + '7' - '0') = 1 * 2 + 7

2

JavaScript 1.8: 106 caratteri

Questa è una soluzione originale che mi è venuta in mente prima di trovare questo post:

function(n){return!(n.split('').reverse().reduce(function(p,c,i){return(+c&&((c*(1+i%2)%9)||9))+p},0)%10)}

Modulo leggibile:

function luhnCheck(ccNum) {
    return !(                                  // True if the result is zero.
             ccNum.split('').
               reverse().                      // Iterate over the string from rtl.
               reduce(function(prev, cur, idx) {
                 return prev +                 // Sum the results of each character.
                        (+cur &&               // If the current digit is 0, move on.
                         ((cur * (1 + idx % 2) // Double cur at even indices.
                           % 9) || 9));        // Sum the digits of the result.
               }, 0)
            % 10);                             // Is the sum evenly divisible by 10?
}


2

Retina , 43 42 byte

Retina è (molto) più recente di questa sfida.


;
r`(.);.
$1$&
\d
$*
1+
$.&
.
$*
$
$._
0$

La prima riga vuota è significativa.

Stampe 0per falsy e1 per risultati veritieri.

Provalo online!(Leggermente modificato per eseguire tutti i casi di test contemporaneamente.)

Spiegazione


;

Inserire ;in ogni posizione per separare le cifre.

r`(.);.
$1$&

Dall'inizio r, abbiniamo ripetutamente due cifre e raddoppiamo quella sinistra. In questo modo evitiamo una costosa inversione dell'elenco.

\d
$*

Abbiniamo ogni cifra e la convertiamo in tante 1s (ovvero convertiamo ogni cifra in unaria).

1+
$.&

Questo corrisponde a ciascun numero unario e lo converte in decimale sostituendolo con la sua lunghezza. Insieme alla fase precedente, questo aggiunge le cifre raddoppiate.

.
$*

Ancora una volta, abbiniamo ogni personaggio e lo trasformiamo in così tanti 1s. Cioè convertiamo ogni cifra singolarmente in unaria. Questo corrisponde anche ai ;separatori, che vengono trattati come zeri nella conversione, il che significa che vengono semplicemente rimossi. Dal momento che tutti i numeri unari sono ora compressi insieme, abbiamo aggiunto automaticamente le rappresentazioni unarie di tutte le cifre insieme.

$
$._

Alla fine, inseriamo la lunghezza dell'intera stringa, ovvero la rappresentazione decimale del checksum unario.

0$

Infine contiamo il numero di corrispondenze di questa regex, ovvero controlliamo se la rappresentazione decimale termina 0, stampando0 o di 1conseguenza.


2

Powershell, 74 byte

param($s)$s[$s.Length..0]|%{(1+$i++%2)*"$_"}|%{$r+=$_-9*($_-gt9)}
!($r%10)

Spiegazione

  1. per ogni carattere di una stringa argomento, in ordine inverso
  2. ottenere una cifra del doppio valore di una cifra
  3. un doppio valore di una cifra non può essere maggiore di 18. Pertanto, accumuliamo un valore meno 9 se valore> 9
  4. restituisce vero se il resto della divisione per 10 è 0

Test script

$f = {

param($s)$s[$s.Length..0]|%{(1+$i++%2)*"$_"}|%{$r+=$_-9*($_-gt9)}
!($r%10)

}

@(
    ,("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)
) | % {
    $s, $expected = $_
    $result = &$f $s
    "$($result-eq$expected): $result : $s"
}

Produzione

True: True : 49927398716
True: False : 49927398717
True: True : 1234567812345670
True: False : 1234567812345678
True: False : 79927398710
True: False : 79927398711
True: False : 79927398712
True: True : 79927398713
True: False : 79927398714
True: False : 79927398715
True: False : 79927398716
True: False : 79927398717
True: False : 79927398718
True: False : 79927398719
True: True : 374652346956782346957823694857692364857368475368
True: False : 374652346956782346957823694857692364857387456834
True: False : 8
True: True : 0

2

05AB1E , 12 10 byte

RSāÈ>*SOTÖ

Provalo online! o come una suite di test

Spiegazione

R             # reverse input
 S            # split to list of digits
  ā           # push range[1 ... len(input)]
   È          # map isEven on each
    >         # increment
     *        # multiply doubling every other item
      SO      # sum digits
        TÖ    # mod 10 == 0


1

GNU sed, 140 byte

(incluso +1 per la -rbandiera)

s/^(..)*.$/0&/
s/(.)./\1x&/g
s/x[5-9]/1&/g
s/[0x]//g
s/[789]/&6/g
s/[456]/&3/g
s/[369]/&11/g
s/[258]/&1/g
s/.{10}//g
s/.+/false/
s/^$/true/

Sed non è quasi mai il linguaggio più naturale per l'aritmetica, ma qui andiamo:

#!/bin/sed -rf

# zero-pad to even length
s/^(..)*.$/0&/
# double every other digit
s/(.)./\1x&/g
# add carry (converts mod-9 to mod-10)
s/x[5-9]/1&/g
# convert sum to unary
s/[0x]//g
s/[789]/&6/g
s/[456]/&3/g
s/[369]/&11/g
s/[258]/&1/g
# remove whole tens
s/.{10}//g
# output 'true' or false
s/.+/false/
s/^$/true/

1

APL, 38 byte

d←10∘⊥⍣¯1⋄{0=10|+/+/d x×1+~2|⍳⍴x←⌽d ⍵}

si aspetta che il numero sia un numero, non una stringa, ma è solo perché tryAPL (comprensibilmente) non implementa

ulteriormente riducibile, sono sicuro ...


1

PHP - 136 caratteri

function t($c){foreach($a=str_split(strrev($c)) as $k=>&$v){$v=array_sum(str_split(($k % 2)!==0?2*$v:$v));}return !(array_sum($a)% 10);}

1

MATL , 23 20 byte (non concorrenti)

P!Utn:2X\!*t9>+s10\~

Provalo online!

Emette 1 per un numero valido, 0 altrimenti.

Salvato tre byte grazie ai suggerimenti di Luis Mendo.

Spiegazione

P       % flip the order of elements
!       % transpose into column vector
U       % convert char matrix to numeric
t       % duplicate the vector
n       % find the length
:       % create a new vector length n (1, 2, 3, ... n)
2       % number literal
X\      % take it mod 2, to make the new vector (1, 2, 1, ..., (n-1) mod 2 +1)
!       % transpose
*       % element-wise product
t       % duplicate
9       % push 9
>       % 1 if it is greater than 9
+       % add the vectors, this makes the last digit of each the same as the sum of the digits
s       % add them
10      % number literal
\       % mod 10
~       % logical 'not' (element-wise)
        % (implicit) convert to string and display

1

Gelatina , 14 byte

DUḤJḤ$¦DS$€S⁵ḍ

Provalo online!

Spiegazione:

D              get digits
 U             reverse array
   JḤ$         for every other index,
  Ḥ   ¦        double the value
          €    for each value,
       D $     get the digits
        S$     and sum them
           S   sum the list
            ⁵ḍ check if it's divisible by 10

Perché questo non è in competizione?
mudkip201

@ mudkip201 Correggimi se sbaglio, ma questa versione di Jelly non esisteva quando è stata posta la domanda, quindi non è valida per la domanda.
Ellie,

3
Abbastanza sicuro che ci fosse un meta consenso che diceva che le lingue create dopo la sfida non sono più "non concorrenti"
mudkip201
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.