इतिहास
मेरी कंपनी कंपनी के भीतर सभी को एक साप्ताहिक समाचार पत्र भेजती है। इन न्यूज़लेटर्स में शामिल एक पहेली है, कंपनी में एक चिल्लाहट के साथ पिछले हफ्ते की पहेली को ईमेल / समाधान प्रदान करने वाला पहला ईमेल था। इन पहेलियों में से अधिकांश काफी तुच्छ हैं, और ईमानदारी से एक तकनीकी कंपनी के लिए बहुत सुस्त हैं, लेकिन कई महीने पहले एक था, जिसने मेरा ध्यान आकर्षित किया।
मूल पहेली:
नीचे दिए गए आकार को देखते हुए:
आपके पास 1 से 16 तक प्राकृतिक संख्याएँ हैं। उन सभी को इस आकार में फिट करें, जैसे कि सभी सन्निहित पंक्तियों और सन्निहित स्तंभों का योग 29 तक हो।
उदाहरण के लिए, इस पहेली का एक ऐसा समाधान (जो समाचार पत्र को मैंने प्रस्तुत "विहित" समाधान था) निम्नलिखित था:
हालाँकि, इसे हल करने के दौरान, मुझे कुछ रोचक जानकारी मिली:
- केवल एक से अधिक महत्वपूर्ण समाधान हैं; वास्तव में, 9,368 समाधान हैं।
- यदि आप नियम का विस्तार केवल इस बात के लिए करते हैं कि पंक्तियाँ और स्तंभ एक दूसरे के बराबर हों, तो जरूरी नहीं कि 29 ही हों, आपको 33,608 समाधान मिलते हैं:
- 27 की राशि के लिए 4,440 समाधान।
- 28 के योग के लिए 7,400 समाधान।
- 29 की राशि के लिए 9,368 समाधान।
- 30 की राशि के लिए 6,096 समाधान।
- 31 की राशि के लिए 5,104 समाधान।
- 32 की राशि के लिए 1,200 समाधान।
इसलिए मैं और मेरे सहकर्मी (हालांकि ज्यादातर सिर्फ मेरे प्रबंधक थे, क्योंकि वह "जनरल पर्पस" प्रोग्रामिंग कौशल के साथ मेरे अलावा एकमात्र व्यक्ति थे) जो एक चुनौती पर सेट हुए थे, जो कि महीने के अधिकांश समय तक चलता था- हमारे पास अन्य, वास्तविक नौकरी थी- संबंधित दायित्वों को हमें एक कार्यक्रम लिखने की कोशिश करने के लिए उपस्थित होना था - जो हर एक समाधान को सबसे तेज़ तरीके से संभव करेगा।
मूल सांख्यिकी
समस्या को हल करने के लिए मैंने जो पहला कार्यक्रम लिखा था, उसने बस और अधिक से अधिक यादृच्छिक समाधानों की जाँच की, और जब इसका हल मिला तो रुक गया। यदि आपने इस समस्या पर गणितीय विश्लेषण किया है, तो आप शायद पहले से ही जानते हैं कि यह काम नहीं करना चाहिए था; लेकिन किसी तरह मैं भाग्यशाली हो गया, और एकल समाधान खोजने के लिए कार्यक्रम में केवल एक मिनट लगा (जो मैंने ऊपर पोस्ट किया था)। कार्यक्रम के रिपीट रन अक्सर 10 या 20 मिनट लगते हैं, तो जाहिर है कि यह समस्या का कठोर समाधान नहीं था।
मैंने एक पुनरावर्ती समाधान पर स्विच किया, जो पहेली के हर संभव क्रमांकन के माध्यम से पुनरावृत्त हुआ, और कई समाधानों को एक बार में समाप्त कर दिया, जो जोड़ नहीं रहे थे। IE अगर पहली पंक्ति / कॉलम की तुलना मैं पहले से ही बराबर नहीं कर रहा था, तो मैं तुरंत उस शाखा की जांच करना बंद कर सकता हूं, यह जानकर कि पहेली में अनुमति दी गई और कुछ भी नहीं बदलेगा।
इस एल्गोरिथ्म का उपयोग करते हुए, मुझे पहली "उचित" सफलता मिली: कार्यक्रम लगभग 5 मिनट में सभी 33,608 समाधान उत्पन्न कर सकता है और थूक सकता है।
मेरे प्रबंधक का एक अलग दृष्टिकोण था: मेरे काम के आधार पर यह जानते हुए कि एकमात्र संभव समाधान में 27, 28, 29, 30, 31, या 32 के योग थे, उन्होंने एक बहु-थ्रेडेड समाधान लिखा था जो केवल उन विशिष्ट मूल्यों के लिए संभव रकम की जाँच करता था। वह केवल 2 मिनट में अपना कार्यक्रम चलाने में सफल रहे। तो मैं फिर से iterated; मैंने सभी संभावित 3/4 अंकों के योग (कार्यक्रम की शुरुआत में; इसे कुल क्रम में गिना जाता है) और पहले से तैयार पंक्ति के आधार पर शेष मूल्य को देखने के लिए एक पंक्ति के "आंशिक योग" का उपयोग किया, बजाय सभी शेष मूल्यों का परीक्षण, और 72 सेकंड के लिए समय नीचे लाया। फिर कुछ मल्टी-थ्रेडिंग लॉजिक के साथ, मैंने इसे 40 सेकंड तक नीचे ला दिया। मेरे प्रबंधक ने कार्यक्रम को घर ले लिया, कार्यक्रम चलाने के तरीके के बारे में कुछ अनुकूलन किए, और 12 सेकंड के लिए नीचे उतर गए। मैंने पंक्तियों और स्तंभों के मूल्यांकन को फिर से व्यवस्थित किया,
एक महीने के बाद हमारे कार्यक्रमों में से सबसे तेज़ हमारे प्रबंधक के लिए 0.15 सेकंड और मेरे लिए 0.33 सेकंड था। मैं दावा है कि मेरा कार्यक्रम है, तेजी से हालांकि था मेरे प्रबंधक के कार्यक्रम के बाद समाप्त हो गया है, जबकि यह किया लगता है सब समाधान, उन्हें एक पाठ फ़ाइल में बाहर मुद्रण नहीं किया गया। यदि उन्होंने उस तर्क को अपने कोड में जोड़ा, तो यह अक्सर 0.4-0.5 सेकंड से ऊपर हो जाता है।
चूंकि हमने अपनी अंतर-व्यक्तिगत चुनौती को निर्वाह करने की अनुमति दी है, लेकिन निश्चित रूप से, यह सवाल बना हुआ है: क्या इस कार्यक्रम को तेज बनाया जा सकता है?
यही चुनौती मैं आप लोगों को देने जा रहा हूं।
आपकी चुनौती
पैरामीटर हमने "29 के योग" नियम के तहत "सभी पंक्तियों / स्तंभों के बराबर" के रूप में आराम से काम किया है, और मैं उस नियम को आप लोगों के लिए भी सेट करने जा रहा हूं। चुनौती, इसलिए है: एक प्रोग्राम लिखें जो इस (और प्रिंट्स!) को कम से कम समय में इस पहेली को हल करता है। मैं प्रस्तुत समाधानों पर एक सीलिंग स्थापित करने जा रहा हूं: यदि कार्यक्रम अपेक्षाकृत सभ्य कंप्यूटर (<8 वर्ष) पर 10 सेकंड से अधिक समय लेता है, तो संभवतः इसे गिना जाना बहुत धीमा है।
इसके अलावा, मेरे पास पहेली के लिए कुछ बोनस हैं:
- क्या आप समाधान को सामान्य कर सकते हैं ताकि यह 16 नंबरों के किसी भी सेट के लिए काम करे, न कि सिर्फ
int[1,16]? टाइमिंग स्कोर का मूल्यांकन मूल प्रॉम्प्ट संख्या सेट के आधार पर किया जाएगा, लेकिन इस कोडपथ के माध्यम से पारित किया गया। (-10%) - क्या आप कोड को इस तरह से लिख सकते हैं कि वह सुंदर तरीके से डुप्लिकेट संख्याओं के साथ संभालता है और हल करता है? यह उतना सरल नहीं है जितना कि यह प्रतीत हो सकता है! समाधान जो "नेत्रहीन समान हैं" परिणाम सेट में अद्वितीय होना चाहिए। (-5%)
- क्या आप नकारात्मक संख्या को संभाल सकते हैं? (-5%)
आप एक समाधान बनाने की कोशिश भी कर सकते हैं जो फ्लोटिंग-पॉइंट नंबरों को संभालता है, लेकिन निश्चित रूप से, अगर यह पूरी तरह से विफल रहता है तो चौंकें नहीं। यदि आप एक मजबूत समाधान हालांकि, कि एक बड़े बोनस के लायक हो सकता है!
सभी इरादों और उद्देश्यों के लिए, "घुमाव" को अद्वितीय समाधान माना जाता है। तो एक समाधान जो केवल एक अलग समाधान का एक रोटेशन है, अपने स्वयं के समाधान के रूप में गिना जाता है।
मेरे कंप्यूटर पर मेरे द्वारा काम की जाने वाली IDE जावा और C ++ हैं। मैं अन्य भाषाओं से उत्तर स्वीकार कर सकता हूं, लेकिन आपको एक लिंक भी प्रदान करना पड़ सकता है जहां मुझे आपके कोड के लिए एक आसान-से-सेटअप रनटाइम वातावरण मिल सकता है।

