मैं वर्तमान में Codecademy के Full Stack Engineer पाठ्यक्रम से गुजर रहा हूं, अब तक मैं इसके साथ पूरी तरह से ठीक रहा हूं, नई चीजों की खोज कर रहा हूं, अपने दम पर समस्याओं का समाधान कर रहा हूं, लेकिन यह मेरी प्रगति में एक गंभीर बाधा है क्योंकि मैं अभी ऐसा नहीं कर सकता इस तर्क के साथ समस्या की पहचान करें। मेरा मतलब लुहान के एल्गोरिदम पर सवाल उठाना नहीं है, लेकिन गंभीरता से मुझे इस पर कुछ स्पष्टीकरण चाहिए ...

तो मेरी समस्या यह है कि एल्गोरिदम मेरे सभी सरणी को मान्य के रूप में वापस कर रहा है, मेरा कोड नीचे है (कोडेकेडमी द्वारा प्रदान किए गए सरणी):

// All valid credit card numbers
const valid1 = [4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8];
const valid2 = [5, 5, 3, 5, 7, 6, 6, 7, 6, 8, 7, 5, 1, 4, 3, 9];
const valid3 = [3, 7, 1, 6, 1, 2, 0, 1, 9, 9, 8, 5, 2, 3, 6];
const valid4 = [6, 0, 1, 1, 1, 4, 4, 3, 4, 0, 6, 8, 2, 9, 0, 5];
const valid5 = [4, 5, 3, 9, 4, 0, 4, 9, 6, 7, 8, 6, 9, 6, 6, 6];

// All invalid credit card numbers
const invalid1 = [4, 5, 3, 2, 7, 7, 8, 7, 7, 1, 0, 9, 1, 7, 9, 5];
const invalid2 = [5, 7, 9, 5, 5, 9, 3, 3, 9, 2, 1, 3, 4, 6, 4, 3];
const invalid3 = [3, 7, 5, 7, 9, 6, 0, 8, 4, 4, 5, 9, 9, 1, 4];
const invalid4 = [6, 0, 1, 1, 1, 2, 7, 9, 6, 1, 7, 7, 7, 9, 3, 5];
const invalid5 = [5, 3, 8, 2, 0, 1, 9, 7, 7, 2, 8, 8, 3, 8, 5, 4];

// Can be either valid or invalid
const mystery1 = [3, 4, 4, 8, 0, 1, 9, 6, 8, 3, 0, 5, 4, 1, 4];
const mystery2 = [5, 4, 6, 6, 1, 0, 0, 8, 6, 1, 6, 2, 0, 2, 3, 9];
const mystery3 = [6, 0, 1, 1, 3, 7, 7, 0, 2, 0, 9, 6, 2, 6, 5, 6, 2, 0, 3];
const mystery4 = [4, 9, 2, 9, 8, 7, 7, 1, 6, 9, 2, 1, 7, 0, 9, 3];
const mystery5 = [4, 9, 1, 3, 5, 4, 0, 4, 6, 3, 0, 7, 2, 5, 2, 3];

// An array of all the arrays above
const batch = [valid1, valid2, valid3, valid4, valid5, invalid1, invalid2, invalid3, invalid4, invalid5, mystery1, mystery2, mystery3, mystery4, mystery5];

और मेरा कार्य एल्गोरिदम को कार्यान्वित करना:

const validateCred = arr => {

    let checkSum = 0;
    let ifEvenDouble = 0;
    arr.push(checkSum);

    //Iterate through array, double what is needed

    for(let i = arr.length - 2; i >= 0; i--){
      console.log(ifEvenDouble);

      //If ifEvenDouble is even, we are at the 'other' cell

        if((ifEvenDouble % 2) === 0){
          let doubled = arr[i] * 2;

          //If doubled digit is greater than 9, store sum of individual digits
          //Convert the doubled number to a string then extract each member and convert back to number for calculation, add to checkSum and skip to next iteration, otherwise, add arr[i]

          let newDigit = 0;
          if(doubled > 9){
            newDigit = Number(doubled.toString()[0]) + Number(doubled.toString()[1]);
            //Add doubled & split digit to total and continue the loop
            checkSum += newDigit;
            ifEvenDouble++;
            continue;
          }
          //Add doubled digit less than 9 to total and continue the loop
          checkSum += doubled;
          ifEvenDouble++;
          continue;
        }

        //Add current array member to total
        checkSum += arr[i];
        ifEvenDouble++;

    }//End for loop

    console.log(checkSum);
    const checkDigit = (checkSum * 9) % 10;
    const totalSum = checkDigit + checkSum;

    if(totalSum % 10 === 0){
      console.log('Valid');
      return true;
    } else {
      console.log('Invalid');
      return false;
    }
};

validateCred(invalid1); // -> Output: Valid

मेरी समझ से, मेरा कुल योग हमेशा 10 का गुणज होने वाला है, यदि मैं अपने इकाई अंक को 10 से घटा रहा हूं, तो इसे अपने चेकसम में जोड़ना हमेशा होगा मुझे 10 का गुणज दें। क्या मैं गलत हूँ?

संपादित करें: मैं इसे पहले से ही डिबग करने का प्रयास कर रहा हूं, लेकिन जितना अधिक मैं कोर एल्गोरिथम से दूर करता हूं, मैं भटक जाता हूं।

संपादित करें (2): तो नीचे दिए गए लोगों के लिए धन्यवाद, मुझे लगता है कि मेरी समस्या पहले से प्रदान किए गए एक का उपयोग करने के विरोध में अपना खुद का चेक अंक उत्पन्न कर रही थी? मेरा भ्रम यह है कि इस पर विकिपीडिया पृष्ठ पढ़ने से यह कहता है:

'चेक अंक की गणना के लिए उदाहरण: एक खाता संख्या "7992739871" का एक उदाहरण मान लें जिसमें एक चेक अंक जोड़ा जाएगा, जिससे यह फॉर्म 7992739871x बन जाएगा।

और फिर वे एक्स के अलावा संख्याओं के साथ अपनी सभी गणना करने के लिए आगे बढ़े, मुझे लगता है कि यह अब मुख्य भ्रम है।

0
jkn600 12 फरवरी 2021, 16:51

2 जवाब

सबसे बढ़िया उत्तर

आपका एल्गोरिदम अनावश्यक रूप से जटिल है। विकिपीडिया इसका संक्षेप में वर्णन करता है, बस 3 चरणों को लागू करें

  1. सबसे दाहिने अंक से (चेक अंक को छोड़कर) और बाईं ओर चलते हुए, प्रत्येक दूसरे अंक का मान दोगुना करें। इस गणना में चेक अंक को न तो दोगुना किया जाता है और न ही शामिल किया जाता है; दोगुना पहला अंक चेक अंक के ठीक बाईं ओर स्थित अंक है। यदि इस दोहरीकरण संक्रिया का परिणाम 9 से अधिक है (जैसे, 8 × 2 = 16), तो परिणाम के अंकों को जोड़ें (जैसे, 16: 1 + 6 = 7, 18: 1 + 8 = 9) या, समकक्ष , परिणाम से 9 घटाएं (जैसे, 16: 16 - 9 = 7, 18: 18 - 9 = 9)।
  2. सभी अंकों का योग लें (चेक अंक सहित)।
  3. यदि कुल मॉड्यूल 10 0 के बराबर है (यदि कुल शून्य में समाप्त होता है) तो संख्या Luhn सूत्र के अनुसार मान्य है; अन्यथा यह मान्य नहीं है।

मुझे यह भी लगता है कि आपने गलत समझा कि चेक अंक क्या है। आप इसे सरणी में 0 के रूप में जोड़ रहे हैं, और अंत में इसकी गणना करने का प्रयास कर रहे हैं। यह पहले से ही संख्या में है - यह अंतिम अंक है।

const validateCred = arr => {

   let doubleIt = true;
   let sum = 0;
   // From the rightmost digit excluding check digit...
   for(let i = arr.length - 2; i >= 0; i--){
        
        if(doubleIt){
          let doubled = arr[i] * 2;
         
          if(doubled > 9){
            doubled -= 9
          }
          sum += doubled
        }
        else {
          sum += arr[i]
        }
        doubleIt = !doubleIt;

    }

    // Add the check digit to the sum
    sum += arr[arr.length-1];

    // If sum is divisible by 10 it is valid
    if(sum % 10 === 0){
      console.log('Valid');
      return true;
    } else {
      console.log('Invalid');
      return false;
    }
};

const invalid1 = [4, 5, 3, 2, 7, 7, 8, 7, 7, 1, 0, 9, 1, 7, 9, 5];
const valid1 = [4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8];
validateCred(invalid1);
validateCred(valid1);

जिन स्थानों पर आप गलत हुए वे मुख्य रूप से चेक अंक के उपयोग के आसपास थे। आप इसकी गणना करते हुए दिखाई दिए, जबकि यह पहले से ही सरणी में अंतिम तत्व के रूप में है। चेक अंक की गणना के बिना, नीचे दिया गया स्निपेट आपके मूल के बहुत करीब है।

const validateCred = arr => {

    let ifEvenDouble = 0;
   let checkSum=0
    //Iterate through array, double what is needed

    for(let i = arr.length - 2; i >= 0; i--){

      //If ifEvenDouble is even, we are at the 'other' cell

        if((ifEvenDouble % 2) === 0){
          let doubled = arr[i] * 2;

          //If doubled digit is greater than 9, store sum of individual digits
          //Convert the doubled number to a string then extract each member and convert back to number for calculation, add to checkSum and skip to next iteration, otherwise, add arr[i]

          let newDigit = 0;
          if(doubled > 9){
            newDigit = Number(doubled.toString()[0]) + Number(doubled.toString()[1]);
            //Add doubled & split digit to total and continue the loop
            checkSum += newDigit;
            ifEvenDouble++;
            continue;
          }
          //Add doubled digit less than 9 to total and continue the loop
          checkSum += doubled;
          ifEvenDouble++;
          continue;
        }

        //Add current array member to total
        checkSum += arr[i];
        ifEvenDouble++;

    }//End for loop

    const checkDigit = arr[arr.length-1]
    const totalSum = checkDigit + checkSum;

    if(totalSum % 10 === 0){
      console.log('Valid');
      return true;
    } else {
      console.log('Invalid');
      return false;
    }
};


const invalid1 = [4, 5, 3, 2, 7, 7, 8, 7, 7, 1, 0, 9, 1, 7, 9, 5];
const valid1 = [4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8];
validateCred(invalid1);
validateCred(valid1);
2
Jamiec 12 फरवरी 2021, 17:27

मुझे पता है कि सवाल एक बेहतर समाधान के बजाय आप कहां गलत थे, इसके बारे में अधिक था; जेमीक का जवाब पहले से ही काफी अच्छी तरह से शामिल है।

हालाँकि, सरणी विधियों की एक बड़ी संख्या के साथ, हमें अधिक सरल उत्तर लिखने में सक्षम होना चाहिए।

// utility functions
const sum = (ns) => ns .reduce ((a, b) => a + b, 0)
const last = (xs) => xs [xs .length - 1]

// helper function
const doubleDig = (d) => 2 * d > 9 ? 2 * d - 9 : 2 * d

// main function
const luhn = (ds) =>
  (sum ([... ds] .map (Number) .reverse () .slice(1) .map (
    (d, i) => i % 2 == 0 ? doubleDig (d) : d
  )) + Number (last (ds)))  % 10 == 0

// sample data
const batch = [
  /* Valid   */ [4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8], [5, 5, 3, 5, 7, 6, 6, 7, 6, 8, 7, 5, 1, 4, 3, 9], [3, 7, 1, 6, 1, 2, 0, 1, 9, 9, 8, 5, 2, 3, 6], [6, 0, 1, 1, 1, 4, 4, 3, 4, 0, 6, 8, 2, 9, 0, 5], [4, 5, 3, 9, 4, 0, 4, 9, 6, 7, 8, 6, 9, 6, 6, 6],
  /* Invalid */ [4, 5, 3, 2, 7, 7, 8, 7, 7, 1, 0, 9, 1, 7, 9, 5], [5, 7, 9, 5, 5, 9, 3, 3, 9, 2, 1, 3, 4, 6, 4, 3], [3, 7, 5, 7, 9, 6, 0, 8, 4, 4, 5, 9, 9, 1, 4], [6, 0, 1, 1, 1, 2, 7, 9, 6, 1, 7, 7, 7, 9, 3, 5], [5, 3, 8, 2, 0, 1, 9, 7, 7, 2, 8, 8, 3, 8, 5, 4],
  /* Mystery */ [3, 4, 4, 8, 0, 1, 9, 6, 8, 3, 0, 5, 4, 1, 4], [5, 4, 6, 6, 1, 0, 0, 8, 6, 1, 6, 2, 0, 2, 3, 9], [6, 0, 1, 1, 3, 7, 7, 0, 2, 0, 9, 6, 2, 6, 5, 6, 2, 0, 3], [4, 9, 2, 9, 8, 7, 7, 1, 6, 9, 2, 1, 7, 0, 9, 3], [4, 9, 1, 3, 5, 4, 0, 4, 6, 3, 0, 7, 2, 5, 2, 3],
]

// demo
console.log (batch .map (luhn))

console .log (
  luhn ('4539677908016808'),
  luhn ('4532778771091795')
)
.as-console-wrapper {max-height: 100% !important; top: 0}

यह फ़ंक्शन आपूर्ति की गई एकल-अंकीय संख्याओं की सरणी पर काम करता है, लेकिन अंकों की एक स्ट्रिंग पर भी, ताकि luhn ('4539677908016808') luhn ([4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8]) के बराबर हो।

पहले हम सुनिश्चित करते हैं कि हम [... ds] .map (Number) के साथ संख्याओं की एक सरणी के साथ काम कर रहे हैं। फिर हम .reverse सरणी की लंबाई के साथ फ़िदा किए बिना सम और विषम स्थितियों को ट्रैक करना आसान बनाने के लिए सरणी। हम .slice अब-पहले तत्व को बंद कर देते हैं, जिसकी हमें केवल बाद में चेक-डिजिट के रूप में आवश्यकता होगी। अब हम परिणामों पर नक्शा बनाते हैं, सम अंकों को दोगुना करते हैं और आवश्यकतानुसार नौ निकालते हैं (सहायक फ़ंक्शन doubleDig) का उपयोग करते हुए, लेकिन विषम अंकों को बरकरार रखते हुए। हम सहायक sum का उपयोग करके परिणामों को जोड़ते हैं और सहायक last का उपयोग करके अंतिम अंक पाते हैं, इसे एक संख्या में परिवर्तित करते हैं और इसे उस कुल में जोड़ते हैं। हम मापांक आधार 10 लेकर समाप्त करते हैं, और रिपोर्ट करते हैं कि क्या वह मान 0 है।

वे सहायक कार्य उपयोगी होते हैं, और मैं लगभग हमेशा ऐसे के साथ काम करना पसंद करूंगा, लेकिन प्रत्येक को हमारे मुख्य कार्य में केवल एक ही स्थान पर बुलाया जाता है, जिससे यदि हम चाहें तो उन्हें इनलाइन करना आसान हो जाता है, और हम एक स्टैंड-अलोन संस्करण लिख सकते हैं ऐसा करने से:

const luhn = (ds) =>
  ([...ds] .map (Number) .reverse () .slice(1) .map (
    (d, i) => i % 2 == 0 ? (2 * d > 9 ? 2 * d - 9 : 2 * d) : d
  ) .reduce ((a, b) => a + b, 0) + Number (ds [ds .length - 1])) % 10 == 0

मुझे नहीं लगता कि यह कोई सुधार है। जबकि मूल संस्करण घना है, इसका पालन करना भी कठिन नहीं है। यह एक, विशेष रूप से जहां हम एक और टर्नरी के अंदर doubleDig की सशर्त अभिव्यक्ति (टर्नरी) को रेखांकित करते हैं, बहुत बदसूरत लगता है। शायद एक अधिक विस्तृत लेआउट मदद करेगा। लेकिन sum (...) निश्चित रूप से (...) .reduce ((a , b) => a + b, 0) से ज्यादा साफ है और last इसके विकल्प से ज्यादा साफ है। कुल मिलाकर यह प्रेरणाहीन है। लेकिन उपरोक्त सहायक-फ़ंक्शन ब्रेक-डाउन के विकल्प के रूप में पहचानना अच्छा है।

0
Scott Sauyet 12 फरवरी 2021, 19:04