Длина байтовой последовательности 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:

variable v
0xF0 v !
v 1 x-size

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

.s <1> 4  ok

Предполагая, что это работает в tio.run/#forth-gforth , не могли бы вы показать пример? Я не понимаю, как вы могли бы иметь однобайтовую строку UTF-8, если байт 0xF0.
Деннис

> Не могли бы вы показать пример? Я не понимаю, как вы могли бы иметь однобайтовую строку UTF-8, если байт 0xF0. Я добавил пример кода, демонстрирующий, как это сделать. К сожалению, версия gforth для TIO, похоже, не поддерживает слова Unicode (в соответствии с «see x-size», это просто жестко задано для возврата 1).
Цеппелин

Понимаю. Это не то, что я бы назвал строкой 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.
Bubbler

5

C (gcc) , 39 байт

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

Попробуйте онлайн!



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

Ах, если чар подписан.
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



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

Сборка 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

Попробуйте онлайн!

Порт ответа пользователя user202729. Использует соглашения FastCall.



1

05AB1E , 8 7 байт

žy‚àb0k

Порт ответа @Neil 's Charcoal .
-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

@ Грими Понятия не имею, почему у меня не было вообще ..: S Но спасибо за -1.
Кевин Круйссен

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.