Panjang urutan UTF-8 byte

15

Tentukan panjang urutan byte UTF-8 yang diberikan byte pertama. Tabel berikut ini menunjukkan rentang peta yang mana untuk setiap panjang yang mungkin:

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

Catatan tentang celah dalam tabel: 0x80-0xBF adalah byte lanjutan, 0xC0-0xC1 akan memulai urutan yang tidak valid dan panjang, 0xF5-0xFF akan menghasilkan codepoint di luar Unicode maksimum.

Tulis program atau fungsi yang menggunakan byte pertama dari urutan UTF-8 sebagai input dan output atau mengembalikan panjang urutan. I / O fleksibel. Misalnya, input dapat berupa angka, karakter 8-bit atau string satu karakter. Anda dapat mengasumsikan bahwa byte pertama adalah bagian dari urutan yang valid dan termasuk dalam salah satu rentang di atas.

Ini golf kode. Jawaban terpendek dalam byte menang.

Uji kasus

0x00 => 1
0x41 => 1
0x7F => 1
0xC2 => 2
0xDF => 2
0xE0 => 3
0xEF => 3
0xF0 => 4
0xF4 => 4
nwellnhof
sumber
Apakah input daftar 8 bit dapat diterima?
Jonathan Allan
@ Jonathan Allan Tidak, itu akan mengambil I / O yang fleksibel terlalu jauh.
nwellnhof

Jawaban:

5

Keempat, 6 byte

x-size

lihat https://forth-standard.org/standard/xchar/X-SIZE

Input dan output mengikuti model Forth standar:

Memasukkan

Alamat memori + panjang (yaitu 1) dari byte tunggal "string" UTF-8.

Keluaran

Panjang urutan UTF-8 dalam byte.

Kode sampel

Simpan 0xF0 dalam sel memori, dan aktifkan ukuran x:

variable v
0xF0 v !
v 1 x-size

Periksa hasilnya:

.s <1> 4  ok
zeppelin
sumber
Dengan asumsi ini bekerja di tio.run/#forth-gforth , dapatkah Anda menunjukkan contoh? Saya tidak mengerti bagaimana Anda bisa memiliki string UTF-8 byte tunggal jika byte 0xF0.
Dennis
> bisakah Anda menunjukkan contoh? Saya tidak mengerti bagaimana Anda bisa memiliki string UTF-8 byte tunggal jika byte 0xF0. Saya telah menambahkan beberapa kode contoh yang menunjukkan cara melakukannya. Sayangnya, versi TIO dari gforth tampaknya tidak mendukung kata-kata Unicode (menurut "lihat ukuran x", itu hanya kode-keras untuk mengembalikan 1 di sana).
zeppelin
Saya melihat. Bukan itu yang saya sebut string UTF-8, karena F0 sendiri merupakan urutan byte yang tidak valid, sejauh menyangkut UTF-8.
Dennis
> karena F0 sendiri merupakan urutan byte yang tidak benar Benar (itu sebabnya saya telah memasukkan kata "string" dalam tanda kutip), tetapi tugas ini secara khusus tentang mengenali urutan dengan byte pertama, dan Forth tidak benar-benar peduli untuk itu menjadi tidak valid , yang memungkinkan solusi ini, pada gilirannya.
zeppelin
6

Z80Golf , 19 14 byte

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

Cobalah online!

-5 byte berkat @Bubbler

Contoh dengan input 0x41-Cobalah online! Majelis

Contoh dengan input 0xC2-Cobalah online!

Contoh dengan input 0xE0-Cobalah online!

Contoh dengan input 0xF4-Cobalah online!

Majelis:

;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

Cobalah online!

Logern
sumber
Gunakan Bash TIO untuk bekerja dengan perakitan, dengan contoh yang lebih mudah dilihat. Tautan ini juga memiliki versi 15 byte dari solusi Anda. Berikut adalah perbaikan: xor 0xff -> cpl, tidak perlu or a, jr nz, return -> ret nz, ld a,1 -> inc a.
Bubbler
5

C (gcc) , 39 byte

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

Cobalah online!

pengguna202729
sumber
Kenapa chardan tidak int?
R .. GitHub BERHENTI MEMBANTU ICE
@R .. Karena mereka mendapatkan tanda diperpanjang. Misalnya ~(char)0xF0 == ~(int)0xFFFFFFF0(anggap char = signed char, sizeof(int) == 4)
user202729
Ah, anggap char sudah ditandatangani.
R .. GitHub BERHENTI MEMBANTU ICE
4

Jelly ,  8  7 byte

+⁹BIITḢ

Tautan monadik yang menerima byte sebagai integer.

Cobalah online! Atau lihat semua input dievaluasi .

Jika input daftar 8 bit dapat diterima maka metode ini hanya 6 byte: 1;IITḢ namun telah dianggap sebagai berbicara I / O fleksibel terlalu jauh.

Bagaimana?

+⁹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
Jonathan Allan
sumber
3

Jelly , 8 7 byte

»Ø⁷Ba\S

Cobalah online!

Bagaimana itu bekerja

»Ø⁷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.
Dennis
sumber
1

Arang , 12 byte

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

Cobalah online! Tautan adalah untuk mengucapkan versi kode. Penjelasan:

     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
Neil
sumber
1

Perl 6 , 18 byte

{7-msb(255-$_)||1}

Cobalah online!

Port dari jawaban JavaScript user202729. Alternatif dengan Apapun Kode:

(255-*).msb*6%34%7
-(255-*).msb%6%5+1
nwellnhof
sumber
1

x86 Assembly, 11 byte

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

Cobalah online!

Port dari jawaban JavaScript user202729. Menggunakan konvensi panggilan cepat.

nwellnhof
sumber
1

Labirin , 35 byte

? 28& 16/ )!@!
:_1 ";_ _3&""2
   @1

Cobalah online!

Versi kode yang belum dibuka:

?:_128&1!@
      ;
      _16/_3&2!@
            )
            !
            @
Herman L.
sumber
1

05AB1E , 8 7 byte

žy‚àb0k

Port of @Neil 's Charcoal answer .
-1 byte terima kasih kepada @Grimy .

Input sebagai integer.

Cobalah secara online atau verifikasi semua kasus uji .

Penjelasan:

ž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)
Kevin Cruijssen
sumber
1
s)ke untuk 7. Porting jawaban Jelly lainnya memberi 8:₁+b¥η€ËO
Grimmy
@ Grimy Tidak tahu mengapa saya tidak melakukannya sejak awal ..: S Tapi terima kasih atas -1.
Kevin Cruijssen
0

C, 31 byte

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

Cobalah online!

27 byte dengan gcc (-O0)

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

Alternatif, 31 dan 33 byte

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

Saya menemukan ekspresi ini ketika bermain-main dengan Aha! Superoptimizer beberapa tahun yang lalu .

nwellnhof
sumber