Teste holandês de Burgerservicenummer (BSN)

29

Introdução:

Um BSN holandês (BurgerServiceNummer) é válido quando cumpre as seguintes regras:

  • Ele contém apenas dígitos.
  • O comprimento deve ter 8 ou 9 de comprimento.
  • Quando os dígitos são indexados como Acompletos I, o resultado da seguinte soma: 9xA + 8xB + 7xC + 6xD + 5xE + 4xF + 3xG + 2xH + -1xI(NOTA -1 em vez de 1!) Deve ser divisível por 11 e não deve ser 0.

Desafio:

Entrada: uma sequência ou conjunto de caracteres representando o BSN.

Saída: Um resultado verdadeiro ou falso, se a entrada é um BSN válido.

Regras do Desafio:

  • O formato de entrada deve ser uma string ou um conjunto de caracteres. Você não tem permissão para usar uma matriz int de dígitos ou um número (possivelmente octal). (Você tem permissão para convertê-lo em uma matriz int de dígitos, mas não diretamente como argumento.)
  • Apesar da restrição na entrada acima, você pode assumir que todos os casos de teste conterão um ou mais dígitos ( [0-9]+)
  • Com relação ao BSN com comprimento 8 em vez de 9, a Wikipedia holandesa declara o seguinte: " Para os onze testes e para outros usos práticos, um zero à esquerda é adicionado para fazer o número 9 " ( fonte )

Regras gerais:

  • Isso é , então a resposta mais curta em bytes vence.
    Não permita que idiomas com código de golfe o desencorajem a postar respostas com idiomas que não sejam codegolf. Tente encontrar uma resposta o mais curta possível para 'qualquer' linguagem de programação.
  • As regras padrão se aplicam à sua resposta, para que você possa usar STDIN / STDOUT, funções / método com os parâmetros adequados, programas completos. Sua chamada.
  • As brechas padrão são proibidas.
  • Se possível, adicione um link com um teste para o seu código.
  • Além disso, adicione uma explicação, se necessário.

Casos de teste:

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

// Falsey test cases:
000000000
192837465
247594057
88888888
73
3112223342
000000012
Kevin Cruijssen
fonte
4
É verdade que, se houver 8 dígitos, um omite Aa fórmula fornecida?
Isaacg
@isaacg Adicionei a regra sobre isso com um link para a página da Wikipédia (holandesa). Você está realmente certo, ele omite Aa fórmula (ou basicamente adiciona um líder 0para torná-lo comprimento 9, resultando no mesmo resultado que omitir A).
Kevin Cruijssen
O caso de teste para "soma [...] não deve ser 0.": 000000012
betseg 08/12/16
@betseg Adicionei-o à lista
Kevin Cruijssen

Respostas:

8

05AB1E , 23 21 bytes

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

Experimente online! ou como um conjunto de testes

Explicação

`                        # 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
Emigna
fonte
Provavelmente devido a uma versão mais antiga do 05AB1E, mas você pode salvar 3 bytes agora, alterando DgLpara āe para Ā. Experimente online.
Kevin Cruijssen
12

JavaScript (ES6) 57

Entrada como uma matriz de caracteres. reduceRightsalva o dia!

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

Teste

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)
})

edc65
fonte
11
Sempre bom ver uma reduceRightresposta!
Neil
Finalmente encontrou uma maneira de chegar a 58 com map(), apenas para perceber que a sua resposta é realmente 57 bytes de comprimento :-)
Arnauld
@Arnauld Sim eu não posso acreditar que eu contei errado novamente , graças
edc65
8

R, 86 67 bytes

Edit: Obrigado a Jarko Dubbeldam por sugerir o produto escalar!

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

Lê a entrada de stdin e armazena como uma matriz / vetor de caracteres. Subseqüentemente, converta para numérico, multiplique pelo vetor 9...2,-1e verifique todas as condições.

Billywob
fonte
Nao funciona para mim. Você deve dividir xcomo vetor.
djhurio
@djhurio Digite os valores separados por espaço e eles são implicitamente armazenados em um vetor de caracteres. Como alternativa, insira-os um por um pressionando Enter no meio.
Billywob
11
if(l<9)x=c(0,x);s=sum(as.double(x)*c(9:2,-1))pode ser transformado em s=sum(as.double(x)*c(l:2,-1)). Além disso, a soma do produto aos pares de dois vetores é igual à multiplicação de pontos %*%.
JAD
@JarkoDubbeldam Nice! O produto escalar é realmente inteligente.
Billywob
7

JavaScript (ES6), 61 60 59 58 bytes

Toma uma matriz de caracteres como entrada. Retorna false/ true.

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

Casos de teste

Arnauld
fonte
6

C, 112 101 96 98 104 bytes

Obrigado a @MartinEnder por salvar 5 3 bytes ao corrigir meu código !

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;}

Retorna 0 se inválido, 1 se válido. Experimente online!

betseg
fonte
Isso aceita 61mesmo que não seja do tamanho correto.
Christian Sievers
11
Isso não funciona com o meu BSN pessoal.
roberrrt-s
Espero que seja corrigido.
betseg 08/12/19
Não consertado. Também não funciona com o meu.
DavidPostill
11
@Roberrrt, @DavidPostill; está tudo bem agora ou devo desistir? = (
betseg
5

R, 95 79 93 bytes

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

Função sem nome que recebe uma string como argumento. No começo, eu excedi o requisito de ter uma string como entrada em vez de um número, mas isso é bom, porque economiza alguns bytes na conversão.

Não sei ao certo como interpretar a matriz de caracteres, mas se isso significa que você pode usar um vetor de dígitos "1" "2" "3" "4" etcem cadeia como entrada, ele se torna um pouco mais curto:

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

Divide x em um vetor numérico, acrescenta um 0 se o comprimento for 8 e calcula o produto escalar do vetor y e c(9,8,7,6,5,4,3,2,-1). Testa se o resultado é diferente de zero e divisível por 11.

Salvou 16 bytes graças à lógica do @Enigma, anexando implicitamente o 0 na criação do vetor c(length(x):2,-1).

Esqueceu-se de adicionar a verificação do comprimento 8/9, então +14 bytes :(

JAD
fonte
4

Perl, 58 bytes (52 + 6)

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

Correr com

perl -F// -lapE

Entrada passada através de STDIN:

Uso

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

Saídas 1para o valor 0de verdade ou nada para valores de falsey.

Zaid
fonte
Você pode salvar alguns bytes no início: $r+=$_*(-1,2..9)[$i++]for reverse@F. Além disso, -F -pe(e a entrada fornecida sem a nova linha final, echo -npor exemplo) é suficiente (a menos que o seu Perl seja muito antigo, caso em que você precisará -a(mas no Perls recente, é implícito por -F)) Finalmente, seu código tinha 70 bytes de comprimento , não 52;)
Dada
3

C ++ 14, 107 106 bytes

-1 byte para em intvez de autoin para loop.

Como lambda sem nome, retornando via parâmetro de referência. Requer entrada para ser std::stringou um contêiner de char, como 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 uso:

#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;
}
Karl Napf
fonte
3

Befunge, 72 bytes

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

Experimente online!

Explicação

>+~>: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.
James Holderness
fonte
3

MATL, 36 bytes

Não é o programa MATL mais longo que eu já escrevi , mas eu gosto de como if/ elseinstruções ficam muito longas muito rapidamente em idiomas de golfe. Eu sinto que essa solução pode não ser ótima no MATL, mas ainda não posso otimizá-la mais. Estou pensando em usar o duplo 0 em algum lugar, e talvez reduzir o número em todos os tlugares.

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

Experimente online! Explicação:

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.
Sanchises
fonte
Se você pode se contentar com um vetor de coluna: em !Uvez de48-
Luis Mendo
Beat ya :-P
Luis Mendo
@LuisMendo Muito ruim. [a2:9]*resulta em uma multiplicação não-elemento-sensitiva; portanto, !seria necessária outra que compensasse o ganho inicial.
Sanchises
3

MATL , 26 bytes

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

O resultado é um vetor de coluna não vazio, que é verdadeiro se todas as suas entradas forem diferentes de zero .

Experimente online!

Ou verifique todos os casos de teste com cada resultado em uma linha diferente.

Explicação

Isso testa as três condições na seguinte ordem:

  1. A soma ponderada é diferente de zero;
  2. A soma ponderada é dividível por 11;
  3. O comprimento é 8 ou 9.

Considere entrada '8925'para a explicação. ;é o separador de linhas para matrizes.

!     % 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]
Luis Mendo
fonte
Bem feito. Imaginei que uma abordagem sem ?provavelmente seria mais eficiente, mas não consegui descobrir como reduzir o comprimento de 8 ou 9. Você Gn8-tg=é muito inteligente.
Sanchises
11
A propósito, uma entrada de vetor de coluna não se qualificaria como um array de caracteres representando o BSN , poupando o primeiro !?
Sanchises
@Sanchises O problema é que, em seguida, Gempurra um vetor coluna e eu preciso transpô-la para fazer a repetição comg*
Luis Mendo
Oh certo, claro. Deixa pra lá!
Sanchises
3

Haskell, 116 112 102 bytes

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 a soma usada no onze-proef de h, enquanto ftambém verifica o comprimento correto e se o onze-proef não é 0. Especialmente, as verificações de fmuitos bytes.

EDIT: economizou 10 bytes graças a Lynn e divarredondando para baixo.

Renzeee
fonte
11
Que tal f x=div(length x)2==4&&g x>0&&h x?
Lynn
@ Lynn: que é agradável, obrigado.
Renzeee
2

Gelatina , 21 bytes

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

TryItOnline! ou execute todos os casos de teste

Os valores de retorno verdade são diferentes de zero (e são, de fato, o múltiplo de 11).

Quão?

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)
Jonathan Allan
fonte
Infelizmente, só pode aceitar uma resposta em vez de dois, uma vez que o seu tem o mesmo 21 byte-count como @Emigna resposta 05AB1E 's . Mas desde que o Enigma respondeu mais cedo (e sua edição por 21 bytes também foi mais cedo), aceitei a dele.
Kevin Cruijssen 29/06
Isso parece justo para mim!
Jonathan Allan
2

Python 2, 102 bytes

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
TFeld
fonte
2

Python 2, 96 bytes

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

Toma uma string como entrada. A função adiciona '0'a à frente da string, precisa ou não, e usa os índices negativos do Python para adicionar elementos, começando no final da string e trabalhando de frente para frente.

O -1xIé tratado separadamente, usando uma segunda chamada para int(). Eu não conseguia descobrir como evitar isso sem custar mais bytes do que salvei.

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)*ufuncionaria da mesma maneira, pois acrescentaria 1tempos, s[-1]mas subtraí-lo-ia duas vezes e também acrescentaria 0tempos (algo) que, é claro, não afetariam a soma.

mathmandan
fonte
2

Brain-Flak , 345 bytes

Inclui +3 para -a

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

Verdade é 1, Falsy tem um 0 no topo da pilha.

Experimente Online!

Tenho certeza de que existe uma maneira mais curta de fazer a multiplicação em um loop, mas ainda não a encontrei.

#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
Riley
fonte
2

PowerShell v2 +, 96 bytes

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

OK, eu admito, isso parece uma bagunça completa. E meio que é. Mas, tenha paciência comigo e nós passaremos por isso.

Pegamos a entrada $n(como uma charmatriz) e definimos $iigual a 8menos um valor booleano para saber se há 8 itens $n. Significado, se houver 8 itens, $iseria 7.

A próxima seção combina o cálculo com a nossa saída. Trabalhando a partir do interior, nós percorrer $ncom $n|%{...}. A cada iteração, usamos um pseudo-ternário para criar um dos dois resultados - ou -"$_"ou (($i+1)*+"$_"). O índice é baseado em se $ié 0ou não (ou seja, chegamos ao -1xIcaso da equação de desafio), que é pós-decrementada para a próxima rodada. Tudo isso é reunido em parênteses e -joineditado junto +. Por exemplo, com entrada 111222333neste momento, teríamos 9+8+7+12+10+8+9+6+-3. Isso é canalizado para iex(abreviado Invoke-Expressione semelhante a eval) antes de ser armazenado $b. Em seguida, pegamos isso %11e executamos um Boolean-not!(...)nisso (ou seja, se é divisível por 11, essa parte é $true). Isso é associado -and$ba garantir que $bnão seja zero. Esse resultado booleano é deixado no pipeline e a saída é implícita.

Exemplos

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
AdmBorkBork
fonte
2

PHP 139 128 bytes

 $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);

Não foi possível obter a CLI apenas ecoando a verdade de falso. Tinha que fazer dessa maneira. Alguma ideia?

128 bytes: virou "true" e "false" para 1 e 0.

Jeroen
fonte
2

C #, 120 115 bytes

Isso percorre o char[]que recebe como entrada e retorna verdadeiro ou 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

Tenho certeza de que posso raspar alguns bytes, especialmente no confuso return. Todas as idéias são bem-vindas!

Editar: salvou 5 bytes graças a Kevin. Eu não tinha idéia que eu poderia usar em &vez de &&!

levelonehuman
fonte
11
+1! r>0&&r%11==0&&l<10&&l>7pode ser jogado golfe para r>0&r%11<1&l<10&l>7( &&para &e r%11==0para r%11<1). E -'0'pode ser jogado para -48.
Kevin Cruijssen
2

PHP, 86 85 84 83 82 79 bytes

Nota: usa o PHP 7.1 para índices negativos de string.

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

Execute assim:

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

Versão para PHP <7.1 (+10 bytes)

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

Explicação

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.

Tweaks

  • Maneira mais curta de distinguir entre cadeia vazia e "0", salvou um byte
  • Como 10000000é inválido, não é necessário comparar com greater than or equals, greater thanbasta salvar um byte
  • Maneira mais curta de subtrair o dígito menos significativo
  • Negar char em vez de XOR, salvando um byte
  • Salva 3 bytes usando -Rpara $argndisponibilizar
aross
fonte
2

Java 8, 115 98 bytes

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;}

Estou surpreso que ninguém tenha postado uma resposta Java ainda, então aqui está uma.

Explicação:

Experimente aqui.

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
Kevin Cruijssen
fonte
1

Clojure, 114 bytes

Bem, isso é algo, -subtrai o restante dos argumentos do primeiro, para que lide com o caso especial de peso -1. Esta função retorna nilpara entradas de tamanho inválido, mas nas ifcláusulas elas operam da mesma forma que false. (#{8 9}(count v))retorna nilse o comprimento de vnão for 8 ou 9.

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

Casos de teste:

(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"]}
NikoNyrh
fonte
1

Stax , 23 bytes

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

Execute e depure online!

Explicação

Usa a versão descompactada para explicar.

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.
Weijun Zhou
fonte