कौन कोलमोगोरोव जटिलता विजेता बनना चाहता है?


22

आप मिशन आज एक पाठ कंप्रेसर का आविष्कार करने के लिए है।

कार्य

आप दो कार्य लिखेंगे:

  • पैकर एक समारोह है कि ASCII वर्ण (U + 0000 U + 007F करने के लिए) के एक स्ट्रिंग स्वीकार करता है और एक यूनिकोड स्ट्रिंग (U + 0000 U + 10FFFF करने के लिए) आउटपुट, संभव सबसे कम वर्ण युक्त है।

  • अनपैकर एक समारोह है कि एक इनकोडिंग यूनिकोड स्ट्रिंग स्वीकार करता है और बिल्कुल मूल ASCII स्ट्रिंग आउटपुट है।

इनपुट

एकमात्र अधिकृत इनपुट ASCII स्ट्रिंग (पैकर के लिए) और पैक्ड यूनिकोड स्ट्रिंग (अनपैकर के लिए) है। कोई उपयोगकर्ता इनपुट, कोई इंटरनेट कनेक्शन, फ़ाइल सिस्टम का कोई उपयोग नहीं।

आपके कार्यों में अंग्रेजी शब्दों की इस सूची तक पहुँच हो सकती है । आप इस सूची का उपयोग स्थानीय txt फ़ाइल के रूप में कर सकते हैं, या इसकी सामग्री को अपने स्रोत कोड में स्ट्रिंग या स्ट्रिंग के रूप में कॉपी कर सकते हैं

आप अपने कार्यों में नीचे दिए गए स्निपेट को हार्डकोड नहीं कर सकते।

उत्पादन

दोनों कार्यों के लिए केवल अधिकृत आउटपुट एक स्ट्रिंग है।

अनपैकर के आउटपुट में पैकर के इनपुट के बिल्कुल समान अक्षर होने चाहिए।

आपके इनपुट और आउटपुट सभी यूनिकोड (UTF-8/16/32, GB18030, ...) का समर्थन करने वाले किसी भी वर्ण एन्कोडिंग का उपयोग कर सकते हैं, क्योंकि आपका स्कोर केवल आउटपुट में यूनिकोड वर्णों की संख्या पर निर्भर करेगा। कृपया सटीक जो एन्कोडिंग आप उपयोग कर रहे हैं, हालांकि।

अपने आउटपुट में यूनिकोड वर्णों की संख्या की गणना करने के लिए, आप इस टूल का उपयोग कर सकते हैं: http://mothereff.in/byte-counter

स्कोरिंग

आपकी प्रविष्टि को 10 निम्नलिखित पाठ स्निपेट्स को पैक करने और अनपैक करने में सक्षम होना चाहिए (जो मैंने इस मंच पर लिया था)।

आपका स्कोर आपके 10 पैक्ड स्ट्रिंग्स (यूनिकोड वर्णों में) के आकार का योग होगा + आपके दो कार्यों का आकार (यूनिकोड वर्णों में भी)

यदि आप इसका उपयोग करते हैं, तो डिक्शनरी के आकार की गणना न करें।

कृपया अपनी प्रविष्टियों में प्रत्येक स्निपेट और उनके पैक्ड संस्करण का "स्कोर" शामिल करें।

सबसे कम स्कोर जीतता है।

डेटा

आपके स्कोर की गणना करने के लिए यहां स्निपेट सांकेतिक हैं:

1: रिक रोल गीत (1870 बी): हम गोल्फ को कोड करने के लिए कोई अजनबी नहीं हैं, आप नियमों को जानते हैं, और इसलिए मैं ऐसा करता हूं

हम प्यार करने के लिए अजनबी नहीं हैं
आप नियमों को जानते हैं और इसलिए मैं
एक पूर्ण प्रतिबद्धता जो मैं सोच रहा हूँ
आपको यह किसी अन्य व्यक्ति से नहीं मिलेगा
मैं आपको बताना चाहता हूं कि मैं कैसा महसूस कर रहा हूं
समझ में आ जाएगा

नेवर गोना गिव यू अप
आपको कभी निराश नहीं होने देंगे
कभी भी इधर-उधर भागना नहीं चाहिए
तुम कभी रोना मत
कभी अलविदा न कहना
कभी भी झूठ मत बोलना और आपको चोट पहुँचाना

हम एक दूसरे को इतने लंबे समय से जानते हैं
आपका दिल दुख रहा है लेकिन
आप इसे कहते हुए बहुत शर्मा रहे हैं
अंदर हम दोनों जानते हैं कि क्या चल रहा है
हम खेल जानते हैं और हम इसे खेलने वाले हैं
और अगर आप मुझसे पूछें कि मैं कैसा महसूस कर रहा हूं
मुझे मत बताओ कि तुम देखने के लिए बहुत अंधे हो

नेवर गोना गिव यू अप
आपको कभी निराश नहीं होने देंगे
कभी भी इधर-उधर भागना नहीं चाहिए
तुम कभी रोना मत
कभी अलविदा न कहना
कभी भी झूठ मत बोलना और आपको चोट पहुँचाना

नेवर गोना गिव यू अप
आपको कभी निराश नहीं होने देंगे
कभी भी इधर-उधर भागना नहीं चाहिए
तुम कभी रोना मत
कभी अलविदा न कहना
कभी भी झूठ मत बोलना और आपको चोट पहुँचाना

(ऊह, आपको छोड़ देना)
(ऊह, आपको छोड़ देना)
(ऊह)
कभी देने वाला नहीं, देने वाला कभी नहीं
(तुम्हें त्याग रहा हूं)
(ऊह)
कभी देने वाला नहीं, देने वाला कभी नहीं
(तुम्हें त्याग रहा हूं)

हम एक दूसरे को इतने लंबे समय से जानते हैं
आपका दिल दुख रहा है लेकिन
आप इसे कहते हुए बहुत शर्मा रहे हैं
अंदर हम दोनों जानते हैं कि क्या चल रहा है
हम खेल जानते हैं और हम इसे खेलने वाले हैं

मैं आपको बताना चाहता हूं कि मैं कैसा महसूस कर रहा हूं
समझ में आ जाएगा

नेवर गोना गिव यू अप
आपको कभी निराश नहीं होने देंगे
कभी भी इधर-उधर भागना नहीं चाहिए
तुम कभी रोना मत
कभी अलविदा न कहना
कभी भी झूठ मत बोलना और आपको चोट पहुँचाना

नेवर गोना गिव यू अप
आपको कभी निराश नहीं होने देंगे
कभी भी इधर-उधर भागना नहीं चाहिए
तुम कभी रोना मत
कभी अलविदा न कहना
कभी भी झूठ मत बोलना और आपको चोट पहुँचाना

नेवर गोना गिव यू अप
आपको कभी निराश नहीं होने देंगे
कभी भी इधर-उधर भागना नहीं चाहिए
तुम कभी रोना मत
कभी अलविदा न कहना
कभी भी झूठ मत बोलना और आपको चोट पहुँचाना

2: द गोल्फर (412 बी): गोल्फिंग एएससीआईआई-कला

      '\ _। । |> 18 >>
        \ _। '। |
       हे >> 'ओ |
        \ _। |
        / \ _ |
       / / ' |
 jgs ^^^^^^^ `^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^

3: संख्या हीरा (233 बी): इस हीरे को प्रिंट करें

        1
       121
      12321
     1234321
    123454321
   12345654321
  1234567654321
 123456787654321
12345678987654321
 123456787654321
  1234567654321
   12345654321
    123454321
     1234321
      12321
       121
        1

4: चार बार वर्णमाला (107 बी): चार बार वर्णमाला मुद्रित करें

abcdefghijklmnopqrstuvwxyz
qwertyuiopasdfghjklzxcvbnm
pyfgcrlaoeuidhtnsqjkxbmwvz
zyxwvutsrqponmlkjihgfedcba

5: पुराने मैकडॉनल्ड्स के बोल (203 बी): पुराने मैकडॉनल्ड्स फ़ंक्शन

ओल्ड मैकडोनाल्ड के पास एक खेत था, EIEIO,
और उस खेत पर उसने एक गाय, EIEIO,
यहाँ एक म्यू म्यू के साथ और एक म्यू म्यू के साथ,
यहाँ एक म्यू, हर जगह एक म्यू म्यू,
ओल्ड मैकडोनाल्ड के पास एक खेत था, EIEIO!

6: क्लॉक लिरिक्स के आसपास रॉक (144b): रॉक अराउंड द क्लॉक

1, 2, 3 बजे, 4 बजे रॉक,
5, 6, 7 बजे, 8 बजे रॉक,
9, 10, 11 बजे, 12 बजे रॉक,
हम आज रात घड़ी के आसपास रॉक करने जा रहे हैं।

7: हैलो वर्ल्ड (296 बी): एएससीआईआई कला में दुनिया को "हैलो" कहें

 _ _ _ _ _ _ _ _
| | | | ___ | | | ___ __ _____ _ __ | | __ | | |
| | _ | | / _ \ _ | | / _ \ _ \ _ / \ / / \ _ | '__ | | / _ _ | |
| _ | __ / | | (_) | \ VV / (_) | | | | (_ | | _ |
| _ | | _ | \ ___ | _ | _ | \ ____ () \ _ / \ _ / \ ____ / | | _ | _ | \ __, _ (_)
                    | /

8: आयरिश आशीर्वाद (210 बी): एक पुरानी आयरिश आशीर्वाद

काश ये रास्ता उठ कर आप से मिले
मय द विंड बी ऑल्वेज़ एट यूअर बैक
आपके चेहरे पर सूरज की चमक गर्म हो सकती है
बारिश आपके खेतों पर नरम पड़ती है
और जब तक हम फिर से नहीं मिलते
भगवान आपको अपने हाथ की ओट में रखे

9: एक पुरानी महिला गीत थी (1208b): एक बूढ़ी महिला थी

एक बूढ़ी औरत थी जिसने एक मक्खी को निगल लिया था।  
मुझे नहीं पता कि उसने वह मक्खी क्यों निगल ली,  
शायद वह मर जाएगी।

एक बूढ़ी औरत थी जिसने एक मकड़ी को निगल लिया,  
उस झुरमुट और iggled और उसके अंदर jiggled।  
उसने मक्खी को पकड़ने के लिए मकड़ी को निगल लिया,  
मुझे नहीं पता कि उसने वह मक्खी क्यों निगल ली,  
शायद वह मर जाएगी।

एक बूढ़ी औरत थी जिसने एक पक्षी को निगल लिया,  
एक पक्षी को निगलने के लिए कितना बेतुका है।  
वह मकड़ी को पकड़ने के लिए चिड़िया को निगल गई,  
उसने मक्खी को पकड़ने के लिए मकड़ी को निगल लिया,  
मुझे नहीं पता कि उसने वह मक्खी क्यों निगल ली,  
शायद वह मर जाएगी।

एक बूढ़ी औरत थी जिसने एक बिल्ली को निगल लिया,  
कल्पना कीजिए कि एक बिल्ली को निगलने के लिए।  
उसने पक्षी को पकड़ने के लिए बिल्ली को निगल लिया,  
वह मकड़ी को पकड़ने के लिए चिड़िया को निगल गई,  
उसने मक्खी को पकड़ने के लिए मकड़ी को निगल लिया,  
मुझे नहीं पता कि उसने वह मक्खी क्यों निगल ली,  
शायद वह मर जाएगी।

एक बूढ़ी औरत थी जिसने एक कुत्ते को निगल लिया,  
एक कुत्ते को निगलने के लिए क्या हॉग।  
उसने कुत्ते को बिल्ली को पकड़ने के लिए निगल लिया,  
उसने पक्षी को पकड़ने के लिए बिल्ली को निगल लिया,  
वह मकड़ी को पकड़ने के लिए चिड़िया को निगल गई,  
उसने मक्खी को पकड़ने के लिए मकड़ी को निगल लिया,  
मुझे नहीं पता कि उसने वह मक्खी क्यों निगल ली,  
शायद वह मर जाएगी।

एक बूढ़ी औरत थी जिसने घोड़े को निगल लिया,  
वह बेशक मर गई।

10: gettysburg पता (1452b): गेटीसबर्ग एड्रेस कितना यादृच्छिक है

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

कुल (असम्बद्ध): 6135 चार्ट / बाइट्स।

मज़े करो!


7
यह एक भाषा का आविष्कार करने के लिए एक चुनौती नहीं है, यह कुछ को संपीड़ित करने के लिए एक चुनौती है।
जस्टिन

2
मुझे लगता है कि स्कोर में संकलक / निष्पादक (कंप्रेसर / डीकंप्रेसर) के आकार को शामिल नहीं करना इस चुनौती को थोड़ा-सा खुला बनाता है। कुछ बिंदु पर, शब्दकोश और हार्ड-कोडिंग के बीच की रेखा बहुत पतली हो जाएगी।
डेनिस

2
डारन, और यहाँ मैं पहले से ही टाइप कर रहा था private static final String RICK_ROLL_RETURN = "We're no strangers to love...
ग्राफ थ्योरी

1
मुझे नहीं लगता कि आपने डेनिस के अवलोकन को संबोधित किया है।
पीटर टेलर

1
@xem मुझे लगता है कि #Task, #Input, #Output, #Scoring जैसे अनुभागों में जानकारी को व्यवस्थित करके पोस्ट को बेहतर बनाया जा सकता है। मुझे यह भी लगता है कि कंप्रेसर और डिकम्प्रेसर के लिए स्रोत कोड का आकार स्कोर में शामिल होना चाहिए। यह कुछ भी चोट नहीं करता है, लेकिन यह समस्या को हल करता है डेनिस ने बताया।
रेनबोल्ट

जवाबों:


6

हास्केल - 5322 अंक

कोड के बाइट्स: 686

मूल आकार : 6147 = 1871+415+234+108+204+145+297+211+1209+1453

एन्कोडेड आकार: 4636 = 1396+233+163+92+153+115+197+164+979+1144

स्कोर : 686+ 4636

चरित्र गणना संपीड़न: ~25%

कोड

एक तरफ अनुकूलन, यह उनके प्रमुख कारकों के रूप में 0और 7fयूनिकोड पात्रों के बीच मूल्यों को संग्रहीत करता है।

यह एन्कोडेड आउटपुट के बाइट्स की संख्या को कम नहीं करता है, यह केवल यूनिकोड वर्णों की संख्या को कम करता है। उदाहरण के लिए, परीक्षण # 4 शामिल हैं 108, वर्ण और एन्कोडेड उत्पादन 92। उनके संबंधित आकार हालांकि 108और 364बाइट्स हैं।

import Data.Bits
import Data.List
import Data.Numbers.Primes
import qualified Data.Text as T
a=nub$concat$map(primeFactors)[0..127]
d(a:r)c=let s=shift c 5in if s<=0x10ffffthen d r(s+a)else c:d r a
d[]c=[c]
f(a:r)=let o=a.&.0x1fin(if o/=a then f((shiftR a 5):r)else f r)++[o]
f[]=[]
g=T.pack.map(toEnum).(\(a:r)->d r a).concatMap j.map(map(\x->head$elemIndices x a)).map(primeFactors.fromEnum).T.unpack
h=T.pack.map(toEnum.product.map((!!)a)).i.f.reverse.map(fromEnum).T.unpack
i(a:r)=let z=a`clearBit`4;x=if a`testBit`4then(take z$repeat$head r,tail r)else splitAt z r in[fst x]++i(snd x)
i[]=[]
j x@(a:_)=let l=length x in if(take l(repeat a))==x then[l`setBit`4,a]else[l]++x
j[]=[0]

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

  • एन्कोडिंग

    1. प्रत्येक वर्ण अपने संख्यात्मक समकक्ष में परिवर्तित हो जाता है, इस नंबर पर कॉल करने देता है n
    2. nफिर इसके प्रमुख कारकों की सूची में परिवर्तित किया जाता है ps
      • यह आसानी से होता है कि १२ through के माध्यम से संख्या ० में ३२ सामान्य प्रमुख कारक हैं, जिन्हें छोड़कर 1। इसका मतलब है कि वे, कारक, 5 बिट्स पर अनुक्रमित के रूप में संग्रहीत किए जा सकते हैं।
      • 1 एक विशेष मामला है और एक खाली सूची द्वारा दर्शाया गया है।
    3. psएन्कोडिंग के साथ अब शुरू हो सकता है।
      1. प्रत्येक संख्या को ps32 अद्वितीय कारकों की सूची में इसके सूचकांक में परिवर्तित किया जाता है (उपरोक्त कोड में इस सूची को इस प्रकार पहचाना जाता है a)।
      2. (इस बिंदु पर ध्यान रखें कि हम प्रमुख कारकों की सूची की एक सूची के साथ काम कर रहे हैं) अगले कदम पर आगे बढ़ने के लिए, psचपटा होना चाहिए। डेटा की अखंडता को बनाए रखने के लिए, प्रत्येक सूची को दो भागों की दूसरी सूची में परिवर्तित किया जाता है
        1. पहला तत्व अपनी लंबाई संग्रहीत करता है और यदि यह एक ही कारक से बना होता है।
          • प्रति सूची में अधिकतम 6 प्रमुख कारक हैं, यह जानकारी सबसे सही 3 बिट्स पर संग्रहीत है। पांचवें बिट का उपयोग यह दर्शाता है कि सूची में एकल कारक शामिल है या नहीं।
        2. सूची में दो अलग-अलग कारकों से कम होने पर शेष तत्व स्वयं सूचकांक या एकल सूचकांक हैं।
      3. इन सूचियों तो, एक भी चपटी सूची में concatenated रहे हैं fs
    4. इसके तत्वों को fsबिट शिफ्टिंग का उपयोग करके यूनिकोड वर्णों में पैक किया जा सकता है।
  • डिकोडिंग

    • रिवर्स में एन्कोडिंग चरणों को करें।
    • यदि आप सोच रहे हैं कि यह कैसे 1फिट बैठता है, तो मैं आपको याद दिलाना चाहूंगा product [] == 1

टेस्ट

परीक्षण के लिए इस इंटरफ़ेस का उपयोग करना दर्दनाक होगा इसलिए मैंने नीचे दिए गए परिणामों को प्रदान करने के लिए इस फ़ंक्शन का उपयोग किया।

edTest f = do
    t <- readFile f
    let txt = T.pack t
        enc = g txt
        dec = h enc
        tst = txt == dec
    putStrLn $ (show $ T.length txt) ++ "," ++ (show $ T.length enc) ++ "," ++ (show $ T.length dec)++","++(show tst)
    putStrLn $ if not tst then T.unpack txt ++ "\n---NEXT---\n" ++ T.unpack dec else ""


λ> edTest "1"
1871,1396,1871,True

λ> edTest "2"
412,233,412,True

λ> edTest "3"
234,163,234,True

λ> edTest "4"
108,92,108,True

λ> edTest "5"
204,153,204,True

λ> edTest "6"
145,115,145,True

λ> edTest "7"
297,197,297,True

λ> edTest "8"
211,164,211,True

λ> edTest "9"
1209,979,1209,True

λ> edTest "10"
1453,1144,1453,True

नमूना

gपरीक्षण # 4 के लिए एन्कोडिंग फ़ंक्शन का आउटपुट यह है
"\99429\582753\135266\70785\35953\855074\247652\1082563\68738\49724\164898\68157\99429\67973\1082404\587873\73795\298017\330818\198705\69861\1082435\595009\607426\36414\69873\855074\265249\346275\67779\68738\77985\1082513\821353\132131\101410\247652\1082562\49724\164898\67649\594977\34915\67746\50273\135265\103997\563265\103457\1086021\99399\584802\70753\73889\34882\582722\411459\67779\68740\1084516\1082563\1091681\103491\313282\49724\164897\68705\135741\69858\50241\607426\35905\608421\1082435\69858\50274\71777\43075\298018\280517\1082404\67971\36017\955425\67665\919600\100452\132129\214883\35057\856097\101474\70753\135737"
या यदि आप गिबरीश का एक निपुण हैं, तो यह
𘑥򎑡𡁢𑒁豱󐰢𼝤􈓃𐲂숼𨐢𐨽𘑥𐦅􈐤򏡡𒁃񈰡񐱂𰠱𑃥􈑃򑑁򔓂踾𑃱󐰢񀰡񔢣𐣃𐲂𓂡􈒑󈡩𠐣𘰢𼝤􈓂숼𨐢𐡁򑐡衣𐢢쑡𡁡𙘽򉡁𙐡􉉅𘑇򎱢𑑡𒂡衂򎑂񤝃𐣃𐲄􈱤􈓃􊡡𙑃񌟂숼𨐡𐱡𡈽𑃢쑁򔓂豁򔢥􈑃𑃢쑢𑡡ꡃ񈰢񄟅􈐤𐦃貱󩐡𐡑󠠰𘡤𠐡𴝣裱󑀡𘱢𑑡𡈹

अतिरिक्त नोट

  • Http://mothereff.in/byte-counter , Directory लिस्टिंग और edTestपरीक्षणों के आकार का उपयोग करना सभी सुसंगत हैं लेकिन फिर भी प्रश्न में संकेतित आकार से भिन्न होते हैं।
  • टेस्ट # 10 (ईएम डैश के एक जोड़े में शामिल है ) है कि मैं के साथ बदल दिया -, क्योंकि वे के बाहर हैं 0- 7fसीमा।
  • उदाहरण के लिए, 00आधार मामले के दौरान, शेष चौथे बिट का उपयोग करके आगे के संपीड़न को प्राप्त किया जा सकता है , 01सभी को 10दोहराएं, अंतिम 11को छोड़कर, पिछले दो को छोड़कर दोहराएं।
  • परीक्षण फाइलें और कोड सभी यहां उपलब्ध हैं https://github.com/gxtaillon/codegolf/tree/master/Kolmogorov

नमस्कार, इस उत्तर के लिए धन्यवाद! :) मुझे समझ में नहीं आया कि जब आप परिवर्तित होते हैं तो बाइनरी में क्या होता abcdefghijklm...है 𘑥򎑡𡁢𑒁豱󐰢𼝤..., क्या आप इसे थोड़ा और स्पष्ट कर सकते हैं? इसके अलावा, मैंने चार काउंट तय किए हैं और प्रश्न में # 10 में एम-डैश को परिवर्तित किया है। मेरे चार गिनती अभी भी तुम्हारी तुलना में अलग हैं, हालांकि। डननो क्यों, मैंने mothereff.in टूल का इस्तेमाल किया।
xem

@xem जटिल विवरण सामने आए हैं।
१२:२२ पर gxtaillon

मेरा मन (लाक्षणिक रूप से) सचमुच इस विचार से उड़ा है कि अंक 0 और 2-127 को 5 बिट्स पर एन्कोड किया जा सकता है। क्या आपको यह खुद पता चला या यह कुछ ज्ञात था? बोनस प्रश्न: आपको कितने प्रिंट करने योग्य आस्की पात्रों को संग्रहीत करने की आवश्यकता है, अर्थात 95 विभिन्न वर्ण?
xem

@xem संख्या 5 बिट्स पर एन्कोडेड नहीं हैं, उनके प्रत्येक कारक हैं। मुझे बहुत खुशी होगी अगर मुझे केवल 7 बिट्स को एन्कोडिंग करने का एक तरीका मिल गया है 5. Ascii वर्णों के लिए, इस पद्धति का उपयोग करके उन्हें अभी भी प्रत्येक 5 बिट्स की आवश्यकता होगी।
gxtaillon

1
चूंकि आपके द्वारा निर्दिष्ट सीमा में प्रति संख्या में अधिकतम 6 कारक हैं, इसलिए लंबाई 5 बिट्स "ब्लॉक" में से 3 का उपयोग करती है। फिर इंडेक्स 5 बिट्स पर एन्कोड किए जाते हैं, हां। इस कार्यान्वयन में, लंबाई ब्लॉक में 2 अप्रयुक्त बिट्स में से एक का उपयोग अतिरिक्त संपीड़न प्राप्त करने के लिए किया जाता है।
gxtaillon

4

सी ++ (सी ++ 11), 2741 अंक

यह उत्तर UTF-32 का उपयोग संपीड़ित पाठ के लिए एन्कोडिंग के रूप में करता है।

#include <cstdio>
#include <iostream>
#include <locale>
#include <string>
#define L locale
using namespace std;long b,n,i,l;void c(){string d;char x;while((x=cin.get())!=EOF)d+=x;b=(d.size()*7)%20;n=5;wcout.imbue(L());for(char y:d){b=b<<7|y&127;n+=7;if(n>=20)wcout.put(b>>(n-=20)&0xFFFFF);}if(n)wcout.put(b<<20-n&0xFFFFF);}void d(){wstring d;wchar_t w;wcin.imbue(L());while((w=wcin.get())!=EOF)d+=w;l=-1;for(wchar_t y:d){b=b<<20|y;n+=20;if(l<0)l=b>>15&31,n-=5;while(n>=7&(i<d.size()-1|n>20-l))cout.put(b>>(n-=7)&127);++i;}}int main(int t,char**a){L::global(L("en_US.utf8"));**++a<'d'?c():d();}

चार गिनती और स्कोरिंग

कोड: 593 वर्ण (अनुगामी न्यूलाइन छीन लिया गया है)

संपीड़ित पाठ (यूनिकोड वर्ण) : 654 + 145 + 82 + 38 + 51 + 104 + 73 + 423 + 506 = 2148 ( wc -mबाइट्स के बजाय यूनिकोड वर्णों की संख्या के साथ गिना जाता है , बाइट मायने रखता है, जैसा कि @ gxtaillon के उत्तर के साथ है) मूल से अधिक, कुल 8413 बाइट्स, जैसा कि गिना जाता है wc -c)।

संपीड़न अनुपात (यूसीआईआईआई को यूनिकोड) : 35.01% (प्रश्न से 6135 बाइट्स का उपयोग करके wc -c) (समान )

सावधान:

बहुत सारे गोले यूनिकोड वर्णों को संभाल नहीं सकते हैं जो यह प्रोग्राम बनाता है। इस प्रकार, decompressing पाठ को कहीं से काट दिया जा सकता है जब शेल एक चरित्र को संभाल नहीं सकता है, क्योंकि stdinशेल से इनपुट लिया जाता है।

संकलन

इसका संकलन करना चाहिए clang++ और g++ -std=c++11, लेकिन यह ऑपरेटर की पूर्ववर्तीता के बारे में कुछ चेतावनियों को दिखाएगा, जैसा कि एक अभिव्यक्ति के साथ b<<20-n&0xFFFFFव्यवहार नहीं किया जाएगा ((b << 20) - n) & 0xFFFFF, जैसा कि कोई उम्मीद कर सकता है, बल्कि इसके रूप में (b << (20 - n)) & 0xFFFFF

प्रयोग

  • एक निष्पादन योग्य, उदाहरण के लिए कार्यक्रम संकलित करें ./compress
  • प्रोग्राम ./compress cको संपीड़ित करने या ./compress dविघटित करने के लिए चलाएं । (सावधान, विकल्प छोड़ना एक SEGFAULT देता है (त्रुटि जाँच इतना चरित्र महंगा है ...) और अन्य विकल्प (जैसे कि उपयोग करना)D इसके बजाय का करना d) अप्रत्याशित परिणाम दे सकते हैं
  • इनपुट से पढ़ा stdinऔर आउटपुट लिखा हैstdout

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

Ungolfed

#include <cstdio>
#include <iostream>
#include <locale>
#include <string>

using namespace std;

long b, n, i, l;

// Compress
void c() {
    string d;
    char x;
    // Read from STDIN until EOF
    while((x = cin.get()) != EOF)
        d += x;
    // Calculate the number of bits used from the last unicode character
    // (maximum 19) and store it into the first 5 bits
    b = (d.size() * 7) % 20;
    n = 5;
    // Set the output locale to allow unicode
    wcout.imbue(locale());
    // For each character in the input...
    for (char y : d) {
        // Add its bit representation (7 bits) to the right of the buffer
        // by shifting the buffer left and ORing with the character code
        b = (b << 7) | (y & 127);
        // Add 7 to the bit counter
        n += 7;
        // If enough data is present (20 bits per output character),
        // calculate the output character by shifting the buffer right,
        // so that the last 20 bits are the left 20 bits of the buffer.
        // Also decrement the bit counter by 20, as 20 bits are removed.
        if (n >= 20)
            wcout.put((b >> (n -= 20)) & 0xFFFFF);
    }
    // If there are still bits in the buffer, write them to the front of
    // another unicode character
    if (n)
        wcout.put((b << (20 - n)) & 0xFFFFF);
}

// Decompress
void d() {
    wstring d;
    wchar_t w;
    // Set STDIN to UNICODE
    wcin.imbue(locale());
    // Read wide characters from STDIN (std::wcin) until EOF
    while ((w = wcin.get()) != EOF)
        d += w;
    // `l' represents the number of bits used in the last unicode character.
    // It will be set later
    l = -1;
    // For each input character...
    for (wchar_t y : d) {
        // Add it to the buffer and add 20 to the bit counter
        b = (b << 20) | y;
        n += 20;
        // If the number of bits in the last unicode character has not been
        // set yet, read the first 5 buffer bits into `l'. This is
        // necessary because the last character may contain more than 7
        // (one entire uncompressed character) unused bits which may
        // otherwise be interpreted as garbage.
        if (l < 0) {
            l = (b >> 15) & 31;
            n -= 5;
        }
        // As long as there is data to turn into output characters
        // (at least 7 bits in the buffer and either not the last
        // unicode character or before the unused bits)
        while (n >= 7 && ((i < d.size() - 1) || (n > (20 - l)))
            cout.put((b >> (n -= 7)) & 127); // Output the left 7 bits in the buffer as an ASCII character
        ++i; // Increment the character index, so that we know when we reach the last input character
    }
}
int main(int t, char**a) {
    // Set the default locale to en_US.utf8 (with unicode)
    locale::global(locale("en_US.utf8"));
    // Decide whether to compress or decompress.
    // This is just fancy pointer stuff for a[1][0] < 'd' ? c() : d()
    (**(++a) < 'd') ? c() : d();
}

व्याख्या

से सभी यूनिकोड वर्ण के रूप में U+0000करने के लिए U+10FFFFअनुमति दी जाती है, हम यूनिकोड वर्ण प्रति 20 बिट का उपयोग कर सकते हैं:U+FFFFF 20 बिट का उपयोग करता है और अभी भी अनुमत श्रेणी में शामिल है। इस प्रकार, हम बस यूनिकोड वर्णों में सभी व्यक्तिगत ASCII चार बिट्स को एक यूनिकोड वर्ण में एकाधिक ASCII वर्णों को संग्रहीत करने का प्रयास करते हैं। हालाँकि, हमें पिछले यूनिकोड चरित्र में प्रयुक्त बिट्स की संख्या को संग्रहीत करने की भी आवश्यकता है, क्योंकि अप्रयुक्त कचरा बिट्स को अन्यथा उचित संकुचित ASCII वर्णों के रूप में व्याख्या किया जा सकता है। जैसा कि पिछले यूनिकोड चरित्र में प्रयुक्त बिट्स की अधिकतम संख्या 20 है, हमें उसके लिए 5 बिट्स की आवश्यकता होगी, जिन्हें संपीड़ित डेटा की शुरुआत में रखा गया है।

उदाहरण आउटपुट

यह उदाहरण # 4 के लिए आउटपुट है (जैसा कि दिया गया है less):

<U+4E1C5><U+8F265><U+CD9F4><U+69D5A><U+F66DD><U+DBF87><U+1E5CF><U+A75ED>
<U+DFC79><U+F42B8><U+F7CBC><U+BA79E><U+BA77F>쏏𦛏<U+A356B><U+D9EBC><U+63ED8>
<U+B76D1><U+5C3CE><U+6CF8F><U+96CC3><U+BF2F5><U+D3934><U+74DDC><U+F8EAD>
<U+7E316><U+DEFDB><U+D0AF5><U+E7C77><U+EDD7A><U+73E5C><U+786FD><U+DB766>
<U+BD5A7><U+467CD><U+97263><U+C5840>

( चरित्र कोड के रूप में 쏏𦛏दे <U+C3CF><U+266CF>, लेकिन मुझे लगता है कि गलत हो सकता है)


2

पायथन 3, 289 + 818 = 1107 अंक

केवल हल्के से गोल्फ।

import zlib as Z
def p(s):
 z=int.from_bytes(Z.compress(s),'big');o=''
 while z:
  z,d=divmod(z,1<<20)
  if d>0xd000:d+=1<<16
  o+=chr(d)
 return o[::-1]
def u(s):
 i=0
 for c in s:
  d=ord(c)
  if d>0xe000:d-=1<<16
  i=(i<<20)+d
 return Z.decompress(i.to_bytes(i.bit_length()//8+1,'big'))

कुल कोड आकार 289 बाइट्स है, और दिए गए 6135 बाइट्स को 818 यूनिकोड वर्णों में एन्कोड करता है - कुल आउटपुट बाइट काउंट 3201 बाइट्स है, जो मूल इनपुट से काफी छोटा है।

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

उदाहरण # 4 से आउटपुट, जैसा कि less(37 यूनिकोड वर्ण) द्वारा देखा गया है :

x<U+AC0DC><U+BB701><U+D0200><U+D00B0><U+AD2F4><U+EEFC5>𤆺<U+F4F34>멍<U+3C63A><U+2F62C><U+BA5B6><U+4E70A><U+F7D88><U+FF138><U+40CAE>
<U+CB43E><U+C30F5><U+6FFEF>𥠝<U+698BE><U+9D73A><U+95199><U+BD941><U+10B55E><U+88889><U+75A1F><U+4C4BB><U+5C67A><U+1089A3><U+C75A7>
<U+38AC1><U+4B6BB><U+592F0>ᚋ<U+F2C9B>

परीक्षण के लिए चालक कार्यक्रम:

if __name__ == '__main__':
    import os
    total = 0
    for i in range(1,10+1):
        out = p(open('data/%d.txt'%i,'rb').read())
        total += len(out)
        open('out/%d.bin'%i,'w',encoding='utf8').write(out)
    print(total)
    for i in range(1,10+1):
        out = u(open('out/%d.bin'%i,'r',encoding='utf8').read())
        open('data2/%d.txt'%i,'wb').write(out)

आउटपुट बाइट मायने रखता है:

 607 out/1.bin
 128 out/2.bin
 101 out/3.bin
 143 out/4.bin
 177 out/5.bin
 145 out/6.bin
 186 out/7.bin
 222 out/8.bin
 389 out/9.bin
1103 out/10.bin
3201 total

1
क्या यह तथ्य नहीं है कि यह एक कम्प्रेशन लाइब्रेरी का उपयोग कर धोखा दे रहा है?
बीटा डेके

@ बेताडे: यह सवाल में प्रतिबंधित नहीं करता है, इसलिए मुझे लगा कि यह उचित खेल है।
nnonneo 17

इसके अलावा, आपको एक डिकम्प्रेसर को शामिल करने की आवश्यकता है।
बीटा डेके

@ बीटाडेके: pपैकर uहै, अनपैकर है।
nnonneo 15

1

पायथन 2 - 1141 अंक

from zlib import *;v=256
def e(b):
 x=0
 for c in compress(b,9):x=(x*v)+ord(c)
 b=bin(x)[2:]
 return "".join(unichr(int("1"+b[a:a+19],2))for a in range(0,len(b),19))
def d(s):
 y=int("".join(bin(ord(a))[3:]for a in s),2);x=""
 while y:y,d=(y/v,chr(y%v));x=d+x
 return decompress(x)

कोड आकार 281बाइट्स है और यह 6135बाइट्स को इनकोड करता है860 यूनिकोड वर्णों ।

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

एनकोड करने के लिए:

  1. स्ट्रिंग को एन्कोड किया जाए।
  2. एक आधार 256 नंबर के रूप में संकुचित स्ट्रिंग की व्याख्या करें।
  3. संख्या को बाइनरी में बदलें।
  4. बाइनरी को 19बिट्स के समूहों में विभाजित 1करें, उनमें से प्रत्येक की शुरुआत में थोड़ा सा जोड़ें और फिर यूनिकोड वर्णों में परिवर्तित करें।

डिकोडिंग रिवर्स है।

ध्यान दें कि अजगर के कुछ संस्करण केवल यूनिकोड वर्णों को संभाल सकते हैं 0xFFFF, और इस प्रकार यह कोड ए बढ़ाएगा ValueError

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