# 计算ISBN-13校验位

28

## 正式规格

• t完全由13个十进制数字组成（没有其他字符）；
• st的前缀；
• t中奇数位置（即第一，第三，第五等）的所有数字的总和，加上t中偶数位置（即第二，第四，第六等）的所有数字的总和的三倍。10的倍数。

## 示例/测试用例

`978030640615`

`9780306406157`

1

sepp2k 2011年

1

Kevin Brown

6

FlipTack

RosLuP

14

## Golfscript-25个字符

``````{...+(;2%+{+}*3-~10%`+}:f
``````

``````...+(;2%+{+}*3-~10%
``````

Golfscript-32个字符

``````{.{2+}%.(;2%{.+}%+{+}*~)10%`+}:f
``````

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
'978030640615' -1293
10%     mod 10
'978030640615' 7
`       convert to str
'978030640615' '7'
+       join the strings
'9780306406157'
``````

Rob

@MikeDtrick，这些字符是GS定义功能的方式。19个字符的版本可以完成您的建议，但该问题要求“功能”
gnibbler

Erik the Outgolfer

8

## Python-44个字符

``````f=lambda s:s+`-sum(map(int,s+s[1::2]*2))%10`
``````

Python-53个字符

``````def f(s):d=map(int,s);return s+`-sum(d+d[1::2]*2)%10`
``````

Eelvex

@Eelvex，输入字符串应该总是12位数字
gnibbler

Eelvex

7

``````i s=s++show(sum[-read[c]*m|c<-s|m<-cycle[1,3]]`mod`10)
``````

ბიმო

7

## APL（27个字符）

``````F←{⍵,⍕10|10-(12⍴1 3)+.×⍎¨⍵}
``````

• `⍎¨⍵`：执行/评估（`⍎``¨`右参数（`⍵`）中给出的每个（）字符。
• `(12⍴1 3)``⍴`将向量整形（）`1 3``12`-element向量（重复填补空白）。
• `+.×``+.×`取其左参数（`(12⍴1 3)`）和右参数（`⍎¨⍵`）的点积（）。
• `10-`：从10减去。
• `10|`：除以后的余数`10`
• `⍕`：格式化数字（即，使用字符表示）。
• `⍵,`：将（`,`）我们计算出的数字附加到正确的参数上。

6

## PHP- 86 85 82个字符

``````function c(\$i){for(\$a=\$s=0;\$a<12;)\$s+=\$i[\$a]*(\$a++%2?3:1);return\$i.(10-\$s%10)%10;}
``````

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

Nellius 2011年

6

## Windows PowerShell，57

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

5

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

5

## 红宝石-73 65个字符

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

`"\\1"`-> `'\1'`
Nemo157

@Nemo，谢谢，我的红宝石有点生锈
gnibbler 2011年

Hauleth 2012年

4

C＃（94个字符）

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

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

4

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

4

## Perl，53个字符

``````sub i{\$_=shift;s/(.)(.)/\$s+=\$1+\$2*3/ge;\$_.(10-\$s)%10}
``````

4

## C＃– 89 77个字符

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

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

9992足够大，因此所有ASCII字符的总和都小于该值（以便我们可以乘以10，并确保结果为正，不需要乘以10两次），并且不能被零整除，因为我们将将所有这些额外的2 * 12 * 48（十二个ASCII数字，分别由1和3加权）== 1152，这使我们可以保留一个额外的字符（而不是两次减去48，我们减去0只是为了将char转换为int，但我们需要编写9992），而不是990。

``string T(string i){int s=2,j=0;for(;j<12;)s+=i[j]*(9-j++%2*2);return i+s%10;}``

4

## J- 55 45 38

``````f=:3 :'y,":10|10-10|+/(12\$1 3)*"."0 y'
``````

``````f '978030640615'
9780306406157
``````

``````f=:,":@(10(10&|@-)(10&|@+/@((12\$1 3)*(i.12)&(".@{))))
``````

1
`(i.12)(".@{)y`可以替换为`"."0 y`
J Guy

3

## Ruby-80个字符

``````def f s;s+(10-s.bytes.zip([1,3]*6).map{|j,k|(j-48)*k}.inject(:+)%10).to_s[0];end
``````

3

## dc，44个字符

``````[d0r[I~3*rI~rsn++lndZ0<x]dsxx+I%Ir-I%rI*+]sI
``````

``````dc -e'[d0r[I~3*rI~rsn++lndZ0<x]dsxx+I%Ir-I%rI*+]sI' -e '978030640615lIxp'
``````

3

# Q，36个字符

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

2

D-97个字符

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

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

D的强制转换运算符的冗长性无疑使编写简短的强迫性代码变得更加困难。

2

Java-161个字符 :(

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

2012年

1

# Q（44个字符）

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

skeevey 2012年

1

## 斯卡拉84

``````def b(i:String)=i+(10-((i.sliding(2,2).map(_.toInt).map(k=>k/10+k%10*3).sum)%10)%10)
``````

``````val isbn="978030640615"
b(isbn)
``````

``````"9780306406157"
``````

1

# C，80 79个字符

``````s;char*f(char*p){for(s=2;*p;s+=7**p++)s+=9**p++;*p++=48+s%10;*p=0;return p-13;}
``````

``````#include <stdio.h>
#define N 12
int main()
{
char b[N+2];
fgets(b, N+1, stdin);
puts(f(b));
return 0;
}
``````

1

# 常规75，66个字符

``````i={int i;it+(10-it.inject(0){t,c->t+(i++&1?:3)*(c as int)}%10)%10}
``````

``````String z = "978030640615"
println i(z)

-> 9780306406157
``````

1

### APL（25）

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

RosLuP

1

# Perl 6，29个字节

``{\$_~-:1[.comb «*»(1,3)]%10}``

2
@JoKing这实际上是APL和J领域的一个非常古老的技巧：）
Bubbler

978186197371的错误结果似乎是8而不是9 ...
RosLuP

RosLuP

1

# Python 2中，78 76个字节

``lambda n:n+`10-(sum(int(a)+3*int(b)for a,b in zip(n[::2],n[1::2]))%10or 10)```

Jo King

RosLuP

RosLuP

1

# APL（Dyalog Unicode），18 字节SBCS

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

`≢` 参数长度（12）

`9 7⍴⍨` 周期性地重塑`[9,7]`到该长度

`+.×` 以下的点积：

`⍎¨` `评估每个字符

`10|` 那的mod-10

`,∘⍕` 在此之前进行以下分类：

`⊢` 未经修改的论点

1

# dc，25个字节

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

0

# MATLAB-82个字符

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

0

## R，147个字符

``````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="")}
``````

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

0

# J，25

``````,[:":10|0(-+/)"."0*1 3\$~#
``````
```   f =：，[：“：10 | 0（-+ /）”。“ 0 * 1 3 \$〜＃
f'978030640615'
9780306406157
```