g | x | w | all
Bytes Lang Time Link
009Vyxal 3250506T202413ZThemooni
072Tcl250506T160101Zsergiol
079Tcl130601T220319ZJohannes
081Tcl171119T131358Zsergiol
010Thunno 2230625T163731ZThe Thon
nan230201T113648ZThe Thon
020Pyt230201T021154ZKip the
014Japt221027T143415ZShaggy
nan221027T141503Zbigyihsu
008Vyxal221027T112859Zlyxal
019K ngn/k210121T172315Zcoltim
010Jelly210121T160806Zcaird co
053Perl110210T001411Zninjalj
048Perl 5200310T183123ZXcali
01105AB1E200310T120812ZKevin Cr
028Perl 6181022T142249Znwellnho
057JavaScript190309T214019ZMax
076APLNARS181024T065914Zuser5898
010Stax181022T214600Zrecursiv
024><>190308T102134ZEmigna
025dc190306T175640ZSophia L
069Kotlin190305T155330ZAdam
018APL Dyalog Unicode190305T141120ZAdá
021J181023T062330ZBubbler
106MBASIC181023T190217Zwooshiny
038J110202T192632ZEelvex
076Python 2181022T173507ZTriggern
052Powershell181023T113912Zmazzy
016Husk171119T222431Zბიმო
064Tcl171119T171846Zsergiol
057Windows PowerShell110210T000117ZJoey
241Clojure 264 >121030T185152ZProgramm
nan120331T182839ZAshwini
077C# –121003T161042ZMormegil
161Java 161 Characters110209T232205ZOctavian
071Javascript 73120523T163346ZPaul
025APL120523T154801Zmarinus
025J120331T200210Zephemien
066Groovy120331T083659ZArmand
036Q120309T162953Ztmartin
147R120319T134657ZPaolo
065Ruby110201T222820Zgnibbler
082MATLAB120313T223821ZGriffin
079C120311T171010Zhan
084Scala120311T001835Zuser unk
027APL120302T203450ZDillon C
044Q120302T182130Zskeevey
044dc110210T004728Zninjalj
089Python110201T200125Zgrokus
066Haskell110201T200933Zsepp2k
082PHP110201T193411ZAurel B&
025Golfscript110201T201824Zgnibbler
054Haskell110202T043019ZJoey Ada
097D110202T002035ZJonathan
094C#110201T235503ZNellius
080Ruby110201T211320ZNemo157
044Python110201T210621Zgnibbler

Vyxal 3, 9 bytes

UDWf①-∑t&

Vyxal It Online!

I/O as lists of ints.

-1 byte by Weird Glyphs

UDWf①-∑t&­⁡​‎‎⁡⁠⁡‏‏​⁡⁠⁡‌⁢​‎‎⁡⁠⁢‏‏​⁡⁠⁡‌⁣​‎‎⁡⁠⁣‏⁠‎⁡⁠⁤‏‏​⁡⁠⁡‌⁤​‎‎⁡⁠⁢⁡‏⁠‎⁡⁠⁢⁢‏‏​⁡⁠⁡‌⁢⁡​‎‎⁡⁠⁢⁣‏‏​⁡⁠⁡‌⁢⁢​‎‎⁡⁠⁢⁤‏‏​⁡⁠⁡‌⁢⁣​‎‎⁡⁠⁣⁡‏‏​⁡⁠⁡‌⁢⁤​‎‏​⁢⁠⁡‌­
U          # ‎⁡uninterleave implicit input
 D         # ‎⁢triplicate leaf #2
  Wf       # ‎⁣wrap the entire stack and flatten it
    ①-     # ‎⁤substract 10 from every digit
      ∑    # ‎⁢⁡sum them
       t   # ‎⁢⁢keep the last digit (==%10)
        &  # ‎⁢⁣prepend implicit input
# ‎⁢⁤implicit print
💎

Created with the help of Luminespire.

<script type="vyxal3">
UDWf①-∑t&
</script>
<script>
    args=[["[9,7,8,0,3,0,6,4,0,6,1,5]"],["[9,7,8,0,3,0,3,4,0,6,1,5]"]]
</script>
<script src="https://themoonisacheese.github.io/snippeterpreter/snippet.js" type="module"/>

Tcl, 72 bytes

proc f c {list $c[expr -([lmap a\ b [split $c {}] {list +$a+3*$b}])%10]}

Try it online!

Tcl, 79

proc f c {lmap a\ b [split $c {}] {incr d [expr $a+3*$b]};list $c[expr -$d%10]}

Tcl, 81 bytes

proc C s {list $s[expr -([lmap c [split $s ""] {list +$c*([incr i]%2?1:3)}])%10]}

Try it online!

Thunno 2, 10 bytes

zʂẸ3×+ṄT%a

Attempt This Online!

Explanation

zʂẸ3×+ṄT%a  # Implicit input   ->  978030640615
z           # Uninterleave     ->  [[9,8,3,6,0,1],[7,0,0,4,6,5]]
 ʂ          # Sum each         ->  [27,22]
  Ẹ         # Dump onto stack  ->  27, 22
   3×       # Triple           ->  27, 66
     +      # Add              ->  93
      Ṅ     # Negate           ->  -93
       T%   # Mod 10           ->  7
         a  # Append to input  ->  9780306406157
            # Implicit output

Thunno, \$ 17 \log_{256}(96) \approx \$ 13.99 bytes

DZLdZl.SAu3*+n10%

Attempt This Online!

Port of Kevin Cruijssen's 05AB1E answer.

Explanation

DZLdZl.SAu3*+n10%  # Implicit input
DZL                # Print the input without a trailing newline
   dZl             # Convert it to a list of digits and uninterleave
      .SAu         # Sum each list and dump onto the stack
          3*+      # Multiply the top one by 3 and add together
             n10%  # Negate and mod by 10
                   # This is output implicitly, concatenated onto the input,
                   # which was output without a newline at the start

Pyt, 20 bytes

йУř⁺1∧2*⁺·1ᴇ%1ᴇ-~ǰ

Try it online!

Đ                          implicit input; Đuplicate
 ą                         convert to ąrray of digits
  ĐŁ                       Đuplicate and get Łength
    ř⁺1∧                   řangify [1,2,...,n], increment, and AND with 1
        2*⁺                double and increment (yielding [1,3,1,3,...])
           ·               dot product
            1ᴇ%            modulo 10
               1ᴇ-~        10 - previous result
                   ǰ       ǰoin stack with no delimiters; implicit print

Japt, 14 bytes

I/O as a string.

+¬xÈ*YgDìÃìÌnA

Try it

+¬xÈ*YgDìÃìÌnA     :Implicit input of string U
+                  :Append
 ¬                 :  Split U
  x                :  Reduce by addition
   È               :  After passing each element at index Y through the following function
    *              :    Multiply by
     Yg            :      Index Y into
       D           :        13
        ì          :        To digit array
         Ã         :  End reduction
          ì        :  To digit array
           Ì       :  Last element
            n      :  Subtract from
             A     :   Ten

Go, 118 bytes

func f(n int)int{o,e:=0,0
for i,x:=1,n;i<13;i++{if i%2==0{o+=x%10}else{e+=x%10}
x/=10}
return n*10+(10-(o+3*e)%10)%10}

Attempt This Online!

Vyxal, 8 bytes

⁽Tẇ∑N₀%J

Try it Online!

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

K (ngn/k), 19 bytes

{x,$10!2+/x*12#9 7}

Try it online!

Uses the 9 7 instead of 1 3 trick from @Bubbler's J answer, as well as 2+/x... to convert ASCII digits to usable numbers (e.g. "0" is 48, so adding two makes it 50 which allows it to work given the mod by 10 later).

Jelly, 10 bytes

ȮD×Ðe3SN%⁵

Try it online!

How it works

ȮD×Ðe3SN%⁵ - Main link. Takes n on the left
Ȯ          - Print n
 D         - Convert to digits
   Ðe      - To even indices:
  ×  3     -   Triple
      S    - Take the sum
       N   - Negate
        %⁵ - Mod 10
             Implicitly print this digit

Perl, 53 chars

sub i{($_)=@_;s/(.)(.)/$s+=$1+$2*3/ger;$_.(10-$s)%10}

Perl 5, 48 bytes

sub f{"@_"=~s/(.)(.)/$t-=$1+3*$2/ger;"@_".$t%10}

Try it online!

Doing this as a full program would be shorter:

Perl 5 -p, 31 bytes

s/(.)(.)/$\-=$1+3*$2/ger;$\%=10

Try it online!

05AB1E, 11 bytes

SιO`3*+θTα«

Try it online or verify a few more test cases.

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)

Perl 6, 29 28 bytes

{$_~:1[.comb «*»(9,7)]%10}

Try it online!

JavaScript, 57 bytes

f=s=>s+(10-s.split``.reduce((a,b,i)=>a+b*(3-i%2*2),0)%10)

You can invoke it like this:

f("978030640615")

Effectively, it goes through each (digit, index) pair (b, i), and works out i % 2 (is i odd?), multiplies it by 2, and subtracts it from 3. Take a look at this:

For odd numbers:

For even numbers:

And so we have now generated the correct multipliers. From there it is simple, just add the current accumulator value, initialised at 0, to the current character multiplied by this generated multiplier. JavaScript automatically casts string to numbers when you do this multiplication.

Calculating the last digit is done by taking the last digit (by computing the value modulo 10), and subtracting this from 10.

APL(NARS), chars 38, bytes 76

{⍵,10∣10-10∣+/w,2×w[v/⍨∼2∣v←⍳≢w←⍎¨⍕⍵]}

I had some other test for see better and get definition from Wikipedia, and examples in the page: https://isbn-information.com/check-digit-for-the-13-digit-isbn.html test:

  h←{⍵,10∣10-10∣+/w,2×w[v/⍨∼2∣v←⍳≢w←⍎¨⍕⍵]}
  h 978186197271
978186197271 2 
  h 978168197271
978168197271 8 
  h 978186197371      
978186197371 9 
  h 978186197375      
978186197375 7 

the formula i use would be in one not APL language if w is the argument =>

f(w)==w,(10-(sum(digit(w),2*digitsEVENINDICES(w))mod 10))mod 10

comment:

{⍵,10∣10-10∣+/w,2×w[v/⍨∼2∣v←⍳≢w←⍎¨⍕⍵]}
                   v/⍨∼2∣v←⍳≢w←⍎¨⍕⍵] call w the array of digits of ⍵, return even index
               2×w[                  consider all the digit even of w and multipy for 2
             w,                      put above that array, the array w
           +/                        sum all
      10-10∣                          10 - (above sum)mod 10
    10∣                               above mod 10
 {⍵,                                 add as digit to the number of argument, and return all that

Stax, 11 10 bytes

╣Γ♠☼ù≤m╒X₧

Run and debug it

This is a complete program instead of a function, as stax does not implement functions.

Unpacked, ungolfed, and commented, it looks like this.

q   print input without popping and without newline
E   explode into array of decimal digits
97E [9,7] (this will become the repetition counts)
:B  repeat elements; repetition counts wrap around to cover all input digits
|+  get sum of array with repeated digts
A%  modulus 10
P   print

Run this one

><>, 24 bytes

0{:9)68**-:nl2%2*7+*+a%!

Try it online!

Explanation

0                      !  # initiates sum (final digit) as 0
 {                        # get the next digit
  :9)68**-                # convert from char to int for any iteration except the last
          :n              # print the digit
            l2%2*7+*      # multiply the digit by either 9 or 7 alternately
                    +     # add to sum
                     a%   # mod sum by 10

dc, 25 bytes

dn[A~9z^8+*rd0<M+]dsMxA%p

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.

Kotlin, 120 108 83 77 69 bytes

{s->s+(10-(s.map{it.toInt()-48}.chunked(2).sumBy{it[0]+3*it[1]})%10)}

Try it online!


Thanks to @ovs for removing 8 bytes!!

APL (Dyalog Unicode), 18 bytesSBCS

Anonymous tacit prefix function taking string as argument. Using Bubbler's approach.

⊢,∘⍕10|⍎¨+.×9 7⍴⍨≢

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

J, 21 bytes

,10":@|1#."."+*9 7$~#

Try it online!

How it works

,10":@|1#."."+*9 7$~#
                    #  Take length of input
               9 7$~   Repeat 9 7 that many times
          "."+*        Multiply (elementwise) to the digits
       1#.             Sum
 10   |                Modulo 10
   ":@                 Format to string
,                      Append to the end of the input string

The negative of a + 3b + c + 3d + ... modulo 10 is equal to 9a + 7b + 9c + 7d + ... modulo 10.

MBASIC, 106 bytes

1 INPUT T$:FOR I=1 TO 12 STEP 2:O=O+VAL(MID$(T$,I,1)):E=E+3*VAL(MID$(T$,I+1,1)):NEXT:PRINT 10-(O+E) MOD 10

It ain't pretty, but it works.

? 978030640615
7

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)&(".@{))))

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

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!).

Powershell, 55 53 52 bytes

Inspired by Joey's answer. 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:

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

Husk, 16 bytes

S:(→sΣz¤*or;¢"97

Try it online!

Explanation

Instead of subtracting the sum from 10 I use negated coefficients, the rest is pretty self-explanatory:

S:(              )  -- apply the following function and append result to itself:
   →s               -- mod 10 / last digit
     Σ              -- sum
      z      ¢"97   -- zip input with ['9','7','9','7'...] under:
       ¤ (r;)       --   convert both chars to number, then
        *           --   multiply

Tcl, 64 bytes

proc C s {list $s[expr ([regsub -all (.)(.) $s {-\1-3*\2}])%10]}

Try it online!

Windows PowerShell, 57

filter i{$_+(990-($_-replace'(.)(.)','+$1+3*$2'|iex))%10}

Clojure 264 -> 241 characters:

(defn s [a b] (let [c (count a)] (if (= 0 c) b (s (rest a) (+ b (* (if (= 0 (m c 2)) 1 3) (first a)))))))
(defn m [a b] (let [f (mod a b)] (if (= f 10) 0 f)))
(defn c [a] (str a (m (- 10 (m (s (map #(read-string %) (map str a)) 0) 10)) 10)))

Usage

(c "978030640615")

Non minified:

(defn sum [collection total]
  (let [len (count collection)]
    (if (= 0 len)
         total
         (sum (rest collection)
           (+ total
            (* (if (= 0 (mod len 2)) 1 3)
             (first collection)))))))

(defn mods [a b]
  (let [f (mod a b)]
    (if (= f 10) 
      0
      f)))


(defn create [isbn] 
  (str isbn
       (mods (- 10 (mods (sum (map #(read-string %) (map str isbn)) 0) 10)) 10))) 

Usage:

(create "978030640615")

New to Clojure so I have to believe that can be knocked down.

Python

>>>r=input()
>>>a=0
>>>for x in r[::2]:
    a+=int(x)
>>>for x in r[1::2]:
    a+=int(x)*3
>>>a=(10-(a%10))%10
print(r+str(a))

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

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

Javascript: 73 71 chars

function _(b){for(i=s=0;12>i;)s+=((i*2&2)+1)*b[i++];return b+(10-s%10)}

Usage:

_('978030640615') //"9780306406157"

APL (25)

{⍵,⍕10-10|+/(⍎¨⍵)×12⍴1,3}

J, 25

,[:":10|0(-+/)"."0*1 3$~#
   f =: ,[:":10|0(-+/)"."0*1 3$~#
   f '978030640615'
9780306406157

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

Q, 36 chars

{x,-3!10-mod[;10]sum(12#1 3)*"I"$'x}

R, 147 characters

f=function(v){s=as.numeric(strsplit(v,"")[[1]]);t=0;for(i in 1:12)if(i%%2==0)t=t+s[i]*3 else t=t+s[i];paste(v,(10-(t%%10))%%10,collapse="",sep="")}

Usage:

f("978030640615")
[1] "9780306406157"

Ruby - 73 65 chars

f=->s{s+((2-(s+s.gsub(/.(.)/,'\1')*2).bytes.inject(:+))%10).to_s}

MATLAB - 82 chars

function c(i)
[i num2str(mod(10-mod(sum(str2num(i(:)).*repmat([1;3],6,1)),10),10))]

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

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"

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←{ ... }):

Q (44 chars)

f:{x,string 10-mod[;10]0+/sum@'2 cut"I"$/:x}

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'

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`

Haskell, 78 71 66 characters

i s=s++(show$mod(2-sum(zipWith(*)(cycle[1,3])(map fromEnum s)))10)

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
}

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'

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, which is supported by GHC (with the -XParallelListComp flag) and Hugs (with the -98 flag).

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.

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!

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

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`