| Bytes | Lang | Time | Link |
|---|---|---|---|
| 009 | Vyxal 3 | 250506T202413Z | Themooni |
| 072 | Tcl | 250506T160101Z | sergiol |
| 079 | Tcl | 130601T220319Z | Johannes |
| 081 | Tcl | 171119T131358Z | sergiol |
| 010 | Thunno 2 | 230625T163731Z | The Thon |
| nan | 230201T113648Z | The Thon | |
| 020 | Pyt | 230201T021154Z | Kip the |
| 014 | Japt | 221027T143415Z | Shaggy |
| nan | 221027T141503Z | bigyihsu | |
| 008 | Vyxal | 221027T112859Z | lyxal |
| 019 | K ngn/k | 210121T172315Z | coltim |
| 010 | Jelly | 210121T160806Z | caird co |
| 053 | Perl | 110210T001411Z | ninjalj |
| 048 | Perl 5 | 200310T183123Z | Xcali |
| 011 | 05AB1E | 200310T120812Z | Kevin Cr |
| 028 | Perl 6 | 181022T142249Z | nwellnho |
| 057 | JavaScript | 190309T214019Z | Max |
| 076 | APLNARS | 181024T065914Z | user5898 |
| 010 | Stax | 181022T214600Z | recursiv |
| 024 | ><> | 190308T102134Z | Emigna |
| 025 | dc | 190306T175640Z | Sophia L |
| 069 | Kotlin | 190305T155330Z | Adam |
| 018 | APL Dyalog Unicode | 190305T141120Z | Adá |
| 021 | J | 181023T062330Z | Bubbler |
| 106 | MBASIC | 181023T190217Z | wooshiny |
| 038 | J | 110202T192632Z | Eelvex |
| 076 | Python 2 | 181022T173507Z | Triggern |
| 052 | Powershell | 181023T113912Z | mazzy |
| 016 | Husk | 171119T222431Z | ბიმო |
| 064 | Tcl | 171119T171846Z | sergiol |
| 057 | Windows PowerShell | 110210T000117Z | Joey |
| 241 | Clojure 264 > | 121030T185152Z | Programm |
| nan | 120331T182839Z | Ashwini | |
| 077 | C# – | 121003T161042Z | Mormegil |
| 161 | Java 161 Characters | 110209T232205Z | Octavian |
| 071 | Javascript 73 | 120523T163346Z | Paul |
| 025 | APL | 120523T154801Z | marinus |
| 025 | J | 120331T200210Z | ephemien |
| 066 | Groovy | 120331T083659Z | Armand |
| 036 | Q | 120309T162953Z | tmartin |
| 147 | R | 120319T134657Z | Paolo |
| 065 | Ruby | 110201T222820Z | gnibbler |
| 082 | MATLAB | 120313T223821Z | Griffin |
| 079 | C | 120311T171010Z | han |
| 084 | Scala | 120311T001835Z | user unk |
| 027 | APL | 120302T203450Z | Dillon C |
| 044 | Q | 120302T182130Z | skeevey |
| 044 | dc | 110210T004728Z | ninjalj |
| 089 | Python | 110201T200125Z | grokus |
| 066 | Haskell | 110201T200933Z | sepp2k |
| 082 | PHP | 110201T193411Z | Aurel B& |
| 025 | Golfscript | 110201T201824Z | gnibbler |
| 054 | Haskell | 110202T043019Z | Joey Ada |
| 097 | D | 110202T002035Z | Jonathan |
| 094 | C# | 110201T235503Z | Nellius |
| 080 | Ruby | 110201T211320Z | Nemo157 |
| 044 | Python | 110201T210621Z | gnibbler |
Vyxal 3, 9 bytes
UDWf①-∑t&
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]}
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]}
Thunno 2, 10 bytes
zʂẸ3×+ṄT%a
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%
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ᴇ-~ǰ
Đ 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
+¬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}
Vyxal, 8 bytes
⁽Tẇ∑N₀%J
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}
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).
12#9 7build a 12-length list of9 7repeated (i.e.9 7 9 7 9 7 9 7 9 7 9 7)x*multiply the underlying ASCII character values by this pattern2+/seed a sum with2to properly offset the input digits10!mod by 10$convert result to a stringx,append it to the input and return
Jelly, 10 bytes
ȮD×Ðe3SN%⁵
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}
Doing this as a full program would be shorter:
Perl 5 -p, 31 bytes
s/(.)(.)/$\-=$1+3*$2/ger;$\%=10
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)
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:
(i % 2)is 1((i % 2) * 2)is 23 - ((i % 2) * 2)is 1
For even numbers:
(i % 2)is 0((i % 2) * 2)is 03 - ((i % 2) * 2)is 3
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₧
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
><>, 24 bytes
0{:9)68**-:nl2%2*7+*+a%!
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
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)}
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⍴⍨≢
≢ 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$~#
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)`
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:
- the index range = (the even positions
1,3,5,7,9,11repeated 2 times + all positions0..11) $r+=58-$_makes a sum of supplements up to10+[char]'0'$s+$r%10outputs 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
Husk, 16 bytes
S:(→sΣz¤*or;¢"97
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
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←{ ... }):
⍎¨⍵: Execute/evaluate (⍎) each (¨) character given in the right argument (⍵).(12⍴1 3): Reshape (⍴) the vector1 3into a12-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 by10.⍕: Format the number (i.e., give a character representation).⍵,: Append (,) our calculated digit to the right argument.
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`