Độ dài của chuỗi UTF-8 byte


15

Xác định độ dài của chuỗi byte UTF-8 cho byte đầu tiên của nó. Bảng sau đây cho thấy phạm vi bản đồ theo từng độ dài có thể:

  Range    Length
---------  ------
0x00-0x7F    1
0xC2-0xDF    2
0xE0-0xEF    3
0xF0-0xF4    4

Lưu ý về các khoảng trống trong bảng: 0x80-0xBF là các byte tiếp tục, 0xC0-0xC1 sẽ bắt đầu một chuỗi quá dài, không hợp lệ, 0xF5-0xFF sẽ dẫn đến một mật mã vượt quá mức tối đa Unicode.

Viết chương trình hoặc hàm lấy byte đầu tiên của chuỗi byte UTF-8 làm đầu vào và đầu ra hoặc trả về độ dài của chuỗi. I / O là linh hoạt. Ví dụ: đầu vào có thể là một số, ký tự 8 bit hoặc chuỗi một ký tự. Bạn có thể giả sử rằng byte đầu tiên là một phần của chuỗi hợp lệ và rơi vào một trong các phạm vi trên.

Đây là mã golf. Câu trả lời ngắn nhất trong byte thắng.

Các trường hợp thử nghiệm

0x00 => 1
0x41 => 1
0x7F => 1
0xC2 => 2
0xDF => 2
0xE0 => 3
0xEF => 3
0xF0 => 4
0xF4 => 4

Đầu vào của danh sách 8 bit có được chấp nhận không?
Jonathan Allan

@Jonathan ALLan Không, điều đó sẽ đưa I / O linh hoạt đi quá xa.
nwellnhof

Câu trả lời:


5

Forth, 6 byte

x-size

xem https://forth-st Chuẩn.org / st Chuẩn / xchar / X-SIZE

Đầu vào và đầu ra theo mô hình Forth tiêu chuẩn:

Đầu vào

Địa chỉ bộ nhớ + chiều dài (tức là 1) của một "chuỗi" UTF-8 byte đơn.

Đầu ra

Độ dài chuỗi UTF-8 tính bằng byte.

Mã mẫu

Lưu trữ 0xF0 trong một ô nhớ và gọi kích thước x:

variable v
0xF0 v !
v 1 x-size

Kiểm tra kết quả:

.s <1> 4  ok

Giả sử điều này hoạt động trong tio.run/#forth-gforth , bạn có thể đưa ra một ví dụ không? Tôi không hiểu làm thế nào bạn có thể có chuỗi UTF-8 một byte nếu byte là 0xF0.
Dennis

> bạn có thể đưa ra một ví dụ? Tôi không hiểu làm thế nào bạn có thể có chuỗi UTF-8 một byte nếu byte là 0xF0. Tôi đã thêm một số mã mẫu minh họa cách thực hiện. Thật không may, phiên bản TIO của gforth dường như không hỗ trợ các từ Unicode (theo "xem kích thước x", nó chỉ được mã hóa cứng để trả về 1 ở đó).
zeppelin

Tôi hiểu rồi. Tuy nhiên, đó không phải là cái mà tôi gọi là chuỗi UTF-8, vì riêng F0 là chuỗi byte không hợp lệ, theo như UTF-8 có liên quan.
Dennis

> vì một mình F0 là một chuỗi byte không hợp lệ Đúng (đó là lý do tại sao tôi đặt từ "chuỗi" trong dấu ngoặc kép), nhưng nhiệm vụ này đặc biệt là nhận ra chuỗi đó bằng byte đầu tiên và Forth không thực sự quan tâm đến việc nó không hợp lệ , mà làm cho giải pháp này có thể, lần lượt.
zeppelin

6

Z80Golf , 19 14 byte

00000000: 2f6f 3e10 37ed 6a3d 30fb ee07 c03c       /o>.7.j=0....<

Hãy thử trực tuyến!

-5 byte nhờ @Bubbler

Ví dụ với đầu vào 0x41-Hãy thử trực tuyến! hội,, tổ hợp

Ví dụ với đầu vào 0xC2-Hãy thử trực tuyến!

Ví dụ với đầu vào 0xE0-Hãy thử trực tuyến!

Ví dụ với đầu vào 0xF4-Hãy thử trực tuyến!

Hội,, tổ hợp:

;input: register a
;output: register a
byte_count:			;calculate 7^(log2(255^a))||1
	cpl			;xor 255
	ld l,a
	log2:
		ld	a,16
		scf
	log2loop:
		adc	hl,hl
		dec	a
		jr	nc,log2loop
	xor 7
	ret nz
	inc a

Hãy thử trực tuyến!


Sử dụng Bash TIO để làm việc với lắp ráp, với các ví dụ dễ nhìn hơn. Liên kết cũng có phiên bản 15 byte của giải pháp của bạn. Dưới đây là những cải tiến: xor 0xff -> cpl, không cần phải or a, jr nz, return -> ret nz, ld a,1 -> inc a.
Bong bóng


4

Thạch ,  8  7 byte

+⁹BIITḢ

Một liên kết đơn âm chấp nhận byte là một số nguyên.

Hãy thử trực tuyến! Hoặc xem tất cả các đầu vào được đánh giá .

Nếu đầu vào của danh sách 8 bit được chấp nhận thì phương thức chỉ có 6 byte: 1;IITḢtuy nhiên, nó được coi là I / O linh hoạt nói chuyện quá xa.

Làm sao?

+⁹BIITḢ - Link: integer       e.g.: 127 (7f)            223 (df)            239 (ef)            244 (f4)
 ⁹      - literal 256
+       - add                       383                 479                 495                 500
  B     - to a list of bits         [1,0,1,1,1,1,1,1,1] [1,1,1,0,1,1,1,1,1] [1,1,1,1,0,1,1,1,1] [1,1,1,1,1,0,1,0,0]
   I    - increments                [-1,1,0,0,0,0,0,0]  [0,0,-1,1,0,0,0,0]  [0,0,0,-1,1,0,0,0]  [0,0,0,0,-1,1,-1,0]
    I   - increments                [2,-1,0,0,0,0,0]    [0,-1,2,-1,0,0,0]   [0,0,-1,2,-1,0,0]   [0,0,0,-1,2,-2,1]
     T  - truthy indices            [1,2]               [2,3,4]             [3,4,5]             [4,5,6,7]
      Ḣ - head                      1                   2                   3                   4



3

Jelly, 8 7 bytes

»Ø⁷Ba\S

Try it online!

How it works

»Ø⁷Ba\S  Main link. Argument: n (integer)

 Ø⁷      Yield 128.
»        Take the maximum of n and 128.
   B     Yield the array of binary digits.
    a\   Cumulatively reduce by AND, replacing 1's after the first 0 with 0's.
      S  Take the sum.



1

Charcoal, 12 bytes

I⌕⍘⌈⟦N¹²⁸⟧²0

Try it online! Link is to verbose version of code. Explanation:

     N          Input number
      ¹²⁸       Literal 128
   ⌈⟦    ⟧      Take the maximum
  ⍘       ²     Convert to base 2 as a string
 ⌕         0    Find the position of the first `0`
I               Cast to string
                Implicitly print



1

x86 Assembly, 11 bytes

00000000 <f>:
   0:   f6 d1                   not    %cl
   2:   0f bd c1                bsr    %ecx,%eax
   5:   34 07                   xor    $0x7,%al
   7:   75 01                   jne    a <l1>
   9:   40                      inc    %eax
0000000a <l1>:
   a:   c3                      ret

Try it online!

Port of user202729's JavaScript answer. Uses fastcall conventions.



1

05AB1E, 8 7 bytes

žy‚àb0k

Port of @Neil's Charcoal answer.
-1 byte thanks to @Grimy.

Input as integer.

Try it online or verify all test cases.

Explanation:

žy       # Push 128
        # Pair it with the (implicit) input-integer
   à     # Take the maximum of this pair (128 and input)
    b    # Convert it to a binary-string
     0k  # Get the 0-based first index of a "0" in this binary-string
         # (and output it implicitly as result)

1
s) to for 7. Porting the other Jelly answer gives another 8: ₁+b¥η€ËO
Grimmy

@Grimy No idea why I didn't had in the first place.. :S But thanks for -1.
Kevin Cruijssen

0

C, 31 bytes

f(x){return(x-160>>20-x/16)+2;}

Try it online!

27 bytes with gcc (-O0)

f(x){x=(x-160>>20-x/16)+2;}

Alternatives, 31 and 33 bytes

f(x){return(10>>15-x/16)+7>>2;}
f(x){return x/128-(-3>>15-x/16);}

I found these expressions when playing around with the Aha! superoptimizer a few years ago.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.