# Dutch Burgerservicenummer (BSN) eleven-test

### Introduction:

A Dutch BSN (BurgerServiceNummer) is valid when it complies to the following rules:

• It only contains digits.
• The length should be either 8 or 9 in length.
• When the digits are indexed as A through I, the result of the following sum: 9xA + 8xB + 7xC + 6xD + 5xE + 4xF + 3xG + 2xH + -1xI (NOTE the -1 instead of 1!) should be divisible by 11, and should not be 0.

### Challenge:

Input: A string or char-array representing the BSN.

Output: A truthy or falsey result whether the input is a valid BSN.

### Challenge Rules:

• The input format should be a string or char-array. You are not allowed to use an int-array of digits, or a (possibly octal) number. (You are allowed to convert it to an int-array of digits yourself, though, but not directly as argument.)
• Despite the restriction on the input above, you can assume all test cases will contain one or more digits ([0-9]+)
• Regarding the BSN with length 8 instead of 9, the Dutch Wikipedia states the following: "For the eleven-test and for other practical uses, a leading zero is added to make the number of length 9." (source)

### General rules:

• This is , so shortest answer in bytes wins.
Don't let code-golf languages discourage you from posting answers with non-codegolfing languages. Try to come up with an as short as possible answer for 'any' programming language.
• Standard rules apply for your answer, so you are allowed to use STDIN/STDOUT, functions/method with the proper parameters, full programs. Your call.
• Default Loopholes are forbidden.

### Test cases:

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

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

• Is it true that if there are 8 digits, one omits A from the formula given? Commented Dec 8, 2016 at 8:29
• @isaacg I've added the rule regarding this with a link to the (Dutch) wikipedia page. You are indeed right, it omits A from the formula (or basically adds a leading 0 to make it length 9, resulting in the same result as omitting A). Commented Dec 8, 2016 at 9:13
• Test case for "sum [...] should not be 0.": 000000012 Commented Dec 8, 2016 at 11:51
• @betseg I've added it to the list Commented Dec 8, 2016 at 11:58
• Hi! I'm doing my solution in python, and am wondering about clarification of truthy and falsey. Python counts the integer 0 as falsey and any other integer as truthy, and my current solution always converts to bools? Commented Oct 18, 2021 at 13:14

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

• Always nice to see a reduceRight answer!
– Neil
Commented Dec 8, 2016 at 11:42
• Finally found a way to reach 58 with map(), just to realize that your answer is actually 57 bytes long :-) Commented Dec 8, 2016 at 15:57
• @Arnauld yep I can't believe I counted wrong again, thanks Commented Dec 8, 2016 at 17:40

# 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

• Probably due to an older version of 05AB1E, but you can save 3 bytes now by changing DgL to ā and 0Ê to Ā. Try it online. Commented Aug 31, 2018 at 10:06
• 89 should actually be 89S, since an input with length 89 could potentially give a false-positive. Commented Nov 7, 2022 at 13:31

## 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.

• Does not work for me. You should split x as vector. Commented Dec 8, 2016 at 13:42
• @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. Commented Dec 8, 2016 at 15:03
• 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 %*%.
Commented Dec 9, 2016 at 9:30
• @JarkoDubbeldam Nice! The dot product is really clever. Commented Dec 9, 2016 at 9:40

## JavaScript (ES6), 616059 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

let f =

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

// truthy
console.log(f([..."111222333"]));
console.log(f([..."123456782"]));
console.log(f([..."232262536"]));
console.log(f([..."010464554"]));
console.log(f([..."10464554"]));
console.log(f([..."44016773"]));

// falsy
console.log(f([..."000000000"]));
console.log(f([..."192837465"]));
console.log(f([..."247594057"]));
console.log(f([..."88888888"]));
console.log(f([..."73"]));
console.log(f([..."3112223342"]));

## C, 1121019698 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!

• This accepts 61 even though it is not of correct length. Commented Dec 8, 2016 at 10:53
• This does not work with my personal BSN. Commented Dec 8, 2016 at 11:03
• Hopefully fixed. Commented Dec 8, 2016 at 11:46
• Not fixed. Doesn't work with mine either. Commented Dec 8, 2016 at 23:32
• @Roberrrt, @DavidPostill; is it OK now or should I just give up? =( Commented Dec 9, 2016 at 15:53

# R, 9579 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 @Emigna, 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 :(

## 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.

• 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 Commented Jan 12, 2017 at 21:27 # 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; }  # Jelly, 21 bytes V€U×JN1¦µL:2=4×Sµ11ḍa  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)  • 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. Commented Jun 29, 2017 at 11:54 • That sounds fair to me! Commented Jun 29, 2017 at 14:50 # Befunge, 72 bytes >+~>:0v ^1\-*68_\2/4-!00p*8>1-10p\910gv @.!+!\%+56:*g00$  _^#!:g01+*-<<


Try it online!

Explanation

>+~>:0v            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.  # 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.  • If you can make do with a column vector: !U instead of 48- Commented Dec 8, 2016 at 15:28 • Beat ya :-P Commented Dec 8, 2016 at 15:42 • @LuisMendo Too bad. [a2:9]* results in a non-element-wise multiplication, so another ! would be needed which would offset the initial gain. Commented Dec 8, 2016 at 15:43 ## 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  # 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]  • 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. Commented Dec 8, 2016 at 15:55 • By the way, wouldn't a column vector input qualify as a char-array representing the BSN, saving you the first !? Commented Dec 9, 2016 at 14:28 • @Sanchises The problem is that then G pushes a column vector and I need to transpose it to do the repetition with g* Commented Dec 9, 2016 at 16:58 • Oh right of course. Never mind! Commented Dec 9, 2016 at 17:30 # Haskell, 116112 102 bytes f x=div(length x)2==4&&g x>0&&h x h=((==0).(mod11)).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. • How about f x=div(length x)2==4&&g x>0&&h x? – lynn Commented Dec 8, 2016 at 17:53 • @Lynn: that is a nice one, thanks. Commented Dec 9, 2016 at 7:50 ## 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.

# Python 3.8 (pre-release), 111110 104 bytes

-1 byte thanks to @Kevin-cruijssen

-6 bytes by reading the rules (yay)

lambda s:len(s)in(8,9)and not(x:=sum(a:=[*map(lambda n,m:int(n)*m,s[::-1],range(1,10))])-2*a[0])%11and x


Try it online!

There's probably more golfing to do, but this is what I have for now.

• You can remove the space at 11and for -1 byte. :) Commented Oct 18, 2021 at 6:31

## 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


# 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.

# 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


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


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 &&!

• +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. Commented Dec 9, 2016 at 7:56

# PHP, 8685848382 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


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 # Java 8, 11598 94 bytes b->{int l=b.length,i=l,r=0;for(;l>7&l<10&i-->0;)r-=(b[i]-48)*(l-i<2?1:i-l);return r>0&r%11<1;}  I'm surprised no one has posted a Java answer yet, so here is one. -4 bytes thanks to @ceilingcat. Explanation: Try it here. b->{ // Method with character-array as parameter and boolean return-type int l=b.length, // Length of the array i=l, // Index-integer, starting at this length r=0; // The result-sum, starting at 0 for(;l>7&l<10 // Start looping if the length is either 8 or 9 &i-->0;) // And continue looping downwards while the index is larger than 0 r-= // Decrease the result-sum by: (b[i]-48) // The current digit *( // Multiplied by: l-i<2? // If l-i is 1: 1 // Simply multiply by 1 : // Else: i-l); // Multiply by i-l return r>0 // Return if the result-sum is larger than 0, &r%11<1;} // and if the result-sum is divisible by 11  # Ly, 58 bytes iy9L[r'0r!]ppry9=[pp8[f'0-srlrpsrl*r,]p'0-N&+[92+%!u;]]u;  Try it online! I thought this would be shorter... There's probably room for improvement? First part, input digits, pad with leading 0 if necessary i - input all digits (as codepoints) y - push the stack size onto the stack 9L[ !]p - if/then block, true if <9 digits r'0r - reverse stack, push 0, reverse again p - pop the stack size entry off the stack  Second part, only process digits if we end up with 9 digits r - reverse the stack y - push the stack size info the stack 9=[pp ... ] - if/then block, true if stack size is 9  Third part, process the first 8 digits 8[ ,]p - loop 8 times f - bring digit forward '0- - convert from char to int s - save digit value rl - copy digit to bottom of stack rp - delete from top of stack s - save current loop var rl - copy to bottom of stack  - increment by one * - multiple with current digit r - reverse stack  Fourth part, process last digit, sum results '0- - convert digit from char to int N - negate &+ - sum all entries on the stack  Fifth part, "is it zero?" and "is divisible by 11?" checks [ ] - if/then block, true is sum is non-zero 92+ - push 11 onto the stack %! - modulo math to get remainder, invert the result u; - print top of stack as int, then exit  Last part, prints "falsey" if some success criteria wasn't met u; - print top of stack (which will be 0) and exit  # AWK, 88 bytes $0="0"$0,n=gsub(a," ")-1{b=n-9;c=9}!b||b==1{for(d-=$n;++b<n;e=d%11)d+=$b*c--}1,$0=!e*!!d


Try it online!

And one I had fun golfing, just to abuse the flexibility of AWK.

$0="0"$0                             - append "0" to the input
gsub(a," ')-1             - re-parse the input, one char per arg
,n=           -1             - set "n", decr RC to get number of chars
{         }  - code block...
b=n-9;      - set "b" to first char to use
c=9   - set "c" to initial multiplier val

!b||b==l                                   - true is we got 8 or 9 chars
{                                } - code block...
for(                  )           - loop over initial 8 chars
d-=$n; - init: "d" set to neg of last digit ++b<n; - test: ends after 8 chars processed e=d%11 - loop-end: "e" is remainder of "%11" d+=$b*c--  - loop-code: multiply and add next digit

1,           - unconditionally run implicit "print $0" code block$0=!e*!!d  - "$0" is 1 if accum value is non-zero and divisible by 11  # K (ngn/k), 42 41 bytes -1 byte from @ngn's improvements {(4=-2!#x)&t&~11!t:+/(|-1,2+!8)*-9#0,.'x}  Try it online! Takes the input as a list of characters. • .'x convert each digit to its integer (e.g. convert "123" to 1 2 3) • -9#0, prepend a 0, then take the last nine values (handles padding 8-digit codes, and avoids errors on input that is not 9 digits long) • (|-1,2+!8)* generate 9 8 7 6 5 4 3 2 -1, and multiply the parsed digits by this • t:+/ take the sum, storing in variable t • t&~11!t check that 11 evenly divides t, and that t is non-zero • (4=-2!#x)& also check that the input is 8 or 9 characters long (literally: the length of the input (integer) divided by 2 is equal to 4) • |/8 9= -> 4=-2! – ngn Commented Oct 27, 2021 at 19:32 # Ruby, 65 bytes -1 byte thanks to Kevin Cruijssen ->n{a,*b=n.to_i.digits i=1 b[6]&&(b[..7].sum{_1*i+=1}-a)%11<1||p}  Attempt This Online! • @KevinCruijssen Thanks. I've updated my answer. Commented Nov 7, 2022 at 16:33 • Looking good now, +1 from me. :) Also, I think you can change the ==0 to <1 for -1 byte. :) Commented Nov 7, 2022 at 18:06 • Don't forget about$. for int vars, -1 byte Commented Nov 8, 2022 at 4:13
• @south I’m told that’s invalid in function submissions because it’s not reusable. See comments here: codegolf.stackexchange.com/posts/comments/563313?noredirect=1 Commented Nov 8, 2022 at 4:17
• @Jordan My understanding might be a little flawed then. Maybe I am making too many assumptions with standard I/O. Will look into it, thanks. Commented Nov 8, 2022 at 4:20

## 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"]}


# Perl 5, 63 + 2 (-F) = 65 bytes

$F[-1]*=-1;map$s+=++$i*$_,reverse@F;say/^.{8,9}$/&&$s&&!(\$s%11)


Try it online!

# 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.

• -1 Commented May 16, 2021 at 8:31

# Python 3.8, 96 bytes

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


Try it online!

Similar to @TFeld's Python 2 answer, but uses Python 3.8 assignment expressions and a few other tricks to get it down to 96 bytes.

# TI-Basic, 60 bytes

max(length(Ans)={8,9})sum(seq(int(10fPart(expr(Ans)/₁₀^(I)))(I-2(I=1)),I,1,9
not(fPart((Ans+not(Ans))/11


Takes input in Ans as a string. Output is stored in Ans and is displayed.