मेरे राक्षस को पहचानने में मेरी मदद करो


35

पृष्ठभूमि

कंप्यूटर गेम में ग्राफिक्स के उपयोग से व्यापक रूप से स्थापित होने से पहले 1987 से कंप्यूटर गेम नेटहैक की तारीखें थीं। खेल में बहुत सारे राक्षस हैं, और संभावित रूप से एक बार स्क्रीन पर फिट होने की आवश्यकता होती है, इसलिए राक्षसों को बहुत कम से कम तरीके से तैयार किया जाता है: एक राक्षस बस स्क्रीन पर एक ASCII चरित्र के रूप में तैयार होता है।

बहुत सारे राक्षस होने के अलावा, राक्षस के बहुत सारे प्रकार हैं। यह जानना महत्वपूर्ण हो सकता है कि कौन सा है; एक बिल्ली का बच्चा और एक अजगर को देखकर आपको अलग तरह से प्रतिक्रिया करनी होगी। जैसे, ASCII का उपयोग राक्षसों का प्रतिनिधित्व करने के लिए किया जाता है; उदाहरण के लिए, एक बिल्ली का बच्चा है f, और एक लाल अजगर है D। इसका मतलब यह है कि यह जानना बहुत मददगार हो सकता है कि किसी दिए गए राक्षस को कैसा दिखेगा, क्योंकि यह आपको इसे पहचानने में मदद करेगा यदि आप इसे खेल में बाद में सामना करते हैं। (ध्यान दें कि ASCII वर्णों की तुलना में अधिक प्रकार के राक्षस हैं, इसलिए उनमें से कुछ साझा करते हैं; एक लाल ड्रैगन और एक नीला ड्रैगन दोनों हैं D।)

कार्य

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

निम्नलिखित स्टैक स्निपेट एक JSON ऑब्जेक्ट है जो उनके संबंधित आउटपुट के लिए संभावित इनपुट की पूरी मैपिंग देता है:

तो मूल रूप से, यहां कार्य "ऊपर दिए गए JSON ऑब्जेक्ट द्वारा दर्शाए गए शब्दकोश में एक कुंजी दिया गया है, संबंधित मान लौटाएं"।

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

स्पष्टीकरण

आप किसी भी उचित इनपुट और आउटपुट फॉर्मेट का उपयोग कर सकते हैं (जैसे कि आप आउटपुट को कैरेक्टर के रूप में, या उसके ASCII कोड के रूप में, या स्ट्रिंग के रूप में जो एक कैरेक्टर लंबा है) का उपयोग कर सकते हैं। यदि आप चाहें, तो आप एक पूर्ण कार्यक्रम के बजाय एक फ़ंक्शन सबमिट कर सकते हैं।

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

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

यह , इसलिए जीतने वाली प्रविष्टि वह प्रविष्टि होगी जो सबसे छोटी है, जिसे बाइट्स में गिना जाता है। सौभाग्य!


6
mail daemon> _ <
रिश्वतवादी

1
सुझाव: शायद आप ASCII प्रतीक के अनुसार राक्षसों की सूची को भी व्यवस्थित कर सकते हैं
क्रिति लिथोस

2
उच्छ्वास - इतना अच्छा खेल था, वो दिन थे ...
ग्रीनएजेड जेड

2
@GreenAsJade अभी भी एक अच्छा खेल है! वास्तव में एक नया संस्करण कुछ महीने पहले निष्क्रियता के कुछ साल बाद जारी किया गया था
nmjcman101

1
एक जंगली भूरा दिखने लगा है !!
मैजिक ऑक्टोपस Urn

जवाबों:


11

जेली के एन्कोडिंग में जेली , 309 बाइट्स

“Æ÷“¥s“ɲ“¡µ’;“ịƊ⁴çNṂ‘_\
OḌ;¢*5$%¥/µ“+⁷ż!¤ña¡jIȧƁfvḶg/Ọ=^ƝĠ0Ẇƭ³½N~=.Ɗ°ɗẇ⁵\ɦ*ɠPf⁾?ṾHḣ 2=⁹ƒ!©ƊĠṣƥ®Ƙ0Yƙ>!ȧtƊN0w,$ɠẎ46fẋ⁷(ṣẆm⁾ŻƓṫµsçwṣḂḲd0Ruṛ’ḃ21+\iµØW“&;:' ”;“¡3ȧ%⁾xƑ?{Ñṃ;Ċ70|#%ṭdṃḃ÷ƑĠẏþḢ÷ݳȦṖcẇọqƁe ʠ°oḲVḲ²ụċmvP[ỴẊẋ€kṢ ȯḂ;jɓỴẏeṾ⁴ḳḢ7Ẓ9ġƤṙb€xÇ4ɗ⁻>Ẉm!Ƈ)%Ḃẇ$ġ£7ȧ`ỵẈƘɗ¡Ṃ&|ƙƥ³ẏrṛbḋƙċ⁻ṁƲRṀẹṾ<ñ⁻Ṅ7j^ɓĊ’b58¤ị;0ị@
ḲÇ€t0”@;Ṫ

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

मैंने तय किया कि यह समय है जब मैं अपनी चुनौती पर था। जेली (और इसके 8-बिट कोडपेज) का उपयोग मुझे ASCII- केवल भाषाओं पर 12.5% ​​का लाभ देता है, और जेली इस चुनौती के लिए सुविधाजनक है क्योंकि छोटे नामों के साथ अंतर्निहित आधार रूपांतरण ऑपरेटर होने के कारण, लेकिन अधिकांश बचत एक बेहतर संपीड़न एल्गोरिथ्म के कारण होता है (यह प्रोग्राम औसतन एक बाइट प्रति राक्षस की तुलना में कम है)।

एल्गोरिथम और स्पष्टीकरण

शब्द-आधारित वर्गीकरण

मैंने तय किया कि एक अच्छा स्कोर प्राप्त करने के लिए, इनपुट की संरचना का अन्य प्रविष्टियों की तुलना में अधिक लाभ लेना आवश्यक था। एक बात जो बहुत ध्यान देने योग्य है, वह यह है कि कई राक्षसों के नाम " विशेषण प्रजाति " के हैं; a red dragonऔर a blue dragonदोनों प्रकार के ड्रैगन हैं, और इस प्रकार दिखाई देते हैं D। कुछ अन्य राक्षसों के रूप में " प्रजाति की नौकरी " के नाम हैं, जैसे कि orc shaman; एक प्रकार का orc होने के नाते, यह ऐसा प्रतीत होता है o। शिकायत करने वाले मामले पूर्ववत हैं; ए kobold zombieदोनों एक कोबोल्ड और एक ज़ोंबी है, और बाद की स्थिति नेटहैक मॉन्स्टर नामकरण में पूर्वता लेती है, इस प्रकार हम इसे वर्गीकृत करना चाहते हैं Z

जैसे, मैंने उन शब्दों को वर्गीकृत किया जो राक्षस नामों में दिखाई देते हैं: एक संकेतक एक शब्द है जो दृढ़ता से उपयुक्त राक्षस वर्ग का sphereसुझाव देता है (जैसे दृढ़ता से पता चलता है कि राक्षस वर्ग में है e); एक अस्पष्ट शब्द एक शब्द बहुत एक सुझाव के कम बनाता है ( lordआप ज्यादा बता नहीं करता है), और अन्य सभी शब्द हैं nonwords है कि हम के बारे में परवाह नहीं है। मूल विचार यह है कि हम दैत्य नाम के शब्द को पीछे से शुरू से देखते हैं, और पहले संकेतक को देखते हैं जो हम देखते हैं। जैसे, यह सुनिश्चित करना आवश्यक था कि प्रत्येक राक्षस का नाम कम से कम एक संकेतक हो, जो पूरी तरह से अस्पष्ट शब्दों द्वारा पीछा किया गया था। अपवाद के रूप में, वे शब्द जो राक्षसों के नामों में दिखाई देते हैं जो एक जैसे दिखते हैं@(सबसे बड़ा समूह) सभी को अस्पष्ट के रूप में वर्गीकृत किया गया है। एक संकेतक से पहले कुछ भी दिखाई दे सकता है; उदाहरण के लिए, रंग के नाम (जैसे red) हमेशा एक संकेतक की तुलना में एक नाम में पहले दिखाई देते हैं, और इस तरह उन्हें गैर-पासवर्ड माना जाता है (जैसा कि उन्हें राक्षस की पहचान निर्धारित करते समय कभी भी जांच नहीं की जाती है)।

अंत में, यह प्रोग्राम हैश टेबल पर आ जाता है, जैसे अन्य प्रोग्राम करते हैं। हालाँकि, तालिका में सभी राक्षस नामों के लिए प्रविष्टियाँ नहीं हैं, या उन सभी शब्दों के लिए जो राक्षस नामों में दिखाई देते हैं; बल्कि, इसमें केवल संकेतक होते हैं। अस्पष्ट शब्दों का हैश तालिका में दिखाई नहीं देता है, लेकिन खाली स्लॉट्स को सौंपा जाना चाहिए (हमेशा अस्पष्ट शब्द देखने की कोशिश करना) खाली हो जाएगा। गैर-पासवर्ड के लिए, यह कोई मायने नहीं रखता है कि शब्द तालिका में दिखाई देता है या नहीं, या हैश टकराता है या नहीं, क्योंकि हम कभी भी एक गैर-शब्द को देखने के मूल्य का उपयोग नहीं करते हैं। (तालिका काफी विरल है, इसलिए अधिकांश गैर-कीवर्ड तालिका में दिखाई नहीं देते हैं, लेकिन कुछ, जैसे कि flesh, तालिका में हैश टकराव के परिणामस्वरूप पाए जाते हैं।)

यहाँ कुछ उदाहरण हैं कि कार्यक्रम का यह भाग कैसे काम करता है:

  • woodchuckएक एकल शब्द लंबा है (इस तरह एक संकेतक), और टेबल लुकअप woodchuckहमें इच्छित उत्तर देता है r
  • abbotएक एकल शब्द भी लंबा है, लेकिन एक जैसा दिखता है @। जैसे, abbotएक अस्पष्ट शब्द माना जाता है; तालिका लुकअप खाली आता है, और हम @डिफ़ॉल्ट रूप से उत्तर देते हैं ।
  • vampire lordएक संकेतक ( vampireसंबंधित V) और एक अस्पष्ट शब्द ( lord, जो तालिका में नहीं है) के होते हैं। इसका मतलब है कि हम दोनों शब्दों (रिवर्स ऑर्डर में) की जांच करते हैं, फिर सही उत्तर देते हैं V
  • gelatinous cubeएक नॉनवर्ड ( हैश टकराव के कारण gelatinousसंगत H) और एक संकेतक ( cube, इसी b) के होते हैं। जैसा कि हम केवल तालिका में पाए गए अंतिम शब्द को लेते हैं, यह bउम्मीद के मुताबिक रिटर्न करता है।
  • gnome mummyके gnomeलिए Gऔर mummyइसी से संबंधित दो संकेतक होते हैं M। हम अंतिम संकेतक लेते हैं, और प्राप्त करते हैं M, जो हम चाहते हैं।

शब्द-आधारित वर्गीकरण को संभालने के लिए कोड जेली कार्यक्रम की अंतिम पंक्ति है। यहां देखिए यह कैसे काम करता है:

ḲÇ€t0”@;Ṫ
Ḳ          Split on spaces
 ǀ        Call function 2 (table lookup) on each entry
   t0      Remove trailing zeroes (function 2 returns 0 to mean "not found")
     ”@;   Prepend an @ character
        Ṫ  Take the last result

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

टेबल संपीड़न

बेशक, इनपुट को शब्दों में तोड़ना समस्या को स्वयं हल नहीं करता है; हमें अभी भी संकेतक और संबंधित राक्षस वर्गों (और अस्पष्ट शब्दों से पत्राचार की कमी) के बीच पत्राचार को दोहराना है। ऐसा करने के लिए, मैंने 181 प्रविष्टियों (181 संकेतकों के अनुरूप) के साथ एक विरल तालिका का निर्माण किया; यह 378 राक्षसों पर एक बड़ा सुधार है!), और 966 कुल प्रविष्टियाँ (हैश फ़ंक्शन के 966 आउटपुट मानों के अनुरूप)। तालिका को दो तारों के उपयोग के माध्यम से कार्यक्रम में एन्कोड किया गया है: पहली स्ट्रिंग तालिका में "अंतराल" के आकार को निर्दिष्ट करती है (जिसमें कोई प्रविष्टि नहीं होती है); और दूसरा तार राक्षस वर्ग को निर्दिष्ट करता है जो प्रत्येक प्रविष्टि से मेल खाता है। इन दोनों को आधार रूपांतरण के माध्यम से संक्षिप्त रूप में दर्शाया गया है।

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

“…’ḃ21+\iµØW“&;:' ”;“…’b58¤ị;0ị@
“…’                              Base 250 representation of the gap sizes
   ḃ21                           Convert to bijective base 21 
      +\                         Cumulative sum (converts gaps to indexes)
        i                        Find the input in this list
         µ                       Set as the new default for missing arguments

          ØW                     Uppercase + lowercase alphabets (+ junk we ignore)
            “&;:' ”;             Prepend "&;:' "
                    “…’          Base 250 representation of the table entries
                       b58       Convert to base 58
                          ¤      Parse the preceding two lines as a unit
                           i     Use the table to index into the alphabets
                            ;0   Append a zero
                              i@ Use {the value as of µ} to index into the table

आधार विशेष 21 आधार 21 की तरह है, सिवाय इसके कि 21 एक कानूनी अंक है और 0 नहीं है। यह हमारे लिए एक अधिक सुविधाजनक एन्कोडिंग है क्योंकि हम 1 के अंतराल के रूप में दो आसन्न प्रविष्टियों की गणना करते हैं, ताकि हम संचयी योग के माध्यम से मान्य अनुक्रमितों को पा सकें। जब यह मान रखने वाली तालिका के हिस्से में आता है, तो हमारे पास 58 अद्वितीय मूल्य होते हैं, इसलिए हम पहले 58 लगातार पूर्णांक में डिकोड करते हैं, और फिर एक लुकअप तालिका का उपयोग करके फिर से डिकोड करते हैं जो इन्हें उपयोग किए जा रहे वास्तविक वर्णों में मैप करता है। (इनमें से अधिकांश अक्षर हैं, इसलिए हम इस माध्यमिक लुकअप तालिका को गैर-पत्र प्रविष्टियों के साथ शुरू करते हैं &;:' , और फिर सिर्फ एक जेली स्थिरांक को जोड़ते हैं जो अपरकेस और लोअरकेस वर्णमाला के साथ शुरू होता है; इसमें कुछ अन्य कबाड़ भी हैं लेकिन हम परवाह नहीं करते हैं उसके बारे में।)

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

हैश फंकशन

कार्यक्रम का शेष भाग हैश फ़ंक्शन है। यह बस के साथ पर्याप्त शुरू होता हैOḌ; यह इनपुट स्ट्रिंग को अपने ASCII कोडों में परिवर्तित करता है, और फिर अंतिम कोड की गणना करता है, साथ ही 10 बार दंडात्मक कोड, और कोड के 100 गुना से पहले कोड, और इसी तरह (यह जेली में बहुत कम प्रतिनिधित्व है क्योंकि यह आमतौर पर अधिक उपयोग किया जाता है स्ट्रिंग → पूर्णांक रूपांतरण समारोह)। हालाँकि, यदि हम सीधे मापांक ऑपरेशन के माध्यम से इस हैश को कम कर देते हैं, तो हमें एक बड़ी तालिका की आवश्यकता होगी। इसलिए इसके बजाय, मैं तालिका को कम करने के लिए संचालन की एक श्रृंखला के साथ शुरू करता हूं। वे प्रत्येक इस तरह काम करते हैं: हम वर्तमान हैश मूल्य की पांचवीं शक्ति लेते हैं; तब हम मूल्य मोड्यूल को एक स्थिर (जो कि हम किस ऑपरेशन का उपयोग कर रहे हैं पर निर्भर करता है) को कम करते हैं। यह श्रृंखला लागत (परिणामी तालिका आकार को कम करने के संदर्भ में) की तुलना में अधिक लागत देती है (संचालन की श्रृंखला को स्वयं को एन्कोड करने की आवश्यकता के संदर्भ में), दो तरीकों से: यह तालिका बना सकती हैबहुत छोटा (3566 प्रविष्टियों के बजाय 966), और कई चरणों का उपयोग लाभकारी टक्करों को पेश करने का अधिक अवसर देता है (यह बहुत ज्यादा नहीं हुआ, लेकिन इस तरह की एक टक्कर है: दोनों Deathऔर Yeenoghuहैश से 806, इस प्रकार हमें एक को हटाने की अनुमति मिलती है तालिका से प्रवेश, क्योंकि वे दोनों जाते हैं&)। यहाँ उपयोग किए जाने वाले मोडुली [3529, 2163, 1999, 1739, 1523, 1378, 1246, 1223, 1145, 966] हैं। संयोग से, पांचवीं शक्ति को बढ़ाने का कारण यह है कि यदि आप सीधे मूल्य लेते हैं, तो अंतराल समान आकार के रहते हैं, जबकि घातांक अंतराल को चारों ओर ले जाता है और तालिका के समान वितरण के बाद इसे समान रूप से वितरित करना संभव बनाता है। एक स्थानीय न्यूनतम में फंसने के बजाय श्रृंखला (अधिक समान रूप से वितरित अंतराल अंतराल के आकार के एक टसर एन्कोडिंग के लिए अनुमति देते हैं)। इस तथ्य को रोकने के लिए एक विषम शक्ति होनी चाहिए कि x - = (- x ) worked टकरावों का परिचय दे, और 5 ने 3 से बेहतर काम किया।

कार्यक्रम की पहली पंक्ति डेल्टा एन्कोडिंग का उपयोग करके मोडुली के अनुक्रम को एन्कोड करती है:

“…’;“…‘_\
“…’       Compressed integer list encoding, arbitrary sized integers
   ;      Append
    “…‘   Compressed integer list encoding, small integers (≤ 249)
       _\ Take cumulative differences

कार्यक्रम के शेष, दूसरी पंक्ति की शुरुआत, हैश फ़ंक्शन को लागू करती है:

OḌ;¢*5$%¥/
O           Take ASCII codepoints
 Ḍ          "Convert from decimal", generalized to values outside the range 0-9
  ;¢        Append the table of moduli from the previous line
         /  Then reduce by:
    *5$       raising to the power 5 (parsing this as a group)
       %¥     and modulusing by the right argument (parsing this as a group, too).

सत्यापन

यह पर्ल स्क्रिप्ट है जिसका उपयोग मैंने यह सत्यापित करने के लिए किया था कि कार्यक्रम सही ढंग से काम करता है:

use warnings;
use strict;
use utf8;
use IPC::Run qw/run/;

my %monsters = ("Aleax", "A", "Angel", "A", "Arch Priest", "@", "Archon", "A",
"Ashikaga Takauji", "@", "Asmodeus", "&", "Baalzebub", "&", "Chromatic Dragon",
"D", "Croesus", "@", "Cyclops", "H", "Dark One", "@", "Death", "&", "Demogorgon",
"&", "Dispater", "&", "Elvenking", "@", "Famine", "&", "Geryon", "&",
"Grand Master", "@", "Green-elf", "@", "Grey-elf", "@", "Hippocrates", "@",
"Ixoth", "D", "Juiblex", "&", "Keystone Kop", "K", "King Arthur", "@",
"Kop Kaptain", "K", "Kop Lieutenant", "K", "Kop Sergeant", "K", "Lord Carnarvon",
"@", "Lord Sato", "@", "Lord Surtur", "H", "Master Assassin", "@", "Master Kaen",
"@", "Master of Thieves", "@", "Medusa", "@", "Minion of Huhetotl", "&",
"Mordor orc", "o", "Nalzok", "&", "Nazgul", "W", "Neferet the Green", "@", "Norn",
"@", "Olog-hai", "T", "Oracle", "@", "Orcus", "&", "Orion", "@", "Pelias", "@",
"Pestilence", "&", "Scorpius", "s", "Shaman Karnov", "@", "Thoth Amon", "@",
"Twoflower", "@", "Uruk-hai", "o", "Vlad the Impaler", "V", "Wizard of Yendor",
"@", "Woodland-elf", "@", "Yeenoghu", "&", "abbot", "@", "acid blob", "b",
"acolyte", "@", "air elemental", "E", "aligned priest", "@", "ape", "Y",
"apprentice", "@", "arch-lich", "L", "archeologist", "@", "attendant", "@",
"baby black dragon", "D", "baby blue dragon", "D", "baby crocodile", ":",
"baby gray dragon", "D", "baby green dragon", "D", "baby long worm", "w",
"baby orange dragon", "D", "baby purple worm", "w", "baby red dragon", "D",
"baby silver dragon", "D", "baby white dragon", "D", "baby yellow dragon", "D",
"balrog", "&", "baluchitherium", "q", "barbarian", "@", "barbed devil", "&",
"barrow wight", "W", "bat", "B", "black dragon", "D", "black light", "y",
"black naga hatchling", "N", "black naga", "N", "black pudding", "P",
"black unicorn", "u", "blue dragon", "D", "blue jelly", "j", "bone devil", "&",
"brown mold", "F", "brown pudding", "P", "bugbear", "h", "captain", "@",
"carnivorous ape", "Y", "cave spider", "s", "caveman", "@", "cavewoman", "@",
"centipede", "s", "chameleon", ":", "chickatrice", "c", "chieftain", "@",
"clay golem", "'", "cobra", "S", "cockatrice", "c", "couatl", "A", "coyote", "d",
"crocodile", ":", "demilich", "L", "dingo", "d", "disenchanter", "R", "djinni",
"&", "dog", "d", "doppelganger", "@", "dust vortex", "v", "dwarf king", "h",
"dwarf lord", "h", "dwarf mummy", "M", "dwarf zombie", "Z", "dwarf", "h",
"earth elemental", "E", "electric eel", ";", "elf mummy", "M", "elf zombie", "Z",
"elf", "@", "elf-lord", "@", "energy vortex", "v", "erinys", "&", "ettin mummy",
"M", "ettin zombie", "Z", "ettin", "H", "fire ant", "a", "fire elemental", "E",
"fire giant", "H", "fire vortex", "v", "flaming sphere", "e", "flesh golem", "'",
"floating eye", "e", "fog cloud", "v", "forest centaur", "C", "fox", "d",
"freezing sphere", "e", "frost giant", "H", "gargoyle", "g", "garter snake", "S",
"gas spore", "e", "gecko", ":", "gelatinous cube", "b", "ghost", " ", "ghoul",
"Z", "giant ant", "a", "giant bat", "B", "giant beetle", "a", "giant eel", ";",
"giant mimic", "m", "giant mummy", "M", "giant rat", "r", "giant spider", "s",
"giant zombie", "Z", "giant", "H", "glass golem", "'", "glass piercer", "p",
"gnome king", "G", "gnome lord", "G", "gnome mummy", "M", "gnome zombie", "Z",
"gnome", "G", "gnomish wizard", "G", "goblin", "o", "gold golem", "'",
"golden naga hatchling", "N", "golden naga", "N", "gray dragon", "D", "gray ooze",
"P", "gray unicorn", "u", "green dragon", "D", "green mold", "F", "green slime",
"P", "gremlin", "g", "grid bug", "x", "guard", "@", "guardian naga hatchling",
"N", "guardian naga", "N", "guide", "@", "healer", "@", "hell hound pup", "d",
"hell hound", "d", "hezrou", "&", "high priest", "@", "hill giant", "H",
"hill orc", "o", "hobbit", "h", "hobgoblin", "o", "homunculus", "i",
"horned devil", "&", "horse", "u", "housecat", "f", "human mummy", "M",
"human zombie", "Z", "human", "@", "hunter", "@", "ice devil", "&", "ice troll",
"T", "ice vortex", "v", "iguana", ":", "imp", "i", "incubus", "&", "iron golem",
"'", "iron piercer", "p", "jabberwock", "J", "jackal", "d", "jaguar", "f",
"jellyfish", ";", "ki-rin", "A", "killer bee", "a", "kitten", "f", "knight", "@",
"kobold lord", "k", "kobold mummy", "M", "kobold shaman", "k", "kobold zombie",
"Z", "kobold", "k", "kraken", ";", "large cat", "f", "large dog", "d",
"large kobold", "k", "large mimic", "m", "leather golem", "'", "lemure", "i",
"leocrotta", "q", "leprechaun", "l", "lich", "L", "lichen", "F", "lieutenant",
"@", "little dog", "d", "lizard", ":", "long worm", "w", "lurker above", "t",
"lynx", "f", "mail daemon", "&", "manes", "i", "marilith", "&", "master lich",
"L", "master mind flayer", "h", "mastodon", "q", "mind flayer", "h", "minotaur",
"H", "monk", "@", "monkey", "Y", "mountain centaur", "C", "mountain nymph", "n",
"mumak", "q", "nalfeshnee", "&", "neanderthal", "@", "newt", ":", "ninja", "@",
"nurse", "@", "ochre jelly", "j", "ogre king", "O", "ogre lord", "O", "ogre", "O",
"orange dragon", "D", "orc mummy", "M", "orc shaman", "o", "orc zombie", "Z",
"orc", "o", "orc-captain", "o", "owlbear", "Y", "page", "@", "panther", "f",
"paper golem", "'", "piranha", ";", "pit fiend", "&", "pit viper", "S",
"plains centaur", "C", "pony", "u", "priest", "@", "priestess", "@", "prisoner",
"@", "purple worm", "w", "pyrolisk", "c", "python", "S", "quantum mechanic", "Q",
"quasit", "i", "queen bee", "a", "quivering blob", "b", "rabid rat", "r",
"ranger", "@", "raven", "B", "red dragon", "D", "red mold", "F",
"red naga hatchling", "N", "red naga", "N", "rock mole", "r", "rock piercer", "p",
"rock troll", "T", "rogue", "@", "rope golem", "'", "roshi", "@", "rothe", "q",
"rust monster", "R", "salamander", ":", "samurai", "@", "sandestin", "&",
"sasquatch", "Y", "scorpion", "s", "sergeant", "@", "sewer rat", "r", "shade", " ",
"shark", ";", "shocking sphere", "e", "shopkeeper", "@", "shrieker", "F",
"silver dragon", "D", "skeleton", "Z", "small mimic", "m", "snake", "S",
"soldier ant", "a", "soldier", "@", "spotted jelly", "j", "stalker", "E",
"steam vortex", "v", "stone giant", "H", "stone golem", "'", "storm giant", "H",
"straw golem", "'", "student", "@", "succubus", "&", "tengu", "i", "thug", "@",
"tiger", "f", "titan", "H", "titanothere", "q", "tourist", "@", "trapper", "t",
"troll", "T", "umber hulk", "U", "valkyrie", "@", "vampire bat", "B",
"vampire lord", "V", "vampire", "V", "violet fungus", "F", "vrock", "&", "warg",
"d", "warhorse", "u", "warrior", "@", "watch captain", "@", "watchman", "@",
"water demon", "&", "water elemental", "E", "water moccasin", "S", "water nymph",
"n", "water troll", "T", "werejackal", "d", "wererat", "r", "werewolf", "d",
"white dragon", "D", "white unicorn", "u", "winged gargoyle", "g",
"winter wolf cub", "d", "winter wolf", "d", "wizard", "@", "wolf", "d",
"wood golem", "'", "wood nymph", "n", "woodchuck", "r", "wraith", "W", "wumpus",
"q", "xan", "x", "xorn", "X", "yellow dragon", "D", "yellow light", "y",
"yellow mold", "F", "yeti", "Y", "zruty", "z");

for my $monster (sort keys %monsters) {
    run ["./jelly", "fu", "monsters.j", $monster], \ "", \my $out;
    print "$monster -> \"$out\" (",
        ($out ne $monsters{$monster} ? "in" : ""), "correct)\n";
}

10

जावास्क्रिप्ट (ईएस 6), 915 ... 902 890 बाइट्स

w=>[..."aZM?o@;LWu&P?D@zF@W: @aT&@nCEfvQ&R&Tb'b@&p@:Srn @ahlrdpdT'TRv:HUYG@&fSfYdG&SGHL@Mh@G@gs';@CS@km@OsirA@q@njOZS@O@';HYqHE&DJavq&&aYaBmZMf;bv@EqHg@Z@;dm@M@?@rs@d@@oDAosDT@d@ZeBVrq@jFooD@VV&&BvMEDKiuiPC@&@DYrD&eD@D@@:AwccKZiF:DKLXAwdL@w&@@u'Hc@@q&;D:::WjdN@N@xD&eFh@gh@&Md?&Ye@@&h@hNN'Z&qtKEd@@HtH&@'@&@xd&dZsv@oo@FDyd@@&&@&@HS'Hw?DF@@@MPfDfi'AH&@@pkZkuMyZhFNN'P?d@u@NN&B@uo'fdi@?ke&"].find((_,i)=>!(s-=`GD4~#_@'R<1*~7C7RbZ6F'"Sa&!*1),#''3'.+B6(K$.l%9&!#0@51""~/+!gaW!/.(5'-@0'';!%C.&""!-.$16.2>(#&g!!O,#8A50O!)*(9b|Z4@7V).;*A*HWO(g1$/*-4&SL1I#K$#"3"#=e/'V~4'B(*,.3),$@D3)*76-"\\&kL7(-4#=7!!#+(B/B!-%!"_+!")+)0$1:E84!L191&)(255)!3O<,90NN6&;Q2'"bO=*h7.%1![<o!%M'G5/R.0$-J*%\\~6T?>)16""L&!X94T4"3$!2'^070Y2a"##)#"&n&(+1*&!-M""73R5%'y0~$-6<".MV?+1*ED>!B6b!)%&)8.+$&X0~Q'E%8&#%S/H.1<#>~!sU`.charCodeAt(i)-32),w=w.replace(/\W/g,1),s=parseInt((w+=w+w)[0]+w[2]+w[3]+w[6]+[...w].pop(),36)%8713)

प्रारूपित

नीचे कोड का एक स्वरूपित संस्करण है जिसमें ट्रैन्डकेटेड पेलोड डेटा है।

w => [..."aZM(…)"].find(
  (_, i) =>
    !(s -= `GD4(…)`.charCodeAt(i) - 32),
    w = w.replace(/\W/g, 1),
    s = parseInt((w += w + w)[0] + w[2] + w[3] + w[6] + [...w].pop(), 36) % 8713
)

यह काम किस प्रकार करता है

चरण 1

हम पहले राक्षस नाम को कम करते हैं:

  1. गैर-अल्फ़ान्यूमेरिक वर्ण (स्थान और डैश) को प्रतिस्थापित करना है 1
  2. यह सुनिश्चित करने के लिए कि हम अगले चरण के साथ काम करने के लिए पर्याप्त वर्ण हैं, इस स्ट्रिंग को 3 बार दोहरा रहे हैं।
  3. केवल 1, 3, 4, 7 वां और अंतिम अक्षर रखते हैं।

उदाहरण:

1.34..7..L
Demogorgon -> Dmorn
^ ^^  ^  ^

             1.34..7.L
orc mummy -> orc1mummy -> oc1my
             ^ ^^  ^ ^

        1.34..7....L
xorn -> xornxornxorn -> xrnrn
        ^ ^^  ^    ^

यह कुछ टकराव की ओर जाता है। उदाहरण के लिए, "Master Assassin"और "Master Kaen"दोनों के लिए कम कर रहे हैं "Mst1n"। सौभाग्य से, सभी टकराने वाले राक्षस नाम एक ही प्रतीक ( @इस मामले में) साझा करते हैं ।

चरण 2

फिर, हम इस 5-वर्ण स्ट्रिंग को दशमलव में परिवर्तित करने के लिए एक बेस 36 मात्रा के रूप में व्याख्या करते हैं (यह ऑपरेशन केस असंवेदनशील है) और हम एक मॉडुलो लागू करते हैं 8713, जिसे कुंजी की टक्कर-मुक्त सूची बनाने के लिए अनुभवजन्य रूप से चुना गया था।

उदाहरण:

Dmorn --[from base 36]--> 22893539 --[MOD 8713]--> 4488
oc1my --[from base 36]--> 40872778 --[MOD 8713]--> 95
xrnrn --[from base 36]--> 56717843 --[MOD 8713]--> 4926

चरण 3

सभी कुंजियाँ आरोही क्रम में क्रमबद्ध हैं:

[ 39, 75, 95, 192, 255, 287, 294, 344, 372, 389, 399, 516, 551, 574, 624, ..., 8635, 8688 ]

डेल्टा मूल्यों में परिवर्तित:

[ 39, 36, 20, 97, 63, 32, 7, 50, 28, 17, 10, 117, 35, 23, 50, ..., 83, 53 ]

और रेंज में ASCII वर्णों के रूप में एन्कोड किया गया [ 32, 126 ]। कुछ मध्यवर्ती डमी मान तब डाले जाते हैं जब दो लगातार कुंजियों के बीच का अंतर अधिकतम परिमाण परिमाण से अधिक हो।

अंत में, चाबियों की सूची को उसी क्रम में व्यवस्थित प्रतीकों की सूची में मैप किया जाता है।

परीक्षा


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

@ ais523 यह वही है जो मुझे फ़ायरफ़ॉक्स में परीक्षण करने के लिए मिलता है। मैं क्रोम के लिए (कम से कम) उसे ठीक करने की कोशिश करूंगा।
अरनौल

2
@ ais523 अब एफएफ, क्रोम और एज पर ठीक काम करना चाहिए। उसके लिए माफ़ करना।
अरनौलद

मुझे संख्याओं में परिवर्तित नामों से बिट्स निकालने का विचार था, लेकिन मैं स्पष्ट रूप से बहुत छोटा सोच रहा था। बधाई!
जोनास श्फ़र

8

जावा, 1130 बाइट्स

import java.util.*;class G{public static void main(String[]u){BitSet s=BitSet.valueOf(Base64.getDecoder().decode("D94FuoCWYEIhCTEgLWwRNU/CMB1cE7XBhxBsBCusihaASRg14IJpQMOIDJdFx3BOdDcmThdhILVkCgGsEmhII8UE+SB4kDYEEJzw7Tw54oUEQZe0AUHCACH6nAdqgiZgJhASCIPAEAzJBmuMIrBCHE8IiFjgKQwrN4/90B4QFaLBQBEwTArRBMLCLHQOUQs7ZXZ8B8uGC1EbeAMJBdihUDgCIwGUEKgEAu4W2SJkIAhzB1IQSHgNiEAwABQECV5BvAB7eizABXxFLEg5iMA3whhAFXOKHXEURB7UA7PQjgUK7sji8CmIC0FJsTB4tAMFgiARB3hOJATDsBkgGKnGmWIiIWBRwkMgToQJ49G8gTR4IqcB4vJwDBHSVBLQhpwHsUFipqBcWWaEsCBoGBF0AlNAE305HAfdU1AEbELBO0EERAfkmMkgZcEXDIa4MAp4HcENmYAMBB7UBbTwBqQPSMS9kVkEBMhCudAqBAKaR1CzZggDRw8WMAh0FQPEyKAsRAxzBwn0grwDMQMyQMdADRtFUBAsBQetRRBwcUgrlsQ1IkosBc9B6iBcjAkSDDKgEAQ1wgLIMEEwMkYB42ERBCdiEJMAt1wYSIAQkdIEI0UPNhALsDnRQ1AT/HQi1AyCEwiICOICpiAPlB8MwxnBPIk6JYaIgDy8NJHDsiAqzK0JAXpQPXgPLwJuEEbMTAGBYlQbDESvAXJAAQ=="));int i,j,k,c,d,h=u[0].hashCode(),a=(h&4092)>>2|(h>>5)&1024|(h>>7)&2048|(h>>9)&4096;char r='@';for(i=k=0;i<4297;i+=14){for(c=0,j=7;j>=0;j--)c+=c+(s.get(i+j)?1:0);if((k+=c)==a){for(d=0,j=13;j>=8;j--)d+=d+(s.get(i+j)?1:0);r=d<5?" &':;".charAt(d):(char)((d<31?60:66)+d);}}System.out.println(r);}}

Ungolfed:

import java.util.*;

class G {
    public static void main(String[] u) {
        BitSet s = BitSet.valueOf(Base64.getDecoder().decode(
                "D94FuoCWYEIhCTEgLWwRNU/CMB1cE7XBhxBsBCusihaASRg14IJpQMOIDJdFx3BOdDcmThdhILVkCgGsEmhII8UE+SB4kDYEEJzw7Tw54oUEQZe0AUHCACH6nAdqgiZgJhASCIPAEAzJBmuMIrBCHE8IiFjgKQwrN4/90B4QFaLBQBEwTArRBMLCLHQOUQs7ZXZ8B8uGC1EbeAMJBdihUDgCIwGUEKgEAu4W2SJkIAhzB1IQSHgNiEAwABQECV5BvAB7eizABXxFLEg5iMA3whhAFXOKHXEURB7UA7PQjgUK7sji8CmIC0FJsTB4tAMFgiARB3hOJATDsBkgGKnGmWIiIWBRwkMgToQJ49G8gTR4IqcB4vJwDBHSVBLQhpwHsUFipqBcWWaEsCBoGBF0AlNAE305HAfdU1AEbELBO0EERAfkmMkgZcEXDIa4MAp4HcENmYAMBB7UBbTwBqQPSMS9kVkEBMhCudAqBAKaR1CzZggDRw8WMAh0FQPEyKAsRAxzBwn0grwDMQMyQMdADRtFUBAsBQetRRBwcUgrlsQ1IkosBc9B6iBcjAkSDDKgEAQ1wgLIMEEwMkYB42ERBCdiEJMAt1wYSIAQkdIEI0UPNhALsDnRQ1AT/HQi1AyCEwiICOICpiAPlB8MwxnBPIk6JYaIgDy8NJHDsiAqzK0JAXpQPXgPLwJuEEbMTAGBYlQbDESvAXJAAQ=="));

        int i, j, k, c, d, h = u[0].hashCode(), 
            a = (h & 4092) >> 2 | (h >> 5) & 1024 | (h >> 7) & 2048 | (h >> 9) & 4096;
        char r = '@';
        for (i = 0, k = 0; i < 4297; i += 14) {
            for (c = 0, j = 7; j >= 0; j--)
                c += c + (s.get(i + j) ? 1 : 0);
            if ((k += c) == a) {
                for (d = 0, j = 13; j >= 8; j--)
                    d += d + (s.get(i + j) ? 1 : 0);
                r = d < 5 ? " &':;".charAt(d) : (char) ((d < 31 ? 60 : 66) + d);
            }
        }
        System.out.println(r);
    }
}

राक्षस नाम हैं:

  • जावा hashcodeविधि => 32 बिट्स का उपयोग करके हैशेड
  • मुखौटा 1001001000111111111100 => 13 बिट्स के साथ
  • सबसे छोटे से लेकर सबसे बड़े तक छांटे गए
  • फिर हम क्रमबद्ध सूची => 8 बिट के डेल्टा मान का उपयोग करते हैं

प्रदर्शन चरित्र 6 बिट्स पर एन्कोडेड है।

इसलिए प्रत्येक टपल (राक्षस का नाम, वर्ण) 14 बिट का उपयोग करता है। सभी ट्यूपल्स को एक बिटसेट और बेस 64 एन्कोडेड में सहेजा गया है।

मैं base64 एन्कोडिंग और बिटसेट ऑपरेशन के साथ बहुत सारे बाइट खो देता हूं :-)


आप इसे लंबोदर अभिव्यक्ति बनाकर आकार को कम कर सकते हैं ()->{...}:। सवाल अपने "स्पष्टीकरण" खंड में ऐसा कहता है।
ओलिवियर ग्रेगोइरे 21

5

गणितज्ञ, 1067 बाइट्स (मैक ओएस रोमन वर्ण एन्कोडिंग)

FromCharacterCode[Mod[Tr/@{c=ToCharacterCode@#,c^2},216,32],"MacintoshRoman"]/.Inner[Rule,";¤7«´3πœ(ú-UU=6z±'¥ÿ†tƒ|\¢KÛd§≤jSóKWÊ8‰Ñwiøì¡ÛhÓ\‡¨:–*~‚¬æº¢»‘¤Á^∫„·nLÒ¤b|$|ÇòCóÌÈS_Ñä.Ëí 5y«KΔË\Ãò™_E`J’ëΔñTV–N„'„Ÿà¥xpîH#-PP)ÈÊVQ©LrBt}∑WÉ∏dÿå„•Tz∑Âao¿rÃ^bbP¨}ëÖ◇1èÇ&d¢¤ái√,B}±BˆÍdA´íBtæÅ/m√yQ6,uãÊ≤/Î!ïøuΩÒÉ)ë“∕C$RY•ÍÍu£oÉÓå‚Ïl.·1‚40ÃÚ¨ÇÆÅccflÓ8Ï Gáç3EÑ¥fXñ¨Àìz~j÷–ñÓz0~ôWtñ}μÎ◇f||Dd\ ÙH﷿É∑Ì´|¿Ö_»RT8Ûª|Äqü‘&6Ãác›Yˆ¿ô5≈ënÚqΩåVä>∫æ∂p ¨jtöåoÌfløÏÏò§¤flÈ;À∑Ѥ·›9né∕<·ì∕ÿmŸ«Ì»j√üà‰÷“5ïä^Ûe◇kd‡“(Ïö71›iΟÁm„ÈïÒß„kÕπ°ÊÓÒçÓfˆ¨flÁ9k|¶ä∕l~Òød‹jZÏ2[kÎ√3ÛâìÓΔE]ıIÚ>{#ÁÖ‚Üâ;·?l^vàß‹‘jîÙÇÅÉú¥äärÆæ™∏Üi≈mØÂ’-%USÌâ’ı Ê›·Ëÿb‡ıÖ31nh™Δ$~%À0n-À´sflk∑p.o5vz}mè]ÎÅç©lt;Îu„ŸW„›ˆˆÍ﷿Ä*7m8‰πór,„Õш/”Ë∕ªß9±‡¶çÁ•âg˜fló)ÖÔ¡'wúæ0ñ„Kûr"~(a=StringPartition)~2,"AAA&&DH&&&&&D&KKKKH&o&WT&&soV&bEYLDD:DDwDwDDDD&q&WBDyNNPuDj&FPhYss:c'ScAd:LdR&dvhhMZhE;MZv&MZHaEHve'evCdeHgSe:b ZaBa;mMrsZH'pGGMZGGo'NNDPuDFPgxNNdd&Hohoi&ufMZ&Tv:i&'pJdf;AafkMkZk;fdkm'iqlLFd:wtf&i&LhqhHYCnq&:jOODMoZooYf';&SCuwcSQiabrBDFNNrpT'qR:&Ysr eFDZmSajEvH'H'&ifHqtTUBVVF&du&ESnTdrdDugddd'nrWqXDyFYz"~a~1,List]/.x_/;StringLength@x>1->"@"&

एक स्ट्रिंग को इनपुट के रूप में लेते हैं और एक चरित्र को वापस करते हैं। फ़ंक्शन का निम्न रूप है:

1  FromCharacterCode[
2    Mod[Tr/@{c=ToCharacterCode@#,c^2},216,32]
3    ,"MacintoshRoman"] /.
4  Inner[Rule,
5    GIANT_STRING_1 ~(a=StringPartition)~2,
6    GIANT_STRING_2 ~a~1,
7    List]
8  /. x_/;StringLength@x>1 -> "@" &

यहाँ GIANT_STRING_1 एक स्ट्रिंग है जिसमें मैक OS रोमन वर्ण एन्कोडिंग में 608 एक-बाइट वर्ण हैं (जिनमें से कोई भी 00-1F श्रेणी में नहीं हैं), जबकि GIANT_STRING_2 एक स्ट्रिंग है जिसमें 304 ASCII वर्ण हैं।

लाइन 2 हैश फ़ंक्शन शुरू करता है: यह इनपुट स्ट्रिंग को वर्ण कोडों की सूची में परिवर्तित करता है (क्योंकि वे सभी मुद्रण योग्य ASCII हैं) अप्रासंगिक, फिर उन वर्ण कोडों का योग और उनके वर्गों का योग, दोनों modul 216 और मजबूर करना 32 और 255 के बीच झूठ बोलने का जवाब। फिर 1 और 3 लाइनों में पूर्णांकों के जोड़े के आदेश दिए गए दो-वर्ण स्ट्रिंग्स में परिवर्तित होते हैं, जो कि हैश मूल्य है जो हम अंततः उपयोग करते हैं।

लाइन ५४ द्वि-चरित्र तार की सूची में GIANT_STRING_1 को बदल देता है; लाइन 6 एक एकल-वर्ण स्ट्रिंग्स की सूची में GIANT_STRING_2 को बदल देता है। फिर लाइनें 4 और 5 उन दो सूचियों को 304 प्रतिस्थापन नियमों के एक सेट में परिवर्तित करती हैं: यदि आप ऐसे और-ऐसे दो-वर्ण स्ट्रिंग देखते हैं, तो इसे ऐसे-और-एक-वर्ण स्ट्रिंग में बदल दें। अंत में, लाइन 8 किसी भी शेष दो-वर्ण स्ट्रिंग में बदल जाती है "@"

सूची में 71 राक्षस हैं जिनके प्रतीक हैं "@", और उन को हैशिंग के बिना संभाला जाता है (मैंने एक अन्य उत्तर पर ais523 द्वारा एक टिप्पणी से इस विचार को चुरा लिया)। यह सिर्फ इतना होता है कि अन्य 304 हैश मूल्य सभी अद्वितीय हैं! और इसलिए एल्गोरिथ्म में किसी अन्य संशोधन की आवश्यकता नहीं है। (यह एक भाग्यशाली विराम है , जिसमें अक्षरों के वर्णों की रकम और अक्षरों के समरूप होने के बाद से "human"मैप किए जाने की आवश्यकता है , जैसा कि उन कोडों के वर्गों के योग हैं - पूर्णांक के रूप में, यहां तक ​​कि modulo 216 भी नहीं!"@""human""shark"


3

पायथन, 2055 बाइट्स

def f(s):import re;m=re.search(s[-3:-1]+s[:2]+str(len(s))+"(.)","omgn5Gteen13vligr7glero10'akga12Sanso11aragi9rgoDe10&tiet5HleVl16Vanst11Hmpmo14nubge15brsho5uingo21Nbuin7&gobl11Dgobl12Duaja6faule10lkest7Eolic9Ttawa15EanKo14KanKo12Kviba12&gore10Dimim3iutzr5zingn10Ganhi10Herfr15emmel9Mlele13'guNa6Wkaja6dotco6docvr5&petr7tmaor10oarli6:nhpi7;moma11&icli4Linbl20Nolwa11Titwr6Wtlgi12ateru12Rbign12Zozgr9Plepa11'oufo9vingu23Norhi8onena10&tati5Hiosc8sinre18Nligo6obeki10aeaow7Yeyfl12elewo10'adsh5 anfr11Hapap3Ygrog4Obequ9ahopy6Steki6fgogr11Dgogr12Dpepi9Sngdi5dindw10hlegl11'imgr11Pbava11Bcero12phaOl8Tdoli10dcuwi15dargn14GotIx5Dinbl13Parwa4dpuhe14dtisa9&ilba14:liho9onyer6&euAs8&aupl14Cttle9qmmdw11Molbr10Fmism11mncPe10&mpwa11noror3oispy8caumo16Clest11'haUr8okekr6;bigi12ZbuBa9&gowh12Dbiko13Zbiet12Zmmgn11Molwe8dmowa11&icde8Lbiho6hdola9dleJu7&otMi18&ulum10Uenpi9&luho10ighye12ymamu5qorwh13ughbl11yylga8gKoKe12Knndj6&mmet11Magbl10Narsh5;osgh5 orxo4Xoltr5Tdoma8qopCy7Hceir12pgoba18Dorlo9wgoba16Dbidw12ZinFa6&goor13DeaAl5Aiuba14qloac9bkemo6Yniqu16QteDi8&aufo14Ckesh8Fetye4Yolro9ryema18hersh15eaggo11Nrase9ranig6:ghba12Winbr13Polwi11dgeti5fzoNa6&orga9emmko12Manfi8aorgn10Gatco6Alecl10'goye13Deabu7hinog9Oheli6Feoch9:ynly4fngte5ieeel12;rawe7ricch11caior11ocala9fguvi13Fangi9aangi5Hhepa7fdesa10:cuOr5&rswa8ubrco5Sorva12Vxaxa3xovlu12tbaba3Bilcr9:geAn5Aolwo4dviic9&tafi14Ecegl13pbugr8xorpu11wgoCh16Dicar9Laggu13Ndegi12shoAr6Aolla12kedce9sitma8&erti11qicma11Lbior10Zviho12&test12vbusu8&fofo3ddeca11srara9rolko6kmpwo10ntaea15Ellbl10jgosi13Daksn5Svibo10&tosk8Zicco10cvera5Bgoba15DatDe5&goba17Dpuwu6qkawe10dmmhu11Mdodo3dunhe10dtcsa9Yckge5:tefi11vsiqu6iloqu14bewne4:yoGe6&caho8fucwo9rorMo10oisje9;taai13Eardw5holye11Fordw10hlloc11jough5Zerfl14emila11mtedu11vthro5qteic10vtuLo11Hmmor9Mirva7Vbagi9Bolro10Tmako13kleir10'biel10Zmmgi11Mnema5ilego10'olre8Forbl13usiwa14Sroba6&agre8Nrohe6&orgr12ulefl11'ocja10JghYe8&aumi8HiuSc8sbihu12Zriki6Ayemi11horko11kolgr10Furle6ianfi10Hmigi11monpo4ullsp13jaiKo11Ktedi12Rapca15Yorog9Oylwi15geegi9;orba14worba16w");return m.group(1)if m else'@'

यहाँ मेरा परीक्षण हार्नेस है, यदि यह किसी और की मदद करता है।

MAPPING = {
    # as given in the original question
}
def validate_solution(f):
    for k, v in MAPPING.iteritems():
        vv = f(k)
        if vv != v:
            print 'FAIL: f(%s) = %s instead of %s' % (k, vv, v)
    print 'SUCCESS!'

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

वह है: जो मैं पाना चाहता था

def f(monster_name):
    small_string = f1(monster_name)
    integer_index = f2(small_string)
    symbol = "relatively_short_table"[integer_index]
    return symbol

लेकिन मैं केवल उतना ही पाने में कामयाब रहा

def f(monster_name):
    small_string = f1(monster_name)
    symbol = {relatively_large_dict}[small_string]
    return symbol

जहां मेरा तानाशाहीपूर्ण नज़रिया गोल्फ के लिए {relatively_large_dict}[small_string]व्यक्त किया जाता re.match(small_string+"(.)", "relatively_large_string")है।


2

जावास्क्रिप्ट (ईएस 6), 1178

n=>'@0uy1c8@@@@@@2cb7sj0sb5rhcm626435y6js6u651b1nj5jg85g2xj02l4wh31u2py2xl96h5fz6ys46tc7821p2e9c1o1td1cy834@2sq2c055iabn91f82vahc6ytagh5d363i@@@@@@@@@@@@@@@@@@@7hh2wf2nd1bu2d93cm0gu862@144819a6v2h44o41d4@@@@@@0c404806f3fa0z8@04c82o1vfac3@c10a3g08g@82e0lr7bf26p2dibcb11t9y19q6bbh4db7tr3592u2bof4913edawy84p1cr@bap1qzb1o033bt6@8d93v230t4240w9ahh8cy@09u0a60sd1qd@1n23ak1bt614bax0ro7sd57xagg22s1gj@@be0@74l01c28qcdi@1so83t0c068s@2jh7as7ddalq0vxag68pn6b9@0gabu71zp54m6997imb2047h@10s0zo0mv@aww6ixbqgag7@944@bza76b@1a053c2yn6101eh8en@4je6fq97t1py9f0@6co@b3k5my44p@4edb737t9@0tl@00rau75y369z5hk0ot@23d2wicb90uwb54a9l3gw9lv3z51nv@@@@@@@amy81e3kh9yc90e59d@6528z42ic@7uv6bm58t@3av0w004t05aavs3oq3040irawj0ov1n90213h89yn0vs@0mcc284fv6uyaxp@3242ok39h0jd06905v1ia@7zc9659bk@ax30ua0um0652sa65daqd@00z03d2ra1f95751xu@9x10676yz@72w33r24b63d@2d7@ats6f678u@bcg9uf6h6@1b60us2d17ygbxn72106t02g@adublf05q@8xu5wobqb1tc1c73cs7pj@87k3cj2xq6258l379y@0q42qy3vs3y70r9@06v2a9@ast4su12w0ko4y77dn@7oubr07ju1ct5qe81v@0d52kb66t4zj@93508c@af30kj@299'.replace(/@\w*/g,v=>~-v.search((100+h.toString(36)).slice(-3))%3?++i:r=String.fromCharCode(i),i=32,r='@',n.replace(/\w/g,c=>h=parseInt(c,36)^(h*3)&16383,h=0))&&r

कम गोल्फ वाला

n=>(
'@0uy1c8@@@@@@2cb7sj0sb5rhcm626435y6js6u651b1nj5jg85g2xj02l4wh31u2py2xl96h5fz6ys46tc7821p2e9c1o1td1cy834@2sq2c055iabn91f82vahc6ytagh5d363i@@@@@@@@@@@@@@@@@@@7hh2wf2nd1bu2d93cm0gu862@144819a6v2h44o41d4@@@@@@0c404806f3fa0z8@04c82o1vfac3@c10a3g08g@82e0lr7bf26p2dibcb11t9y19q6bbh4db7tr3592u2bof4913edawy84p1cr@bap1qzb1o033bt6@8d93v230t4240w9ahh8cy@09u0a60sd1qd@1n23ak1bt614bax0ro7sd57xagg22s1gj@@be0@74l01c28qcdi@1so83t0c068s@2jh7as7ddalq0vxag68pn6b9@0gabu71zp54m6997imb2047h@10s0zo0mv@aww6ixbqgag7@944@bza76b@1a053c2yn6101eh8en@4je6fq97t1py9f0@6co@b3k5my44p@4edb737t9@0tl@00rau75y369z5hk0ot@23d2wicb90uwb54a9l3gw9lv3z51nv@@@@@@@amy81e3kh9yc90e59d@6528z42ic@7uv6bm58t@3av0w004t05aavs3oq3040irawj0ov1n90213h89yn0vs@0mcc284fv6uyaxp@3242ok39h0jd06905v1ia@7zc9659bk@ax30ua0um0652sa65daqd@00z03d2ra1f95751xu@9x10676yz@72w33r24b63d@2d7@ats6f678u@bcg9uf6h6@1b60us2d17ygbxn72106t02g@adublf05q@8xu5wobqb1tc1c73cs7pj@87k3cj2xq6258l379y@0q42qy3vs3y70r9@06v2a9@ast4su12w0ko4y77dn@7oubr07ju1ct5qe81v@0d52kb66t4zj@93508c@af30kj@299'
.replace(/@\w*/g, v= > 
   (v.search((100 + h.toString(36)).slice(-3))-1) % 3  
     ? ++i : r = String.fromCharCode(i),
   i=32,
   r='@',
   n.replace(/\w/g,c => h=parseInt(c,36) ^ (h*3) & 16383,h=0)
)
&& r

परीक्षा

F=
n=>'@0uy1c8@@@@@@2cb7sj0sb5rhcm626435y6js6u651b1nj5jg85g2xj02l4wh31u2py2xl96h5fz6ys46tc7821p2e9c1o1td1cy834@2sq2c055iabn91f82vahc6ytagh5d363i@@@@@@@@@@@@@@@@@@@7hh2wf2nd1bu2d93cm0gu862@144819a6v2h44o41d4@@@@@@0c404806f3fa0z8@04c82o1vfac3@c10a3g08g@82e0lr7bf26p2dibcb11t9y19q6bbh4db7tr3592u2bof4913edawy84p1cr@bap1qzb1o033bt6@8d93v230t4240w9ahh8cy@09u0a60sd1qd@1n23ak1bt614bax0ro7sd57xagg22s1gj@@be0@74l01c28qcdi@1so83t0c068s@2jh7as7ddalq0vxag68pn6b9@0gabu71zp54m6997imb2047h@10s0zo0mv@aww6ixbqgag7@944@bza76b@1a053c2yn6101eh8en@4je6fq97t1py9f0@6co@b3k5my44p@4edb737t9@0tl@00rau75y369z5hk0ot@23d2wicb90uwb54a9l3gw9lv3z51nv@@@@@@@amy81e3kh9yc90e59d@6528z42ic@7uv6bm58t@3av0w004t05aavs3oq3040irawj0ov1n90213h89yn0vs@0mcc284fv6uyaxp@3242ok39h0jd06905v1ia@7zc9659bk@ax30ua0um0652sa65daqd@00z03d2ra1f95751xu@9x10676yz@72w33r24b63d@2d7@ats6f678u@bcg9uf6h6@1b60us2d17ygbxn72106t02g@adublf05q@8xu5wobqb1tc1c73cs7pj@87k3cj2xq6258l379y@0q42qy3vs3y70r9@06v2a9@ast4su12w0ko4y77dn@7oubr07ju1ct5qe81v@0d52kb66t4zj@93508c@af30kj@299'.replace(/@\w*/g,v=>~-v.search((100+h.toString(36)).slice(-3))%3?++i:r=String.fromCharCode(i),i=32,r='@',n.replace(/\w/g,c=>h=parseInt(c,36)^(h*3)&16383,h=0))&&r


monsters = {
  "Aleax": "A",
  "Angel": "A",
  "Arch Priest": "@",
  "Archon": "A",
  "Ashikaga Takauji": "@",
  "Asmodeus": "&",
  "Baalzebub": "&",
  "Chromatic Dragon": "D",
  "Croesus": "@",
  "Cyclops": "H",
  "Dark One": "@",
  "Death": "&",
  "Demogorgon": "&",
  "Dispater": "&",
  "Elvenking": "@",
  "Famine": "&",
  "Geryon": "&",
  "Grand Master": "@",
  "Green-elf": "@",
  "Grey-elf": "@",
  "Hippocrates": "@",
  "Ixoth": "D",
  "Juiblex": "&",
  "Keystone Kop": "K",
  "King Arthur": "@",
  "Kop Kaptain": "K",
  "Kop Lieutenant": "K",
  "Kop Sergeant": "K",
  "Lord Carnarvon": "@",
  "Lord Sato": "@",
  "Lord Surtur": "H",
  "Master Assassin": "@",
  "Master Kaen": "@",
  "Master of Thieves": "@",
  "Medusa": "@",
  "Minion of Huhetotl": "&",
  "Mordor orc": "o",
  "Nalzok": "&",
  "Nazgul": "W",
  "Neferet the Green": "@",
  "Norn": "@",
  "Olog-hai": "T",
  "Oracle": "@",
  "Orcus": "&",
  "Orion": "@",
  "Pelias": "@",
  "Pestilence": "&",
  "Scorpius": "s",
  "Shaman Karnov": "@",
  "Thoth Amon": "@",
  "Twoflower": "@",
  "Uruk-hai": "o",
  "Vlad the Impaler": "V",
  "Wizard of Yendor": "@",
  "Woodland-elf": "@",
  "Yeenoghu": "&",
  "abbot": "@",
  "acid blob": "b",
  "acolyte": "@",
  "air elemental": "E",
  "aligned priest": "@",
  "ape": "Y",
  "apprentice": "@",
  "arch-lich": "L",
  "archeologist": "@",
  "attendant": "@",
  "baby black dragon": "D",
  "baby blue dragon": "D",
  "baby crocodile": ":",
  "baby gray dragon": "D",
  "baby green dragon": "D",
  "baby long worm": "w",
  "baby orange dragon": "D",
  "baby purple worm": "w",
  "baby red dragon": "D",
  "baby silver dragon": "D",
  "baby white dragon": "D",
  "baby yellow dragon": "D",
  "balrog": "&",
  "baluchitherium": "q",
  "barbarian": "@",
  "barbed devil": "&",
  "barrow wight": "W",
  "bat": "B",
  "black dragon": "D",
  "black light": "y",
  "black naga hatchling": "N",
  "black naga": "N",
  "black pudding": "P",
  "black unicorn": "u",
  "blue dragon": "D",
  "blue jelly": "j",
  "bone devil": "&",
  "brown mold": "F",
  "brown pudding": "P",
  "bugbear": "h",
  "captain": "@",
  "carnivorous ape": "Y",
  "cave spider": "s",
  "caveman": "@",
  "cavewoman": "@",
  "centipede": "s",
  "chameleon": ":",
  "chickatrice": "c",
  "chieftain": "@",
  "clay golem": "'",
  "cobra": "S",
  "cockatrice": "c",
  "couatl": "A",
  "coyote": "d",
  "crocodile": ":",
  "demilich": "L",
  "dingo": "d",
  "disenchanter": "R",
  "djinni": "&",
  "dog": "d",
  "doppelganger": "@",
  "dust vortex": "v",
  "dwarf king": "h",
  "dwarf lord": "h",
  "dwarf mummy": "M",
  "dwarf zombie": "Z",
  "dwarf": "h",
  "earth elemental": "E",
  "electric eel": ";",
  "elf mummy": "M",
  "elf zombie": "Z",
  "elf": "@",
  "elf-lord": "@",
  "energy vortex": "v",
  "erinys": "&",
  "ettin mummy": "M",
  "ettin zombie": "Z",
  "ettin": "H",
  "fire ant": "a",
  "fire elemental": "E",
  "fire giant": "H",
  "fire vortex": "v",
  "flaming sphere": "e",
  "flesh golem": "'",
  "floating eye": "e",
  "fog cloud": "v",
  "forest centaur": "C",
  "fox": "d",
  "freezing sphere": "e",
  "frost giant": "H",
  "gargoyle": "g",
  "garter snake": "S",
  "gas spore": "e",
  "gecko": ":",
  "gelatinous cube": "b",
  "ghost": " ",
  "ghoul": "Z",
  "giant ant": "a",
  "giant bat": "B",
  "giant beetle": "a",
  "giant eel": ";",
  "giant mimic": "m",
  "giant mummy": "M",
  "giant rat": "r",
  "giant spider": "s",
  "giant zombie": "Z",
  "giant": "H",
  "glass golem": "'",
  "glass piercer": "p",
  "gnome king": "G",
  "gnome lord": "G",
  "gnome mummy": "M",
  "gnome zombie": "Z",
  "gnome": "G",
  "gnomish wizard": "G",
  "goblin": "o",
  "gold golem": "'",
  "golden naga hatchling": "N",
  "golden naga": "N",
  "gray dragon": "D",
  "gray ooze": "P",
  "gray unicorn": "u",
  "green dragon": "D",
  "green mold": "F",
  "green slime": "P",
  "gremlin": "g",
  "grid bug": "x",
  "guard": "@",
  "guardian naga hatchling": "N",
  "guardian naga": "N",
  "guide": "@",
  "healer": "@",
  "hell hound pup": "d",
  "hell hound": "d",
  "hezrou": "&",
  "high priest": "@",
  "hill giant": "H",
  "hill orc": "o",
  "hobbit": "h",
  "hobgoblin": "o",
  "homunculus": "i",
  "horned devil": "&",
  "horse": "u",
  "housecat": "f",
  "human mummy": "M",
  "human zombie": "Z",
  "human": "@",
  "hunter": "@",
  "ice devil": "&",
  "ice troll": "T",
  "ice vortex": "v",
  "iguana": ":",
  "imp": "i",
  "incubus": "&",
  "iron golem": "'",
  "iron piercer": "p",
  "jabberwock": "J",
  "jackal": "d",
  "jaguar": "f",
  "jellyfish": ";",
  "ki-rin": "A",
  "killer bee": "a",
  "kitten": "f",
  "knight": "@",
  "kobold lord": "k",
  "kobold mummy": "M",
  "kobold shaman": "k",
  "kobold zombie": "Z",
  "kobold": "k",
  "kraken": ";",
  "large cat": "f",
  "large dog": "d",
  "large kobold": "k",
  "large mimic": "m",
  "leather golem": "'",
  "lemure": "i",
  "leocrotta": "q",
  "leprechaun": "l",
  "lich": "L",
  "lichen": "F",
  "lieutenant": "@",
  "little dog": "d",
  "lizard": ":",
  "long worm": "w",
  "lurker above": "t",
  "lynx": "f",
  "mail daemon": "&",
  "manes": "i",
  "marilith": "&",
  "master lich": "L",
  "master mind flayer": "h",
  "mastodon": "q",
  "mind flayer": "h",
  "minotaur": "H",
  "monk": "@",
  "monkey": "Y",
  "mountain centaur": "C",
  "mountain nymph": "n",
  "mumak": "q",
  "nalfeshnee": "&",
  "neanderthal": "@",
  "newt": ":",
  "ninja": "@",
  "nurse": "@",
  "ochre jelly": "j",
  "ogre king": "O",
  "ogre lord": "O",
  "ogre": "O",
  "orange dragon": "D",
  "orc mummy": "M",
  "orc shaman": "o",
  "orc zombie": "Z",
  "orc": "o",
  "orc-captain": "o",
  "owlbear": "Y",
  "page": "@",
  "panther": "f",
  "paper golem": "'",
  "piranha": ";",
  "pit fiend": "&",
  "pit viper": "S",
  "plains centaur": "C",
  "pony": "u",
  "priest": "@",
  "priestess": "@",
  "prisoner": "@",
  "purple worm": "w",
  "pyrolisk": "c",
  "python": "S",
  "quantum mechanic": "Q",
  "quasit": "i",
  "queen bee": "a",
  "quivering blob": "b",
  "rabid rat": "r",
  "ranger": "@",
  "raven": "B",
  "red dragon": "D",
  "red mold": "F",
  "red naga hatchling": "N",
  "red naga": "N",
  "rock mole": "r",
  "rock piercer": "p",
  "rock troll": "T",
  "rogue": "@",
  "rope golem": "'",
  "roshi": "@",
  "rothe": "q",
  "rust monster": "R",
  "salamander": ":",
  "samurai": "@",
  "sandestin": "&",
  "sasquatch": "Y",
  "scorpion": "s",
  "sergeant": "@",
  "sewer rat": "r",
  "shade": " ",
  "shark": ";",
  "shocking sphere": "e",
  "shopkeeper": "@",
  "shrieker": "F",
  "silver dragon": "D",
  "skeleton": "Z",
  "small mimic": "m",
  "snake": "S",
  "soldier ant": "a",
  "soldier": "@",
  "spotted jelly": "j",
  "stalker": "E",
  "steam vortex": "v",
  "stone giant": "H",
  "stone golem": "'",
  "storm giant": "H",
  "straw golem": "'",
  "student": "@",
  "succubus": "&",
  "tengu": "i",
  "thug": "@",
  "tiger": "f",
  "titan": "H",
  "titanothere": "q",
  "tourist": "@",
  "trapper": "t",
  "troll": "T",
  "umber hulk": "U",
  "valkyrie": "@",
  "vampire bat": "B",
  "vampire lord": "V",
  "vampire": "V",
  "violet fungus": "F",
  "vrock": "&",
  "warg": "d",
  "warhorse": "u",
  "warrior": "@",
  "watch captain": "@",
  "watchman": "@",
  "water demon": "&",
  "water elemental": "E",
  "water moccasin": "S",
  "water nymph": "n",
  "water troll": "T",
  "werejackal": "d",
  "wererat": "r",
  "werewolf": "d",
  "white dragon": "D",
  "white unicorn": "u",
  "winged gargoyle": "g",
  "winter wolf cub": "d",
  "winter wolf": "d",
  "wizard": "@",
  "wolf": "d",
  "wood golem": "'",
  "wood nymph": "n",
  "woodchuck": "r",
  "wraith": "W",
  "wumpus": "q",
  "xan": "x",
  "xorn": "X",
  "yellow dragon": "D",
  "yellow light": "y",
  "yellow mold": "F",
  "yeti": "Y",
  "zruty": "z"
}
err = ok = 0

for(name in monsters) {
  code = monsters[name]
  result = F(name)
  if (result != code)
    console.log('ERROR',++err, name, result, code)
  else
    ++ok
}
console.log('Errors',err,'OK', ok)


2

जावास्क्रिप्ट, 1185 बाइट्स

s=>{h=0;for(i of s)h=(h<<5)-h+i.charCodeAt()|0;for(v of "Aqgh201etxitsxy0_&ctpzfekt09j36uafamqw46mz1qcxvnnoego4212nxfivutt09qyac4td1ayiotfh3dvub5fggzjqa58h37bnva3dzy_D9wlywkgkifldlp6t46v97basg905f8wadwt0w49q0gk9c8edz9e33uj6esjl_Hkkt54kr0qdlxs6hxdxxyegrdzcmz8ymvg_Ki0enu0ct1shv_o193ve2y3tpa71xu3pud405o7_We09jfsayx_Tw2gk0spoqab5c9k_s7timco3yh674rp1_Vppq2k9t1q_b3mo3tac13_E0r50a7vi5a0kgim_Y2omnjbkq59mw5njf5t_Lu9z2bj6w2128_:n0gngsocqeuh5czhyiedwd3a_w9lf1hv1rra7r_qmckg7rbhlldbvros4f44h_B32t12yzdci83_yjkb3va_Nt2cbaqd46toc29anic1qq3es_P3mkmtv2l4j8r_ukjb44lwm5vkaz5hwkh_j3oo7uj9ip_Fzuk8mh1rpfw7obl6s9fsq_hzmwz3f7kdhiaj4enlxha1_c0q0yu8tnf_'nf7c1sks8rzgxhw83vjq0s76xhrvppbgn_Slr90h5su3zokncwi2m_doi5t2p4vw6dryycyhtl6eujb1ta26752ta7hr19d9vceq_Rqk8tsy_vuxwglitt4u25zfhj5q_M4j7tjk9cryvqn8101u5h646p_Ztzwr09t8ckxx3hbsl6r7dqv7qxmnwt_;u7r3e9trqqkmdj5tlx_apoj0ngpcqy6r7t8gw9_e2wtyw9oyve8uxlf_C8tpo3hlb3_gxji2n2nl4_ kwft9p_maxcdzat5e_rcy28c360mmndp8ksxh_pegqkkuur3_Gh6f8pheo0nn2_xu6yjdx_iz538jwkbwuh4ge7ymj_f3eytt6khltgxj13itedbz_Jlgk_knskybpe8n69a_llnv_tuxgkxc_nod5ob3cft_Oij0a222q3_Q6af_Uc5x_Xzjn_z6iq".split`_`)if(~v.slice(1).match(/.../g).indexOf(h.toString(36).slice(-3)))return v[0];return"@"}

यहाँ पाए गए जावास्क्रिप्ट स्ट्रिंग हैश के एक गोल्फ संस्करण का उपयोग करता है। तालिका में संग्रहीत वास्तविक हैश (वह लंबी स्ट्रिंग) उस विधि द्वारा उत्पादित हैश का पूर्ण मूल्य लेता है, इसे बेस -36 में परिवर्तित करता है, और सभी लेकिन कम से कम तीन महत्वपूर्ण अंकों को गिराता है।


1
जहाँ तक मैं बता सकता हूँ, आप {पहला चरित्र, अंतिम चरित्र, लम्बाई} हैशिंग कर रहे हैं, तो एक बड़े लुकअप टेबल का उपयोग कर रहे हैं? यह समझ में आता है, लेकिन मुझे लगता है कि आपके द्वारा किए जाने वाले कुछ सुधार हो सकते हैं: तालिका में कुछ डुप्लिकेट प्रविष्टियाँ हैं, और आप @तालिका से प्रविष्टियों को हटाकर और @इनपुट के लिए डिफ़ॉल्ट होने पर बहुत अधिक स्थान बचा सकते हैं नहीं मिला है।

2
cavewomanऔर chameleonएक ही पहले चार, पिछले चार और लंबाई है, कि एक समस्या हो सकती है?
अरनौद

1
split("_")बन सकता है split बैकटिक _ बैकटिक
user2428118

@SuperChafouin फिक्स्ड।
SuperJedi224

1
@ SuperJedi224 अन्य हैं: Cyclopsऔर Croesus, baluchitheriumऔर baby long worm, crocodileऔर centipede, और 24 और
अरनौद

1

पायथन 3, 1915 1900 बाइट्स

बदलाव का:

  • चरित्र के बजाय ASCII कोड के साथ काम करें और आउटपुट करें (सहेजे गए 15 बाइट्स)

पहले कमांड लाइन तर्क के रूप में राक्षस नाम को पास करें, stdout पर चरित्र प्राप्त करें।

import sys
D=b'`"\x08\x04\x02&@Yx\xf6\x90a\x00Z\x00\x00c\x00X\x00\x00f\x00z\x00\x00hS\x12\x06\t@PSTft?z\x0fnK\nH\x87\xa2ig\t\t\x12 &;@FZkoq\x05\xfc~?\x1b\x80\xc2,z\r\xf3Y\x141\x9cS\x10\x80jU\x06\x08\t&;@BKpqr\x9f\xbe\xbb\xf9O\xcde\x03!kK\x11\x07\x07&:@WYsu\x1boDv\xc9i\x90lS$\x06\r@Sdirw\x1f\x1d\x198\xb3\xb2\x91\x0fm\xa5\x03A@mB#\x07\x07@GPWdiv\x7f;n\xb3Bk\xa5ng\x07\x0c\x16&@EHSVcdfqru\x01\xfen\x83q\xd8\xf3\x1c.\xe5\xac^\x87\t\xaaT\xd4D\x9c\xe1*Io;\x03\x05\x06@desu\x01\xf7\x95R0\x88pc \x08\n:@KMNknq\xfd\xfe\ru\xb2z\xea\\\x9b\x05qC\x08\x07\x06&@AGOfhy\xe2\xbbA\xf2ArS\x1e\x08\x08&@JVYdfi_\x1c\xd8/k\x89\xa8\xe0sw\x08\x0b\x1c&;@Kdfhijou\t\xe0[# \\\x9a\xd3F(L\xfapM\tp\xa8t\xccp\x8d\x11e+\x05\x0c\x8a\x08t+)\x04\x02@PQT\xf2\x94uG\x1c\x06\t&@Uilq\x0f\ryl\xc4`\xa5\x10\x90v\x85\r\x0e$&:@FKLNORSWYry\x9f\x97\xf8\xae\xb8\xdf\xdd\xc1\xcdl\xb2\xc9L|\xbb;\x92\xb8j\xb0\xa99\xdd\x9c\xb8\xd0\x8bh\x95\x88T\xb3;1\xb6\x0bwb\x06\x0c\x11&:;@DGHOVhkm\x02\xfe\x8fO{\xd9u\xac&\xd7\x90\x9fe\xc0\xf44GxW\x07\x07\x0bADHScdv?>\xdd<:\xb7s.\x8cI\x07yR\x07\x07\t&:@bcht;Zx\x16sO\x8d\xab\xc3ze\x0b\x08\x14&@ABCaqs\x01}\xbe=\x15\xc6\xcdL\xa1\xc8\x9e.\xf7\x02\xc1Xq4\x99\t{G\x16\x06\t@Faefg\x1f\x9bU$2P`\xa8\x80|G\x15\x06\x07&\';@Go\x1c1\\\xa7*\x0bS}s\x06\n" &@AHLYZdh\xf6\x1e\t\xb93N2\xc27\xd6\xd8\xd8*\xe5L\xa3\xa4f\x860A\xfa:7.\xdd\x9b)\xb80\x85\xc4\xb4\x83~W\x0e\x07\r&:@ERbd>\x1b\xda\x15\xd4\x92\x0eM\xacJH\x04c\x7fG\x00\x06\x08:@dghx\x1f\xbc\xf4Z\xa1%\xd3C'
R=range
N=sys.argv[1].lower()
B=0
for c in N:B|=ord(c)&0x7f;B<<=7
B%=2**62-1
P=N.split()
F=ord(P[-1][0])^(ord(P[-1][1])>>2)
while D:
 f=D[0];ik,j,h,n=D[1:5];i=ik>>4;k=ik&15;D=D[5:];c=D[:h];m=D[h:h+n];m=int.from_bytes(m,"big");s=1;C=j;b=(h-1).bit_length()
 for x in R(i-1):s<<=k;s|=1
 s<<=j;z=(B&s)>>j;x=0;u=1
 for y in R(i):x<<=1;x|=bool(z&u);u<<=k
 if f!=F:D=D[h+n:];continue
 while m:
  if m&(2**i-1)==x:m>>=i;C=c[m&(2**b-1)];break
  m>>=b+i
 break
print(C)

जब मैंने प्रश्न पढ़ा, तो मुझे लगा कि "मुझे इसे संपीड़ित करने की आवश्यकता है"। पहला कदम सभी नामों को कम करना था।

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

 'd' (37) => & @ D L R d h
 'g' (31) =>   & ' : @ G H Z g o
 's' (30) =>   & : ; @ E F H K P S Y Z e k o s
 'm' (28) => & @ F H M Q R S Y i m q r
 'c' (24) => : @ A C H S b c d f s v
 'p' (20) => & ; @ P S c d f p u
 'w' (20) => @ G W d q r u w
 'a' (19) => & @ A L Y a t
 'h' (17) => & @ N U d f h i o u
 'l' (17) => : @ F G K L O V f h i k l q y
 'n' (15) => & : @ N W n
 't' (14) => @ H T f i q t
 'b' (14) => & @ B a b h q x
 'k' (13) => ; @ A G K O f h k
 'e' (12) => & ; @ E H e
 'o' (12) => & @ O P T Y o
 'z' ( 9) => Z z
 'v' ( 9) => & @ S V v
 'r' ( 8) => @ B q r
 'j' ( 8) => & ; J d f j
 'f' ( 6) => & F d h
 'i' ( 5) => & : D V i
 'u' ( 4) => o u
 'y' ( 3) => & @ Y
 'x' ( 2) => X x
 'q' ( 1) => i

स्प्रेडआउट को और बेहतर बनाने के लिए, मैंने XOR-ing द्वारा अंतिम शब्द के दूसरे वर्ण को दाएं में बदल दिया, बिट्स में दाईं ओर शिफ्ट कर दिया, पहले चरित्र में (आइए इस निर्माण को कहते हैं first_key):

 '}' (29) =>   & @ A H L Y Z d h
 'v' (25) => & : @ F K L N O R S W Y r y
 'x' (25) => A D H S c d v
 's' (21) => & ; @ K d f h i j o u
 'p' (21) => : @ K M N k n q
 'z' (19) => & @ A B C a q s
 'n' (19) => & @ E H S V c d f q r u
 '|' (18) => & ' ; @ G o
 'l' (17) => @ S d i r w
 '~' (16) => & : @ E R b d
 '{' (15) => @ F a e f g
 'w' (14) => & : ; @ D G H O V h k m
 'i' (14) =>   & ; @ F Z k o q
 'j' (13) => & ; @ B K p q r
 'u' (12) => & @ U i l q
 'm' (12) => @ G P W d i v
 '\x7f' (11) => : @ d g h x
 'o' (11) => @ d e s u
 'h' (11) => @ P S T f t
 'y' (10) => & : @ b c h t
 'r' ( 9) => & @ J V Y d f i
 'k' ( 9) => & : @ W Y s u
 'a' ( 8) => Z
 'q' ( 7) => & @ A G O f h
 't' ( 6) => @ P Q T
 '`' ( 4) => & @ Y x
 'c' ( 1) => X
 'f' ( 1) => z

जैसा कि आप देख सकते हैं, यह हमें नौ नाम देता है जो विशिष्ट रूप से केवल उस जानकारी के साथ मैप किए जा सकते हैं। अच्छा!

अब मुझे शेष मानचित्रण खोजने की आवश्यकता थी। इसके लिए मैंने पूर्ण (निम्न-आवरण) नाम को पूर्णांक में परिवर्तित करके शुरू किया:

def name_to_int(name):
    bits = 0
    for c in name:
        bits |= ord(c) & 0x7f
        bits <<= 7
    return bits

यह केवल एक विशाल पूर्णांक में नामों के 7bit ASCII मूल्यों को एक साथ समेट रहा है। हम इस मॉडुलो 4611686018427387903(2 the-1) को अगले चरणों के लिए लेते हैं।

अब मैं एक बिटमास्क खोजने की कोशिश करता हूं जो एक पूर्णांक बनाता है जो बदले में अलग-अलग राक्षस पात्रों को अलग करता है। बिट मास्क समान रूप से फैले हुए (जैसे 101010101या 1000100010001) होते हैं और बिट्स ( i>=1) और प्रसार ( k>=1) की संख्या से समरूप होते हैं । इसके अलावा, मास्क को 32*iबिट तक स्थानांतरित कर दिया जाता है। वे पूर्णांक नाम के साथ AND-ed हैं और परिणामस्वरूप पूर्णांक का उपयोग मैपिंग में एक कुंजी के रूप में किया जाता है। सबसे अच्छा (रन करके i*number_of_mapping_entries) संघर्ष-मुक्त मानचित्रण का उपयोग किया जाता है।

मास्क और पूर्णांक नाम से प्राप्त पूर्णांक jबिट्स द्वारा वापस स्थानांतरित कर दिए जाते हैं और उनके शून्य से छीन लिए जाते हैं (हम स्टोर करते हैं i, kऔर jमैपिंग के साथ उस पुनर्निर्माण में सक्षम होने के लिए), जिससे बहुत सारी जगह बचती है।

इसलिए अब हमारे पास दो-स्तरीय मानचित्रण है: first_keyहैशमैप से, और हैशमैप का पूरा नाम राक्षस चार्ट में विशिष्ट रूप से है। हमें किसी तरह इसे स्टोर करने की जरूरत है। शीर्ष-स्तरीय मानचित्रण की प्रत्येक प्रविष्टि इस तरह दिखाई देती है:

Row = struct.Struct(
    ">"
    "B"  # first word char
    "B"  # number of bits (i) and bit spacing (k)
    "B"  # shift (j) or character to map to if i = 0
    "B"  # number of monster characters
    "B"  # map entry bytes
)

राक्षस पात्रों और दूसरे स्तर की मैपिंग के बाद।

दूसरे स्तर की मैपिंग को एक बड़े पूर्णांक में पैक करके इसे बाइट्स में परिवर्तित करके क्रमबद्ध किया जाता है। प्रत्येक मान और कुंजी को लगातार पूर्णांक में स्थानांतरित किया जाता है, जो मैपिंग को पुनर्निर्माण योग्य बनाता है (प्रति कुंजी / मान बिट्स की संख्या वर्णों की संख्या से और i, दोनों पंक्ति प्रविष्टि में संग्रहीत है)।

यदि किसी प्रविष्टि में नक्शे के लिए केवल एक ही संभव राक्षस चरित्र है, iशून्य है, वर्णों की संख्या और मानचित्रण भी शून्य बाइट्स हैं। चरित्र को संग्रहीत किया जाता है जहां jसामान्य रूप से संग्रहीत किया जाएगा।

पूरा डेटा आकार में 651 बाइट्स है, जिसे 1426 बाइट्स के रूप में अजगर बाइट स्ट्रिंग के रूप में क्रमबद्ध किया गया है।

डिकोडिंग कार्यक्रम अनिवार्य रूप से इसे दूसरे तरीके से करता है: पहले यह first_keyइसी प्रविष्टि के लिए डेटा को खोजता है और खोजता है। फिर यह नाम के हैश की गणना करता है और इसी प्रविष्टि के लिए हैशमैप के माध्यम से खोज करता है।

अपुष्ट विकोडक

#!/usr/bin/python3
import sys
import math

data = b'`"\x08\x04\x02&@Yx\xf6\x90a\x00Z\x00\x00c\x00X\x00\x00f\x00z\x00\x00hS\x12\x06\t@PSTft?z\x0fnK\nH\x87\xa2ig\t\t\x12 &;@FZkoq\x05\xfc~?\x1b\x80\xc2,z\r\xf3Y\x141\x9cS\x10\x80jU\x06\x08\t&;@BKpqr\x9f\xbe\xbb\xf9O\xcde\x03!kK\x11\x07\x07&:@WYsu\x1boDv\xc9i\x90lS$\x06\r@Sdirw\x1f\x1d\x198\xb3\xb2\x91\x0fm\xa5\x03A@mB#\x07\x07@GPWdiv\x7f;n\xb3Bk\xa5ng\x07\x0c\x16&@EHSVcdfqru\x01\xfen\x83q\xd8\xf3\x1c.\xe5\xac^\x87\t\xaaT\xd4D\x9c\xe1*Io;\x03\x05\x06@desu\x01\xf7\x95R0\x88pc \x08\n:@KMNknq\xfd\xfe\ru\xb2z\xea\\\x9b\x05qC\x08\x07\x06&@AGOfhy\xe2\xbbA\xf2ArS\x1e\x08\x08&@JVYdfi_\x1c\xd8/k\x89\xa8\xe0sw\x08\x0b\x1c&;@Kdfhijou\t\xe0[# \\\x9a\xd3F(L\xfapM\tp\xa8t\xccp\x8d\x11e+\x05\x0c\x8a\x08t+)\x04\x02@PQT\xf2\x94uG\x1c\x06\t&@Uilq\x0f\ryl\xc4`\xa5\x10\x90v\x85\r\x0e$&:@FKLNORSWYry\x9f\x97\xf8\xae\xb8\xdf\xdd\xc1\xcdl\xb2\xc9L|\xbb;\x92\xb8j\xb0\xa99\xdd\x9c\xb8\xd0\x8bh\x95\x88T\xb3;1\xb6\x0bwb\x06\x0c\x11&:;@DGHOVhkm\x02\xfe\x8fO{\xd9u\xac&\xd7\x90\x9fe\xc0\xf44GxW\x07\x07\x0bADHScdv?>\xdd<:\xb7s.\x8cI\x07yR\x07\x07\t&:@bcht;Zx\x16sO\x8d\xab\xc3ze\x0b\x08\x14&@ABCaqs\x01}\xbe=\x15\xc6\xcdL\xa1\xc8\x9e.\xf7\x02\xc1Xq4\x99\t{G\x16\x06\t@Faefg\x1f\x9bU$2P`\xa8\x80|G\x15\x06\x07&\';@Go\x1c1\\\xa7*\x0bS}s\x06\n" &@AHLYZdh\xf6\x1e\t\xb93N2\xc27\xd6\xd8\xd8*\xe5L\xa3\xa4f\x860A\xfa:7.\xdd\x9b)\xb80\x85\xc4\xb4\x83~W\x0e\x07\r&:@ERbd>\x1b\xda\x15\xd4\x92\x0eM\xacJH\x04c\x7fG\x00\x06\x08:@dghx\x1f\xbc\xf4Z\xa1%\xd3C'


def name_to_int(name):
    bits = 0
    for c in name:
        bits |= ord(c) & 0x7f
        bits <<= 7
    return bits


def make_mask(nbits, k):
    mask = 1
    for i in range(nbits-1):
        mask <<= k
        mask |= 1
    return mask


def collapse_mask(value, nbits, k):
    bits = 0
    shift = 0
    for i in range(nbits):
        bits <<= 1
        bits |= bool(value & (1<<shift))
        shift += k
    return bits


name = sys.argv[1].casefold()
last_word = name.split()[-1]
last_word_char = chr(ord(last_word[0]) ^ (ord(last_word[1]) >> 2))
while data:
    first_char = chr(data[0])
    ik, j, nchars, nbytes = data[1:5]

    i = ik >> 4
    k = ik & 15

    data = data[5:]
    if first_char != last_word_char:
        # skip this entry
        data = data[nchars+nbytes:]
        continue

    chars, mapping = data[:nchars], data[nchars:nchars+nbytes]
    result = j
    if i == 0:
        break

    mapping = int.from_bytes(mapping, "big")

    name_bits = name_to_int(name) % (2**62-1)
    mask = make_mask(i, k) << j
    key = collapse_mask((name_bits & mask) >> j, i, k)
    bits_per_key = i
    key_mask = 2**(bits_per_key)-1
    bits_per_value = math.ceil(math.log(len(chars), 2))
    value_mask = 2**(bits_per_value)-1
    while mapping:
        if mapping & key_mask == key:
            mapping >>= bits_per_key
            result = chars[mapping & value_mask]
            break
        mapping >>= bits_per_value+bits_per_key

    break
print(chr(result))

विश्लेषण उपकरण

यह वह उपकरण है जिसे मैंने बनाया है और डेटा उत्पन्न करने के लिए उपयोग किया है - अपने जोखिम पर पढ़ें:

#!/usr/bin/python3
import base64
import collections
import math
import json
import struct
import zlib

data = json.load(open("data.json"))

reverse_pseudomap = {}
forward_pseudomap = {}
forward_info = {}
reverse_fullmap = {}
hits = collections.Counter()
monster_char_hitmap = collections.Counter()

for name, char in data.items():
    name = name.casefold()
    parts = name.split()
    monster_char_hitmap[char] += 1

    # if len(parts) > 1:
    #     key = first_char + parts[0][0]
    # else:
    #     key = first_char + last_part[1]

    key = chr(ord(parts[-1][0]) ^ (ord(parts[-1][1]) >> 2))
    # key = parts[-1][0]

    hits[key] += 1
    reverse_pseudomap.setdefault(char, set()).add(key)
    forward_pseudomap.setdefault(key, set()).add(char)
    forward_info.setdefault(key, {})[name] = char
    reverse_fullmap.setdefault(char, set()).add(name)


for char, hit_count in sorted(hits.items(), key=lambda x: x[1], reverse=True):
    monsters = forward_pseudomap[char]
    print(" {!r} ({:2d}) => {}".format(
        char,
        hit_count,
        " ".join(sorted(monsters))
    ))


def make_mask(nbits, k):
    mask = 1
    for i in range(nbits-1):
        mask <<= k
        mask |= 1
    return mask


def collapse_mask(value, nbits, k):
    bits = 0
    shift = 0
    for i in range(nbits):
        bits <<= 1
        bits |= bool(value & (1<<shift))
        shift += k
    return bits


def expand_mask(value, nbits, k):
    bits = 0
    for i in range(nbits):
        bits <<= k
        bits |= value & 1
        value >>= 1
    return bits


assert collapse_mask(expand_mask(0b110110, 6, 3), 6, 3)
assert expand_mask(collapse_mask(0b1010101, 7, 3), 7, 3)


def name_to_int(name):
    # mapped_name = "".join({"-": "3", " ": "4"}.get(c, c) for c in name)
    # if len(mapped_name) % 8 != 0:
    #     if len(mapped_name) % 2 == 0:
    #         mapped_name += "7"
    #     mapped_name = mapped_name + "="*(8 - (len(mapped_name) % 8))
    # print(mapped_name)
    # return base64.b32decode(
    #     mapped_name,
    #     casefold=True,
    # )

    bits = 0
    for c in name:
        bits |= ord(c) & 0x7f
        bits <<= 7
    return bits


compressed_maps = {}
max_bit_size = 0
nmapentries = 0


for first_char, monsters in sorted(forward_info.items()):
    monster_chars = forward_pseudomap[first_char]
    print("trying to find classifier for {!r}".format(first_char))
    print("  {} monsters with {} symbols".format(
        len(monsters),
        len(monster_chars))
    )
    bits = math.log(len(monster_chars), 2)
    print("  {:.2f} bits of clever entropy needed".format(
        bits
    ))

    bits = math.ceil(bits)

    int_monsters = {
        name_to_int(name): char
        for name, char in monsters.items()
    }

    reverse_map = {}
    for name, char in int_monsters.items():
        reverse_map.setdefault(char, set()).add(name)

    solution = None
    solution_score = float("inf")

    if bits == 0:
        char = ord(list(int_monsters.values())[0][0])
        solution = 0, 0, char, {}

    for i in range(bits, 3*bits+1):
        print("  trying to find solution with {} bits".format(i))
        for k in [2, 3, 5, 7, 11]:
            mask = make_mask(i, k)
            for j in range(0, 32*bits):
                bucketed = {}
                for int_name, char in int_monsters.items():
                    bucket = (int_name % (2**62-1)) & mask
                    try:
                        if bucketed[bucket] != char:
                            break
                    except KeyError:
                        bucketed[bucket] = char
                else:
                    new_solution_score = i*len(bucketed)
                    if new_solution_score < solution_score:
                        print("   found mapping: i={}, k={}, j={}, mapping={}".format(
                            i, k, j, bucketed
                        ))
                        solution = i, k, j, bucketed
                        solution_score = new_solution_score
                mask <<= 1

    if solution is not None:
        print("  solution found!")

    chars = "".join(sorted(set(int_monsters.values())))
    i, k, j, mapping = solution

    # sanity check 1
    if i > 0:
        mask = make_mask(i, k) << j
        for int_name, char in int_monsters.items():
            key = (int_name % (2**62-1)) & mask
            assert mapping[key] == char

    compressed_mapping = {}
    for hash_key, char in mapping.items():
        hash_key = collapse_mask(hash_key >> j, i, k)
        max_bit_size = max(hash_key.bit_length(), max_bit_size)
        compressed_mapping[hash_key] = chars.index(char)

    nmapentries += len(compressed_mapping)
    compressed_maps[first_char] = i, k, j, chars, compressed_mapping

    print(" ", compressed_maps[first_char])

    print()

print("max_bit_size =", max_bit_size)
print("nmapentries =", nmapentries)

print("approx size =", (1+math.ceil(max_bit_size/8))*nmapentries)


# first we need to map first word chars to compressed mappings
Row = struct.Struct(
    ">"
    "B"  # first word char
    "B"  # number of bits (i) and bit spacing (k)
    "B"  # shift (j) or character to map to if i = 0
    "B"  # number of characters
    "B"  # map entry bytes
)


def map_to_bytes(i, nchars, mapping):
    bits_per_value = math.ceil(math.log(nchars, 2))
    bits_per_key = i

    bits = 0
    # ensure that the smallest value is encoded last
    for key, value in sorted(mapping.items(), reverse=True):
        assert key.bit_length() <= bits_per_key
        assert value.bit_length() <= bits_per_value

        bits <<= bits_per_value
        bits |= value
        bits <<= bits_per_key
        bits |= key

    return bits.to_bytes(math.ceil(bits.bit_length() / 8), "big")


def bytes_to_map(i, nchars, data):
    data = int.from_bytes(data, "big")

    bits_per_value = math.ceil(math.log(nchars, 2))
    bits_per_key = i
    key_mask = 2**(bits_per_key)-1
    value_mask = 2**(bits_per_value)-1

    mapping = {}
    while data:
        key = data & key_mask
        data >>= bits_per_key
        value = data & value_mask
        data >>= bits_per_value
        assert key not in mapping
        mapping[key] = value

    return mapping


parts = bytearray()
for first_char, (i, k, j, chars, mapping) in sorted(compressed_maps.items()):
    raw_data = map_to_bytes(i, len(chars), mapping)
    recovered_mapping = bytes_to_map(i, len(chars), raw_data)
    assert recovered_mapping == mapping, "{}\n{}\n{}\n{} {}".format(
        mapping,
        recovered_mapping,
        raw_data,
        i, len(chars),
    )
    assert len(raw_data) <= 255

    print(" {!r} => {} {} {} {} {}".format(
        first_char,
        i, k, j,
        len(chars),
        raw_data
    ))

    assert k <= 15
    assert i <= 15

    if i == 0:
        chars = ""

    row = Row.pack(
        ord(first_char),
        (i << 4) | k, j,
        len(chars),
        len(raw_data),
    )
    row += chars.encode("ascii")
    row += raw_data
    parts.extend(row)

parts = bytes(parts)
print(parts)
print(len(parts))
print(len(str(parts)))
print(len(str(zlib.compress(parts, 9))))

परीक्षण चालक

#!/usr/bin/python3
import json
import subprocess
import sys

with open("data.json") as f:
    data = json.load(f)

for name, char in data.items():
    stdout = subprocess.check_output(["python3", sys.argv[1], name])
    stdout = stdout.decode().rstrip("\n")
    if char != stdout:
        print("mismatch for {!r}: {!r} != {!r}".format(
            name, char, stdout
        ))

0

awk 73 + 2060 बाइट्स

s{while(!(i=index(s,$0)))sub(/.$/,"");print substr(s,i+length(),1)}{s=$0}

इसके लिए डेटा तैयार किया गया था:

  "Aleax": "A",            Al A     # first of alphabet truncate to len=1
  "Angel": "A",            An A
  "Arch Priest": "@",      Arch @   # this needs to come
  "Archon": "A",           Archo A  # before this
  "Ashikaga Takauji": "@", Ash @
  "Asmodeus": "&",         Asm &    

(2060 वर्ण) अर्थात। दैत्य चरित्र के साथ सबसे छोटी अनोखी तार को नाम और अंत में इस रूप में जोड़ा गया:

AlAAnAArch@ArchoAAsh@Asm&

(एक गैर-मैच को चिह्नित करने के लिए स्ट्रिंग की शुरुआत में एक फॉल बैक चार होने की जरूरत है) जब एक मैच की खोज हो रही है तो नाम को चार से अंत तक चार से छोटा किया जाता है जब तक कि कोई मैच नहीं होता है और मैच के बाद अगला चार वापस किया जाता है :

$ cat monster
Aleax
$ awk -f program.awk monsters_string monster
A

मैं अभी भी कुछ आयोजन के साथ राक्षस स्ट्रिंग से कुछ बाइट्स दाढ़ी कर सकता हूं:

AAnArch@ArchoAsh@Asm&

राक्षसों के नाम के साथ शुरू होने वाले डेटा के आकार को ध्यान में रखते हुए A 38 बाइट्स से घटकर 22 हो जाएगा, मतलब औसतन 2060 से 1193 तक डेटा का आकार गिराना।

यह अभी भी प्रगति पर है और राक्षस स्ट्रिंग को थोड़ी देर बाद प्रकाशित किया जाएगा।

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