Lunghezza di una sequenza di byte UTF-8


15

Determina la lunghezza di una sequenza di byte UTF-8 dato il suo primo byte. La tabella seguente mostra quali intervalli sono mappati per ogni possibile lunghezza:

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

Note sugli spazi vuoti nella tabella: 0x80-0xBF sono byte di continuazione, 0xC0-0xC1 darebbe inizio a una sequenza troppo lunga e non valida, 0xF5-0xFF comporterebbe un punto di codice oltre il massimo Unicode.

Scrivi un programma o una funzione che accetta il primo byte di una sequenza di byte UTF-8 come input e output o restituisce la lunghezza della sequenza. L'I / O è flessibile. Ad esempio, l'input può essere un numero, un carattere a 8 bit o una stringa di un carattere. Si può presumere che il primo byte faccia parte di una sequenza valida e rientri in uno degli intervalli sopra indicati.

Questo è il codice golf. Vince la risposta più breve in byte.

Casi test

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

È accettabile l'immissione di un elenco di 8 bit?
Jonathan Allan,

@JonathanAllan No, ciò porterebbe troppo lontano l'I / O flessibile.
nwellnhof

Risposte:


5

Avanti, 6 byte

x-size

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

Ingresso e uscita seguono un modello Forth standard:

Ingresso

Indirizzo di memoria + lunghezza (ovvero 1) di una "stringa" UTF-8 a byte singolo.

Produzione

Lunghezza della sequenza UTF-8 in byte.

Codice d'esempio

Archivia 0xF0 in una cella di memoria e invoca x-size:

variable v
0xF0 v !
v 1 x-size

Controlla il risultato:

.s <1> 4  ok

Supponendo che funzioni in tio.run/#forth-gforth , potresti mostrare un esempio? Non capisco come si possa avere una stringa UTF-8 a byte singolo se il byte è 0xF0.
Dennis,

> potresti mostrare un esempio? Non capisco come si possa avere una stringa UTF-8 a byte singolo se il byte è 0xF0. Ho aggiunto un codice di esempio che dimostra come farlo. Sfortunatamente, la versione TIO di gforth non sembra supportare le parole Unicode (secondo "vedi x-size", è solo hardcoded per restituire 1 lì).
zeppelin,

Vedo. Non è quello che chiamerei una stringa UTF-8, dato che F0 da solo è una sequenza di byte non valida, per quanto riguarda UTF-8.
Dennis,

> poiché F0 da solo è una sequenza di byte non valida True (ecco perché ho messo la parola "stringa" tra virgolette), ma questa attività riguarda in particolare il riconoscimento della sequenza dal suo primo byte e Forth non si interessa davvero che non sia valida , che rende possibile questa soluzione, a sua volta.
Zeppelin,

6

Z80Golf , 19 14 byte

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

Provalo online!

-5 byte grazie a @Bubbler

Esempio con input 0x41-Provalo online! montaggio

Esempio con input 0xC2-Provalo online!

Esempio con input 0xE0-Provalo online!

Esempio con input 0xF4-Provalo online!

Montaggio:

;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

Provalo online!


Utilizzare Bash TIO per lavorare con l'assemblaggio, con esempi più facili da vedere. Il collegamento ha anche una versione a 15 byte della soluzione. Qui ci sono i miglioramenti: xor 0xff -> cpl, non c'è bisogno di or a, jr nz, return -> ret nz, ld a,1 -> inc a.
Bubbler,


4

Gelatina ,  8  7 byte

+⁹BIITḢ

Un collegamento monadico che accetta il byte come intero.

Provalo online! Oppure vedi tutti gli input valutati .

Se un input di un elenco di 8 bit era accettabile, allora il metodo è di soli 6 byte: 1;IITḢtuttavia è stato considerato come parlare I / O flessibile troppo lontano.

Come?

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

Gelatina , 8 7 byte

»Ø⁷Ba\S

Provalo online!

Come funziona

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

Carbone , 12 byte

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

Provalo online! Il collegamento è alla versione dettagliata del codice. Spiegazione:

     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

Perl 6 , 18 byte

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

Provalo online!

Porta della risposta JavaScript dell'utente202729. Alternative con qualunque codice:

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

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

Provalo online!

Porta della risposta JavaScript dell'utente202729. Utilizza convenzioni di chiamata rapida.



1

05AB1E , 8 7 byte

žy‚àb0k

La risposta del carbone di legna di Port of @Neil .
-1 byte grazie a @Grimy .

Immettere come numero intero.

Provalo online o verifica tutti i casi di test .

Spiegazione:

ž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)a per 7. Porting dell'altra risposta di Jelly dà un altro 8:₁+b¥η€ËO
Grimmy

@Grimy Non ho idea del perché non ho avuto in primo luogo ..: S Ma grazie per -1.
Kevin Cruijssen,

0

C, 31 byte

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

Provalo online!

27 byte con gcc (-O0)

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

Alternative, 31 e 33 byte

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

Ho trovato queste espressioni giocando con l'Aha! superottimizzatore alcuni anni fa .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.