[Question]
  [
Write a function which, given the first 12 digits of an [ISBN-13](https://en.wikipedia.org/wiki/International_Standard_Book_Number#ISBN-13_check_digit_calculation) code, will calculate the entire ISBN via calculating and appending an appropriate check digit.
Your function's input is a string containing the first 12 digits of the ISBN. Its output is a string containing all 13 digits.
## Formal specification
Write a function which, when given a string *s* consisting entirely of exactly 12 decimal digits (and no other characters), returns a string *t* with the following properties:
* *t* consists of exactly 13 decimal digits (and no other characters);
* *s* is a prefix of *t*;
* the sum of all digits in odd positions in *t* (i.e. the first, third, fifth, etc.), plus three times the sum of all digits in even positions in *t* (i.e. the second, fourth, sixth, etc), is a multiple of 10.
## Example / test case
**Input**  
`978030640615`
**Output**  
`9780306406157`
## Victory condition
As a [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'") challenge, the shortest answer wins.
  
[Answer]
## Golfscript - 25 chars
```
{...+(;2%+{+}*3-~10%`+}:f
```
Whole program version is only 19 chars
```
...+(;2%+{+}*3-~10%
```
Check back here for analysis later. Meanwhile check out my old uninspired answer
**Golfscript - 32 chars**
Similar to the luhn number calculation
```
{.{2+}%.(;2%{.+}%+{+}*~)10%`+}:f
```
Analysis for 978030640615
```
{...}:f this is how you define the function in golfscript
.       store an extra copy of the input string
        '978030640615' '978030640615'
{2+}%   add 2 to each ascii digit, so '0'=>50, I can get away with this instead
        of {15&}% because we are doing mod 10 math on it later
        '978030640615' [59 57 58 50 53 50 56 54 50 56 51 55]
.       duplicate that list
        '978030640615' [59 57 58 50 53 50 56 54 50 56 51 55] [59 57 58 50 53 50 56 54 50 56 51 55]
(;      trim the first element off
        '978030640615' [59 57 58 50 53 50 56 54 50 56 51 55] [57 58 50 53 50 56 54 50 56 51 55]
2%      select every second element
        '978030640615' [59 57 58 50 53 50 56 54 50 56 51 55] [57 50 50 54 56 55]
{.+}%   double each element by adding to itself
        '978030640615' [59 57 58 50 53 50 56 54 50 56 51 55] [114 100 100 108 112 110]
+       join the two lists together
        '978030640615' [59 57 58 50 53 50 56 54 50 56 51 55 114 100 100 108 112 110]
{+}*    add up the items in the list
        '978030640615' 1293
~       bitwise not
        '978030640615' -1294
)       add one
        '978030640615' -1293            
10%     mod 10
        '978030640615' 7
`       convert to str
        '978030640615' '7'
+       join the strings
        '9780306406157'
```
[Answer]
## Python - 44 chars
```
f=lambda s:s+`-sum(map(int,s+s[1::2]*2))%10`
```
Python - 53 chars
```
def f(s):d=map(int,s);return s+`-sum(d+d[1::2]*2)%10`
```
[Answer]
## Haskell - 54 characters
```
i s=s++show(sum[-read[c]*m|c<-s|m<-cycle[1,3]]`mod`10)
```
This requires support for [parallel list comprehensions](http://cvs.haskell.org/Hugs/pages/users_guide/hugs-ghc.html#ZIP-COMPREHENSION), which is supported by GHC (with the `-XParallelListComp` flag) and Hugs (with the `-98` flag).
[Answer]
## APL (27 characters)
```
F←{⍵,⍕10|10-(12⍴1 3)+.×⍎¨⍵}
```
I'm using Dyalog APL as my interpreter. Here's a quick explanation, mostly from right to left (within the function definition, `F←{ ... }`):
* `⍎¨⍵`: Execute/evaluate (`⍎`) each (`¨`) character given in the right argument (`⍵`).
* `(12⍴1 3)`: Reshape (`⍴`) the vector `1 3` into a `12`-element vector (repeating to fill the gaps).
* `+.×`: Take the dot product (`+.×`) of its left argument (`(12⍴1 3)`) and its right argument (`⍎¨⍵`).
* `10-`: Subtract from 10.
* `10|`: Find the remainder after division by `10`.
* `⍕`: Format the number (i.e., give a character representation).
* `⍵,`: Append (`,`) our calculated digit to the right argument.
[Answer]
## PHP - ~~86~~ ~~85~~ 82 chars
```
function c($i){for($a=$s=0;$a<12;)$s+=$i[$a]*($a++%2?3:1);return$i.(10-$s%10)%10;}
```
Re-format and explanation:
```
function c($i){                     // function c, $i is the input
    for($a=$s=0;$a<12;)             // for loop x12 - both $a and $s equal 0
                                    // notice there is no incrementation and
                                    // no curly braces as there is just one
                                    // command to loop through
        $s+=$i[$a]*($a++%2?3:1);    // $s (sum) is being incremented by
                                    // $ath character of $i (auto-casted to
                                    // int) multiplied by 3 or 1, depending
                                    // wheter $a is even or not (%2 results
                                    // either 1 or 0, but 0 == FALSE)
                                    // $a is incremented here, using the
                                    // post-incrementation - which means that
                                    // it is incremented, but AFTER the value
                                    // is returned
    return$i.(10-$s%10)%10;         // returns $i with the check digit
                                    // attached - first it is %'d by 10,
                                    // then the result is subtracted from
                                    // 10 and finally %'d by 10 again (which
                                    // effectively just replaces 10 with 0)
                                    // % has higher priority than -, so there
                                    // are no parentheses around $s%10
}
```
[Answer]
## Windows PowerShell, 57
```
filter i{$_+(990-($_-replace'(.)(.)','+$1+3*$2'|iex))%10}
```
[Answer]
## Haskell, ~~78~~ ~~71~~ 66 characters
```
i s=s++(show$mod(2-sum(zipWith(*)(cycle[1,3])(map fromEnum s)))10)
```
[Answer]
## Ruby - ~~73~~ 65 chars
```
f=->s{s+((2-(s+s.gsub(/.(.)/,'\1')*2).bytes.inject(:+))%10).to_s}
```
[Answer]
**C# (94 characters)**
```
string I(string i){int s=0,j=0;for(;j<12;)s+=(i[j]-48)*(j++%2<1?1:3);return i+((10-s%10)%10);}
```
With linebreaks/whitespace for readability:
```
string I(string i) 
{ 
    int s = 0, j = 0;
    for (; j < 12; )
        s += (i[j] - 48) * (j++ % 2 < 1 ? 1 : 3); 
    return i + ((10 - s % 10) % 10); 
}
```
Tested on several ISBNs from books on my shelf, so I know it's working!
[Answer]
**Python - ~~91~~, 89**
```
0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
|         |         |         |         |         |         |         |         |         |
 def c(i):return i+`(10-(sum(int(x)*3for x in i[1::2])+sum(int(x)for x in i[::2]))%10)%10`
```
[Answer]
## C# – ~~89~~ 77 characters
```
string I(string s){return s+(9992-s.Sum(x=>x-0)-2*s.Where((x,i)=>i%2>0).Sum(x=>x-0))%10;}
```
Formatted for readability:
```
string I(string s)
{
    return s +
            (9992
            - s.Sum(x => x - 0)
            - 2 * s.Where((x, i) => i%2 > 0).Sum(x => x - 0)
            ) % 10;
}
```
We do not multiply by one or three, we just add everything, plus we add all even-placed characters one more time, multiplied by two.
9992 is large enough so that the sum of all ASCII characters is less than that (so that we may mod by 10 and be sure the result is positive, no need to mod by 10 twice), and is not divisible by zero because we add up all those extra 2\*12\*48 (twelve ASCII digits, weighed by 1 and 3) == 1152, which allows us to spare one extra character (instead of twice subtracting 48, we subtract 0 just to convert from char to int, but instead of 990, we need to write 9992).
But then again, even though much less beautiful ;-), this old-school solution gets us to 80 characters (but this is almost C-compatible):
```
string T(string i){int s=2,j=0;for(;j<12;)s+=i[j]*(9-j++%2*2);return i+s%10;}
```
[Answer]
## J - 55 45 38
```
f=:3 :'y,":10|10-10|+/(12$1 3)*"."0 y'
```
eg
```
f '978030640615'
9780306406157
```
old way:
```
f=:,":@(10(10&|@-)(10&|@+/@((12$1 3)*(i.12)&(".@{))))
```
[Answer]
# [Perl 6](https://github.com/nxadm/rakudo-pkg), ~~29~~ 28 bytes
```
{$_~:1[.comb «*»(9,7)]%10}
```
[Try it online!](https://tio.run/##DcNRCoJAEADQq8yHikrI7M7szE5UF4mQivZLMexLoi7UEfrzYlsP3v02D5LHBaoE@/ws@vfWHbvrNF5g/bTrt7aNNqfS4Ss/zgukuugbSNMMO9OIhMIoLoAEUi//RhGcobcgkZU9GLEohajq@ZB/ "Perl 6 – Try It Online")
[Answer]
## Ruby - 80 characters
```
def f s;s+(10-s.bytes.zip([1,3]*6).map{|j,k|(j-48)*k}.inject(:+)%10).to_s[0];end
```
[Answer]
## dc, 44 chars
```
[d0r[I~3*rI~rsn++lndZ0<x]dsxx+I%Ir-I%rI*+]sI
```
Invoke as `lIx`, e.g:
```
dc -e'[d0r[I~3*rI~rsn++lndZ0<x]dsxx+I%Ir-I%rI*+]sI' -e '978030640615lIxp'
```
[Answer]
# Q, 36 chars
```
{x,-3!10-mod[;10]sum(12#1 3)*"I"$'x}
```
[Answer]
## Perl, 53 chars
```
sub i{($_)=@_;s/(.)(.)/$s+=$1+$2*3/ger;$_.(10-$s)%10}
```
[Answer]
**D - 97 characters**
```
auto f(string s){int n;foreach(i,c;s)n+=((i&1)*2+1)*(c-48);return s~cast(char)((10-n%10)%10+48);}
```
Formatted more legibly:
```
auto f(string s)
{
    int n;
    foreach(i, c; s)
        n += ((i & 1) * 2 + 1) * (c - 48);
    return s ~ cast(char)((10 - n % 10) % 10 + 48);
}
```
The verbosity of D's cast operator definitely makes it harder to write obsessively short code though.
[Answer]
**Java - 161 Characters** :(
```
int b[]=new int[a.length];
int d=0,n=0,j=1;
for(char c:a.toCharArray())b[d++]=Integer.valueOf(c+"");
for(int i:b)n+=(j++%2==0)?(i*3):(i*1);
return a+(10-(n%10));
```
[Answer]
# [APL (Dyalog Unicode)](https://www.dyalog.com/), 18 [bytes](https://codegolf.meta.stackexchange.com/a/9429/43319 "When can APL characters be counted as 1 byte each?")[SBCS](https://github.com/abrudz/SBCS ".dyalog files using a single byte character set")
Anonymous tacit prefix function taking string as argument. Using [Bubbler's approach](https://codegolf.stackexchange.com/a/174553/43319).
```
⊢,∘⍕10|⍎¨+.×9 7⍴⍨≢
```
[Try it online!](https://tio.run/##SyzI0U2pTMzJT////1HXIp1HHTMe9U41NKh51Nt3aIW23uHplgrmj3q3POpd8ahz0f@0R20TgDKP@qZ6@j/qaj603vhR20QgLzjIGUiGeHgG/09TULc0tzAwNjAzMTAzNFUHAA "APL (Dyalog Unicode) – Try It Online")
`≢` length of argument (12)
`9 7⍴⍨` cyclically reshape `[9,7]` to that length
`+.×` dot product of the following with that:
`⍎¨` `evaluate each character
`10|` mod-10 of that
`,∘⍕` prepend the following the the stringification of that:
`⊢` the unmodified argument
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E/wiki/Commands), 11 [bytes](https://github.com/Adriandmen/05AB1E/wiki/Codepage)
```
SιO`3*+θTα«
```
[Try it online](https://tio.run/##yy9OTMpM/f8/@NxO/wRjLe1zO0LObTy0@v9/S3MLA2MDMxMDM0NTAA) or [verify a few more test cases](https://tio.run/##yy9OTMpM/V9TVmmvpPCobZKCkn2ly//gczv9E4y1tM/tCDm38dDq/zr/Lc0tDIwNzEwMzAxNucxMjc2NzIDY0tiCy9DSwMjS1MzCxNzEiMvS2MTM3NjUwtzcyAQA).
**Explanation:**
```
S            # Convert the (implicit) input to a list of digits
             #  i.e. 978030640615 → [9,7,8,0,3,0,6,4,0,6,1,5]
 ι           # Uninterleave it
             #  → [[9,8,3,6,0,1],[7,0,0,4,6,5]]
  O          # Sum each inner list
             #  → [27,22]
   `         # Push them both separated to the stack
    3*       # Multiply the top one by 3
             #  → 66
      +      # Sum them together
             #  → 93
       θ     # Only leave the last digit
             #  → 3
        Tα   # Take the absolute difference of this digit with 10
             #  → 7
          «  # And append this digit to the (implicit) input
             #  → 9780306406157
             # (after which it is output implicitly as result)
```
[Answer]
# [Vyxal](https://github.com/Vyxal/Vyxal), 8 bytes
```
⁽Tẇ∑N₀%J
```
[Try it Online!](https://vyxal.pythonanywhere.com/#WyIiLCIiLCLigb1U4bqH4oiRTuKCgCVKIiwiIiwiOTc4MDMwNjQwNjE1Il0=)
Port of Jelly
## Explained
```
⁽Tẇ∑N₀%J
⁽Tẇ       # Triple every second digit
   ∑N     # -sum of that
     ₀%   # modulo by 10
       J  # append that result to the original input
```
[Answer]
# Q (44 chars)
```
f:{x,string 10-mod[;10]0+/sum@'2 cut"I"$/:x}
```
[Answer]
## Scala 84
```
def b(i:String)=i+(10-((i.sliding(2,2).map(_.toInt).map(k=>k/10+k%10*3).sum)%10)%10)
```
Testing:
```
val isbn="978030640615"
b(isbn)
```
Result:
```
"9780306406157"
```
[Answer]
# C, 80 79 characters
The function modifies the string in place, but returns the original string pointer to satisfy the problem requirements.
```
s;char*f(char*p){for(s=2;*p;s+=7**p++)s+=9**p++;*p++=48+s%10;*p=0;return p-13;}
```
Some explanation: Instead of subtracting 48 (the ASCII value of the digit `0`) from each input character, the accumulator `s` is initialized so that it is modulo 10 equal to 48+3\*48+48+3\*48...+48+3\*48 = 24\*48 = 1152. The step `10-sum` can be avoided by accumulating `s` by subtraction instead of addition. However, the module operator `%` in C would not give a usable result if `s` was negative, so instead of using `s-=` the multipliers 3 and 1 are replaced by -3=7 modulo 10 and -1=9 modulo 10, respectively.
Test harness:
```
#include <stdio.h>
#define N 12
int main()
{
     char b[N+2];
     fgets(b, N+1, stdin);
     puts(f(b));
     return 0;
}
```
[Answer]
# Groovy 75, 66 chars
```
i={int i;it+(10-it.inject(0){t,c->t+(i++&1?:3)*(c as int)}%10)%10}
```
use:
```
String z = "978030640615"
println i(z)
-> 9780306406157
```
[Answer]
### APL (25)
```
{⍵,⍕10-10|+/(⍎¨⍵)×12⍴1,3}
```
[Answer]
# Powershell, ~~55~~ ~~53~~ 52 bytes
*Inspired by [Joey's answer](https://codegolf.stackexchange.com/a/791/80745). I'm impressed with her regex.*
```
"$args"+($args-replace'(.)(.)','+40-$1-3*$2'|iex)%10
```
## Powershell, 55 bytes, whithout regex
```
param($s)$s[1,3,5,7,9,11*2+0..11]|%{$r+=58-$_};$s+$r%10
```
Explanation:
* the index range = (the even positions `1,3,5,7,9,11` repeated 2 times + all positions `0..11`)
* `$r+=58-$_` makes a sum of supplements up to `10+[char]'0'`
* `$s+$r%10` outputs the result
Test script:
```
$f = {
param($s)$s[1,3,5,7,9,11*2+0..11]|%{$r+=58-$_};$s+$r%10
}
@(
    ,("978030640615" , "9780306406157")
) | % {
    $s,$expected = $_
    $result = &$f $s
    "$($result-eq$expected)"
    $s
    $result
}
```
Output:
```
True
978030640615
9780306406157
```
[Answer]
# [Python 2](https://docs.python.org/2/), ~~78~~ 76 bytes
```
lambda n:n+`10-(sum(int(a)+3*int(b)for a,b in zip(n[::2],n[1::2]))%10or 10)`
```
[Try it online!](https://tio.run/##XY7RCoIwFIav3VPsJraTCzYtrcGexAQnKQk6xc2Levnlkoi6Ov8HH@f/p4e7jybxrbr6Xg/1TWMjTVwJfqB2GWhnHNUQp/sQamjHGWtW487gZzdRU0iZlMwUIlyAneCrIDhU3jXWWVWgiJJLfuYpz448EyfC8A/nBNjXSf@cjTkBVCIUusNXhufGLr0LI94tEkXTvO7DLQ0M7BOU2kz/Ag "Python 2 – Try It Online")
Takes a string as an argument.
# Explanation:
Using python slice notation, converts a string into a list of character pairs. ("978030640615" -> [("9","7"), ("8", "0"), ("3", "0"), ("6", "4"), ("0", "6"), ("1", "5")] )
For that list of pairs, converts each item into an integer and returns a+3b.
Sums all the results.
Gets the sum modulo 10, OR 10 if the remainder is 0. (This prevents the final digit from being 10 instead of 0.)
Removes the remainder from 10 to get the check digit.
Converts the calculated check digit to a string via deprecated backtick expression.
Returns the original number plus the calculated check digit.
# Edit:
Saved 2 byes by removing spaces (thanks [Jo King](https://codegolf.stackexchange.com/users/76162/jo-king)!).
[Answer]
# [dc](https://www.gnu.org/software/bc/manual/dc-1.05/html_mono/dc.html), 25 bytes
```
dn[A~9z^8+*rd0<M+]dsMxA%p
```
[Try it online!](https://tio.run/##S0n@b2luYWBsYGZiYGZo@j8lL9qxzrIqzkJbqyjFwMZXOzal2LfCUbXg/38A "dc – Try It Online")
I know there's already a dc answer here, but 25<44 so I guess I feel 19 bytes of okay about it. 
This uses the fact that `8+9^z` is equivalent to either `-3` or `-1` mod 10 depending on whether z is even or odd. So I use `A~` to break the number into digits on the stack, but as I build the stack I multiply each digit by `8+9^z` where z is the current stack size. Then I add them all as the *function* stack unrolls, and print the last digit.
]