बाइट्स / चरित्र


28

कार्य

UTF-8 स्ट्रिंग (किसी भी तरह से) का जवाब (किसी भी तरह से) को देखते हुए एक समतुल्य सूची जहां हर तत्व बाइट्स की संख्या को संबंधित इनपुट वर्ण को एनकोड करने के लिए उपयोग किया जाता है।

उदाहरण

!1

Ciao1 1 1 1

tʃaʊ1 2 1 2

Adám1 1 2 1

ĉaŭ2 1 2(एकल पात्र)

ĉaŭ1 2 1 1 2(संयोजन ओवरले का उपयोग करता है)

チャオ3 3 3

(खाली इनपुट) → (खाली आउटपुट)

!±≡𩸽1 2 3 4

Ull (एक अशक्त बाइट) → 1

नल बाइट्स

यदि नल बाइट्स से परे रीडिंग इनपुट रखने का एकमात्र तरीका कुल बाइट गिनती को जानना है, तो आप किसी भी तरह से बाइट काउंट प्राप्त कर सकते हैं (यहां तक ​​कि उपयोगकर्ता इनपुट)।

यदि आपकी भाषा अशक्त बाइट्स को संभाल नहीं सकती है, तो आप मान सकते हैं कि इनपुट में नल नहीं हैं।


1
यदि इनपुट खाली है तो क्या हम 0 या किसी अन्य गलत मूल्य का उत्पादन कर सकते हैं?
एलेक्स ए।

2
क्या मैं बिना अलग किए बाइट काउंट प्रिंट कर सकता हूं? उच्चतम संभव मान 6 है, इसलिए यह असंदिग्ध है।
डेनिस

3
क्या हमें अशक्त बाइट्स का समर्थन करना है? वे कुछ भाषाओं में एक वास्तविक दर्द हो सकते हैं ...
डेनिस

3
आपको उस पोस्ट में जोड़ना चाहिए। मुझे नहीं पता कि ज्यादातर भाषाएं यह बताने के लिए पर्याप्त हैं कि क्या इससे कोई फर्क पड़ता है, लेकिन मुझे लगता है कि यह कम से कम दो उत्तरों को अमान्य कर देता है।
डेनिस

2
@ Adám हाँ, यह होगा। C में, उदाहरण के लिए, C स्ट्रिंग NUL बाइट के साथ समाप्त होती है, इसलिए जैसे ही आप पाते हैं आप पढ़ना बंद कर देते हैं। यदि आप स्ट्रिंग की लंबाई जानते हैं, तो आप कई बाइट्स, NUL और सभी के बाद पढ़ना बंद कर देते हैं।
बिल्ली

जवाबों:


10

अजगर, ९ 9 बाइट्स

@ बाइटनेस के लिए धन्यवाद 2 बाइट्स बचाने के लिए!

mlc.Bd8

परीक्षण सूट

इनपुट के हर चरित्र को बाइनरी प्रतिनिधित्व में रूपांतरित करता है और फिर इसे लंबाई के भाग 8 में विभाजित करता है। उन विखंडों की संख्या फिर उस चरित्र को एनकोड करने के लिए आवश्यक बाइट्स की मात्रा है।


1
आप विभाजन के बजाय बंटवारे के साथ 2 बाइट्स बचा सकते हैं और फिर .E pyth.herokuapp.com/ ...
माल्टीसेन

@Maltysen यह चतुर है, धन्यवाद!
डेनकर

1
समान लंबाई का उत्तर जो एक समान चाल पर निर्भर करता है:mlhc8.B
FryAmTheEggman

@LeakyNun तो टेस्ट केस देना आसान होगा जो फेल होता है, नहीं?
जू

एक और बाइट को बचाने के लिए, 8 के विखंडू में विभाजित होने के बजाय, प्रत्येक 8 वें लें: ml%8.B(अब dनिहित है)।
एंडर्स कासोर्ग

21

पायथन 3, 42 36 बाइट्स

lambda x:[len(i.encode())for i in x]

13
-1 बाइट: उपयोग maplambda x:map(len,map(str.encode,x))
NoOneIsHere

11

सी, 68 65 बाइट्स

b;main(c){for(;~c;b=c/64^2?b?putchar(b+48)/48:1:b+1)c=getchar();}

3 बाइट बंद करने के लिए @FryAmTheEggman को धन्यवाद!

Ideone पर इसका परीक्षण करें ।


11

एपीएल, 15 वर्ण

≢¨'UTF-8'∘⎕ucs¨

अंग्रेजी में: प्रत्येक वर्ण को UTF-8 में परिवर्तित करें (जिसका अर्थ है: बाइट्स प्रतिनिधित्व का वेक्टर) और इसकी टैली प्राप्त करें।


एक बाइट सहेजें:≢¨'UTF-8'∘⎕ucs¨
14

वास्तव में @ Adám ... चीयर्स।
lstefano

एक दिलचस्प (लेकिन लंबे समय तक) सरणी आधारित दृष्टिकोण:+⌿0 7 11 16∘.≤2⍟⎕UCS
Adám

संस्करण 16.0:0 7 11 16⍸2⍟⎕UCS
20

7

गोल्फस्क्रिप्ट, 16 बाइट्स

{64/2=}%1,/{,)}*

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

पृष्ठभूमि

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

UTF-8 ASCII और गैर-ASCII वर्णों को अलग-अलग तरीके से एन्कोड करता है:

  • 128 से नीचे के सभी कोड पॉइंट इनकोडेड हैं 0xxxxxxx

  • अन्य सभी कोड बिंदुओं को एन्कोड किया गया है 11xxxxxx 10xxxxxx ... 10xxxxxx

इसका मतलब यह है कि प्रत्येक यूनिकोड वर्ण के एन्कोडिंग में एकल 0xxxxxxxबाइट या एकल 11xxxxxxबाइट और 1 से 5 10xxxxxxबाइट्स होते हैं।

द्वारा इनपुट के सभी बाइट्स विभाजित करके 64 , हम बारी 0xxxxxxxमें 0 या 1 , 11xxxxxxमें 3 , और 10xxxxxxमें 2

यदि हम भागफल की तुलना 2 से करते हैं - 1 को 2 के लिए धक्का ; और 0 के लिए 0 , 1 , और 3 - प्रत्येक वर्ण को 0 में बदल दिया जाएगा , इसके बाद 1 से 5 1 है

जो कुछ बचा है उसे 0 की घटनाओं पर परिणामी स्ट्रिंग को विभाजित करना है , उन शून्य के बीच 1 की संख्या की गणना करें और एक राशि में जोड़ें।

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

{     }%          Map the following over all bytes in the input.
 64/                Divide the byte by 64.
    2=              Compare the quotient with 2, pushing 1 or 0.
        1,        Push range(1), i.e., [0].
          /       Split the array of Booleans around zeroes.
           {  }*  Fold; for each run of ones but the first:
            ,       Push its length.
             )      Increment.

6

PowerShell v4, 58 बाइट्स

[char[]]$args[0]|%{[Text.Encoding]::UTF8.GetByteCount($_)}

एनबी

ठीक है, यह काम करना चाहिए, और लगभग सभी परीक्षण मामलों में करता है, सिवाय इसके 𩸽कि किसी तरह 3,3मेरी मशीन पर गिना जाता है । वह चरित्र मेरे कंप्यूटर पर 7 बाइट्स के रूप में भी दिखाता है । मुझे संदेह है कि यह Windows या .NET संस्करण में किसी प्रकार के बग के कारण है जो मैं स्थानीय रूप से चला रहा हूं, क्योंकि @Mego में वह समस्या नहीं है । ( संपादित करें: @cat BOM के कारण इसे इंगित करता है । उस रहस्य को सुलझाने के लिए धन्यवाद, @cat! )

हालाँकि, यह अभी भी समस्या के सभी के लिए खाता नहीं है। मुझे लगता है कि मुझे पता है कि कुछ समस्याएं कहां से आ रही हैं, हालांकि। .NET के अंदर, सभी तार UTF-16 कोड इकाइयों (जो System.Char प्रकार है) से बना है। बहुत ढीला typecasting कि PowerShell का उपयोग करता है के साथ, वहाँ एक है बहुत कुछ निहित कास्टिंग और पृष्ठभूमि में प्रकार के बीच रूपांतरण की। संभवतः यह हमारे द्वारा देखे जा रहे व्यवहार के लिए एक योगदान कारक है - उदाहरण के लिए, [system.text.encoding]::utf8.getchars([System.Text.UTF8Encoding]::UTF8.GetBytes('𩸽'))एक एकल वर्ण के बजाय, दो unprintables देता है।


व्याख्या

बहुत सीधा कोड। इनपुट लेता है $args[0]और स्पष्ट रूप से इसे चार-सरणी के रूप में रखता है ताकि हम स्ट्रिंग के प्रत्येक घटक के माध्यम से लूप कर सकें |%{...}। प्रत्येक पुनरावृत्ति, हम वर्तमान चरित्र के बाइट की गिनती प्राप्त करने के लिए .NET कॉल [System.Text.Encoding]::UTF8.GetByteCount()( System.निहित है) का उपयोग करते हैं $_। इसे बाद के आउटपुट के लिए पाइपलाइन पर रखा गया है। चूँकि यह s का एक संग्रह है [int]जो लौटाया जाता है, एक सरणी में कास्टिंग निहित है।

टेस्ट रन

PS C:\Tools\Scripts\golfing> .\bytes-per-character.ps1 'tʃaʊ'
1
2
1
2

PS C:\Tools\Scripts\golfing> .\bytes-per-character.ps1 'Adám'
1
1
2
1

PS C:\Tools\Scripts\golfing> .\bytes-per-character.ps1 'ĉaŭ'
2
1
2

PS C:\Tools\Scripts\golfing> .\bytes-per-character.ps1 'ĉaŭ'
1
2
1
1
2

PS C:\Tools\Scripts\golfing> .\bytes-per-character.ps1 'チャオ'
3
3
3

PS C:\Tools\Scripts\golfing> .\bytes-per-character.ps1 '!±≡𩸽'
1
2
3
3
3

जोड़ने के लिए यह ठीक-ठीक null-बाइट्स आवश्यकता के लिए खाता है जिसे मैंने मूल रूप से पोस्ट किए जाने के बाद चुनौती में जोड़ा था, बशर्ते आप किसी पाठ फ़ाइल से डेटा खींचते हैं और इसे निम्नानुसार पाइप करते हैं:

PS C:\Tools\Scripts\golfing> gc .\z.txt -Encoding UTF8|%{.\bytes-per-character.ps1 $_}
2
1
1
1

z.txt


That character even shows as 7 bytes on my computer.हां, यह बाइट-ऑर्डर मार्क के कारण है जो कि आपको यूटीएफ -8 के साथ विंडोज पर मिलता है। नोटपैड को ++ का उपयोग करने के लिए कहें UTF-8 without BOM(जैसा कि आपको हमेशा BOM से बचना चाहिए , विशेषकर यूनिटी के साथ हमदर्दी के लिए) और आपको लगेगा फ़ाइल में 4 बाइट्स का आकार है, क्योंकि BOM 3 और 4 + 3 = 7 है
cat

@cat आह, हाँ, यह समझ में आता है। ठीक है, ताकि फ़ाइल आकार में अंतर के लिए खातों। हालाँकि, यह अभी भी शेल के अंदर भिन्न व्यवहार के लिए जिम्मेदार नहीं है। उदाहरण के लिए, इसे बिना BOM के UTF-8 के रूप में सहेजा जा रहा है, और get-content -Encoding UTF8 .\z.txt|%{.\bytes-per-character.ps1 $_}अभी भी चल रहा है 3,3
AdmBorkBork



6

जावास्क्रिप्ट (ईएस 6), 54 45 43 बाइट्स

s=>[...s].map(c=>encodeURI(c).length/3-8&7)

संपादित करें: @ l4m2 की मदद से 2 बाइट्स सहेजे गए।


s=>[...s].map(c=>encodeURI(c).length/3-4&3)
l4m2

@ l4m2 जो गैर-बीएमपी वर्णों के लिए विफल रहता है लेकिन मैं इसे ठीक करने में सक्षम था।
नील


5

पर्ल 6 ,  77 69  63 बाइट्स

put +$0 if $_».base(2).fmt("%8d")~~/^(1)**2..*|^(" ")/ while $_=$*IN.read: 1
put +$0 if $_».fmt("%8b")~~/^(1)**2..*|^(" ")/ while $_=$*IN.read: 1

put 1+$0 if $_».fmt("%8b")~~/^1(1)+|^" "/while $_=$*IN.read: 1
put 1+$0 if $_».fmt("%0.8b")~~/^1(1)+|^0/while $_=$*IN.read: 1

चूंकि पर्ल 6 एनएफजी स्ट्रिंग्स का उपयोग करता है इसलिए मुझे सीधे बाइट्स में खींचना पड़ता है, जो इस सुविधा को रोक देता है।
(एनएफजी एनएफसी की तरह है सिवाय इसके कि सिंथेटिक रचित कोडपाइंट्स भी बनाए जाएं)

आउटपुट को नए सिरे से अलग किया जाता है।

परीक्षा:

for text in '!' 'Ciao' 'tʃaʊ' 'Adám' 'ĉaŭ' 'ĉaŭ' 'チャオ' '' '!±≡𩸽' '𩸽\0𩸽';
do
  echo -en $text |
  perl6 -e 'put 1+$0 if $_».fmt("%8b")~~/^1(1)+|^" "/while $_=$*IN.read: 1' |

  # combine all of the lines into a single one for display purposes
  env text=$text perl6 -e 'put qq["%*ENV<text>"], "\t\t", lines.gist'
done
"!"     (1)
"tʃaʊ"      (1 2 1 2)
"Adám"      (1 1 2 1)
"ĉaŭ"       (2 1 2)
"ĉaŭ"     (1 2 1 1 2)
"チャオ"       (3 3 3)
""      ()
"!±≡𩸽"     (1 2 3 4)
"𩸽\0𩸽"        (4 1 4)

स्पष्टीकरण:

# turns the list in 「$0」 into a count, and adds one
# 「put」 prints that with a trailing newline
put 1+$0 

   # if the following is true
   if

       # format the input byte to base 2 and pad it out to 8 characters
       $_».fmt("%8b")

       ~~ # smart match against

       # check to see if it starts with more than one 1s, or a space
       # ( also sets 「$0」 to a list that is 1 shorter
       # than the number of bytes in this codepoint )
       / ^1 (1)+ | ^" " /

           # for every byte in STDIN
           while
               $_ = $*IN.read: 1

यह काम करता है क्योंकि मल्टी-बाइट कोडपॉइंट में पहली बाइट में इसके अंदर एनकोडेड बाइट्स की संख्या होती है, और कोडपॉइंट में अन्य बाइट्स में सबसे अधिक बिट सेट होता है, लेकिन अगला उच्चतम नहीं होता है। जबकि सिंगल बाइट कोडपॉइंट्स में सबसे ज्यादा बिट सेट नहीं है।


नहीं कर सकते हैं read:1और / या /while$इसके बजाय? और अगर है कि काम करता है, if$?
आउटगोल्फ

@ E @G as नहीं क्योंकि कुछ अलग किया जाएगा। मैं whileहालांकि इससे पहले अंतरिक्ष को हटा सकता हूं ।
ब्रैड गिल्बर्ट

क्या आप एनएफजी काउंटरमेशर्स की व्याख्या कर सकते हैं?
जुल्लुगोज़

अगर मैं इस कार्यक्रम के STDIN में एक NUL बाइट प्रतिध्वनित करता हूं, तो यह प्रिंट करता है \n1\n1\n, क्या यह जानबूझकर है? मूलतः, क्या यह NUL बाइट्स को संभालता है?
बिल्ली

@cat यह क्यों नहीं होगा? जब मैं ऐसा करता हूं: perl -e 'print "𩸽\0𩸽"' | perl6 -e '...'मुझे 4␤1␤4वैसा ही मिलता है , जैसा मैं उम्मीद करता हूं। (हालांकि मैं पोस्ट करने के बाद nuls के बारे में भाग जोड़ा गया था)
ब्रैड गिल्बर्ट b2gills 13:24 पर जुआन

5

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

import math
lambda x:[ord(i)<128and 1or int((math.log2(ord(i))-1)//5+1)for i in x]

यह अन्य पायथन उत्तर की तुलना में अधिक लंबा है, और अन्य उत्तरों के बहुमत, लेकिन लॉगरिदम से जुड़े एक दृष्टिकोण का उपयोग करता है जो मैंने अभी तक नहीं देखा है।

एक अनाम फ़ंक्शन जो इनपुट लेता है, तर्क के माध्यम से, एक स्ट्रिंग के रूप में और एक सूची देता है।

Ideone पर इसे आज़माएं

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

यह विधि उस तरीके पर निर्भर करती है जिसमें UTF-8 एक वर्ण के कोड-बिंदु को एन्कोड करता है। यदि कोड-पॉइंट 128 से कम है, तो चरित्र ASCII में एन्कोडेड है:

0xxxxxxx

जहां xकोड बिंदु के बिट्स का प्रतिनिधित्व करता है। हालाँकि, 128 से अधिक या उससे अधिक के कोड-पॉइंट्स के लिए, पहले बाइट को 1बाइट्स की कुल संख्या के साथ समान संख्या में गद्देदार किया जाता है, और बाद में बाइट्स शुरू होते हैं 10। कोड-पॉइंट के बिट्स को कम से कम संभव मल्टीबाइट अनुक्रम देने के लिए दर्ज किया जाता है, और शेष बिट्स बन जाते हैं 0

No. of bytes  Format
1             0xxxxxxx
2             110xxxxx 10xxxxxx
3             1110xxxx 10xxxxxx 10xxxxxx
4             11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
...           ...

इत्यादि।

अब यह देखा जा सकता है कि प्रत्येक संख्या बाइट्स के लिए n, कोड-पॉइंट बिट्स की संख्या के लिए ऊपरी सीमा द्वारा दी गई है (-n+7)+6(n-1) = 5n+1। इसलिए, cप्रत्येक के लिए ऊपरी सीमा कोड-बिंदु nदशमलव में, द्वारा दी गई है c= 2^(5n+1)। इससे पता चलता है n = (log2(c)-1)/5। तो किसी भी कोड-बिंदु के लिए, बाइट की संख्या उपरोक्त अभिव्यक्ति का मूल्यांकन करके, और फिर छत पर ले जाकर पाई जा सकती है।

हालाँकि, यह सीमा में कोड बिंदुओं के लिए काम नहीं करता है 64 <= c <= 127, क्योंकि 1ASCII- जैसे 1 बाइट वर्णों के लिए पैडिंग की कमी का मतलब है कि गलत ऊपरी सीमा की भविष्यवाणी की गई है, और इसके log2लिए अपरिभाषित है c = 0, जो कि एक अशक्त बाइट होता है। इनपुट में मौजूद है। इसलिए, यदि c <= 127, 1n के लिए मान लौटाया जाता है।

यह वही है जो कोड कर रहा है; iस्ट्रिंग में प्रत्येक वर्ण के लिए x, कोड-पॉइंट ordफ़ंक्शन का उपयोग करके पाया जाता है , और फ़्लिप विभाजन के बजाय पूर्णांक का उपयोग करके 5और फिर जोड़कर अभिव्यक्ति की छत पाई जाती है 1। चूंकि पायथन का फ्लोट प्रकार हमेशा पूर्णांक का प्रतिनिधित्व करता है x.0, यहां तक ​​कि पूर्णांक विभाजन के बाद, परिणाम intशून्य ट्रेस को हटाने के लिए फ़ंक्शन को पास किया जाता है। यदि ord(i) <= 127, तार्किक शॉर्ट-सर्किटिंग का मतलब है कि 1इसके बजाय वापस आ गया है। प्रत्येक वर्ण के लिए बाइट की संख्या एक सूची में एक तत्व के रूप में संग्रहीत की जाती है, और यह सूची वापस आ जाती है।


5

जावा 10, 100 96 95 67 61 बाइट्स

a->{for(var c:a)System.out.print(c.getBytes("utf8").length);}

-4 बाइट्स रिक्त स्थान को हटाते हैं क्योंकि यह टिप्पणी में अनुमति दी जाती है
-1 बाइट बदलने के UTF-8लिए utf8
-28 बाइट्स जावा 7 से 8 तक जा रहा है ( -3 के a->{...}बजाय void c(char[]i)throws Exception{...})
-3 बाइट्स को चरित्र-सरणी के बजाय स्ट्रिंग-सरणी के रूप में इनपुट लेते हैं, और
-3 बाइट्स जावा 8 से 10 ( varबजाय String)

स्पष्टीकरण:

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

a->{                      // Method with String-array parameter and no return-type
  for(var c:a)            //  Loop over the input-array
    System.out.print(     //   Print:
      c.getBytes("utf8")  //    The bytes as array in UTF-8 of the current item,
       .length);}         //    and print the amount of bytes in this array

क्या यह अशक्त बाइट्स के लिए काम करता है?
बिल्ली

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

3

जूलिया, 34 बाइट्स

s->s>""?map(sizeof,split(s,"")):[]

यह एक अनाम फ़ंक्शन है जो एक स्ट्रिंग को स्वीकार करता है और एक पूर्णांक सरणी देता है। इसे कॉल करने के लिए, इसे एक वैरिएबल पर असाइन करें।

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

इसे ऑनलाइन आज़माएं! (सभी परीक्षण मामले शामिल हैं)


s->[sizeof("$c")for c=s]कुछ बाइट्स बचाता है।
डेनिस

अजीब; करता है split("","")वापस नहीं []? (जावास्क्रिप्ट "".split("")करता है।)
नील

@ नील split("","")प्रकट होता है ""(पायथन के विपरीत जो एक अपवाद देता है) लेकिन मुझे []और ""जूलिया में अनुकूलता के बारे में कुछ भी पता नहीं है ।
बिल्ली

@ नील नं, split("", "") == [""]यानी खाली तत्व वाले एक तत्व सरणी, लेकिन मुद्दा यह है sizeof("") == 0, जो ओपी ने कहा कि अनुमति नहीं है।
एलेक्स ए।

@ डेनिस गैर-अनुक्रमिक तारों के लिए विफल हो जाएगा। (हालांकि एक उदाहरण ऑफहैंड के बारे में नहीं सोच सकते।)
एलेक्स ए।

3

PHP, 92 57 बाइट्स

दूसरे विचार पर आप ऐसा कर सकते हैं जिसके आसपास बहुत कम फ़फ़िंग हो:

<?php for(;$a=strlen(mb_substr($argv[1],$i++,1));)echo$a;

यह ऑनलाइन ध्यान दें कि यह थोड़ा लंबा है क्योंकि यह प्रोग्राम तर्क के बजाय स्टडिन का उपयोग करता है।
इस संस्करण में आपको stderr को भेजे गए नोटिस को अनदेखा करना होगा लेकिन यह ठीक है

पुराने संस्करण:
अन्य php उत्तर के बजाय एक अलग दृष्टिकोण का उपयोग करता है। Php में मल्टी-बाइट स्ट्रिंग्स के लिए देशी समर्थन की कमी पर निर्भर करता है।

<?php for($l=strlen($a=$argv[1]);$a=mb_substr($a,1);$l=$v)echo$l-($v=strlen($a));echo$l?:'';

अच्छा जवाब! मुझे लगता है कि आप उद्घाटन टैग को पूरी तरह से छोड़ सकते हैं, या इसे बदल सकते हैं<?=
बिल्ली

टैग के बिना यह एक प्रोग्राम के बजाय एक कोड स्निपेट है, और यहां तक ​​कि अगर इसकी अनुमति है तो यह मुझे अस्पष्ट रूप से गंदा महसूस करता है। वैकल्पिक टैग के साथ आपको एक पार्स त्रुटि मिलती है (या कम से कम मैंने php 5.5 पर किया है जो कि मैं उपयोग कर रहा हूं)।
14:55 पर user55641

ठीक है :) मुझे नहीं पता PHP (न ही मैं चाहता हूं, खांसी ), लेकिन मैं आपको यहां बताऊंगा
cat

3

एमएसीएस लिस्प, 55 49 बाइट्स

(lambda(s)(mapcar'string-bytes(mapcar'string s)))

पहले स्ट्रिंग को वर्णों की सूची में विच्छेदित करता है (mapcar 'string s)stringEmacs लिस्प में समारोह वर्णों की एक सूची लेता है और उनमें से बाहर एक स्ट्रिंग बनाता है। Emacs जिस तरह से तारों को विभाजित करता है mapcar(यानी पूर्णांक की सूची में, वर्ण या तार नहीं), इस स्पष्ट रूपांतरण की आवश्यकता है। फिर string-bytesस्ट्रिंग्स की उस सूची पर फ़ंक्शन को मैप करता है ।

उदाहरण:

(mapcar 'string "abc") ; => ("a" "b" "c")
(mapcar 'string-bytes '("a" "b" "c")) ; => (1 1 1) 

परीक्षण के मामलों:

(mapcar
 (lambda(s)(mapcar'string-bytes(mapcar'string s)))
 '("!""Ciao""tʃaʊ""Adám""ĉaŭ""ĉaŭ""チャオ""""!±≡𩸽""\0"))
;; ((1) (1 1 1 1) (1 2 1 2) (1 1 2 1) (2 1 2) (1 2 1 1 2) (3 3 3) nil (1 2 3 4) (1))

पुराना उत्तर:

(lambda(s)(mapcar(lambda(s)(string-bytes(string s)))s))

Ungolfed:

 (lambda (s)
   (mapcar
    ;; we can't use string-bytes directly,
    ;; since Emacs mapcar yields a list of ints instead of characters
    ;; therefore we need a wrapper function here. 
    (lambda (s)
      (string-bytes (string s)))
    s))

परीक्षण के मामलों:

(mapcar
 (lambda(s)(mapcar(lambda(s)(string-bytes(string s)))s))
 '("!""Ciao""tʃaʊ""Adám""ĉaŭ""ĉaŭ""チャオ""""!±≡𩸽""\0"))
;; ((1) (1 1 1 1) (1 2 1 2) (1 1 2 1) (2 1 2) (1 2 1 1 2) (3 3 3) nil (1 2 3 4) (1))


nilयदि आप परिणाम को समतल करते हैं तो क्या होता है ?
19

1
@ Adám nilएक खाली सूची है (और Emacs में "झूठा" कहने का एकमात्र तरीका)। हालांकि Emacs में कोई मानक समतल नहीं है (आप डैश का उपयोग कर सकते हैं -flatten) कोई भी संभावित कार्यान्वयन इसे समाप्त कर देगा।
लॉर्ड यूमा

3

जावास्क्रिप्ट (नोड), 27 बाइट्स

s=>s.map(Buffer.byteLength)

यह अलग-अलग वर्णों के एक सरणी के रूप में इनपुट लेता है, और बाइट काउंट की एक सरणी देता है।

Bufferकच्चे बाइनरी डेटा का प्रतिनिधित्व करने का एक तरीका है। Buffer.byteLength (स्ट्रिंग) स्ट्रिंग में बाइट्स की संख्या देता है। UTF-8 डिफ़ॉल्ट एन्कोडिंग है। ध्यान दें कि केवल Node.js में बफर हैं, न कि ब्राउज़र JS। समतुल्य ब्राउज़र समतुल्य को बूँद कहा जाता है , जो 31 बाइट्स में आता है:

s=>s.map(e=>new Blob([e]).size)

परीक्षा

इस फ़ाइल को सहेजें और इसे नोड के माध्यम से चलाएं, या इसे ऑनलाइन आज़माएं

var f =
  s=>s.map(Buffer.byteLength)

var tests = [
  ["!"],
  ["C","i","a","o"],
  ["t","ʃ","a","ʊ"],
  ["A","d","á","m"],
  ["ĉ","a","ŭ"],
  ["c","̂","a","u","̆"],
  ["チ","ャ","オ"],
  [],
  ["!","±","≡","𩸽"]
];

tests.forEach(test => {
  console.log(test, f(test));
});

यह परिणाम होना चाहिए:

$ node bytes.js
[ '!' ] [ 1 ]
[ 'C', 'i', 'a', 'o' ] [ 1, 1, 1, 1 ]
[ 't', 'ʃ', 'a', 'ʊ' ] [ 1, 2, 1, 2 ]
[ 'A', 'd', 'á', 'm' ] [ 1, 1, 2, 1 ]
[ 'ĉ', 'a', 'ŭ' ] [ 2, 1, 2 ]
[ 'c', '̂', 'a', 'u', '̆' ] [ 1, 2, 1, 1, 2 ]
[ 'チ', 'ャ', 'オ' ] [ 3, 3, 3 ]
[] []
[ '!', '±', '≡', '�' ] [ 1, 2, 3, 4 ]

3

बैश, 74 बाइट्स

golfed

xxd -p|fold -2|cut -c1|tr -d '89ab'|echo `tr -t '01234567cbef' '[1*]2234'`

कलन विधि

हेक्सडंप इनपुट स्ट्रिंग, प्रति पंक्ति 2 वर्ण गुना, केवल पहले चार को काटें

echo -ne '!±≡𩸽' | xxd -p|fold -2|cut -c1

2
c
b
e
8
a
f
a
b
b

(एक हेक्स चार के रूप में प्रत्येक इनपुट बाइट के 4 उच्च क्रम बिट्स, प्रति पंक्ति एक)

"निरंतरता बाइट्स" 0x80..0xBF निकालें

tr -d '89ab'

2
c

e


f

(क्या बचा है, एक यूनिकोड चार के पहले बाइट के 4 बिट्स है)

चार्ट की लंबाई में पहले बिट्स को मैप करें, आउटपुट को प्रिंट करें और प्रिंट करें

echo `tr -t '01234567cbef' '[1*]2234'`

1 2 3 4

परीक्षा

 U() { xxd -p|fold -2|cut -c1|tr -d '89ab'|echo `tr -t '01234567cbef' '[1*]2234'`;}

 echo -ne '!' | U 
 1

 echo -ne 'Ciao' | U
 1 1 1 1

 echo -ne 'tʃaʊ' | U
 1 2 1 2

 echo -ne 'Adám' | U
 1 1 2 1

 echo -ne 'ĉaŭ' | U
 2 1 2

 echo -ne 'ĉaŭ' | U
 1 2 1 1 2

 echo -ne 'チャオ' | U
 3 3 3
 echo -ne '!±≡𩸽' | U
 1 2 3 4

 echo -ne "\x0" | U
 1

 echo -ne '' | U

+1 अच्छा तरीका। आप वास्तव में इनपुट से सीधे परिणाम पढ़ते हैं।
Adám

-tकरने के लिए विकल्प trमेरे लिए अपरिचित था, और जाहिरा तौर पर एक जीएनयू विस्तार है। आदेश प्रतिस्थापन के बाद पाइपिंग echoभी थोड़ा अधिक विस्तृत विवरण के लायक हो सकती है।
ट्रिपलआई


2

सी #, 89 82 बाइट्स

I=>{var J="";foreach(char c in I){J+=Encoding.UTF8.GetByteCount(c+"");}return J;};

एक साधारण सी # लैम्ब्डा जो स्ट्रिंग के माध्यम से पुनरावृत्ति करता है और अंतरिक्ष से अलग की गई सूची लौटाता है।

संपादित करें: कुछ बहुत अच्छी टिप्पणियों के लिए 6 बाइट्स सहेजे गए।


बहुत यकीन है कि आप कर सकते हैंvar J="";...
बिल्ली

इसके अलावा, ओपी एक टिप्पणी में कहता है कि आपको आउटपुट को अलग करने की आवश्यकता नहीं है 1121और 1 2 1 2दोनों ठीक हैं
बिल्ली

1
@ धन्यवाद, मुझे 6 बाइट्स
बचाए

इसके अलावा, आपके पास एक अतिरिक्त जगह है} return J;};
बिल्ली

लगता है जैसे आपको using System.Textया उसके लिए आवश्यक हैं - आयात मुफ्त नहीं हैं।
बिल्ली

2

हास्केल, 85 बाइट्स

import Data.ByteString as B
import Data.ByteString.UTF8
(B.length.fromString.pure<$>)

थोड़ा देर से, लेकिन यह छोटा होगाmap$...
H.PWiz


1

सी, 85 बाइट्स।

l(unsigned char* c){while(*c){int d=(*c>>4)-11;
d=d<0?1:d+(d==1);putchar(48+d);c+=d;}}

एन्कोडिंग और स्किप करने के लिए बाद के बाइट्स की संख्या निर्धारित करने के लिए प्रत्येक बाइट के उच्च 4 बिट्स की जांच करता है;


क्या यह नल बाइट्स पर काम करता है?
बिल्ली

हां, while *c एक खाली स्ट्रिंग पर बाहर निकलता है, और बहु ​​बाइट कोडपॉइंट के बीच में `c + = d 'स्किल्स नल करता है।
एशेल्ली

1
यह गलत है। char*C में एक स्ट्रिंग ( , वास्तव में) का अंत एक अशक्त बाइट के साथ चिह्नित है। स्ट्रिंग के वास्तविक छोर से नल बाइट्स को भेद करना असंभव है।
डेनिस

@ डेनिस प्रीकली क्योंकि कोई अंतर नहीं है :)
बिल्ली

1
ओपी ने एक टिप्पणी में कहा (और अब यह पोस्ट में है) आप एक तर्क के रूप में बाइट्स में स्ट्रिंग की लंबाई का अनुरोध कर सकते हैं, इसलिए ऐसा करें और यह फिर से मान्य होगा
बिल्ली

1

फैक्टर, 57 87 82 80 बाइट्स

[ [ dup zero? [ drop "1"] [ >bin length 4 /i 10 >base ] if ] { } map-as ""join ]

व्याख्या की:

USING: kernel math math.parser sequences ;
IN: byte-counts

: string>byte-counts ( str -- counts )
  [                  ! new quotation: takes a char as a fixnum
    dup zero?        ! true if this is a NUL byte
    [ drop "1" ]     ! NUL bytes have length 1
    [ >bin           ! else, convert to binary string
      length         ! length of binary string
      4              ! the constant 4
      /i             ! integer division
      number>string  ! 4 -> "4"
    ] if             ! conditionally execute one of the previous quotations
  ]                  ! end
  { } map-as         ! map and clone-like an { } array
  "" join ;          ! join array of 1strings on empty string

इकाई परीक्षण:

USING: tools.test byte-counts ;
IN: byte-counts.tests

{ "1" } [ "!" string>byte-counts ] unit-test
{ "1111" } [ "Ciao" string>byte-counts ] unit-test
{ "1212"} [ "tʃaʊ" string>byte-counts ] unit-test
{ "1121" } [ "Adám" string>byte-counts ] unit-test
{ "212" } [ "ĉaŭ" string>byte-counts ] unit-test
{ "12112" } [ "ĉaŭ" string>byte-counts ] unit-test
{ "333" } [ "チャオ" string>byte-counts ] unit-test
{ "" } [ "" string>byte-counts ] unit-test
{ "1234" } [ "!±≡𩸽" string>byte-counts ] unit-test
{ "1" } [ "\0" string>byte-counts ] unit-test

वे सभी अब, गुजरते हैं। सी:


1

स्विफ्ट 2.2, 67 52 50 बाइट्स

for c in i.characters{print(String(c).utf8.count)}

बुरी तरह से बदसूरत। वहाँ स्विफ्ट में एक चरित्र के लिए UTF-8 लंबाई प्राप्त करने के लिए कोई रास्ता नहीं है, इसलिए मैं चरित्र से स्ट्रिंग के माध्यम से पुनरावृति करने की जरूरत है, परिवर्तित Characterएक करने के लिए String, और पाते हैं countकि एकल चरित्र का String(हे, कम से कम वहाँ एक अंतर्निहित करने की विधि)। अनुकूलन की तलाश में, संभवतः एक स्कैनर का उपयोग करना।

संशोधन 1: के countबजाय का उपयोग करके 15 बाइट्स सहेजे गए underestimateCount()

संशोधन 2: प्रत्येक क्लोजर के लिए फॉर-इन लूप का उपयोग करके एक और 2 वर्ण को सहेजा गया।


1

जंग, 53 बाइट्स

|s:&str|for c in s.chars(){print!("{}",c.len_utf8())}

Rust में utf-8 char primitives, iterators और lambdas हैं, इसलिए यह सीधा था। टेस्ट कोड:

fn main() {
    let s = "Löwe 老虎 Léopard💖💖💖💖";
    let f =|s:&str|for c in s.chars(){print!("{}",c.len_utf8())};
    f(s);
}

आउटपुट

1211133112111114444 

1

jq, 26 वर्ण

(23 वर्ण कोड + 3 वर्ण कमांड लाइन विकल्प)

(./"")[]|utf8bytelength

उम्मीद है कि प्रतिस्पर्धा हो। हालांकि इस सवाल से 9 ++ महीने पहले जोड़ाutf8bytelength गया था , लेकिन यह अभी भी जारी किए गए संस्करण में शामिल नहीं है।

नमूना रन:

bash-4.3$ ./jq -R '(./"")[]|utf8bytelength' <<< 'tʃaʊ'
1
2
1
2

bash-4.3$ ./jq -R '(./"")[]|utf8bytelength' <<< 'ĉaŭ '
1
2
1
1
2
1

bash-4.3$ ./jq -R '(./"")[]|utf8bytelength' <<< 'チャオ'
3
3
3

bash-4.3$ ./jq -R '(./"")[]|utf8bytelength' <<< ''

bash-4.3$ ./jq -R '(./"")[]|utf8bytelength' <<< '!±≡𩸽'
1
2
3
4


1

स्माइलबासिक, 69 बाइट्स

DEF C B
WHILE I<LEN(B)Q=INSTR(BIN$(B[I],8),"0")I=I+Q+!Q?Q+!Q
WEND
END

इनपुट बाइट्स की एक सरणी है।

UTF-8 वर्ण में बाइट्स की संख्या 1पहले बाइट में अग्रणी बिट्स की संख्या के बराबर है (जब तक कि कोई 1एस नहीं हैं , उस स्थिति में चरित्र 1 बाइट है)। अग्रणी 1s की संख्या को खोजने के लिए, प्रोग्राम 0बाइनरी प्रतिनिधित्व में पहले पाता है , फिर 1 जोड़ता है यदि यह 0 था।

0xxxxxxx - no leading ones, 1 byte
110xxxxx 10xxxxxx - 2 leading ones, 2 bytes
1110xxxx 10xxxxxx 10xxxxxx - 3 leading ones, 3 bytes
etc.

1

एफ #, 59 54 66 बाइट्स

(s)=seq{for c in s->System.Text.Encoding.UTF8.GetByteCount([|c|])}

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

कंसोल में इसका परीक्षण करते समय !±≡𩸽, यह कांजी को दो वर्णों में विभाजित करता है, प्रत्येक 3 बाइट्स लंबे समय तक। अन्य सभी परीक्षण मामले ठीक काम करते हैं।

संपादित करें: यह पता चला है कि सामान्य नाम स्थान आयात निहित नहीं हैं। एक और 12 वर्ण।


1) टिम्मी डी के पॉवरशेल उत्तर में 6-बाइट्स-प्रति-कांजी समस्या समान है। मैं इसे विंडोज को यूनिकोड में गूंगा और बेकार होने का श्रेय दूंगा। 2) अगर आपको किसी फाइल से पढ़ते समय कांजी के लिए 6 बाइट्स मिलते हैं, UTF-8 without BOMतो यह गलत है और इसे ठीक किया जाना चाहिए। 3) लगता है जैसे F # को SML की तरह बयान let f(x)= ...समाप्त करने की आवश्यकता है ;;। 4) आप इस अनाम फ़ंक्शन को नाम देना छोड़ सकते हैं, अर्थात (s)=seq{for c in s->Encoding.UTF8.GetByteCount([|c|])}
बिल्ली

इसके अलावा, मैं error FS0039: The namespace or module 'Encoding' is not definedइसे चलाने की कोशिश कर रहा हूँ । मैं क्या गलत कर रहा हूं?
बिल्ली

इसके अलावा, प्रोग्रामिंग पहेलियाँ और कोड गोल्फ में आपका स्वागत है, यह एक अच्छा पहला जवाब है! : D
बिल्ली

@cat आपको System.Textनामस्थान खोलने की आवश्यकता है । मैं मान रहा हूं कि नाम स्थान खुलता है और प्रवेश कोड शामिल है, एस्ट्रोदान के सी # उत्तर से आ रहा है।
मुहरबंद इंटरफ़ेस

आप किसी भी बाइट्स गिनती करने के लिए की जरूरत है import, #include, open, load, require, using, USING:आदि PPCG पर यहाँ। एस्ट्रोदान का C # उत्तर भी इसी तरह गलत है, और मैंने उन्हें इस बारे में सूचित किया।
बिल्ली

1

05AB1E , 15 बाइट्स

ÇεDžy‹i1ë.²<5÷>

इसे ऑनलाइन आज़माएं। सभी परीक्षण मामलों में प्रत्येक के लिए
हैडरεका उपयोग किया जाता है; आउटपुट वर्ण-सूचियों को सुंदर प्रिंट करने के लिए
पाद लेखï]J]»(ï: पूर्णांक और वर्णों को पूर्णांक:;]पास if- और के लिए और प्रत्येक के लिए ;J: एक साथ अंकों में शामिल हों ;}: करीबी हेडर foreach ;»: नई लाइनों से जुड़ें)।

स्पष्टीकरण:

Ç                   # Convert each character to its unicode value
 εD                 # Foreach over this list
      i             #  If the current item
     ‹              #  is smaller than
   žy               #  128
       1            #   Use 1
        ë           #  Else
         .²         #   Use log_2
           <        #   minus 1
            5÷      #   integer-divided by 5
              >     #   plus 1

चूँकि 05AB1E में अक्षरों का उपयोग Çकरने के लिए पात्रों को परिवर्तित करने के लिए कोई भी भवन नहीं है, इसलिए मैं पात्रों को उनके यूनिकोड मानों में परिवर्तित करने के लिए उपयोग करता हूं , और प्रत्येक के लिए छद्म कोड में निम्नलिखित कार्य करता हूं:

if(unicodeValue < 128)
  return 1
else
  return log_2(unicodeValue-1)//5+1    # (where // is integer-division)

@TheBikingViking के पायथन 3 उत्तर से प्रेरित ।


0

Zsh , 41 बाइट्स

for c (${(s::)1})set +o multibyte&&<<<$#c

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

Zsh UTF-8 से अवगत है, इसलिए हम पात्रों पर स्ट्रिंग को विभाजित करते हैं, फिर मल्टीबाइट को अक्षम करते हैं और प्रत्येक चरित्र की लंबाई को प्रिंट करते हैं।

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