Довжина послідовності байт 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 як вхід і вихід або повертає довжину послідовності. Введення / виведення гнучко. Наприклад, вхід може бути числом, 8-бітовим символом або односимвольним рядком. Можна припустити, що перший байт є частиною дійсної послідовності і потрапляє в один із діапазонів вище.

Це код гольфу. Виграє найкоротша відповідь у байтах.

Тестові справи

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

Чи прийнятний вклад списку з 8 біт?
Джонатан Аллан

@JonathanAllan Ні, це забирає гнучкі введення / виведення занадто далеко.
nwellnhof

Відповіді:


5

По-четверте, 6 байт

x-size

дивіться https://forth-standard.org/standard/xchar/X-SIZE

Введення та вихід відповідає стандартній моделі Forth:

Вхідні дані

Адреса пам'яті + довжина (тобто 1) однобайтової "рядок" UTF-8.

Вихідні дані

Довжина послідовності UTF-8 у байтах.

Зразок коду

Зберігайте 0xF0 у комірці пам'яті та викликайте x-size:

variable v
0xF0 v !
v 1 x-size

Перевірте результат:

.s <1> 4  ok

Якщо припустити, що це працює в tio.run/#forth-gforth , ви могли б показати приклад? Я не розумію, як у вас може бути однобайтовий рядок UTF-8, якщо байт дорівнює 0xF0.
Денніс

> Ви могли б показати приклад? Я не розумію, як у вас може бути однобайтовий рядок UTF-8, якщо байт дорівнює 0xF0. Я додав зразок коду, що демонструє, як це зробити. На жаль, TIO версія gforth, схоже, не підтримує слова Unicode (згідно з "див. X-size", повернути 1 туди просто жорстко).
zeppelin

Я бачу. Це не те, що я б назвав рядком UTF-8, оскільки, як тільки F0, є недійсною послідовністю байтів, що стосується UTF-8.
Денніс

> як тільки F0 є недійсною послідовністю байтів True (саме тому я поставив слово "string" у лапки), але це завдання стосується розпізнавання послідовності першим байтом, а Forth насправді не піклується про те, щоб вона була недійсною , що робить це можливим, у свою чергу.
зеппелін

6

Z80Golf , 19 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 a, jr nz, return -> ret nz, ld a,1 -> inc a.
Бубон

5

C (gcc) , 39 байт

t(char x){x=(__builtin_clz(~x)-24)%7u;}

Спробуйте в Інтернеті!


Чому charі ні int?
R .. GitHub СТОП ДОПОМОГАТИ

@R .. Тому що вони отримують знак подовжений. Наприклад ~(char)0xF0 == ~(int)0xFFFFFFF0(припустимо char = signed char, sizeof(int) == 4)
user202729

Ах, якщо припустити, що Char підписаний.
R .. GitHub ЗАСТОСУЄТЬСЯ ДОПОМОГАТИ

4

Желе ,  8  7 байт

+⁹BIITḢ

Монадична посилання, що приймає байт як ціле число.

Спробуйте в Інтернеті! Або дивіться оцінені всі входи .

Якщо введення списку з 8 біт було прийнятним, тоді метод становить лише 6 байт:, 1;IITḢпроте він вважається занадто далеко розмовляючим гнучким входом / виводом.

Як?

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









1

x86 Збірка, 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

Спробуйте в Інтернеті!

Відповідь JavaScript на користувач202729. Використовує умови швидкого виклику.



1

05AB1E , 8 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.
Кевін Круїйсен

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.