दिन के यादृच्छिक गोल्फ # 6: एक डी 20 रोल करें


17

श्रृंखला के बारे में

सबसे पहले, आप इसे किसी भी अन्य कोड गोल्फ चुनौती की तरह मान सकते हैं, और श्रृंखला के बारे में चिंता किए बिना इसका जवाब दे सकते हैं। हालांकि, सभी चुनौतियों के बीच एक लीडरबोर्ड है। आप लीडरबोर्ड के साथ पहली पोस्ट में श्रृंखला के बारे में कुछ और जानकारी पा सकते हैं ।

हालांकि मेरे पास श्रृंखला के लिए विचारों का एक समूह है, भविष्य की चुनौतियां अभी तक पत्थर में सेट नहीं हैं। यदि आपके पास कोई सुझाव है, तो कृपया मुझे संबंधित सैंडबॉक्स पोस्ट पर बताएं ।

छेद 6: रोल a d20

टेबल-टॉप RPGs में एक बहुत ही आम मरना बीस-पक्षीय डाई (एक आइसोसाहेड्रॉन , जिसे आमतौर पर d20 के रूप में जाना जाता है ) है। इस तरह के मर को रोल करना आपका काम है। हालाँकि, यदि आप केवल 1 और 20 के बीच एक यादृच्छिक संख्या वापस कर रहे थे, तो यह थोड़ा तुच्छ होगा। तो आपका काम किसी दिए गए मरने के लिए एक यादृच्छिक जाल उत्पन्न करना है।

हम निम्नलिखित नेट का उपयोग करेंगे:

यहाँ छवि विवरण दर्ज करें

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

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]

यह निम्न मृत्यु के अनुरूप होगा (मज़ेदार तथ्य: यह जादू द्वारा इस्तेमाल किया गया जाल है : जीवन की गिनती / स्पिन-डाउन जाइस)।

यहाँ छवि विवरण दर्ज करें

हालाँकि, यह एकमात्र शुद्ध नहीं है जो इस मृत्यु का प्रतिनिधित्व करता है। हम कैसे चेहरे को अनियंत्रित करते हैं, इसके आधार पर, 60 अलग-अलग जाल हैं। यहाँ दो और हैं:

[1, 8, 9, 10, 2, 3, 4, 5, 6, 7, 17, 18, 19, 11, 12, 13, 14, 15, 16, 20]
[10, 9, 18, 19, 11, 12, 3, 2, 1, 8, 7, 17, 16, 20, 13, 14, 4, 5, 6, 15]

या रेखांकन (मैंने सरलता के लिए चेहरे के लेबल नहीं घुमाए):

यहाँ छवि विवरण दर्ज करें यहाँ छवि विवरण दर्ज करें

चुनौती

दिए गए डाई के अनुरूप एक पूर्णांक (जैसा कि ऊपर वर्णित है) और पूर्णांक N, आउटपुट Nस्वतंत्र रूप से, समान रूप से यादृच्छिक d20 नेट का प्रतिनिधित्व करने वाले पूर्णांक की एक सूची को देखते हुए । (अर्थात, 60 संभावित जालों में से प्रत्येक के उत्पन्न होने की समान संभावना होनी चाहिए।)

बेशक, PRNGs की तकनीकी सीमाओं के कारण, सही एकरूपता असंभव होगी। आपके सबमिशन की एकरूपता का आकलन करने के उद्देश्य से, निम्नलिखित कार्यों को पूरी तरह से समान वितरण प्रदान करने के रूप में माना जाएगा:

  • PRNG (किसी भी सीमा से अधिक) से एक संख्या प्राप्त करना, जो कि (लगभग) एकरूप होने के लिए प्रलेखित है।
  • मॉडुलो या गुणा (या कुछ अन्य ऑपरेशन जो समान रूप से मान वितरित करता है) के माध्यम से एक छोटे सेट पर संख्याओं के एक बड़े सेट पर एक समान वितरण का मानचित्रण करता है। बड़े सेट में छोटे सेट के रूप में कम से कम 1024 बार संभव मान शामिल होते हैं।

इन मान्यताओं को देखते हुए आपके एल्गोरिथ्म को एक समान रूप से समान वितरण प्राप्त करना चाहिए।

आपका कार्यक्रम एक सेकंड से भी कम समय में 100 नेट उत्पन्न करने में सक्षम होना चाहिए (इसलिए यादृच्छिक नेट उत्पन्न करने की कोशिश न करें जब तक कि ऊपर मरने से मेल नहीं खाता)।

आप STDIN (या निकटतम विकल्प), कमांड-लाइन तर्क या फ़ंक्शन तर्क के माध्यम से इनपुट लेने और STDOUT (या निकटतम वैकल्पिक), फ़ंक्शन रिटर्न मान या फ़ंक्शन (आउट) पैरामीटर के माध्यम से परिणाम आउटपुट कर सकते हैं।

इनपुट और आउटपुट किसी भी सुविधाजनक, अस्पष्ट, फ्लैट सूची प्रारूप में हो सकते हैं। आप मान सकते हैं कि d20 के चेहरे के मूल्य अलग-अलग, सकारात्मक पूर्णांक हैं, जो आपकी भाषा के प्राकृतिक पूर्णांक प्रकार में फिट होते हैं।

यह कोड गोल्फ है, इसलिए सबसे छोटा सबमिशन (बाइट्स में) जीतता है। और निश्चित रूप से, प्रति उपयोगकर्ता सबसे कम सबमिशन भी श्रृंखला के समग्र लीडरबोर्ड में प्रवेश करेगा।

नमूना आउटपुट

इनपुट के लिए

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]

60 संभावित जाल (बशर्ते मैंने कोई गलती न की हो), कोई विशेष क्रम में नहीं हैं, ये हैं:

[11, 10, 9, 18, 19, 20, 13, 12, 3, 2, 1, 8, 7, 17, 16, 15, 14, 4, 5, 6]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
[8, 7, 17, 18, 9, 10, 2, 1, 5, 6, 15, 16, 20, 19, 11, 12, 3, 4, 14, 13]
[3, 12, 13, 14, 4, 5, 1, 2, 10, 11, 19, 20, 16, 15, 6, 7, 8, 9, 18, 17]
[3, 4, 5, 1, 2, 10, 11, 12, 13, 14, 15, 6, 7, 8, 9, 18, 19, 20, 16, 17]
[11, 19, 20, 13, 12, 3, 2, 10, 9, 18, 17, 16, 15, 14, 4, 5, 1, 8, 7, 6]
[4, 14, 15, 6, 5, 1, 2, 3, 12, 13, 20, 16, 17, 7, 8, 9, 10, 11, 19, 18]
[2, 10, 11, 12, 3, 4, 5, 1, 8, 9, 18, 19, 20, 13, 14, 15, 6, 7, 17, 16]
[4, 5, 1, 2, 3, 12, 13, 14, 15, 6, 7, 8, 9, 10, 11, 19, 20, 16, 17, 18]
[10, 2, 1, 8, 9, 18, 19, 11, 12, 3, 4, 5, 6, 7, 17, 16, 20, 13, 14, 15]
[3, 2, 10, 11, 12, 13, 14, 4, 5, 1, 8, 9, 18, 19, 20, 16, 15, 6, 7, 17]
[7, 8, 1, 5, 6, 15, 16, 17, 18, 9, 10, 2, 3, 4, 14, 13, 20, 19, 11, 12]
[13, 12, 11, 19, 20, 16, 15, 14, 4, 3, 2, 10, 9, 18, 17, 7, 6, 5, 1, 8]
[16, 15, 14, 13, 20, 19, 18, 17, 7, 6, 5, 4, 3, 12, 11, 10, 9, 8, 1, 2]
[15, 16, 17, 7, 6, 5, 4, 14, 13, 20, 19, 18, 9, 8, 1, 2, 3, 12, 11, 10]
[20, 13, 12, 11, 19, 18, 17, 16, 15, 14, 4, 3, 2, 10, 9, 8, 7, 6, 5, 1]
[5, 4, 14, 15, 6, 7, 8, 1, 2, 3, 12, 13, 20, 16, 17, 18, 9, 10, 11, 19]
[10, 11, 12, 3, 2, 1, 8, 9, 18, 19, 20, 13, 14, 4, 5, 6, 7, 17, 16, 15]
[4, 3, 12, 13, 14, 15, 6, 5, 1, 2, 10, 11, 19, 20, 16, 17, 7, 8, 9, 18]
[19, 20, 13, 12, 11, 10, 9, 18, 17, 16, 15, 14, 4, 3, 2, 1, 8, 7, 6, 5]
[1, 8, 9, 10, 2, 3, 4, 5, 6, 7, 17, 18, 19, 11, 12, 13, 14, 15, 16, 20]
[8, 1, 5, 6, 7, 17, 18, 9, 10, 2, 3, 4, 14, 15, 16, 20, 19, 11, 12, 13]
[18, 9, 8, 7, 17, 16, 20, 19, 11, 10, 2, 1, 5, 6, 15, 14, 13, 12, 3, 4]
[12, 3, 2, 10, 11, 19, 20, 13, 14, 4, 5, 1, 8, 9, 18, 17, 16, 15, 6, 7]
[2, 3, 4, 5, 1, 8, 9, 10, 11, 12, 13, 14, 15, 6, 7, 17, 18, 19, 20, 16]
[10, 9, 18, 19, 11, 12, 3, 2, 1, 8, 7, 17, 16, 20, 13, 14, 4, 5, 6, 15]
[9, 8, 7, 17, 18, 19, 11, 10, 2, 1, 5, 6, 15, 16, 20, 13, 12, 3, 4, 14]
[16, 17, 7, 6, 15, 14, 13, 20, 19, 18, 9, 8, 1, 5, 4, 3, 12, 11, 10, 2]
[17, 7, 6, 15, 16, 20, 19, 18, 9, 8, 1, 5, 4, 14, 13, 12, 11, 10, 2, 3]
[1, 5, 6, 7, 8, 9, 10, 2, 3, 4, 14, 15, 16, 17, 18, 19, 11, 12, 13, 20]
[9, 18, 19, 11, 10, 2, 1, 8, 7, 17, 16, 20, 13, 12, 3, 4, 5, 6, 15, 14]
[16, 20, 19, 18, 17, 7, 6, 15, 14, 13, 12, 11, 10, 9, 8, 1, 5, 4, 3, 2]
[5, 1, 2, 3, 4, 14, 15, 6, 7, 8, 9, 10, 11, 12, 13, 20, 16, 17, 18, 19]
[8, 9, 10, 2, 1, 5, 6, 7, 17, 18, 19, 11, 12, 3, 4, 14, 15, 16, 20, 13]
[13, 20, 16, 15, 14, 4, 3, 12, 11, 19, 18, 17, 7, 6, 5, 1, 2, 10, 9, 8]
[6, 15, 16, 17, 7, 8, 1, 5, 4, 14, 13, 20, 19, 18, 9, 10, 2, 3, 12, 11]
[6, 5, 4, 14, 15, 16, 17, 7, 8, 1, 2, 3, 12, 13, 20, 19, 18, 9, 10, 11]
[7, 6, 15, 16, 17, 18, 9, 8, 1, 5, 4, 14, 13, 20, 19, 11, 10, 2, 3, 12]
[19, 18, 17, 16, 20, 13, 12, 11, 10, 9, 8, 7, 6, 15, 14, 4, 3, 2, 1, 5]
[14, 15, 6, 5, 4, 3, 12, 13, 20, 16, 17, 7, 8, 1, 2, 10, 11, 19, 18, 9]
[17, 18, 9, 8, 7, 6, 15, 16, 20, 19, 11, 10, 2, 1, 5, 4, 14, 13, 12, 3]
[6, 7, 8, 1, 5, 4, 14, 15, 16, 17, 18, 9, 10, 2, 3, 12, 13, 20, 19, 11]
[14, 13, 20, 16, 15, 6, 5, 4, 3, 12, 11, 19, 18, 17, 7, 8, 1, 2, 10, 9]
[20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
[7, 17, 18, 9, 8, 1, 5, 6, 15, 16, 20, 19, 11, 10, 2, 3, 4, 14, 13, 12]
[15, 6, 5, 4, 14, 13, 20, 16, 17, 7, 8, 1, 2, 3, 12, 11, 19, 18, 9, 10]
[9, 10, 2, 1, 8, 7, 17, 18, 19, 11, 12, 3, 4, 5, 6, 15, 16, 20, 13, 14]
[2, 1, 8, 9, 10, 11, 12, 3, 4, 5, 6, 7, 17, 18, 19, 20, 13, 14, 15, 16]
[12, 13, 14, 4, 3, 2, 10, 11, 19, 20, 16, 15, 6, 5, 1, 8, 9, 18, 17, 7]
[17, 16, 20, 19, 18, 9, 8, 7, 6, 15, 14, 13, 12, 11, 10, 2, 1, 5, 4, 3]
[18, 17, 16, 20, 19, 11, 10, 9, 8, 7, 6, 15, 14, 13, 12, 3, 2, 1, 5, 4]
[18, 19, 11, 10, 9, 8, 7, 17, 16, 20, 13, 12, 3, 2, 1, 5, 6, 15, 14, 4]
[11, 12, 3, 2, 10, 9, 18, 19, 20, 13, 14, 4, 5, 1, 8, 7, 17, 16, 15, 6]
[15, 14, 13, 20, 16, 17, 7, 6, 5, 4, 3, 12, 11, 19, 18, 9, 8, 1, 2, 10]
[19, 11, 10, 9, 18, 17, 16, 20, 13, 12, 3, 2, 1, 8, 7, 6, 15, 14, 4, 5]
[12, 11, 19, 20, 13, 14, 4, 3, 2, 10, 9, 18, 17, 16, 15, 6, 5, 1, 8, 7]
[20, 16, 15, 14, 13, 12, 11, 19, 18, 17, 7, 6, 5, 4, 3, 2, 10, 9, 8, 1]
[13, 14, 4, 3, 12, 11, 19, 20, 16, 15, 6, 5, 1, 2, 10, 9, 18, 17, 7, 8]
[5, 6, 7, 8, 1, 2, 3, 4, 14, 15, 16, 17, 18, 9, 10, 11, 12, 13, 20, 19]
[14, 4, 3, 12, 13, 20, 16, 15, 6, 5, 1, 2, 10, 11, 19, 18, 17, 7, 8, 9]

किसी भी अन्य नेट के लिए, बस इनपुट (जहां 1-आधारित है) में वें नंबर के iसाथ हर घटना को प्रतिस्थापित करें ।ii

संबंधित चुनौतियाँ

लीडरबोर्ड

श्रृंखला की पहली पोस्ट एक लीडरबोर्ड उत्पन्न करती है।

यह सुनिश्चित करने के लिए कि आपके उत्तर दिखाई दे रहे हैं, कृपया प्रत्येक मार्कलाइन के साथ निम्नलिखित मार्कडाउन टेम्पलेट का उपयोग करते हुए, हर उत्तर को शुरू करें:

## Language Name, N bytes

Nआपके प्रस्तुत करने का आकार कहां है। यदि आप अपने स्कोर में सुधार करते हैं, तो आप पुराने अंकों को हेडलाइन में रख सकते हैं , उनके माध्यम से स्ट्राइक करके। उदाहरण के लिए:

## Ruby, <s>104</s> <s>101</s> 96 bytes

(भाषा को वर्तमान में नहीं दिखाया गया है, लेकिन स्निपेट को इसकी आवश्यकता है और इसे पार्स करें, और मैं भविष्य में एक उप-भाषा लीडरबोर्ड जोड़ सकता हूं।)


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

यह लगभग मेरे सैंडबॉक्स पोस्ट की तरह है!
R

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

कभी अपना नहीं देखा। यह अजीब है, मैंने सोचा कि मैंने पहले पृष्ठ पर सभी को पढ़ा। लेकिन नहीं, मैंने स्वतंत्र रूप से मेरा बनाया।
R

नहीं होना चाहिए कि शीर्षक "एक खुलासा 20"?
टाइटस

जवाबों:


7

रूबी, 160 बाइट्स (Rev B)

मार्टिन ब्यूटनर के सुझावों के लिए 17 बाइट्स ने धन्यवाद दिया।

->a,n{n.times{k=rand 60
%w{ABCD@GHIJKLMNEFPQRSO PFENOSRQHG@DCMLKJIAB GFPQHIA@DENOSRJKBCML}.map{|b|k.times{a=b.chars.map{|i|a[i.ord-64]}}}
k>29&&a.reverse!
p a}}

रूबी, 177 बाइट्स (रेव A)

->n,a{n.times{k=rand(60)
h=->b{k.times{|j|a=(0..19).map{|i|a[b[i].ord-64]}}}
h['ABCD@GHIJKLMNEFPQRSO']
h['PFENOSRQHG@DCMLKJIAB']
h['GFPQHIA@DENOSRJKBCML']
k>29&&a.reverse!
p a}}

व्याख्या

एक चेहरे (3-गुना), एक शीर्ष (5-गुना) और दो किनारों (2-गुना) के बारे में घुमावों द्वारा सभी संभव अभिविन्यास उत्पन्न करना संभव है। लेकिन सिर्फ कोई चेहरा और किनारा नहीं। कुल्हाड़ियों का सही संबंध होना चाहिए और घुमाव सही क्रम में होना चाहिए, या अजीब चीजें हो सकती हैं।

यह मैंने ऐसा किया है (हालांकि मैं समझता हूं कि मार्टिन ने इसे अलग तरीके से किया था।)

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

क) किनारों के मध्य बिंदु के माध्यम से दाईं ओर दो 2-गुना कुल्हाड़ियों के बारे में रोटेशन (ये एक-दूसरे के समकोण पर हैं। यदि हम उन्हें एक साथ गुणा करते हैं तो हम किनारों की शेष जोड़ी के माध्यम से एक तिहाई 2-गुना अक्ष की खोज करते हैं।)

ख) 2 गुना अक्ष के लिए एक 3 गुना अक्ष तिरछे घुमाव, एक शीर्ष और एक चेहरे के माध्यम से गुजर रहा है।

Icosahedron की समरूपता टेट्राहेड्रॉन की एक सुपरसेट है। नीचे से छवि में https://en.wikipedia.org/wiki/Icosahedron से , पीले चेहरे और लाल चेहरे दो अलग-अलग टेट्राहेड्रा (या वैकल्पिक रूप से एक एकल ऑक्टाहेड्रोन) को परिभाषित करते हैं, जबकि किनारों पर दो नीले चेहरे तीन जोड़े में होते हैं समकोण (और घन के मुखों पर लेटें।)

Icosahedron के सभी झुकावों को उन समरूपता संचालनों द्वारा उत्पन्न किया जा सकता है जो ऊपर वर्णित अतिरिक्त 5-गुना ऑपरेशन हैं।

यहाँ छवि विवरण दर्ज करें

ऊपर वर्णित चार कुल्हाड़ियों में से तीन के बारे में घुमाव, ''निशान के बीच जादू के तारों द्वारा दर्शाए गए हैं । दूसरी 2-गुना अक्ष के बारे में रोटेशन अलग है, और केवल सरणी को उल्टा करके किया जा सकता हैa[]

परीक्षण कार्यक्रम में असंगठित:

f=->a,n{
  n.times{                     #Iterate n times, using the result from the previous iteration to generate the next
    k=rand(60)                 #pick a random number

    h=->b{                     #helper function taking a string representing a transformation
      k.times{|j|              #which is performed on a using the number of times according to k
        a=(0..19).map{|i|a[b[i].ord-64]}
      }
    }

    #Rotate about axes k times (one 5-fold, one 3-fold, two 2-fold)
    #The first three axes have coprime rotation orders
    #And the rotations themselves take care of the modulus operation so no need to add it.
    #The second 2-fold rotation is equivalent to reversing the order
    #And is applied to the last 30 numbers as it is not coprime with the first 2-fold rotation.

    h['ABCD@GHIJKLMNEFPQRSO']  #rotate k times about 5-fold axis
    h['PFENOSRQHG@DCMLKJIAB']  #rotate k times about 3-fold axis
    h['GFPQHIA@DENOSRJKBCML']  #rotate k times about 2-fold axis
    k>29&&a.reverse!
    p a
  }
}

z=(1..20).map{|i|i} 
f[z,50]

वैकल्पिक समाधान 131 बाइट्स (बाइनरी रैंडम वॉक अप्रोच के कारण अमान्य, केवल लगभग सही वितरण देता है।)

->a,n{(n*99).times{|i|s=['@DEFGHIABCMNOPQRJKLS','ABCD@GHIJKLMNEFPQRSO'][rand(2)] 
a=(0..19).map{|i|a[s[i].ord-64]}
i%99==98&&p(a)}}

यह एक हाथापाई है (कार्यक्रमों की तरह, जो रूबिक के घन को घसीटने के लिए इस्तेमाल किया जाता है।)

मेरे द्वारा उपयोग किए जाने वाले विशिष्ट घुमाव दो सबसे स्पष्ट हैं:

-एक 120 डिग्री रोटेशन (पहले आरेख के अनुसार 1 और 20 चेहरे)

-72 डिग्री रोटेशन (प्रथम कोने में 1,2,3,4,5 और 16,17,18,19,20 के लिए कॉमन के बारे में)।

हम 99 बार एक सिक्का पलटा करते हैं, और हर बार जब हम सिर या पूंछ के आधार पर इन दो घुमावों में से एक का प्रदर्शन करते हैं।

ध्यान दें कि इन वैकल्पिक रूप से वैकल्पिक रूप से काफी कम अनुक्रम होते हैं। उदाहरण के लिए, सही रोटेशन इंद्रियों के साथ, 180 डिग्री के रोटेशन को सिर्फ 2 की अवधि के साथ उत्पादित किया जा सकता है।


ऐसा लगता है कि एक ऑपरेशन को चुनने के लिए एक सिक्का फ़्लिप करना एक समान वितरण की तुलना में एक द्विपद वितरण के करीब कुछ उपज देने वाला है।
शुक्राणु

@ अगर राज्य की स्थिति यादृच्छिक चलने से बड़ी होती तो ऐसा होता। लेकिन इस मामले में सिर्फ 6 चरणों का एक यादृच्छिक चलना 2 ^ 6 = 64 संभावनाओं के रूप में खुल सकता है (मैंने उन्हें नहीं गिना है), और हमारा राज्य स्थान केवल 60 है। 99 चरणों के बाद (2 ^ 99 विभिन्न पथ) सब कुछ कम से कम समान रूप से वितरित किया जाना चाहिए क्योंकि संख्या उत्पन्न करने के लिए PRNG के एकल नमूने के रूप में वितरित किया जाता है।
लेवल रिवर सेंट

@ MartinBüttner सुझावों के लिए धन्यवाद, मैंने उन लोगों को लागू किया है जो काम करते हैं। b.mapसीधे काम नहीं करता है, मुझे b.chars.mapइसे काम करने की ज़रूरत है (BTW जो मेरी मशीन में काम नहीं करता है क्योंकि मेरे पास रूबी 1.9.3 है लेकिन यह Ideone पर काम करता है।) यह एक उचित बचत है। मुझे नहीं लगता कि -64काम करने के लिए गैर-संरेखित वर्णों के लिए मैजिक स्ट्रिंग्स को बदलना कार्य को उत्पन्न करता है: उत्पन्न सरणी में स्ट्रिंग्स के बीच एक विभाजक के रूप में (साथ ही स्थान) की %w{}व्याख्या \nकरता है। मुझे नहीं पता कि यह अन्य गैर-संचारी ASCII वर्णों के साथ क्या करेगा।
लेवल रिवर सेंट

@ मैं यह उम्मीद की तुलना में कठिन था - पहले तो मैं चकित था जब मेरा कोड ठीक से काम नहीं कर रहा था, तब मैंने एक ब्रेक लिया और अचानक महसूस किया कि 2-गुना और 3-गुना समरूपता के समान पारस्परिक संबंध होना चाहिए एक टेट्राहेड्रॉन पर (मुझे त्रिकोणीय चेहरे को बदलना था जो मैं एक अलग त्रिकोणीय चेहरे के लिए घूम रहा था।)
लेवल रिवर सेंट

1
नए अनलॉक किए गए ज्यामिति बैज के साथ पहला उपयोगकर्ता होने पर बधाई । :)
मार्टिन एंडर

2

IA-32 मशीन कोड, 118 बाइट्स

Hexdump:

60 33 c0 51 8b 74 24 28 8b fa 6a 05 59 f3 a5 e8
21 00 00 00 20 c4 61 cd 6a 33 00 84 80 ad a8 33
32 00 46 20 44 8e 48 61 2d 2c 33 32 4a 00 21 20
a7 a2 90 8c 00 5b b1 04 51 0f c7 f1 83 e1 1f 49
7e f7 51 8b f2 56 8d 7c 24 e0 b1 14 f3 a4 5f 8b
f3 ac 8b ee d4 20 86 cc e3 0a 56 8d 74 04 e0 f3
a4 5e eb ed 59 e2 db 8b dd 59 e2 cc 59 83 c2 14
e2 91 61 c2 04 00

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

कोड को मूल रूप से एक क्रमचय उत्पन्न करना होता है, जो निम्नलिखित का अनुक्रमिक अनुप्रयोग है:

  1. आदेश 3 का क्रमचय, जिसे मैं कहता हूं p3, 0 ... 2 बार लागू किया गया
  2. क्रम 2 का क्रमपरिवर्तन, जिसे मैं कहता हूं q2, 0 या 1 बार लागू किया गया
  3. आदेश 5 का क्रमचय, जिसे मैं कहता हूं p5, 0 ... 4 बार लागू किया गया
  4. आदेश 2 का एक और क्रमचय, जिसे मैं कहता हूं p2, 0 या 1 बार लागू किया गया

इन क्रमपरिवर्तन के लिए कई संभावित विकल्प हैं। उनमें से एक इस प्रकार है:

p3 = [0   4   5   6   7   8   9   1   2   3  13  14  15  16  17  18  10  11  12  19]
q2 = [4   5   6   7   0   1   2   3  13  14  15  16  17   8   9  10  11  12  19  18]
p5 = [6   7   0   4   5  14  15  16  17   8   9   1   2   3  13  12  19  18  10  11]
p2 = [1   0   7   8   9  10  11   2   3   4   5   6  16  17  18  19  12  13  14  15]

यह विकल्प दूसरों की तुलना में बेहतर है क्योंकि यहां के क्रमपरिवर्तन में अनुक्रमिक सूचकांकों के लंबे रन होते हैं, जिसे रन-लंबाई एन्कोडिंग द्वारा संकुचित किया जा सकता है - 4 क्रमपरिवर्तन के लिए केवल 29 बाइट्स।

यादृच्छिक संख्याओं की पीढ़ी को सरल बनाने के लिए, मैंने उन सभी के लिए 1 (30) सीमा 1 में शक्तियां (कितनी बार प्रत्येक क्रमपरिवर्तन लागू किया गया) चुना। इससे कोड में बहुत अधिक अतिरिक्त काम होता है, क्योंकि उदाहरण के लिए p3एक पहचान क्रमचय बन जाता है, जो प्रत्येक बार 3 गुना गुणा होता है। हालाँकि, कोड उस तरह से छोटा होता है, और जब तक रेंज 30 से विभाज्य होती है, आउटपुट का समान वितरण होगा।

इसके अलावा, शक्तियां सकारात्मक होनी चाहिए ताकि रन-लेंथ डिकोडिंग ऑपरेशन कम से कम एक बार किया जाए।

कोड में 4 नेस्टेड लूप हैं; रूपरेखा इस प्रकार है:

void doit(int n, uint8_t* output, const uint8_t input[20])
{    
    uint8_t temp[20];

    n_loop: for i_n = 0 ... n
    {
        memcpy(output, input, 20);
        expr_loop: for i_expr = 0 ... 3
        {
            power = rand(1 ... 30);
            power_loop: for i_power = 0 ... power
            {
                memcpy(temp, output, 20);
                output_index = 0;
                perm_loop: do while length > 0
                {
                    index = ...; // decode it
                    length = ...; // decode it
                    memcpy(output + output_index, temp + index, length);
                    output_index += length;
                }
            }
        }
        output += 20;
    }
}

मुझे उम्मीद है कि नीचे दिया गया इनलाइन-असेंबली कोड की तुलना में यह छद्म कोड स्पष्ट है।

_declspec(naked) void __fastcall doit(int n, uint8_t* output, const uint8_t* input)
{
    _asm {
        pushad
        xor eax, eax

        n_loop:
            push ecx

            ; copy from input to output
            mov esi, [esp + 0x28]
            mov edi, edx
            push 5
            pop ecx
            rep movsd

            call end_of_data
#define rl(index, length) _emit(length * 32 + index)
            rl(0, 1)
            rl(4, 6)
            rl(1, 3)
            rl(13, 6)
            rl(10, 3)
            rl(19, 1)
            _emit(0)

            rl(4, 4)
            rl(0, 4)
            rl(13, 5)
            rl(8, 5)
            rl(19, 1)
            rl(18, 1)
            _emit(0)

            rl(6, 2)
            rl(0, 1)
            rl(4, 2)
            rl(14, 4)
            rl(8, 2)
            rl(1, 3)
            rl(13, 1)
            rl(12, 1)
            rl(19, 1)
            rl(18, 1)
            rl(10, 2)
            _emit(0)

            rl(1, 1)
            rl(0, 1)
            rl(7, 5)
            rl(2, 5)
            rl(16, 4)
            rl(12, 4)
            _emit(0)

            end_of_data:
            pop ebx ; load the address of the encoded data
            mov cl, 4

            expr_loop:
                push ecx

                make_rand:
                rdrand ecx
                and ecx, 31
                dec ecx
                jle make_rand

                ; input: ebx => encoding of permutation
                ; output: ebp => encoding of next permutation
                power_loop:
                    push ecx

                    ; copy from output to temp
                    mov esi, edx
                    push esi
                    lea edi, [esp - 0x20]
                    mov cl, 20
                    rep movsb
                    pop edi

                    ; ebx => encoding of permutation
                    ; edi => output
                    mov esi, ebx
                    perm_loop:
                        ; read a run-length
                        lodsb
                        mov ebp, esi

                        _emit(0xd4)             ; divide by 32, that is, split into
                        _emit(32)               ; index (al) and length (ah)
                        xchg cl, ah             ; set ecx = length; also makes eax = al
                        jecxz perm_loop_done    ; zero length => done decoding
                        push esi
                        lea esi, [esp + eax - 0x20]
                        rep movsb
                        pop esi
                        jmp perm_loop

                    perm_loop_done:
                    pop ecx
                    loop power_loop

                mov ebx, ebp
                pop ecx
                loop expr_loop

            pop ecx
            add edx, 20
            loop n_loop

        popad
        ret 4
    }
}

कुछ मजेदार कार्यान्वयन विवरण:

  • मैंने उच्च-स्तरीय भाषाओं की तरह, इंडेंट असेंबली का उपयोग किया; अन्यथा कोड एक असंगत गंदगी होगी
  • मैं कोड में संग्रहीत डेटा (एन्कोडेड परमिट) का उपयोग करने के लिए callऔर बाद में उपयोग करता हूंpop
  • jecxzशिक्षा सुविधा मुझे रन लंबाई डिकोडिंग प्रक्रिया के लिए समाप्ति के रूप में एक शून्य बाइट का उपयोग करने देता
  • भाग्य से, संख्या 30 (2 * 3 * 5) लगभग 2 की शक्ति है। इससे मुझे सीमा 1 में संख्या उत्पन्न करने के लिए संक्षिप्त कोड का उपयोग करने की सुविधा मिलती है ... 30:

            and ecx, 31
            dec ecx
            jle make_rand
    
  • मैं aamएक बाइट को बिट फ़ील्ड (3-बिट लंबाई और 5-बिट इंडेक्स) में अलग करने के लिए "सामान्य-उद्देश्य डिवीजन" निर्देश ( ) का उपयोग करता हूं ; भाग्य से, कोड में उस स्थिति में cl = 0, इसलिए मैं दोनों "पक्षों" से लाभ उठाता हूंxchg

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