Голландский Burgerservicenummer (BSN) одиннадцати тест

29

Введение:

Голландский BSN (BurgerServiceNummer) действителен, если он соответствует следующим правилам:

  • Он содержит только цифры.
  • Длина должна быть 8 или 9 в длину.
  • Когда цифры индексируются как Aсквозные I, результат следующей суммы: 9xA + 8xB + 7xC + 6xD + 5xE + 4xF + 3xG + 2xH + -1xI(ЗАМЕТЬТЕ -1 вместо 1!) Должен делиться на 11 и не должен быть 0.

Вызов:

Вход: строка или массив символов, представляющий BSN.

Выход: truthy или falsey результат вход является ли действительным BSN.

Правила соревнований:

  • Формат ввода должен быть строкой или массивом символов. Вы не можете использовать int-массив цифр или (возможно, восьмеричное) число. (Вы можете преобразовать его в массив цифр int самостоятельно, но не в качестве аргумента.)
  • Несмотря на ограничение на вводимые выше данные, можно предположить, что все тестовые случаи будут содержать одну или несколько цифр ( [0-9]+)
  • Что касается BSN с длиной 8 вместо 9, голландская Википедия заявляет следующее: « Для теста с одиннадцатью и для других практических целей добавляется начальный ноль, чтобы сделать число длиной 9 ». ( Источник )

Основные правила:

  • Это , поэтому выигрывает самый короткий ответ в байтах.
    Не позволяйте языкам кода-гольфа отговаривать вас от публикации ответов на языках, не относящихся к кодексу. Попробуйте придумать как можно более короткий ответ для «любого» языка программирования.
  • К вашему ответу применяются стандартные правила , поэтому вы можете использовать STDIN / STDOUT, функции / метод с правильными параметрами, полные программы. Ваш звонок.
  • По умолчанию лазейки запрещены.
  • Если возможно, добавьте ссылку с тестом для вашего кода.
  • Также, пожалуйста, добавьте объяснение, если это необходимо.

Тестовые случаи:

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

// Falsey test cases:
000000000
192837465
247594057
88888888
73
3112223342
000000012
Кевин Круйссен
источник
4
Правда ли, что если есть 8 цифр, то одна пропускается Aиз приведенной формулы?
Исаак
@isaacg Я добавил правило, связанное с этим, со ссылкой на (голландскую) страницу википедии. Вы действительно правы: он исключает Aиз формулы (или, по сути, добавляет ведущий, 0чтобы сделать его длиной 9, что приводит к тому же результату, что и пропуск A).
Кевин Круйссен
Контрольный пример для "sum [...] не должен быть 0.": 000000012
betseg
@betseg Я добавил его в список
Кевин Круйссен

Ответы:

8

05AB1E, 23 21 bytes

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

Try it online! or as a Test suite

Explanation

`                        # 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
источник
Probably due to an older version of 05AB1E, but you can save 3 bytes now by changing DgL to ā and to Ā. Try it online.
Kevin Cruijssen
12

JavaScript (ES6) 57

Input as an array of chars. reduceRight saves the day!

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

edc65
источник
1
Always nice to see a reduceRight answer!
Neil
Finally found a way to reach 58 with map(), just to realize that your answer is actually 57 bytes long :-)
Arnauld
@Arnauld yep I can't believe I counted wrong again, thanks
edc65
8

R, 86 67 bytes

Edit: Thanks to Jarko Dubbeldam for suggesting the dot product!

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

Reads input from stdin and store as an array/vector of characters. Subsequently convert to numeric,multiply with the vector 9...2,-1 and check all conditions.

Billywob
источник
Does not work for me. You should split x as vector.
djhurio
@djhurio Enter the values separated by space and they are implicitly stored in a vector of characters. Alternatively enter them one by one by hitting enter in between.
Billywob
1
if(l<9)x=c(0,x);s=sum(as.double(x)*c(9:2,-1)) can be turned into s=sum(as.double(x)*c(l:2,-1)). Also, the sum of the pairwise product of two vectors is the same as their dot-multiplication %*%.
JAD
@JarkoDubbeldam Nice! The dot product is really clever.
Billywob
7

JavaScript (ES6), 61 60 59 58 bytes

Takes an array of chars as input. Returns false / true.

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

Test cases

Arnauld
источник
6

C, 112 101 96 98 104 bytes

Thanks to @MartinEnder for saving 5 3 bytes while fixing my code!

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

Returns 0 if invalid, 1 if valid. Try it online!

betseg
источник
This accepts 61 even though it is not of correct length.
Christian Sievers
1
This does not work with my personal BSN.
roberrrt-s
Hopefully fixed.
betseg
Not fixed. Doesn't work with mine either.
DavidPostill
1
@Roberrrt, @DavidPostill; is it OK now or should I just give up? =(
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)}

Unnamed function that takes a string as argument. At first I overread the requirement of having a string as input instead of a number, but that's good, because it saves some bytes on conversion.

I am not sure how to interpret the array of characters, but if that means that you can use a vector of stringed digits "1" "2" "3" "4" etc as input, it becomes a bit shorter even:

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

Splits x into a numeric vector, then appends a 0 if length is 8, then calculates the dotproduct of vector y and c(9,8,7,6,5,4,3,2,-1). Tests if the result is both nonzero and divisible by 11.

Saved 16 bytes thanks to the logic by @Enigma, implicitly appending the 0 in the creation of the vector c(length(x):2,-1).

Forgot to add check for length 8/9, so +14 bytes :(

JAD
источник
4

Perl, 58 bytes (52 + 6)

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

Run with

perl -F// -lapE

Input passed through STDIN:

Usage

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

Outputs 1 for as the truthy value, 0 or nothing for falsey values.

Zaid
источник
You can save some bytes at the beginning: $r+=$_*(-1,2..9)[$i++]for reverse@F. Also, -F -pe (and input supplied without final newline, with echo -n for instance) is enough (unless your Perl is too old, in which case you'll need -a (but on recent Perls, it's implied by -F). Finally, your code was 70 bytes long, not 52 ;)
Dada
3

C++14, 107 106 bytes

-1 byte for int instead of auto in for loop.

As unnamed lambda returning via reference parameter. Requires input to be std::string or a container of char, like 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 and usage:

#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
источник
3

Befunge, 72 bytes

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

Try it online!

Explanation

>+~>: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
источник
3

MATL, 36 bytes

Not the longest MATL program I've ever written, but I like how if/else statements get very lengthy very quickly in golfing languages. I feel that this solution may not be optimal in MATL, but as of yet I can't optimize it any further. I'm thinking of using the double 0 somewhere, and maybe cut down on the t's everywhere.

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

Try it online! Explanation:

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
источник
If you can make do with a column vector: !U instead of 48-
Luis Mendo
Beat ya :-P
Luis Mendo
@LuisMendo Too bad. [a2:9]* results in a non-element-wise multiplication, so another ! would be needed which would offset the initial gain.
Sanchises
3

MATL, 26 bytes

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

The result is a non-empty column vector, which is truthy iff all its entries are nonzero.

Try it online!

Or verify all test cases with each result on a different line.

Explanation

This tests the three conditions in the following order:

  1. Weighted sum is nonzero;
  2. Weighted sum is dividible by 11;
  3. Length is 8 or 9.

Consider input '8925' for the explanation. ; is the row separator for matrices.

!     % 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
источник
Well done. I figured that an approach without ? would probably be more efficient, but I couldn't figure out how to shorten the length 8 or 9. Your Gn8-tg= is very clever.
Sanchises
1
By the way, wouldn't a column vector input qualify as a char-array representing the BSN, saving you the first !?
Sanchises
@Sanchises The problem is that then G pushes a column vector and I need to transpose it to do the repetition with g*
Luis Mendo
Oh right of course. Never mind!
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

g counts the sum used in the eleven-proef of h, while f also checks for the correct length and that the eleven-proef is not 0. Especially the checks of f take a lot of bytes.

EDIT: saved 10 bytes thanks to Lynn and div rounding down.

Renzeee
источник
1
How about f x=div(length x)2==4&&g x>0&&h x?
Lynn
@Lynn: that is a nice one, thanks.
Renzeee
2

Jelly, 21 bytes

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

TryItOnline! or run all test cases

Truthy return values are non-zero (and are, in fact, the multiple of 11 sum).

How?

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
источник
Unfortunately I can only accept one answer instead of two, since yours has the same 21 byte-count as @Emigna's 05AB1E answer. But since Enigma answered sooner (and his edit for 21 bytes was also sooner) I've accepted his.
Kevin Cruijssen
That sounds fair to me!
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
источник
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

Takes a string as input. The function adds a '0' to the front of the string whether it needs it or not, and uses Python's negative indices to add elements, starting from the end of the string and working back-to-front.

The -1xI is handled separately, using a second call to int(). I couldn't figure out how to avoid this without costing more bytes than I saved.

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)*u would work just as well, since it would add 1 times s[-1] but then subtract it twice, and it would also add 0 times (something) which of course wouldn't affect the sum.

mathmandan
источник
2

Brain-Flak, 345 Bytes

Includes +3 for -a

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

Truthy is 1, Falsy has a 0 on the top of the stack.

Try it Online!

I'm pretty sure there is a shorter way to do the multiplication in a loop, but I haven't found it yet.

#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
источник
2

PowerShell v2+, 96 bytes

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

OK, I'll admit, this looks like a complete mess. And it kinda is. But, bear with me and we'll get through it.

We take input $n (as a char-array) and set $i equal to 8 minus a Boolean value for whether there are 8 items in $n. Meaning, if there are 8 items, then $i would be 7.

The next section combines the calculation with our output. Working from the inside, we loop through $n with $n|%{...}. Each iteration, we use a pseudo-ternary to come up with one of two results -- either -"$_" or (($i+1)*+"$_"). The index is based on whether $i is 0 or not (i.e., we've hit the -1xI case from the challenge equation), which gets post-decremented for the next go-round. Those are all gathered up in parens and -joined together with +. For example, with input 111222333 at this point we'd have 9+8+7+12+10+8+9+6+-3. That is piped to iex (short for Invoke-Expression and similar to eval) before being stored into $b. We then take that %11 and perform a Boolean-not !(...) on that (i.e., so if it is divisible by 11, this portion is $true). That's coupled with -and$b to ensure that $b is non-zero. That Boolean result is left on the pipeline and output is implicit.

Examples

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
источник
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);

Could not get the CLI to just echo the true of false. Had to make do it this way. Any ideas?

128 bytes: Turned "true" and "false" to 1 and 0.

Jeroen
источник
2

C#, 120 115 bytes

This loops through the char[] it receives as input and returns true or false:

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

I'm sure I can scrape out a few bytes, especially in the messy return. Any ideas welcome!

Edit: Saved 5 bytes thanks to Kevin. I had no idea I could use & instead of &&!

levelonehuman
источник
1
+1! r>0&&r%11==0&&l<10&&l>7 can be golfed to r>0&r%11<1&l<10&l>7 (&& to & and r%11==0 to r%11<1). And -'0' can be golfed to -48.
Kevin Cruijssen
2

PHP, 86 85 84 83 82 79 bytes

Note: uses PHP 7.1 for negative string indices.

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

Run like this:

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

Version for 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

Explanation

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

  • Shorter way to distinguish between empty string and "0", saved a byte
  • Since 10000000 is invalid, no need to compare with greater than or equals, greater than suffices, saving a byte
  • Shorter way to subtract least significant digit
  • Negate char instead of XOR, saving a byte
  • Saved 3 bytes by using -R to make $argn available
aross
источник
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;}

I'm surprised no one has posted a Java answer yet, so here is one.

Explanation:

Try it here.

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
источник
1

Clojure, 114 bytes

Well this is something, - substracts the rest of the arguments from the first one so that handles the special case of weight -1. This function returns nil for inputs of invalid length, but on if clauses they operate the same as false. (#{8 9}(count v)) returns nil if length of v is not 8 or 9.

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

Test cases:

(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
источник
1

Stax, 23 bytes

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

Run and debug online!

Explanation

Uses the unpacked version to explain.

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
источник