바이트 / 캐릭터


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

(널 바이트) → 1

널 바이트

총 바이트 수를 아는 것만으로도 널 바이트를 넘어서 입력을 읽는 유일한 방법이라면 어떤 방법 으로든 (사용자 입력조차도) 바이트 수를 얻을 수 있습니다.

언어에서 널 바이트를 전혀 처리 할 수없는 경우 입력에 널이 포함되지 않은 것으로 가정 할 수 있습니다.


1
입력이 비어 있으면 0 또는 다른 잘못된 값을 출력 할 수 있습니까?
Alex A.

2
분리하지 않고 바이트 수를 인쇄 할 수 있습니까? 가능한 가장 높은 값은 6이므로 모호하지 않습니다.
Dennis

3
널 바이트를 지원해야합니까? 일부 언어에서는 이러한 작업이 매우 어려울 수 있습니다.
Dennis

3
게시물에 추가해야합니다. 나는 그것이 차이를 낼 수 있는지 알 수있을만큼 대부분의 언어를 잘 모르지만 적어도 두 가지 답변을 무효화한다고 생각합니다.
Dennis

2
@ Adám 그렇습니다. 예를 들어 C에서 C 문자열은 NUL 바이트로 끝나므로 찾은 즉시 읽기를 중지합니다. 문자열의 길이를 알고 있으면 NUL과 그 이후의 많은 바이트 수를 읽은 후에 중지합니다.
고양이

답변:


10

Pyth, 9 7 바이트

2 바이트를 절약 한 @Maltysen에게 감사합니다!

mlc.Bd8

테스트 스위트

입력의 모든 문자를 이진 표현으로 변환 한 다음이를 길이가 8 인 청크로 나눕니다. 그런 청크의 수는 해당 문자를 인코딩하는 데 필요한 바이트의 양입니다.



@ Maltysen 영리합니다, 감사합니다!
Denker

1
비슷한 속임수를 사용하는 동일한 길이의 답변 :mlhc8.B
FryAmTheEggman

@LeakyNun 그렇다면 실패한 테스트 사례를 제공하는 것이 간단할까요?
Lause

8 바이트로 나누지 않고 다른 바이트를 저장하려면 매 8 번째를 취하십시오 ml%8.B(현재 d는 암시 적입니다).
Anders Kaseorg

21

파이썬 3, 42 36 바이트

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

13
-1 바이트 :을 사용하십시오 map. lambda x:map(len,map(str.encode,x))
NoOneIsHere6

11

C, 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

APL, 15 자

≢¨'UTF-8'∘⎕ucs¨

영어로 : 각 문자를 UTF-8 (의미 : 바이트 표현 벡터)로 변환하고 그 탈리를 가져옵니다.


바이트 저장 :≢¨'UTF-8'∘⎕ucs¨
Adám

사실 @ Adám ... 건배.
lstefano 2016 년

흥미로운 (그러나 더 긴) 배열 기반 접근법 :+⌿0 7 11 16∘.≤2⍟⎕UCS
Adám

버전 16.0 :0 7 11 16⍸2⍟⎕UCS
Adám

7

GolfScript, 16 바이트

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

온라인으로 사용해보십시오!

배경

GolfScript는 유니 코드가 무엇인지 전혀 모른다. 모든 문자열 (입력, 출력, 내부)은 바이트로 구성됩니다. 꽤 성가 시겠지만이 도전에 완벽합니다.

UTF-8은 ASCII 문자와 비 ASCII 문자를 다르게 인코딩합니다.

  • 128 미만의 모든 코드 포인트는로 인코딩됩니다 0xxxxxxx.

  • 다른 모든 코드 포인트는로 인코딩됩니다 11xxxxxx 10xxxxxx ... 10xxxxxx.

즉, 각 유니 코드 문자의 인코딩에는 단일 0xxxxxxx바이트 또는 단일 11xxxxxx바이트와 ​​1 ~ 5 10xxxxxx바이트가 포함됩니다.

하여 모든 입력 바이트로 나누어 64 우리 좌회전 0xxxxxxx으로 0 또는 1 , 11xxxxxx(3)10xxxxxx2 .

몫과 2를 비교하면 12로 밀고 ; 및 0 에 대해 0 , 1 , 및 3 - 각각의 문자는로 전환한다 0 1 내지 5 다음에, 하나 의.

남은 것은 결과 문자열을 0 발생에서 나누고 0 사이 의 1 수를 세고 그 양을 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($_)}

NB

좋아, 이것은 작동해야 하며 내 컴퓨터에서 𩸽계산되는 것을 제외하고 거의 모든 테스트 사례에서 수행 됩니다 3,3. 이 문자는 내 컴퓨터에서 7 바이트 로 표시됩니다 . @Mego 에는 문제가 없기 때문에 로컬 또는 로컬에서 실행중인 Windows 또는 .NET 버전의 일종의 버그 때문이라고 생각합니다 . ( 편집 : @cat은 이것이 BOM 때문이라고 지적합니다 . 미스터리 @cat를 해결해 주셔서 감사합니다! )

그러나 여전히 모든 문제를 설명하지는 않습니다. 그래도 문제의 일부 가 어디에서 오는지 알고 있다고 생각 합니다. .NET 내에서 모든 문자열은 UTF-16 코드 단위 (System.Char 형식)로 구성됩니다. PowerShell에서 사용하는 형식이 매우 느슨한 경우 백그라운드에서 형식간에 암시 적 캐스팅 및 변환 이 많이 발생 합니다. 아마도 이것은 우리 가보고있는 행동에 기여하는 요인 [system.text.encoding]::utf8.getchars([System.Text.UTF8Encoding]::UTF8.GetBytes('𩸽'))입니다.


설명

매우 간단한 코드입니다. 입력을 받아서 $args[0]명시 적으로 char-array로 캐스트하므로 string의 각 구성 요소를 반복 할 수 있습니다 |%{...}. 반복 할 때마다 .NET 호출 [System.Text.Encoding]::UTF8.GetByteCount()( System.암시 적)을 사용하여 현재 문자의 바이트 수를 가져옵니다 $_. 나중에 출력 할 수 있도록 파이프 라인에 배치됩니다. [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

추가 편집 텍스트 파일에서 데이터를 가져 와서 다음과 같이 파이프하는 경우 원래 게시 한 후 챌린지에 추가 된 널 바이트 요구 사항을 올바르게 설명합니다.

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.예, UTF-8을 사용하여 Windows에서 얻는 바이트 순서 표시 때문입니다 . Notepad ++에게 UTF-8 without BOM( 특히 Unicies와의 호환성을 위해 항상 BOM 을 피해야 함) 알려주십시오. BOM이 3이고 4 + 3 = 7이기 때문에 파일의 크기는 4 바이트입니다.
cat

@cat 아, 맞습니다. 파일 크기의 차이를 설명합니다. 그러나 여전히 셸 자체의 다른 동작을 설명하지는 않습니다. 예를 들어 BOM없이 UTF-8로 저장하고 get-content -Encoding UTF8 .\z.txt|%{.\bytes-per-character.ps1 $_}계속 실행하면을 반환합니다 3,3.
AdmBorkBork 2016 년



6

자바 스크립트 (ES6), 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 BMP 이외의 문자는 실패하지만 문제를 해결할 수있었습니다.
Neil


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

Perl 6 은 NFG 문자열을 사용 하기 때문에 바이트를 직접 가져와야합니다.
(NFG는 합성 합성 코드 포인트도 생성한다는 점을 제외하면 NFC와 유사합니다)

출력은 개행으로 구분됩니다.

테스트:

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$?
Outgolfer Erik

@ EʀɪᴋᴛʜᴇGᴏʟғᴇʀ 아니요 다른 것으로 해석되기 때문입니다. 전에 공간을 제거 할 수 있습니다while그래도 .
Brad Gilbert b2gills

NFG 대책을 설명 할 수 있습니까?
JDługosz 2016 년

이 프로그램의 STDIN에 NUL 바이트를 에코하면 인쇄합니다. \n1\n1\n 의도적으로 됩니까? 기본적으로 NUL 바이트를 처리합니까?
고양이

@cat 왜 그렇지 않습니까? 내가 이것을 할 때 : perl -e 'print "𩸽\0𩸽"' | perl6 -e '...'나는 얻는다4␤1␤4 기대했던 것처럼 습니다. (그래도 난 게시 된 후 NUL을에 대한 부분이 추가되었습니다)
브래드 길버트는 b2gills

5

파이썬 3, 82 바이트

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

이것은 다른 Python 답변과 대부분의 다른 답변보다 훨씬 길지만 아직 보지 못한 로그와 관련된 접근법을 사용합니다.

인수를 통해 입력을 문자열로 받아서 목록을 반환하는 익명 함수입니다.

Ideone에서 사용해보십시오

작동 원리

이 방법은 UTF-8이 문자의 코드 포인트를 인코딩하는 방식에 의존합니다. 코드 포인트가 128보다 작은 경우 문자는 ASCII와 같이 인코딩됩니다.

0xxxxxxx

여기서 x코드 포인트의 비트를 나타냅니다. 그러나 128보다 크거나 같은 코드 포인트의 경우 첫 번째 바이트는 1총 바이트 수와 동일한 수의 s로 채워 지고 후속 바이트가 시작됩니다 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에 대한 상한 코드 포인트 는 10 진수로로 주어진다 c= 2^(5n+1). 이것을 재정렬하면 n = (log2(c)-1)/5. 따라서 모든 코드 포인트의 경우 위의 식을 평가 한 다음 상한값을 가져와 바이트 수를 찾을 수 있습니다.

그러나 범위 내의 코드 포인트에는 작동하지 않습니다. 64 <= c <= 1271 1 바이트 문자에 대한 ASCII 유사 인코딩으로 인한 패딩이 없기 때문에 잘못된 상한이 예측되고 log2정의되지 않은 c = 0null 바이트 인 경우이 입력에 존재합니다. 따라서이면 n c <= 127의 값 1이 반환됩니다.

이것이 바로 코드가하는 일입니다. i문자열의 각 문자 에 대해 x코드 포인트는 ord함수를 사용하여 발견되며 표현식의 상한은로 나누기 5후 정수를 사용하는 대신 정수를 사용하여 찾습니다 1. 파이썬의 float 유형은 항상 정수를 x.0정수 나누기 이후 로 나타 내기 때문에 결과는 int후행 0을 제거하는 함수로 전달 됩니다. 인 경우 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 바이트 는 Java 7에서 8 대신 -28 바이트로 변경 UTF-8됩니다 utf8
(- a->{...}대신 void c(char[]i)throws Exception{...})
-3 바이트는 입력을 문자 배열 대신 문자열 배열로 사용하고
-3 바이트를 입력합니다. (10 자바 8에서가는 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

null 바이트에서도 작동합니까?
고양이

@cat 나중에 널 바이트에 대한 테스트 사례가 추가되었습니다. 그러나 예, null 바이트에서도 작동하며 테스트 사례를 추가했습니다.
Kevin Cruijssen

3

줄리아, 34 바이트

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

이것은 문자열을 허용하고 정수 배열을 반환하는 익명 함수입니다. 호출하려면 변수에 지정하십시오.

접근 방식은 매우 간단합니다. 입력이 비어 있으면 출력이 비어 있습니다. 그렇지 않으면 우리는sizeof 문자열의 바이트 수를 계산 함수를 각 한 문자 하위 문자열에 .

온라인으로 사용해보십시오! (모든 테스트 케이스 포함)


s->[sizeof("$c")for c=s]몇 바이트를 절약합니다.
Dennis

이상한; split("","")반환 하지 []않습니까? (JavaScript의 기능 "".split(""))
Neil

@Neil는 split("","")줄이 나타납니다 ""(예외를 제공 파이썬 달리)하지만 난의 호환성에 대해 아무것도 모르는 []""줄리아에 있습니다.
고양이

@Neil No, split("", "") == [""]즉 빈 문자열을 포함하는 단일 요소 배열이지만 문제는 sizeof("") == 0OP가 허용하지 않는 것입니다.
Alex A.

@Dennis 인덱싱 할 수없는 문자열에는 실패합니다. (그렇지만 손에 든 사례는 생각할 수 없습니다.)
Alex A.

3

PHP, 92 57 바이트

두 번째 생각에 당신은 훨씬 덜 faffing으로 이것을 할 수 있습니다 :

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

온라인으로 사용해보십시오 . 프로그램 인수가 아닌 stdin을 사용하기 때문에 약간 더 깁니다.
이 버전에서는 stderr로 보낸 통지를 무시해야하지만 괜찮습니다 .

이전 버전 :
다른 PHP 답변에 다소 다른 접근 방식을 사용합니다. PHP에서 멀티 바이트 문자열에 대한 기본 지원 부족에 의존합니다.

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

좋은 대답입니다! 시작 태그를 완전히 삭제하거나 다음과 같이 변경할 수 있습니다.<?=
cat

태그가 없으면 프로그램이 아닌 코드 스 니펫이며 허용되는 경우에도 모호하게 더러워집니다. 대체 태그를 사용하면 구문 분석 오류가 발생합니다 (또는 적어도 PHP 5.5에서 사용했습니다).
user55641

좋아요 :) 내가 PHP를 모르는 (도 나는 하시겠습니까 기침 )하지만 난 당신을 가리킬 수 있습니다 : codegolf.stackexchange.com/questions/2913
고양이

3

이맥스 리스프, 55 49 바이트

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

먼저을 사용하여 문자열을 문자 목록으로 분석합니다 (mapcar 'string s). stringEmacs Lisp 의 함수는 문자 목록을 가져 와서 문자열을 만듭니다. 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))

언 골프 드 :

 (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결과를 평평하게하면 어떻게됩니까 ?
Adám

1
@ Adám nil은 빈 목록입니다 (Emacs에서 "false"라고 말하는 유일한 방법). Emacs에는 표준 평탄화가 없지만 (대시를 사용할 수 있음 -flatten) 가능한 구현은 제거합니다.
Lord Yuuma

3

자바 스크립트 (노드), 27 바이트

s=>s.map(Buffer.byteLength)

이것은 입력을 개별 문자의 배열로 받아서 바이트 수의 배열을 반환합니다.

Buffer원시 이진 데이터를 나타내는 방법입니다. Buffer.byteLength (string)문자열 의 바이트 수를 제공합니다. UTF-8이 기본 인코딩입니다. 브라우저 JS가 아닌 Node.js에만 버퍼가 있습니다. 대략적인 브라우저는 Blob 이며 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 바이트

골프

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

연산

16 진 덤프 입력 문자열, 한 줄에 2자를 접고 첫 번째 문자 만 잘라

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

2
c
b
e
8
a
f
a
b
b

(각 입력 바이트의 4 개의 상위 비트를 16 진 문자로 한 줄에 하나씩)

"연속 바이트"제거 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나에게 익숙하지 않은, 그리고 분명히 GNU 확장이다. 이후 의 명령 대체로 파이핑하는 echo것도 약간 더 자세한 설명이 필요합니다.
tripleee


2

C #, 89 82 바이트

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

문자열을 반복하고 공백으로 구분 된 목록을 반환하는 간단한 C # 람다.

편집 : 아주 좋은 의견 덕분에 6 바이트를 절약했습니다.


당신이 할 수있는 확실한 것var J="";...
cat

또한, 당신이 필요로하지 않는 코멘트에서 OP 상태 때문에 출력을 공간-분리 1121하고 1 2 1 2모두 OK입니다
고양이

1
@cat Thanks, 6 바이트를 절약했습니다
AstroDan

또한 추가 공간이 있습니다} return J;};
cat

당신이 필요로하는 것 같습니다 using System.Text-수입은 무료가 아닙니다.
고양이

2

하스켈, 85 바이트

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

조금 늦었지만, 이렇게 짧을 것입니다map$...
H.PWiz


1

C, 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 비트를 검사하여 건너 뛸 인코딩 및 후속 바이트 수를 판별하십시오.


이것은 null 바이트에서 작동합니까?
고양이

예, while *c 빈 문자열 에서 종료되며`c + = d '는 멀티 바이트 코드 포인트 중간에서 널을 건너 뜁니다.
AShelly

1
맞습니다. char*C에서 문자열의 끝 ( , 실제로)은 널 바이트로 표시됩니다. 문자열의 실제 끝과 널 바이트를 구별하는 것은 불가능합니다.
Dennis

@Dennis 차이가 없기 때문에 정확하게 :)
cat

1
OP는 주석에 문자열로 길이를 요청할 수 있다고 주석 (그리고 지금은 게시물에 있음)에 언급 했으므로 그렇게하면 다시 유효합니다.
고양이

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)}

끔찍한 못생긴. Swift에서 문자의 UTF-8 길이를 얻을 수있는 방법이 없으므로 문자별로 문자열을 반복해야합니다.Character 를 해당 단일 문자를 String찾아야합니다countString (최소한 내장 기능이 있습니다) 그렇게하는 방법). 스캐너를 사용하여 최적화를 찾고 있습니다.

개정 1 : 15 바이트를 사용하여 저장 count 대신을underestimateCount() .

개정 2 : 각 클로저에 대해 for-in 루프를 사용하여 다른 2자를 저장했습니다.


1

녹, 53 바이트

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

Rust에는 utf-8 char 프리미티브, 이터레이터 및 람다가 있으므로 간단합니다. 테스트 코드 :

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

SmileBASIC, 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는 첫 번째 바이트 의 선행 비트 수와 같습니다 ( 1s 가 없으면 문자가 1 바이트 임). 선행 1의 수를 찾기 위해 프로그램은 0이진 표현에서 첫 번째 를 찾은 다음 이것이 0 인 경우 1을 더합니다.

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

1

F #, 59 54 66 바이트

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

기술적으로 s는 문자 시퀀스이지만 문자열을 전달할 수있는 암시 적 변환이 있음이 밝혀졌습니다.

콘솔에서 이것을 테스트 할 때 !±≡𩸽 , 한자를 3 바이트 길이의 두 문자로 분할합니다. 다른 모든 테스트 사례는 정상적으로 작동합니다.

편집 : 일반적인 네임 스페이스 가져 오기는 암시 적이 지 않습니다. 다른 12 문자까지.


1) Timmy D의 파워 쉘 답변 은 한 칸당 6 바이트 문제와 동일합니다. 나는 Windows가 멍청하고 유니 코드에서는 쓸모가 없다고 생각합니다. 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

@cat System.Text네임 스페이스 를 열어야합니다 . AstroDan의 C # 답변에서 네임 스페이스가 열리고 항목 코드가 포함되어 있다고 가정합니다.
봉인 된 인터페이스

당신은 어떤의 바이트 계산해야하는 import, #include, open, load, require, using, USING:등 여기 PPCG에 있습니다. AstroDan의 C # 답변도 비슷하게 잘못되었으며, 나는 그 사실을 통보했습니다.
고양이

1

05AB1E , 15 바이트

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

온라인으로 사용해보십시오.
헤더ε는 모든 테스트 사례에 대해 각각 사용됩니다.
바닥 글ï]J]»출력 문자 목록을 꽤 - 인쇄에 (ï: 정수로 소수와 문자,]닫기 경우 - 다른 사람과의 foreach;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에는 문자를 사용 된 바이트 양으로 변환하는 내장 기능이 없으므로 Ç문자를 유니 코드 값으로 변환하는 데 사용 하며 for-each에서는 의사 코드에서 다음을 수행합니다.

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

@TheBikingViking 의 Python 3 답변에서 영감을 얻었습니다 .


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.