Burgerservicenummer olandese (BSN) undici-test


29

Introduzione:

Un BSN olandese (BurgerServiceNummer) è valido quando è conforme alle seguenti regole:

  • Contiene solo cifre.
  • La lunghezza dovrebbe essere di 8 o 9 di lunghezza.
  • Quando le cifre sono indicizzate come Aattraverso I, il risultato della seguente somma: 9xA + 8xB + 7xC + 6xD + 5xE + 4xF + 3xG + 2xH + -1xI(NOTA -1 anziché 1!) Dovrebbe essere divisibile per 11 e non dovrebbe essere 0.

Sfida:

Input: una stringa o char-array che rappresenta il BSN.

Uscita: Un truthy o Falsey risultato se l'input è un BSN valida.

Regole della sfida:

  • Il formato di input dovrebbe essere una stringa o un char-array. Non ti è permesso usare un int-array di cifre o un numero (possibilmente ottale). (Tuttavia, ti è permesso convertirlo in un int-array di cifre, ma non direttamente come argomento.)
  • Nonostante la restrizione sull'input precedente, puoi presumere che tutti i casi di test conterranno una o più cifre ( [0-9]+)
  • Per quanto riguarda la BSN con lunghezza 8 anziché 9, la Wikipedia olandese afferma quanto segue: " Per gli undici test e per altri usi pratici, viene aggiunto uno zero iniziale per fare il numero della lunghezza 9. " ( fonte )

Regole generali:

  • Questo è , quindi vince la risposta più breve in byte.
    Non lasciare che le lingue di code-golf ti scoraggino dal pubblicare risposte con lingue non codegolfing. Prova a trovare una risposta il più breve possibile per "qualsiasi" linguaggio di programmazione.
  • Per la tua risposta valgono regole standard , quindi puoi usare STDIN / STDOUT, funzioni / metodo con i parametri corretti, programmi completi. La tua chiamata.
  • Sono vietate le scappatoie predefinite .
  • Se possibile, aggiungi un link con un test per il tuo codice.
  • Inoltre, si prega di aggiungere una spiegazione, se necessario.

Casi test:

// Truthy test cases:
111222333
123456782
232262536
010464554
10464554
44016773

// Falsey test cases:
000000000
192837465
247594057
88888888
73
3112223342
000000012

4
È vero che se ci sono 8 cifre, si omette Adalla formula fornita?
Isaacg,

@isaacg Ho aggiunto la regola al riguardo con un link alla pagina (olandese) di Wikipedia. Hai davvero ragione, omette Adalla formula (o fondamentalmente aggiunge un vantaggio 0per renderlo di lunghezza 9, con lo stesso risultato dell'omissione A).
Kevin Cruijssen l'

Il test case per "la somma [...] non dovrebbe essere 0.": 000000012
betseg,

@betseg L'ho aggiunto all'elenco
Kevin Cruijssen l'

Risposte:


8

05AB1E , 23 21 byte

`()DgLR*OD11Ö89¹gåP0Ê

Provalo online! o come una suite di test

Spiegazione

`                        # push input as individual chars onto stack
 (                       # negate top value
  )                      # wrap in list
   DgLR                  # range [len(input) ... 1]
       *O                # multiply with list of digits and sum
         D11Ö            # is evenly divisible by 11
             89¹gå       # len(input) is 8 or 9
                  P      # product of sum/divisible by 11/len in (8,9)
                   0Ê    # not equal to 0

Probabilmente a causa di una versione precedente di 05AB1E, ma ora puoi salvare 3 byte cambiando DgLin āe in Ā. Provalo online.
Kevin Cruijssen,

12

JavaScript (ES6) 57

Input come una matrice di caratteri. reduceRightsalva la giornata!

s=>!(i=1,t=s.reduceRight((t,v)=>t-v*++i),!t|t%11|(i|1)-9)

Test

F=
s=>!(i=1,t=s.reduceRight((t,v)=>t-v*++i),!t|t%11|(i|1)-9)


;['111222333','123456782','232262536','010464554','10464554','44016773']
.forEach(t=>{
  var r=F([...t]);console.log(t,r)
})

;['000000000','192837465','247594057','88888888','73','3112223342','3112223342']
.forEach(t=>{
  var r=F([...t]);console.log(t,r)
})


1
Sempre bello vedere una reduceRightrisposta!
Neil,

Finalmente ho trovato un modo per raggiungere 58 con map(), solo per rendermi conto che la tua risposta è in realtà lunga 57 byte :-)
Arnauld

@Arnauld sì, non riesco a credere di aver contato di nuovo sbagliato , grazie
edc65

8

R, 86 67 byte

Modifica: grazie a Jarko Dubbeldam per aver suggerito il prodotto punto!

l=length(x<-scan(,""));s=as.double(x)%*%c(l:2,-1);!s%%11&s&l>7&l<10

Legge input da stdin e memorizza come un array / vettore di caratteri. Successivamente converti in numerico, moltiplica per il vettore 9...2,-1e controlla tutte le condizioni.


Non funziona per me. Dovresti dividere xcome vettore.
djhurio,

@djhurio Immettere i valori separati da spazio e vengono implicitamente memorizzati in un vettore di caratteri. In alternativa, inseriscili uno per uno premendo Invio tra.
Billywob,

1
if(l<9)x=c(0,x);s=sum(as.double(x)*c(9:2,-1))può essere trasformato in s=sum(as.double(x)*c(l:2,-1)). Inoltre, la somma del prodotto a coppie di due vettori è uguale alla loro moltiplicazione dei punti %*%.
JAD

@JarkoDubbeldam Nice! Il prodotto punto è davvero intelligente.
Billywob,

7

JavaScript (ES6), 61 60 59 58 byte

Accetta una matrice di caratteri come input. Restituisce false/ true.

a=>!(a.map(c=>s-=--k?-c*k-c:c,k=a.length&9,s=0)|!s|k|s%11)

Casi test


6

C, 112 101 96 98 104 byte

Grazie a @MartinEnder per aver salvato 5 3 byte durante la correzione del mio codice !

j,i,k,l;f(char*s){l=strlen(s);for(i=l,j=k=0;j<l;)k+=(s[j++]-48)*(i>1?i--:-1);return!(k%11)&&k&&(l^8)<2;}

Restituisce 0 se non valido, 1 se valido. Provalo online!


Questo accetta 61anche se non è della lunghezza corretta.
Christian Sievers,

1
Questo non funziona con il mio BSN personale.
roberrrt-s,

Speriamo risolto.
Betseg,

Non riparato. Non funziona neanche con il mio.
DavidPostill

1
@Roberrrt, @DavidPostill; va bene adesso o dovrei arrendermi? = (
betseg

5

R, 95 79 93 byte

function(x){y=as.double(el(strsplit(x,"")));z=y%*%c((q<-length(y)):2,-1);(z&!z%%11&q>7&q<10)}

Funzione senza nome che accetta una stringa come argomento. All'inizio ho letto il requisito di avere una stringa come input anziché un numero, ma va bene, perché salva alcuni byte sulla conversione.

Non sono sicuro di come interpretare la matrice di caratteri, ma se ciò significa che è possibile utilizzare un vettore di cifre a stringa "1" "2" "3" "4" etccome input, diventa anche un po 'più breve:

function(x){y=as.double(x);z=y%*%c((q<-length(y)):2,-1);(z&!z%%11&q>7&q<10)}

Divide x in un vettore numerico, quindi aggiunge uno 0 se la lunghezza è 8, quindi calcola il punto prodotto del vettore ye c(9,8,7,6,5,4,3,2,-1). Verifica se il risultato è sia diverso da zero che divisibile per 11.

16 byte salvati grazie alla logica di @Enigma, aggiungendo implicitamente lo 0 nella creazione del vettore c(length(x):2,-1).

Hai dimenticato di aggiungere il controllo per la lunghezza 8/9, quindi +14 byte :(


4

Perl, 58 byte (52 + 6)

@N=(-1,2..9);$r+=$_*shift@N for reverse@F;$_=$r&&/^\d{8,9}$/&&!($r%11)

Corri con

perl -F// -lapE

Ingresso passato STDIN:

uso

echo 232262536 | perl -F// -lapE '@N=(-1,2..9);$r+=$_*shift@N for reverse@F;$_=$r&&/^\d{8,9}$/&&!($r%11)'

Output 1come valore di verità 0o niente per valori di falsità.


È possibile salvare alcuni byte all'inizio: $r+=$_*(-1,2..9)[$i++]for reverse@F. Inoltre, -F -pe(e input fornito senza la nuova riga finale, echo -nad esempio) è sufficiente (a meno che il tuo Perl non sia troppo vecchio, nel qual caso ti servirà -a(ma su Perls recenti, è implicito da -F). Infine, il tuo codice era lungo 70 byte , non 52;)
Dada,

3

C ++ 14, 107 106 byte

-1 byte per intanziché autoin per ciclo.

Come lambda senza nome che ritorna tramite parametro di riferimento. Richiede input per essere std::stringo un contenitore di char, come vector<char>.

[](auto c,int&r){int i=c.size();r=7<i&&i<10?-2*c.back()+96:~1<<9;for(int x:c)r+=(x-48)*i--;r=r%11<1&&r>0;}

Ungolfed e utilizzo:

#include<iostream>
#include<string>

auto f=
[](auto c, int& r){
 int i = c.size();
 //if the size is correct, init r to -2*I so we can add I safely later
 //otherwise such a big negative number, that the final test fails
 r = 7<i && i<10 ? -2*c.back()+96 : ~1<<9;
 for (auto x:c)
  r += (x-48)*i--;
 r = r%11<1 && r>0;
}
;

using namespace std;
using namespace std::literals;

int main(){
 int r;
 f("111222333"s,r); std::cout << r << std::endl;
 f("123456782"s,r); std::cout << r << std::endl;
 f("010464554"s,r); std::cout << r << std::endl;
 f("10464554"s,r); std::cout << r << std::endl;
 f("44016773"s,r); std::cout << r << std::endl;
 std::cout << std::endl;
 f("000000000"s,r); std::cout << r << std::endl;
 f("192837465"s,r); std::cout << r << std::endl;
 f("73"s,r); std::cout << r << std::endl;
 f("88888888"s,r); std::cout << r << std::endl;
 f("3112222342"s,r); std::cout << r << std::endl;
 std::cout << std::endl;
 f("99999999"s,r); std::cout << r << std::endl;
 f("999999999"s,r); std::cout << r << std::endl;
}

3

Befunge, 72 byte

>+~>:0`v
^1\-*68_\2/4-!00p*8>1-10p\910gv
@.!+!\%+56:*g00$  _^#!:g01+*-<<

Provalo online!

Spiegazione

>+~>:0`v            Read characters from stdin until EOF, converting each digit into
^1\-*68_              a number on the stack, and keeping a count of the characters read.

      \2/4-!00p     Save !(count/2-4), which is only true for valid lengths (8 and 9).
               *    Multiply the EOF (-1) with the final digit; this is the initial total.

8>1-10p\910gv       Loop over the remaining 8 digits, multiplying each of them by 9-i and
 ^#!:g01+*-<<         add to the total; i goes from 7 down to 0, so 9-i goes from 2 to 9.

               $    Drop the loop counter.
           *g00     Multiply total by the length calculation (invalid lengths become 0).
      %+65:         Make a copy of the total, and calculate modulo 11.
    !\              Boolean not the other copy to check for zero. 
  !+                !(total%11 + !(total)) is only true for non-zero multiples of 11.
@.                  Output the result and exit.

3

MATL, 36 byte

Non è il programma MATL più lungo che abbia mai scritto , ma mi piace come if/ le elseistruzioni diventino molto lunghe molto rapidamente nelle lingue del golf. Ritengo che questa soluzione potrebbe non essere ottimale in MATL, ma al momento non posso ottimizzarla ulteriormente. Sto pensando di usare il doppio 0 da qualche parte, e forse ridurre il t"ovunque".

48-tn8=?0wh]tn9=?P[a2:9]*st11\~Y&}x0

Provalo online! Spiegazione:

48-                                  % Subtract 48 (ASCII '0')
   tn                                % Duplicate. Get length.
     8=?                             % If length equals 8
        0wh                          %     Prepend 0 to the duplicate
           ]                         % End if.
            t                        % Duplicate again.
             n9=?                    % If length equals 9.
                 P                   %     Reverse the duplicate
                  [a2:9]*            %     Element-wise product with [-1 2 ... 9]
                         s           %     Sum
                          t11\       %     Duplicate sum, modulus 11
                              ~Y&    %     Result on stack: modulus==0 AND sum!=0
                                 }   % Else
                                  x0 %     Remove the duplicate. Put 0 on stack.
                                     % Display implicitly.

Se riesci a accontentarti di un vettore di colonna: !Uanziché48-
Luis Mendo l'


@LuisMendo Peccato. [a2:9]*si traduce in una moltiplicazione non saggia, quindi !sarebbe necessaria un'altra che compensi il guadagno iniziale.
Sanchises,

3

MATL , 26 byte

!UGg*R!s0&)s-t11\~Gn8-tg=v

Il risultato è un vettore di colonna non vuoto, che è vero se tutte le sue voci sono diverse da zero .

Provalo online!

Oppure verifica tutti i casi di test con ciascun risultato su una riga diversa.

Spiegazione

Ciò verifica le tre condizioni nel seguente ordine:

  1. La somma ponderata è diversa da zero;
  2. La somma ponderata è divisibile per 11;
  3. La lunghezza è 8 o 9.

Considera l'input '8925'per la spiegazione. ;è il separatore di riga per le matrici.

!     % Implicit input. Transpose into a column vecvtor
      % STACK: ['8'; '9'; '2'; '5']
U     % Convert each digit to number
      % STACK: [8; 9; 2; 5]
Gg    % Push a row array of ones as long as the input
      % STACK: [8; 9; 2; 5], [1 1 1 1]
*     % Multiply, element-wise with broadcast
      % STACK: [8 8 8 8; 9 9 9 9; 2 2 2 2; 5 5 5 5]
R     % Upper triangular part
      % STACK: [8 8 8 8; 0 9 9 9; 0 0 2 2; 0 0 0 5]
!     % Transpose
      % STACK: [8 0 0 0;8 9 0 0;8 9 2 0;8 9 2 5]
s     % Sum of each column. This multiplies last element by 1, second-last by 2 etc
      % STACK: [32 27 4 5]
0&)   % Split into last element and remaining elements
      % STACK: 5, [32 27 4]
s     % Sum of array
      % STACK: 5, 63
-     % Subtract
      % STACK: -58. This is the result of condition 1
t11\  % Duplicate. Modulo 11
      % STACK: -58, 8
~     % Logical negation
      % STACK: -58, 0. This gives condition 2
Gn    % Push numnber of entries in the input
      % STACK: -58, 0, 4
8-    % Subtract 8. For valid lengths (8 or 9) this gives 0 or 1
      % STACK: -58, 0, -4
tg    % Duplicate. Convert to logical: set nonzero values to 1
      % STACK: -58, 0, -4, 1
=     % 1 if equal, 0 otherwise. Lenghts 8 or 9 will give 1. This is condition 3
      % STACK: -58, 0, 0
v     % Vertically concatenate the entire stack. This is truthy iff all values 
      % are non-zero. Implicitly display
      % STACK: [-58; 0; 0]

Molto bene. Ho pensato che un approccio senza ?sarebbe probabilmente più efficiente, ma non sono riuscito a capire come ridurre la lunghezza di 8 o 9. Il tuo Gn8-tg=è molto intelligente.
Sanchises,

1
A proposito, un input vettoriale di colonna non si qualificherebbe come un array di caratteri che rappresenta il BSN , salvandoti per primo !?
Sanchises,

@Sanchises Il problema è che quindi Gspinge un vettore di colonna e devo trasporlo per fare la ripetizione cong*
Luis Mendo

Oh certo, certo. Non importa!
Sanchises,

3

Haskell, 116 112 102 byte

f x=div(length x)2==4&&g x>0&&h x
h=((==0).(`mod`11)).g
g=sum.zipWith(*)(-1:[2..]).map(read.(:[])).reverse

gconta la somma usata nell'undici-proef di h, mentre fcontrolla anche la lunghezza corretta e che l'undici-proef non è 0. Soprattutto i controlli di fprendono molti byte.

EDIT: salvato 10 byte grazie a Lynn e divarrotondamento per difetto.


1
Che ne dici f x=div(length x)2==4&&g x>0&&h x?
Lynn,

@Lynn: è bello, grazie.
Renzeee,

2

Gelatina , 21 byte

V€U×JN1¦µL:2=4×Sµ11ḍa

TryItOnline! o eseguire tutti i casi di test

I valori di ritorno sinceri sono diversi da zero (e sono, in effetti, il multiplo di 11 sum).

Come?

V€U×JN1¦µL:2=4×Sµ11ḍa - Main link: string of digits  e.g. "111222333"
V€                    - eval each - effectively cast each to an integer (keeps leading zeros)
  U                   - upend                        e.g. [ 3, 3, 3, 2, 2, 2, 1, 1, 1]
    J                 - range(length)                e.g. [ 1, 2, 3, 4, 5, 6, 7, 8, 9]
   ×                  - multiply                     e.g. [ 3, 6, 9, 8,10,12, 7, 8, 9]
      1¦              - apply to index 1 (first element)
     N                -     negate                   e.g. [-3, 6, 9, 8,10,12, 7, 8, 9]
        µ             - monadic chain separation   e.g. z=[-3, 6, 9, 8,10,12, 7, 8, 9]
         L            - length(z)                    e.g. 9
          :2          - integer divide by 2          e.g. 4
            =4        - equals 4?                    e.g. 1
               S      - sum(z)                       e.g. 66
              ×       - multiply                     e.g. 66
                µ     - monadic chain separation   e.g. z=66
                 11ḍ  - divides(11, z)               e.g. 1
                    a - and z (for z=0 case)         e.g. 66 (truthy)

Purtroppo non posso accettare solo una risposta invece di due, dal momento che il vostro ha lo stesso 21 byte-count come @Emigna risposta 05AB1E s' . Ma dal momento che Enigma ha risposto prima (e anche la sua modifica per 21 byte è stata prima) ho accettato il suo.
Kevin Cruijssen,

Mi sembra giusto!
Jonathan Allan,

2

Python 2, 102 byte

def f(i):S=sum(a*b for a,b in zip([-1]+range(2,10),map(int,i)[::-1]));return(7<len(i)<10)*(S%11<1)*S>0

2

Python 2, 96 byte

def g(s):u=7<len(s)<10and sum(x*int(('0'+s)[-x])for x in range(2,10))-int(s[-1]);print(u%11<1)*u

Accetta una stringa come input. La funzione aggiunge un carattere '0'all'inizio della stringa, che ne abbia bisogno o meno, e utilizza gli indici negativi di Python per aggiungere elementi, a partire dalla fine della stringa e procedendo dall'inizio alla fine.

Il -1xIviene gestito separatamente, usando una seconda chiamata a int(). Non sono riuscito a capire come evitarlo senza costare più byte di quanti ne abbia salvato.

def g(s):u=7<len(s)<10and sum(x*int(('0'+s)[-x])for x in range(10))-2*int(s[-1]);print(u%11<1)*ufunzionerebbe altrettanto bene, dal momento che aggiungerebbe 1tempi s[-1]ma poi lo sottrarrebbe due volte, e aggiungerebbe anche 0tempi (qualcosa) che ovviamente non influirebbe sulla somma.


2

Brain-Flak , 345 byte

Include +3 per -a

([]){{}({}[((((()()()){}){}){}){}]<>)<>([])}{}<>([][(()()()()){}]){({}[()]){([]){{}{}([])}}}{}([{}])({}({}){})({}({})({}){})({}(({}){}){})({}(({})({})){}{})({}(({})({}){}){})({}((({}))({}){}){}{})({}((({}){}){}){})(({}(((({})){}){}){}{}{}<(((()()())()){}{})>)){{}({}(<>))<>{(({})){({}[()])<>}{}}{}<>([{}()]{}[{}]<(())>){((<{}{}>))}{}(<()>)}{}

Verità è 1, Falsy ha uno 0 in cima alla pila.

Provalo online!

Sono abbastanza sicuro che c'è un modo più breve per fare la moltiplicazione in un ciclo, ma non l'ho ancora trovato.

#reverse and subtract 48 from all numbers (ASCII -> decimal)
([]){{}({}[((((()()()){}){}){}){}]<>)<>([])}{}<> 

([][(()()()()){}])       #height - 8
{({}[()]){               #if not 0 subtract 1
   ([]){{}{}([])}        #if still not 0 pop everything
}}{}                     #this loop pops everything unless there are 8 or 9 digits

([{}])                   # -I
({}({}){})               # H*2
({}({})({}){})           # G*3
({}(({}){}){})           # F*4
({}(({})({})){}{})       # E*5
({}(({})({}){}){})       # D*6
({}((({}))({}){}){}{})   # C*7
({}((({}){}){}){})       # B*8
(({}(((({})){}){}){}{}{} # A*9 pushed twice with:
<(((()()())()){}{})>))   # 11 under it


{{} #if not 0
({}(<>))<>{(({})){({}[()])<>}{}}{}<>([{}()]{}   # mod 11
[{}]<(())>){((<{}{}>))}{}                       # logical not
(<()>)                                          # push 0 to exit loop
}{}
                                                # implicit print

2

PowerShell v2 +, 96 byte

param($n)$i=8-($n.count-eq8);!(($b=($n|%{(-"$_",(($i+1)*+"$_"))[!!$i--]})-join'+'|iex)%11)-and$b

OK, lo ammetto, sembra un casino completo. Ed è un po '. Ma abbi pazienza e ce la faremo.

Prendiamo input $n(come un chararray) e impostiamo $iuguale a 8meno un valore booleano per se ci sono 8 elementi in $n. Significato, se ci sono 8 elementi, allora $isarebbe 7.

La sezione successiva combina il calcolo con il nostro output. Lavorando dall'interno, ci colleghiamo $ncon $n|%{...}. Ogni iterazione, usiamo uno pseudo-ternario per ottenere uno dei due risultati: o -"$_"o (($i+1)*+"$_"). L'indice si basa sul fatto $iè 0o meno (ad esempio, abbiamo colpito il -1xIcaso dall'equazione sfida), che ottiene post-decrementato per il prossimo go-round. Quelli sono tutti raccolti in parentesi e messi -joininsieme +. Ad esempio, con l'input 111222333a questo punto avremmo 9+8+7+12+10+8+9+6+-3. Viene reindirizzato a iex(abbreviato Invoke-Expressione simile a eval) prima di essere archiviato $b. Quindi lo prendiamo %11ed eseguiamo un non booleano!(...)su quello (cioè, se è divisibile per 11, questa porzione è $true). Questo è accoppiato con -and$bper garantire che $bsia diverso da zero. Tale risultato booleano viene lasciato sulla pipeline e l'output è implicito.

Esempi

PS C:\Tools\Scripts\golfing> 111222333,123456782,232262536,010464554,10464554,44016773|%{"$_ -> "+(.\dutch-burgerservicenummer.ps1 ([char[]]"$_"))}
111222333 -> True
123456782 -> True
232262536 -> True
10464554 -> True
10464554 -> True
44016773 -> True

PS C:\Tools\Scripts\golfing> 000000000,192837465,247594057,88888888,73,3112223342,000000012|%{"$_ -> "+(.\dutch-burgerservicenummer.ps1 ([char[]]"$_"))}
0 -> False
192837465 -> False
247594057 -> False
88888888 -> False
73 -> False
3112223342 -> False
12 -> False

2

PHP 139 128 byte

 $u=-1;$i=$argv[1];while($u<=strlen($i)){$c+=($u*(substr($i,-(abs($u)),1)));$u +=$u<0?3:1;}echo($c>0&&!($c%11)&&$u>8&&$u<11?1:0);

Impossibile ottenere che la CLI rispecchi semplicemente il vero del falso. Ho dovuto farlo in questo modo. Qualche idea?

128 byte: trasformato "vero" e "falso" su 1 e 0.


2

C #, 120 115 byte

Questo scorre attraverso il char[]riceve come input e restituisce vero o falso:

bool b(char[]n){int r=0,k,i=0,l=n.Length;for(;i<l;i++){k=i==l-1?-1:l-i;r+=k*(n[i]-48);}return r>0&r%11<1&l<10&l>7;}

Fiddle: https://dotnetfiddle.net/3Kaxrt

Sono sicuro di poter cancellare qualche byte, specialmente nel caos return. Qualche idea benvenuta!

Modifica: salvato 5 byte grazie a Kevin. Non avevo idea di poter usare al &posto di &&!


1
+1! r>0&&r%11==0&&l<10&&l>7può essere golfed a r>0&r%11<1&l<10&l>7( &&a &e r%11==0a r%11<1). E -'0'può essere giocato a golf -48.
Kevin Cruijssen il

2

PHP, 86 85 84 83 82 79 byte

Nota: utilizza PHP 7.1 per indici di stringa negativi.

for($l=log10($a=$argn);~$c=$a[-++$x];)$s+=$x>1?$x*$c:-$c;echo$s%11<1&$l>7&$l<9;

Esegui in questo modo:

echo 010464554 | php -nR 'for($l=log10($a=$argn);~$c=$a[-++$x];)$s+=$x>1?$x*$c:-$c;echo$s%11<1&$l>7&$l<9;';echo
> 1

Versione per PHP <7.1 (+10 byte)

echo 010464554 | php -nR 'for($l=log10($a=$argn);~$c=$a[strlen($a)-++$x];)$s+=$x>1?$x*$c:-$c;echo$s%11<1&$l>7&$l<9;';echo

Spiegazione

for(
  $l=log10(         # Take the log of the input number.
    $a=$argn        # Set input to $a
  );
  ~$c=$a[-++$x];    # Iterate over digits of input (reverse). Negate to
                    # change every char to extended ASCII (all truthy),
                    # without changing empty sting (still falsy, ending
                    # the loop).
)
  $s+=$x>1?         # Add current char to the sum...
     ?$x*$c:-$c;    # multiplied by $x, unless $x is 1; subtract it.
echo
  $s%11<1 &         # Check if sum is divisible by 11, and
  $l>7   &          # log of the input is greater than 7, and
  $l<9;             # log of the input is less than 9. Outputs 0 or 1.

Ritocchi

  • Modo più breve per distinguere tra stringa vuota e "0", salvato un byte
  • Poiché 10000000non è valido, non è necessario confrontarsi con greater than or equals, è greater thansufficiente salvare un byte
  • Modo più breve per sottrarre cifre meno significative
  • Nega il carattere anziché XOR, salvando un byte
  • Salvato 3 byte utilizzando -Rper rendere $argndisponibile

2

Java 8, 115 98 byte

b->{int l=b.length,i=0,r=0,x;for(;l>7&l<10&i<l;r+=(b[i++]-48)*(x<2?-1:x))x=l-i;return r>0&r%11<1;}

Sono sorpreso che nessuno abbia ancora pubblicato una risposta Java, quindi eccone una.

Spiegazione:

Provalo qui.

b->{                  // Method with character-array as parameter and boolean return-type
  int l=b.length,     //  Length of the array
      i=0,            //  Index-integer, starting at 0
      r=0,            //  The result-sum, starting at 0
      x;              //  Temp integer `x`
  for(;l>7&l<10       //  Start looping if the length is either 8 or 9
       &i<l;          //  And continue looping while the index is smaller than the length
      r+=             //    After every iteration, increase the result-sum by:
         (b[i++]-48)  //     The current digit
         *(           //     Multiplied by:
           x<2?       //      If `x` is 1:
            -1        //       Multiply by -1
           :          //      Else:
            x))       //       Simply multiply by `x` 
    x=l-i;            //   Set `x` to the length minus the current index
                      //  End of loop (implicit / single-line body)
  return r>0          //  Return if the result-sum is larger than 0,
    &r%11<1;          //   and if the result-sum is divisible by 11
}                     // End of method

1

Clojure, 114 byte

Bene, questo è qualcosa, -sottrae il resto degli argomenti dal primo in modo da gestire il caso speciale di peso -1. Questa funzione ritorna nilper input di lunghezza non valida, ma sulle ifclausole funzionano allo stesso modo di false. (#{8 9}(count v))ritorna nilse la lunghezza di vnon è 8 o 9.

(fn[v](if(#{8 9}(count v))(#(and(< % 0)(=(mod % 11)0))(apply -(map *(range 1 10)(reverse(map #(-(int %)48)v)))))))

Casi test:

(pprint (group-by f (map str [123456782 232262536 "010464554" 10464554 44016773 "000000000" 192837465 247594057 88888888 73 3112223342 "000000012"])))
{true  ["123456782" "232262536" "010464554" "10464554" "44016773"],
 false ["000000000" "192837465" "247594057" "88888888" "000000012"],
 nil   ["73" "3112223342"]}


1

Stax , 23 byte

╪╦µΘç}<╔▼◘╞i∟~¿≥←║▐√ 4u

Esegui ed esegui il debug online!

Spiegazione

Usa la versione decompressa per spiegare.

i%8A:byr{]ei^*mBN+|+c11%!L|A
i                               Suppress implicit eval
 %8A:b                          Length is 8 or 9 (Element #1 on the final stack)
      yr                        Reverse input
        {     m                 Map each element with
         ]e                         Its numerical value
           i^*                      Multiplied current 1-based loop index
               BN+              Negate the first element
                  |+            Sum (Element #2 on the final stack)
                    c11%!       Sum is multiple of 11 (Element #3 on the final stack)
                         L|A    Collect all the three elements and `and` them.
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.