UTF-8字节序列的长度


15

给定第一个字节,确定UTF-8字节序列的长度。下表显示了哪些范围映射到每个可能的长度:

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

表中空白的注释:0x80-0xBF是连续字节,0xC0-0xC1将开始一个超长的无效序列,0xF5-0xFF将导致一个代码点超出Unicode最大值。

编写一个程序或函数,以UTF-8字节序列的第一个字节作为输入,然后输出或返回序列的长度。I / O是灵活的。例如,输入可以是数字,8位字符或一个字符的字符串。您可以假设第一个字节是有效序列的一部分,并且属于上述范围之一。

这是代码高尔夫。以字节为单位的最短答案将获胜。

测试用例

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

8位列表的输入是否可以接受?
乔纳森·艾伦

@JonathanAllan不,那会使灵活的I / O太过分了。
nwellnhof '18 -10-8

Answers:


5

第四个字节

x-size

看到 https://forth-standard.org/standard/xchar/X-SIZE

输入和输出遵循标准的Forth模型:

输入值

内存地址+单字节UTF-8“字符串”的长度(即1)。

输出量

UTF-8序列长度(以字节为单位)。

样例代码

0xF0存储在存储单元中,并调用x-size:

variable v
0xF0 v !
v 1 x-size

检查结果:

.s <1> 4  ok

假设这在tio.run/#forth-gforth有效,您可以举个例子吗?我不明白如果字节为0xF0,怎么会有单字节UTF-8字符串。
丹尼斯

>您可以举个例子吗?我不明白如果字节为0xF0,怎么会有单字节UTF-8字符串。我添加了一些示例代码来演示如何执行此操作。不幸的是,gforth的TIO版本似乎不支持Unicode单词(根据“ see x-size”,它只是硬编码以在那里返回1)。
齐柏林飞艇

我知道了。不过,这并不是我所说的UTF-8字符串,因为就UTF-8而言,仅F0是无效的字节序列。
丹尼斯

>因为F0本身是无效的字节序列True(这就是为什么我将“字符串”一词用引号引起来),但是此任务专门用于识别序列的第一个字节,因此Forth并不真正关心它是否无效,这又使该解决方案成为可能。
齐柏林飞艇

6

Z80Golf19 14字节

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

在线尝试!

-5个字节,感谢@Bubbler

输入0x41的示例-在线尝试! 部件

输入0xC2-的示例在线尝试!

输入0xE0的示例-在线尝试!

输入0xF4-输入的示例在线尝试!

部件:

;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

在线尝试!


使用Bash TIO处理装配,并提供易于查看的示例。该链接还具有15字节版本的解决方案。以下是本次改进:xor 0xff -> cpl没有必要or ajr nz, return -> ret nzld a,1 -> inc a
Bubbler


4

果冻 8  7 字节

+⁹BIITḢ

接受字节为整数的单子链接。

在线尝试!或查看所有评估的输入

如果可接受8位列表的输入,则该方法只有6个字节: 1;IITḢ,但是它被认为与灵活I / O讨论得太远了。

怎么样?

+⁹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

果冻8 7字节

»Ø⁷Ba\S

在线尝试!

怎么运行的

»Ø⁷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

木炭,12字节

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

在线尝试!链接是详细版本的代码。说明:

     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个字节

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

在线尝试!

user202729的JavaScript回答的端口。使用快速呼叫约定。



1

05AB1E8 7 字节

žy‚àb0k

@Neil的木炭答案的端口。
-1字节感谢@Grimy

输入为整数。

在线尝试验证所有测试用例

说明:

ž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)7。移植其他果冻答案可得到另外8个:₁+b¥η€ËO
Grimmy

@Grimy不知道为什么我没有一开始..:S但是谢谢-1。
凯文·克鲁伊森

0

C,31个字节

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

在线尝试!

带gcc(-O0)的27个字节

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

替代方法,31和33字节

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

我在和Aha玩耍时发现了这些表情!几年前的超级优化器。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.