एक पुनरावर्ती कार्य को कितनी बार बुलाया गया था, इस पर नज़र रखें


62

 function singleDigit(num) {
      let counter = 0
      let number = [...num + ''].map(Number).reduce((x, y) => {return x * y})

      if(number <= 9){
          console.log(number)
      }else{
          console.log(number)
          return singleDigit(number), counter += 1
      }
   }
singleDigit(39)

ऊपर दिया गया कोड पूर्णांक लेता है और इसे अपने ही अंकों से गुणा करके एक अंक में घटा देता है।

उदाहरण 39 है।

3 x 9 = 27.
2 x 7 = 14.
1 x 4 = 4.

कंसोल लॉग करेगा:

27 
14 
4

मैं कैसे ट्रैक कर सकता हूं कि पुनरावर्ती फ़ंक्शन को 3 बार कहा गया था?

मैंने एक काउंटर जोड़ने की कोशिश की है लेकिन यह अपडेट करने में विफल है। किसी भी मदद की सराहना करेंगे


4
.map(Number)*ऑपरेटर बेमानी है क्योंकि ऑपरेटर किसी भी तरह से संख्याओं का मान रखता है। ;-)
रॉब

4
कुछ प्रश्न: 1) नकारात्मक संख्याओं से निपटने के बारे में आपका क्या इरादा है? उदाहरण के लिए, संख्या -57वास्तव में एक -50और एक है -7.. जब इस तरह से देखा जाता है, तो यह एक सकारात्मक संख्या को कम करने में -5x की कमी करेगा । या फिर आप इसके साथ ही ऋणात्मक चिह्न चैनल देखना चाहते हैं और नहीं , यहां तक कि यद्यपि वास्तव में अच्छी तरह से नकारात्मक है। 2) आप उन संख्याओं से निपटने का इरादा कैसे रखते हैं जिनमें एक शून्य शामिल है? क्योंकि यह स्वतः ही शून्य को घटा देगा। इसलिए, आप जितनी बड़ी संख्या में पास होंगे, उतनी ही अधिक संभावना शून्य होगी। दूसरा विकल्प शून्य को छोड़ना होगा-735577
पिंप ट्राइज़किट

3
मुझे लगता है कि मेरे उपरोक्त प्रश्न पुनरावृत्ति को गिनने के बारे में नहीं हैं, बल्कि इस प्रश्न में प्रयुक्त सामग्री के पहेली को सुलझाने वाले पहलू मात्र हैं। कृपया मुझे माफ़ करें।
पिंप ट्रीज़िटक

3
मैं चापलूसी कर रहा हूं कि आपको मेरा जवाब पसंद है, लेकिन व्यावहारिक उद्देश्यों के लिए, मुझे लगता है कि stackoverflow.com/a/59570894/1346276 सबसे साफ सामान्य संस्करण है।
phipsgabler

2
@phipsgabler कोई भी व्यक्ति जो एक बुद्धिमान और सुसंगत उत्तर लिखने के लिए समय लेता है वह एक तरह से योग्य है। धन्यवाद
chs242

जवाबों:


25

यह लगभग पूरी तरह से शैक्षणिक संस्करण है, लेकिन आप इस उद्देश्य के लिए संशोधित फिक्स्ड पॉइंट कॉम्बिनेटर का उपयोग कर सकते हैं ।

अपने मूल कार्य को थोड़ा छोटा करें और सुधारें:

function singleDigit(n) {
    let digitProduct = [...(n + '')].reduce((x, y) => x * y, 1);
    return digitProduct <= 9 ? digitProduct : singleDigit(digitProduct);
}

// singleDigit(123234234) == 0

इस प्रकार से, हम पुनरावर्ती कॉल को निकाल सकते हैं और कर सकते हैं:

function singleDigitF(recur) {
    return function (n) {
        let digitProduct = [...(n + '')].reduce((x, y) => x * y, 1);
        return digitProduct <= 9 ? digitProduct : recur()(digitProduct);
    };
}

इस फ़ंक्शन का उपयोग अब एक निश्चित बिंदु कॉम्बिनेटर के साथ किया जा सकता है; विशेष रूप से मैंने एक वाई कॉम्बिनेटर को लागू किया (सख्त) जावास्क्रिप्ट इस प्रकार है:

function Ynormal(f, ...args) {
    let Y = (g) => g(() => Y(g));
    return Y(f)(...args);
}

हमारे पास कहां है Ynormal(singleDigitF, 123234234) == 0

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

function Ycount(f, ...args) {
    let count = 1;
    let Y = (g) => g(() => {count += 1; return Y(g);});
    return [Y(f)(...args), count];
}

नोड REPL में एक त्वरित जाँच देता है:

> Ycount(singleDigitF, 123234234)
[ 0, 3 ]
> let digitProduct = (n) => [...(n + '')].reduce((x, y) => x * y, 1)
undefined
> digitProduct(123234234)
3456
> digitProduct(3456)
360
> digitProduct(360)
0
> Ycount(singleDigitF, 39)
[ 4, 3 ]

यह कॉम्बीनेटर अब शैली में लिखे किसी भी पुनरावर्ती कार्य में कॉल की संख्या की गिनती के लिए काम करेगाsingleDigitF

(ध्यान दें कि शून्य के बहुत स्रोत होने के दो स्रोत हैं: संख्यात्मक अतिप्रवाह ( 123345456999999999बनना 123345457000000000आदि), और यह तथ्य कि आप निश्चित रूप से कहीं न कहीं एक मध्यवर्ती मूल्य के रूप में शून्य प्राप्त करेंगे, जब इनपुट का आकार बढ़ रहा होगा। "


6
नीच लोगों के लिए: मैं वास्तव में आपके साथ सहमत हूं कि यह सबसे अच्छा व्यावहारिक समाधान नहीं है - यही कारण है कि मैंने इसे "विशुद्ध रूप से अकादमिक" के रूप में उपसर्ग किया है।
phipsgabler

ईमानदारी से, यह एक भयानक समाधान है और मूल प्रश्न के प्रतिगमन / गणित प्रकार के लिए पूरी तरह से अनुकूल है।
शेरेफ

73

आपको अपनी फ़ंक्शन परिभाषा में एक काउंटर तर्क जोड़ना चाहिए:

function singleDigit(num, counter = 0) {
    console.log(`called ${counter} times`)
    //...
    return singleDigit(number, counter+1)
}
singleDigit(39)

6
बहुत बढ़िया। ऐसा लगता है कि मेरा काउंटर काम नहीं कर रहा था क्योंकि मैंने इसे समारोह में घोषित किया था
chs242

7
@ chs242 स्कोप नियम तय करेगा कि इसे फंक्शन में घोषित करने से एक नया इंविटेशन तैयार होगा। stackoverflow.com/questions/500431/…
टैपलर

10
@ chs242 ऐसा नहीं है कि आपने इसे फ़ंक्शन के भीतर घोषित किया है। तकनीकी रूप से यह सभी डिफ़ॉल्ट पैरामीटर समान रूप से कर रहे हैं - आपके मामले में यह केवल इतना है कि अगली बार फ़ंक्शन को पुनरावृत्ति कहा जाने वाला मान कभी नहीं किया गया। ae हर बार जब भी फंक्शन चलता counterहै 0, तब तक वह झुलस जाता है और सेट हो जाता है , जब तक कि आप स्पष्ट रूप से अपनी पुनरावर्ती कॉल में इसे ले नहीं जाते हैं जैसा कि शेराफ करता है। AesingleDigit(number, ++counter)
zfrisch

2
सही @zfrisch मैं समझता हूँ कि अब। इसे समझाने के लिए समय निकालने के लिए धन्यवाद
chs242

35
कृपया बदल ++counterदें counter+1। वे कार्यात्मक रूप से समतुल्य हैं, लेकिन बाद वाले इरादे को बेहतर बताते हैं, (अनावश्यक रूप से) म्यूट और पैरामीटर नहीं, और गलती से पोस्ट-इंक्रीमेंट की संभावना नहीं है। या बेहतर अभी तक, क्योंकि यह एक पूंछ-कॉल है, इसके बजाय एक लूप का उपयोग करें।
ब्लूराजा - डैनी पफ्लुघोटे

37

पारंपरिक समाधान यह है कि गणना को एक पैरामीटर के रूप में कार्य करने के लिए एक और उत्तर के रूप में सुझाव दिया जाए।

हालाँकि, js में एक और समाधान है। कुछ अन्य जवाबों ने केवल पुनरावर्ती कार्य के बाहर गिनती की घोषणा करने का सुझाव दिया:

let counter = 0
function singleDigit(num) {
  counter++;
  // ..
}

यह काम करता है। हालाँकि, यह फ़ंक्शन को गैर-रीएन्ट्रेंट बनाता है (दो बार सही तरीके से नहीं बुलाया जा सकता है)। कुछ मामलों में आप इस समस्या को अनदेखा कर सकते हैं और यह सुनिश्चित कर सकते हैं कि आप singleDigitदो बार कॉल न करें (जावास्क्रिप्ट सिंगल थ्रेडेड है इसलिए ऐसा करना बहुत कठिन नहीं है) लेकिन यह एक बग होने की प्रतीक्षा है यदि आप singleDigitबाद में अतुल्यकालिक होने का अद्यतन करते हैं और यह महसूस भी होता है बदसूरत।

इसका समाधान counterबाहर के वैरिएबल को घोषित करना है लेकिन विश्व स्तर पर नहीं। यह संभव है क्योंकि जावास्क्रिप्ट में क्लोजर हैं:

function singleDigit(num) {
  let counter = 0; // outside but in a closure

  // use an inner function as the real recursive function:
  function recursion (num) {
    counter ++
    let number = [...num + ''].map(Number).reduce((x, y) => {return x * y})

    if(number <= 9){
      return counter            // return final count (terminate)
    }else{
      return recursion(number)  // recurse!
    }
  }

  return recursion(num); // start recursion
}

यह वैश्विक समाधान के समान है लेकिन हर बार जब आप कॉल करते हैं singleDigit(जो अब एक पुनरावर्ती कार्य नहीं है) तो यह एक नया उदाहरण बनाएगाcounter चर ।


1
काउंटर चर केवल singleDigitफ़ंक्शन के भीतर उपलब्ध है और एक तर्क imo पारित किए बिना ऐसा करने का एक वैकल्पिक स्वच्छ तरीका प्रदान करता है। +1
एंड्रयूएल 64

1
चूंकि recursionअब पूरी तरह से अलग है, यह अंतिम पैरामीटर के रूप में काउंटर को पास करने के लिए पूरी तरह से सुरक्षित होना चाहिए। मुझे नहीं लगता कि एक आंतरिक फ़ंक्शन बनाना आवश्यक है। यदि आपको पुनरावर्तन के एकमात्र लाभ के लिए पैरामीटर होने का विचार पसंद नहीं है (मैं इस बात को लेता हूं कि उपयोगकर्ता उन लोगों के साथ गड़बड़ कर सकता है) तो उन्हें Function#bindआंशिक रूप से लागू फ़ंक्शन में लॉक करें ।
कस्टमकॉमैंडर

@ customcommander हाँ, मैंने अपने उत्तर के पहले भाग में इसका उल्लेख किया है the traditional solution is to pass the count as a parameter। यह एक ऐसी भाषा में एक वैकल्पिक समाधान है जिसमें क्लोजर हैं। कुछ मायनों में इसका पालन करना सरल है, क्योंकि यह संभवतया केवल एक ही है, जिसकी बजाय संभवतः अनंत संख्या में परिवर्तनशील उदाहरण हैं। अन्य तरीकों से इस समाधान को जानने में मदद मिलती है जब आप जिस चीज़ को ट्रैक कर रहे हैं वह एक साझा वस्तु है (एक अद्वितीय मानचित्र बनाने की कल्पना करें) या एक बहुत बड़ी वस्तु (जैसे कि HTML स्ट्रिंग)
slebetman

counter--"15 बार दो बार सही ढंग से नहीं बुलाया जा सकता" के अपने दावे को हल करने का पारंपरिक तरीका होगा
मंकीज़ियस

1
@MonkeyZeus इससे क्या फर्क पड़ता है? इसके अलावा, आपको यह कैसे पता चलेगा कि काउंटर को देखने के लिए किस संख्या को शुरू करना है, यह वह गणना है जिसे हम खोजना चाहते हैं?
स्लीपबेटमैन

22

एक अन्य दृष्टिकोण, चूंकि आप सभी संख्याओं का उत्पादन करते हैं, एक जनरेटर का उपयोग करना है।

अंतिम तत्व आपकी संख्या nएक एकल अंक संख्या तक कम हो गई है और यह गिनने के लिए कि आपने कितनी बार पुनरावृत्ति की है, बस सरणी की लंबाई पढ़ें।

const digits = [...to_single_digit(39)];
console.log(digits);
//=> [27, 14, 4]
<script>
function* to_single_digit(n) {
  do {
    n = [...String(n)].reduce((x, y) => x * y);
    yield n;
  } while (n > 9);
}
</script>


अंतिम विचार

आप अपने फ़ंक्शन में रिटर्न-प्रारंभिक स्थिति पर विचार करना चाह सकते हैं । इसमें शून्य के साथ कोई भी संख्या शून्य पर वापस आ जाएगी

singleDigit(1024);       //=> 0
singleDigit(9876543210); //=> 0

// possible solution: String(n).includes('0')

1केवल किसी भी संख्या के लिए यही कहा जा सकता है ।

singleDigit(11);    //=> 1
singleDigit(111);   //=> 1
singleDigit(11111); //=> 1

// possible solution: [...String(n)].every(n => n === '1')

अंत में, आपने स्पष्ट नहीं किया कि क्या आप केवल सकारात्मक पूर्णांक स्वीकार करते हैं। यदि आप नकारात्मक पूर्णांक स्वीकार करते हैं, तो उन्हें तारों में डालना जोखिम भरा हो सकता है:

[...String(39)].reduce((x, y) => x * y)
//=> 27

[...String(-39)].reduce((x, y) => x * y)
//=> NaN

संभावित समाधान:

const mult = n =>
  [...String(Math.abs(n))].reduce((x, y) => x * y, n < 0 ? -1 : 1)

mult(39)
//=> 27

mult(-39)
//=> -27

महान। @ customcommander आपको यह बहुत स्पष्ट रूप से समझाने के लिए धन्यवाद
chs242

6

यहाँ कई दिलचस्प जवाब दिए गए हैं। मुझे लगता है कि मेरा संस्करण एक अतिरिक्त दिलचस्प विकल्प प्रदान करता है।

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

  {
    digit: 4,
    steps: [39, 27, 14, 4],
    calls: 3
  }

यदि आप चाहें, तो आप चरणों को लॉग कर सकते हैं या उन्हें आगे की प्रक्रिया के लिए संग्रहीत कर सकते हैं।

यहाँ एक संस्करण है जो ऐसा करता है:

const singleDigit = (n, steps = []) =>
  n <= 9
    ? {digit: n, steps: [... steps, n], calls: steps .length}
    : singleDigit ([... (n + '')] .reduce ((a, b) => a * b), [... steps, n])

console .log (singleDigit (39))

ध्यान दें कि हम ट्रैक करते हैं steps लेकिन प्राप्त करते हैं calls। जबकि हम कॉल काउंट को एक अतिरिक्त पैरामीटर के साथ ट्रैक कर सकते हैं, जो कुछ भी हासिल नहीं करता है। हम भी map(Number)कदम को छोड़ देते हैं - ये गुणा से किसी भी मामले में संख्याओं के लिए मजबूर हो जाएंगे।

यदि आपको उस डिफ़ॉल्ट के बारे में चिंता है steps पैरामीटर के आपके एपीआई के हिस्से के रूप में उजागर हो रहा है, तो इस तरह से आंतरिक फ़ंक्शन का उपयोग करके इसे छिपाना काफी आसान है:

const singleDigit = (n) => {
  const recur = (n, steps) => 
    n <= 9
      ? {digit: n, steps: [... steps, n], calls: steps .length}
      : recur ([... (n + '')] .reduce ((a, b) => a * b), [... steps, n])
  return recur (n, [])
}

और या तो मामले में, एक हेल्पर फ़ंक्शन में अंक गुणन निकालने के लिए यह थोड़ा साफ हो सकता है:

const digitProduct = (n) => [... (n + '')] .reduce ((a, b) => a * b)

const singleDigit = (n, steps = []) =>
  n <= 9
    ? {digit: n, steps: [... steps, n], calls: steps .length}
    : singleDigit (digitProduct(n), [... steps, n])

2
एक और महान जवाब;) कृपया ध्यान दें कि जब n नकारात्मक है, digitProductतो वापस आ जाएगी NaN( -39 ~> ('-' * '3') * '9')। तो आप n का एक पूर्ण मूल्य और उपयोग करना चाहते हैं -1या 1अपने कम मूल्य के प्रारंभिक मूल्य के रूप में उपयोग कर सकते हैं।
कस्टमकॉम

@customcommander: वास्तव में, यह वापस आ जाएगी {"digit":-39,"steps":[-39],"calls":0}के बाद से, -39 < 9। जबकि मैं मानता हूं कि यह कुछ त्रुटि-जाँच के साथ हो सकता है: क्या पैरामीटर एक संख्या है? - क्या यह एक सकारात्मक पूर्णांक है? - आदि मुझे नहीं लगता कि मैं इसमें शामिल होने के लिए अपडेट करूंगा। यह एल्गोरिथ्म को कैप्चर करता है, और त्रुटि-हैंडलिंग अक्सर किसी के कोड-बेस के लिए विशिष्ट है।
स्कॉट सॉयट

6

यदि आप केवल यह गिनने की कोशिश कर रहे हैं कि यह कितनी बार कम हो गया है और विशेष रूप से पुनरावृत्ति की परवाह नहीं कर रहा है ... तो आप केवल पुनरावर्तन को हटा सकते हैं। नीचे दिया गया कोड मूल पोस्ट के लिए वफादार रहता है क्योंकि इसकी num <= 9आवश्यकता में कमी नहीं आती है। इसलिए, singleDigit(8)होगा count = 0, और singleDigit(39)होगा count = 3, बस ओपी और स्वीकार किए जाते हैं जवाब प्रदर्शन कर रहे हैं की तरह:

const singleDigit = (num) => {
    let count = 0, ret, x;
    while (num > 9) {
        ret = 1;
        while (num > 9) {
            x = num % 10;
            num = (num - x) / 10;
            ret *= x;
        }
        num *= ret;
        count++;
        console.log(num);
    }
    console.log("Answer = " + num + ", count = " + count);
    return num;
}

यह संख्या 9 या उससे कम (यानी। num <= 9) संसाधित करने के लिए अनावश्यक है । दुर्भाग्य से ओपी कोड प्रक्रिया करेगा num <= 9यहां तक ​​कि इसे गिनता भी नहीं है। उपरोक्त कोड बिल्कुल भी प्रोसेस या काउंट नहीं करेगा num <= 9। यह बस इसे गुजरता है।

मैं उपयोग नहीं करने का चयन करता हूं .reduceक्योंकि वास्तविक गणित निष्पादित करने के लिए बहुत तेज था। और, मेरे लिए, समझना आसान है।


आगे की सोच गति पर

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

दोनों का उपयोग करना .map(Number)और console.log(प्रत्येक कमी कदम पर) दोनों बहुत बहुत लंबे निष्पादित और अनावश्यक के लिए कर रहे हैं। बस .map(Number)ओपी से हटाने के बारे में 4.38x तक इसे गिरा दिया। console.logइसे हटाने के लिए इसे इतना कम करना ठीक से परीक्षण करना लगभग असंभव था (मैं इसके लिए इंतजार नहीं करना चाहता था)।

तो, customcommander के जवाब के समान है , न .map(Number)ही उपयोग और न ही console.logपरिणामों को एक सरणी में धकेलना और बहुत अधिक तेजी से उपयोग .lengthकरना count। दुर्भाग्य के लिए customcommander के जवाब है, एक का उपयोग कर जनरेटर समारोह वास्तव में बहुत धीमी गति से (है कि इसका जवाब 2.68x के बारे में बिना ओपी की तुलना में धीमी है .map(Number)औरconsole.log )

इसके अलावा, .reduceमैंने केवल वास्तविक गणित का उपयोग करने के बजाय उपयोग किया। इस अकेले परिवर्तन ने फ़ंक्शन के मेरे संस्करण को 3.59x के एक कारक द्वारा फैलाया।

अंत में, पुनरावृत्ति धीमा है, यह स्टैक स्पेस लेता है, अधिक मेमोरी का उपयोग करता है, और इसकी एक सीमा है कि यह कितनी बार "पुनरावृत्ति" कर सकता है। या, इस मामले में, कमी के कितने चरण इसका उपयोग पूर्ण कमी को पूरा करने के लिए कर सकते हैं। पुनरावृत्त छोरों के लिए अपनी पुनरावृत्ति को बाहर निकालना यह सब स्टैक पर एक ही जगह पर रखता है और इसकी कोई सैद्धांतिक सीमा नहीं है कि इसे खत्म करने के लिए कितने कमी चरणों का उपयोग किया जा सकता है। इस प्रकार, यहां ये फ़ंक्शन लगभग किसी भी आकार के पूर्णांक को "कम" कर सकते हैं, केवल निष्पादन समय तक सीमित है और एक सरणी कितनी लंबी हो सकती है।

यह सब ...

const singleDigit2 = (num) => {
    let red, x, arr = [];
    do {
        red = 1;
        while (num > 9) {
            x = num % 10;
            num = (num - x) / 10;
            red *= x;
        }
        num *= red;
        arr.push(num);
    } while (num > 9);
    return arr;
}

let ans = singleDigit2(39);
console.log("singleDigit2(39) = [" + ans + "],  count = " + ans.length );
 // Output: singleDigit2(39) = [27,14,4],  count = 3

उपरोक्त फ़ंक्शन बहुत तेज़ चलता है। यह ओपी से (बिना तेजी 3.13x के बारे में है .map(Number)और console.logतेजी से) और 8.4x के बारे में customcommander के जवाब। ध्यान रखें कि console.logओपी को हटाने से यह कमी के प्रत्येक चरण में एक नंबर उत्पन्न करने से रोकता है। इसलिए, इन परिणामों को एक सरणी में धकेलने के लिए यहाँ की आवश्यकता है।

पीटी


1
इस उत्तर में बहुत अधिक शिक्षा मूल्य है इसलिए उसके लिए धन्यवाद। I feel good code is also fast.मैं कहता हूँ कि कोड गुणवत्ता को आवश्यकताओं के पूर्वनिर्धारित सेट के विरुद्ध मापा जाना चाहिए। यदि प्रदर्शन उनमें से एक नहीं है, तो आप कोड को बदलकर कुछ भी हासिल नहीं करते हैं जिसे कोई भी "तेज" कोड के साथ समझ सकता है। आपको विश्वास नहीं होगा कि मैंने देखी गई कोड की मात्रा को उस बिंदु के प्रतिपादक के रूप में दर्शाया गया है जिसे कोई भी अब और नहीं समझ सकता है (किसी कारण से इष्टतम कोड भी अनैजेड हो जाता है;)। अंत में जानते हैं कि आलसी जनित सूचियाँ किसी को माँग पर वस्तुओं का उपभोग करने की अनुमति देती हैं।
कस्टमकॉम

धन्यवाद मेरा मानना ​​है। IMHO, कैसे करना है के वास्तविक गणित को पढ़ना मेरे लिए समझना आसान था .. [...num+''].map(Number).reduce((x,y)=> {return x*y})या यहां तक [...String(num)].reduce((x,y)=>x*y)कि उन बयानों से भी जिन्हें मैं यहां अधिकांश उत्तरों में देख रहा हूं। तो, मेरे लिए, यह प्रत्येक पुनरावृत्ति और बहुत तेजी से होने वाले व्हाट्सएप की बेहतर समझ का अतिरिक्त लाभ था । हां, छोटा कोड (जिसकी जगह है) पढ़ने में बहुत कठिन है। लेकिन उन मामलों में आम तौर पर जानबूझकर इसकी पठनीयता की परवाह नहीं की जाती है, बल्कि सिर्फ काटने और चिपकाने और आगे बढ़ने का अंतिम परिणाम होता है।
ट्रिज्किट

क्या जावास्क्रिप्ट में पूर्णांक विभाजन नहीं है ताकि आप C के बराबर कर सकें digit = num%10; num /= 10;? num - xविभाजित करने से पहले अनुगामी अंक को हटाने के लिए पहले करने के बाद जेआईटी कंपाइलर को एक अलग विभाजन करने के लिए मजबूर करना संभव है, जिसे उसने शेष प्राप्त करने के लिए किया था।
पीटर कॉर्ड्स

मुझे ऐसा नहीं लगता। ये कुछ हैं var(जेएस में कोई एस नहीं है int)। इसलिए, यदि आवश्यक हो, तो फ्लोट में n /= 10;परिवर्तित nहो जाएगा । num = num/10 - x/10इसे एक फ्लोट में बदल सकते हैं, जो समीकरण का लंबा रूप है। इसलिए, मुझे num = (num-x)/10;इसे पूर्णांक बनाए रखने के लिए रिफैक्ट किए गए संस्करण का उपयोग करना होगा। ऐसा कोई तरीका नहीं है जो मैं जावास्क्रिप्ट में पा सकता हूं जो आपको एकल विभाजन ऑपरेशन के भागफल और शेष दोनों दे सकता है। इसके अलावा, digit = num%10; num /= 10;दो अलग-अलग कथन हैं और इस प्रकार दो अलग-अलग डिवीजन ऑपरेशन हैं। सी का उपयोग करने के बाद से मुझे थोड़ी देर हो गई है, लेकिन मुझे लगा कि यह सच है।
पिंप ट्राइजकिट

6

console.countअपने फ़ंक्शन में कॉल क्यों न करें ?

संपादित करें: स्निपेट को अपने ब्राउज़र में आज़माने के लिए:

function singleDigit(num) {
    console.count("singleDigit");

    let counter = 0
    let number = [...num + ''].map(Number).reduce((x, y) => {return x * y})

    if(number <= 9){
        console.log(number)
    }else{
        console.log(number)
        return singleDigit(number), counter += 1
    }
}
singleDigit(39)

मेरे पास यह क्रोम 79 और फ़ायरफ़ॉक्स 72 में काम कर रहा है


हर बार फ़ंक्शन को कॉल किए जाने पर काउंटर को रीसेट होने पर
कंसोल

2
मुझे आपकी समस्या समझ में नहीं आती क्योंकि मैंने इसे क्रोम और फ़ायरफ़ॉक्स में काम किया है, मैंने अपने उत्तर में एक स्निपेट जोड़ा
मिस्टरमैट

6

आप इसके लिए क्लोजर का उपयोग कर सकते हैं।

बस counterफ़ंक्शन के बंद होने में स्टोर करें ।

यहाँ उदाहरण है:

function singleDigitDecorator() {
	let counter = 0;

	return function singleDigitWork(num, isCalledRecursively) {

		// Reset if called with new params 
		if (!isCalledRecursively) {
			counter = 0;
		}

		counter++; // *

		console.log(`called ${counter} times`);

		let number = [...(num + "")].map(Number).reduce((x, y) => {
			return x * y;
		});

		if (number <= 9) {
			console.log(number);
		} else {
			console.log(number);

			return singleDigitWork(number, true);
		}
	};
}

const singleDigit = singleDigitDecorator();

singleDigit(39);

console.log('`===========`');

singleDigit(44);


1
लेकिन इस तरह से काउंटर अगली कॉल पर गिना जाता है, इसे प्रत्येक शुरुआती कॉल पर रीसेट करना होगा। यह एक कठिन प्रश्न की ओर जाता है: कैसे एक पुनरावर्ती कार्य को अलग संदर्भ से कहा जाता है, इस मामले में वैश्विक बनाम फ़ंक्शन को कैसे बताया जाए।
रॉब

यह केवल एक विचार के साथ आने के लिए उदाहरण है। यह उपयोगकर्ता से उसकी जरूरतों को पूछकर संशोधित किया जा सकता है।
खोलियावको

@RobG मुझे आपका सवाल समझ नहीं आ रहा है। पुनरावर्ती फ़ंक्शन को क्लोजर के बाहर नहीं बुलाया जा सकता है क्योंकि यह एक आंतरिक फ़ंक्शन है। इसलिए संदर्भ को अलग करने की कोई संभावना या आवश्यकता नहीं है क्योंकि
स्लीबेटमैन

@slebetman काउंटर को कभी भी रीसेट नहीं किया जाता है। द्वारा लौटाया गया फ़ंक्शन singleDigitDecorator()हर बार उसी काउंटर को बढ़ाता रहेगा जो इसे कहा जाता है।
कस्टमकॉमेंडर

1
@ slebetman- समस्या यह है कि एकलडिजिटकोर द्वारा लौटाया गया फ़ंक्शन उसके काउंटर को रीसेट नहीं करता है जब उसे दोबारा कॉल किया जाता है। वह फ़ंक्शन है जिसे काउंटर रीसेट करने के लिए जानना आवश्यक है, अन्यथा प्रत्येक उपयोग के लिए फ़ंक्शन का एक नया उदाहरण आवश्यक है। Function.caller के लिए एक संभावित उपयोग मामला ? ;-)
रोबोग

1

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

from functools import reduce

def single_digit(n: int) -> tuple:
    """Take an integer >= 0 and return a tuple of the single-digit product reduction
    and the number of reductions performed."""

    def _single_digit(n, i):
        if n <= 9:
            return n, i
        else:
            digits = (int(d) for d in str(n))
            product = reduce(lambda x, y: x * y, digits)
            return _single_digit(product, i + 1)

    return _single_digit(n, 0)

>>> single_digit(39)
(4, 3)

1
अजगर में, मैं इस तरह से कुछ पसंद करेंगे
phipsgabler
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.