आईएसबीएन -13 चेक अंक की गणना करें


28

एक फ़ंक्शन लिखें, जो एक आईएसबीएन -13 कोड के पहले 12 अंकों को देखते हुए , पूरे आईएसबीएन की गणना एक उपयुक्त अंक अंकों की गणना और जोड़कर करेगा।

आपके फ़ंक्शन का इनपुट एक स्ट्रिंग है जिसमें आईएसबीएन के पहले 12 अंक हैं। इसका आउटपुट एक स्ट्रिंग है जिसमें सभी 13 अंक होते हैं।

औपचारिक विनिर्देश

एक समारोह, जो जब एक स्ट्रिंग दी लिखें रों वास्तव में 12 दशमलव अंक (और कोई अन्य वर्ण) की पूरी तरह से मिलकर, एक स्ट्रिंग रिटर्न टी निम्नलिखित गुणों के साथ:

  • टी में वास्तव में 13 दशमलव अंक होते हैं (और कोई अन्य वर्ण नहीं);
  • s t का एक उपसर्ग है ;
  • टी (यानी पहले, तीसरे, पांचवें, आदि) में विषम स्थिति में सभी अंकों का योग , और साथ ही टी (यानी दूसरे, चौथे, छठे, आदि) में भी सभी अंकों के तीन गुना अंकों का योग है , 10 के कई।

उदाहरण / परीक्षण का मामला

इनपुट
978030640615

उत्पादन
9780306406157

विजय की स्थिति

एक के रूप में चुनौती, कम से कम जवाब जीत।


1
क्या इनपुट और आउटपुट में डैश या केवल अंक होते हैं?
19

1
वर्णन, इनपुट और आउटपुट केवल अंक हैं
केविन ब्राउन

क्या पूर्ण आईएसबीएन -13 का उत्पादन भी स्वीकार्य है?
श्री ललामा

6
ध्यान दें कि प्रश्न वास्तव में स्वयं समाहित होने चाहिए, इसलिए यहां एल्गोरिदम का विवरण शामिल करना उपयोगी होगा।
FlipTack

मेरे लिए ऊपर की पोस्ट उदाहरण परीक्षण के खराब है ... पिछले 10 isbn पर होगा और उस में से 0 को अंतिम अंक के रूप में वापस करना होगा ...
RosLuP

जवाबों:


14

गोल्फस्क्रिप्ट - 25 वर्ण

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

पूरे कार्यक्रम का संस्करण केवल 19 वर्ण है

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

बाद में विश्लेषण के लिए यहां देखें। इस बीच मेरे पुराने नायाब जवाब की जाँच करें

गोल्फस्क्रिप्ट - 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
)       add one
        '978030640615' -1293            
10%     mod 10
        '978030640615' 7
`       convert to str
        '978030640615' '7'
+       join the strings
        '9780306406157'

एक दुभाषिया के माध्यम से कोड चलाने के बाद, मुझे लगता है कि आप पहले {और अंतिम तीन पात्रों से छुटकारा पाकर कुछ पात्रों (अपने 32 चरित्र लुहान-आधारित समाधान में) को बचा सकते हैं ; }:f। मुझे आश्चर्य है कि अगर एक ही चीज को पहले समाधान के लिए किया जा सकता है ...
रोब

@ मायिकड्रिक, वे पात्र हैं जो जीएस को एक फ़ंक्शन को परिभाषित करते हैं। 19 चार संस्करण आप क्या सुझाव है कि करता है, लेकिन सवाल एक "समारोह" के लिए कहा
gnibbler

ओह ठीक है, स्पष्टीकरण के लिए धन्यवाद।
रोब

आपको इसकी आवश्यकता नहीं है :f(हाँ, मुझे पता है कि फ़ंक्शंस को आम तौर पर वापस नाम दिया गया था)।
आउटगॉल्फ

8

पायथन - 44 वर्ण

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

पायथन - 53 वर्ण

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

मुझे लगता है कि f ('9780306406159') आउटपुट '97803064061598' के बजाय '9780306406157'
EHXx

@ बारहवीं, इनपुट स्ट्रिंग हमेशा 12 अंकों की होनी चाहिए
gnibbler

आह, किसी तरह '9' में घुस गया। क्षमा करें ...
21

7

हास्केल - 54 वर्ण

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

इसके लिए समानांतर सूची समझ के लिए समर्थन की आवश्यकता होती है , जो जीएचसी ( -XParallelListCompध्वज के साथ ) और हग्स ( -98ध्वज के साथ) द्वारा समर्थित है ।


क्या आपको उस ध्वज को गिनती में शामिल करने की आवश्यकता नहीं है? कि इसके अलावा, आप की जगह ले सकता [1,3]द्वारा [9,7]और निकालें -जो आपको एक बाइट :) बचाता है
ბიმო

7

एपीएल (27 अक्षर)

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

मैं अपने इंटरप्रेटर के रूप में Dyalog APL का उपयोग कर रहा हूं। यहाँ एक त्वरित स्पष्टीकरण है, ज्यादातर दाएं से बाएं (फ़ंक्शन परिभाषा के भीतर F←{ ... }):

  • ⍎¨⍵: सही तर्क में दिए गए प्रत्येक ( ¨) चरित्र का निष्पादन / मूल्यांकन ( ) करें।
  • (12⍴1 3): Reshape ( ) वेक्टर 1 3को एक 12सेलेक्ट वेक्टर (अंतराल को भरने के लिए दोहराते हुए) में।
  • +.×: +.×इसके बाएँ तर्क ( (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
}

बिल्कुल वही दृष्टिकोण जो मैंने अपने C # उत्तर में लिया था। लगता है PHP ~ 9 अक्षर अधिक कुशल है!
नेलियस


5

हास्केल, 78 71 66 वर्ण

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'?
निमो 157

@ नीमो, धन्यवाद, मेरा माणिक थोड़ा
कठोर है

रूबी 1.9 सिंटैक्स का उपयोग करें f=->s{...}। 6 चार्ट सहेजें। s<<(...).to_s48 जोड़ने और उपयोग करने के बजाय भी लिखें Fixnum#chr
हौलेथ

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

मेरे शेल्फ पर पुस्तकों से कई ISBN पर परीक्षण किया गया है, इसलिए मुझे पता है कि यह काम कर रहा है!


4

पायथन - 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`

सूची तर्क में पहले तर्क और for(और inतीसरे) के बीच वैकल्पिक स्थान इतने लंबे समय तक होते हैं कि इसे पार्सर द्वारा विभाजित किया जा सकता है (चर नाम का उपयोग नहीं)। -2 वहाँ चरस।
निक टी


4

सी # - 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 को केवल चार से इंट में बदलने के लिए घटाते हैं। लेकिन 990 के बजाय, हमें 9992 लिखना होगा)।

लेकिन फिर भी, भले ही बहुत कम सुंदर; ;-), यह पुराने स्कूल समाधान हमें 80 वर्णों में मिलता है (लेकिन यह लगभग सी-संगत है):

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

4

जे - ५५ ४५ ३ 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

रूबी - 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

डीसी, 44 चार्ट

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

के रूप में आह्वान lIxजैसे,:

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


2

डी - 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

जावा - 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));

यह उत्तर पहली आवश्यकता को पूरा नहीं करता है, क्योंकि यह एक फ़ंक्शन नहीं है।
हान

1

क्यू (44 वर्ण)

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

यह वास्तव में गलत है मुझे लगता है
स्की


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

कुछ स्पष्टीकरण: 0प्रत्येक इनपुट चरित्र से 48 (अंक के ASCII मूल्य ) को घटाने के बजाय , संचयक sको आरंभीकृत किया जाता है ताकि यह modulo 10 के बराबर 48 + 3 * 48 + 48 + 3 * 48 ... + 48 + 3 * ४ = = २४ * ४ = = ११५२। कदम 10-sumको sजोड़ के बजाय घटाव द्वारा संचित किया जा सकता है । हालांकि, %सी में मॉड्यूल ऑपरेटर sनकारात्मक होने पर एक प्रयोग करने योग्य परिणाम नहीं देगा , इसलिए s-=मल्टीप्लायरों 3 और 1 का उपयोग करने के बजाय क्रमशः -3 = 7 मोडुलो 10 और -1 = 9 मोडुलो 10 द्वारा प्रतिस्थापित किया जाता है।

दोहन ​​परीक्षण:

#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

एपीएल (25)

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

एल्गो को 10 से खत्म करना होगा | क्योंकि यह 0 के स्थान पर 10 वापस कर सकता है
RosLuP

1

पर्ल 6 , 29 बाइट्स

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

इसे ऑनलाइन आज़माएं!


तो आधार 1 को राशि के विकल्प के रूप में इस्तेमाल किया जा सकता है? दिलचस्प!
जो राजा

2
@JoKing यह वास्तव में एपीएल और जे की दुनिया में एक बहुत पुरानी चाल है :)
बुबलर

978186197371 के लिए गलत परिणाम यह 8 नहीं 9 लगता है ...
RosLuP

क्षमा करें, मुझे लगता है कि मैंने गलत संख्या को चिपका दिया था
RosLuP

1

पायथन 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)`

इसे ऑनलाइन आज़माएं!

एक स्ट्रिंग को एक तर्क के रूप में लेता है।

स्पष्टीकरण:

पायथन स्लाइस नोटेशन का उपयोग करना, एक स्ट्रिंग को वर्ण जोड़े की सूची में परिवर्तित करता है। ("978030640615" -> [("9", "7"), ("8", "0"), ("3", "0"), ("6", "4"), ("0" "," 6 "), (" 1 "," 5 ")])

जोड़े की उस सूची के लिए, प्रत्येक आइटम को पूर्णांक में परिवर्तित करता है और + 3 बी देता है।

सभी परिणाम बताते हैं।

शेष १०, या १० का योग हो जाता है, यदि शेष ० है (यह अंतिम अंक को ०. की बजाय १० होने से रोकता है)

चेक अंक प्राप्त करने के लिए शेष 10 से निकालता है।

हटाए गए बैकटिक अभिव्यक्ति के माध्यम से परिकलित चेक अंक को एक स्ट्रिंग में परिवर्तित करता है।

मूल संख्या और परिकलित चेक अंक लौटाता है।

संपादित करें:

रिक्त स्थान हटाकर 2 बचे (धन्यवाद जो किंग !)।


आप इससे पहले रिक्त स्थान निकाल सकते हैं forऔरor
जो राजा

मेरा परिणाम है कि 978186197371 का अंतिम अंक 8 है और 9 नहीं है ... मुझे अपने Apl समाधान में केवल उसी लिंक से नंबर मिलता है जिसे मैं प्रिंट करता हूं
RosLuP

क्षमा करें, मुझे लगता है कि मैंने गलत नंबर चिपका दिया है ...
RosLuP

1

एपीएल (Dyalog यूनिकोड) , 18 बाइट्स SBCS

अनाम टैटिट उपसर्ग फ़ंक्शन तर्क के रूप में स्ट्रिंग ले रहा है। बबलर के दृष्टिकोण का उपयोग करना ।

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

इसे ऑनलाइन आज़माएं!

 तर्क की लंबाई (12)

9 7⍴⍨ चक्रीय रूप [9,7]से उस लंबाई पर फिर से क्लिक करें

+.× उस के साथ निम्नलिखित के डॉट उत्पाद:

⍎¨ `प्रत्येक चरित्र का मूल्यांकन करें

10| mod-10 का

,∘⍕ निम्नलिखित की कठोरता को रोकें:

 असम्बद्ध तर्क


1

डीसी , 25 बाइट्स

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

इसे ऑनलाइन आज़माएं!

मुझे पता है कि यहां पहले से ही एक डीसी का जवाब है, लेकिन 25 <44 इसलिए मुझे लगता है कि मुझे इसके बारे में 19 बाइट्स ठीक लग रहे हैं। यह इस तथ्य का उपयोग करता है कि z या सम या विषम के आधार पर या 8+9^zतो 10 -3या -1mod के बराबर है । इसलिए मैं A~स्टैक पर अंकों को संख्या में तोड़ने के लिए उपयोग करता हूं, लेकिन जैसा कि मैं स्टैक का निर्माण करता हूं मैं प्रत्येक अंक को गुणा करता हूं 8+9^zजहां z वर्तमान स्टैक आकार है। फिर मैं उन सभी को फ़ंक्शन स्टैक अनियंत्रित करता हूं , और अंतिम अंक प्रिंट करता हूं ।



0

आर, 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

जे, २५

,[:":10|0(-+/)"."0*1 3$~#
   f =:, [: ": 10 | 0 (- + /)"। "0 * 1 3 $ ~ #
   f '978030640615'
9780306406157
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.