Tugas
Diberikan string UTF-8 (dengan cara apa pun) jawaban (dengan cara apa pun) daftar setara di mana setiap elemen adalah jumlah byte yang digunakan untuk menyandikan karakter input yang sesuai.
Contohnya
!
→ 1
Ciao
→ 1 1 1 1
tʃaʊ
→ 1 2 1 2
Adám
→ 1 1 2 1
ĉaŭ
→ 2 1 2
(karakter tunggal)
ĉaŭ
→ 1 2 1 1 2
(menggunakan kombinasi overlay)
チャオ
→ 3 3 3
(input kosong) →
(output kosong)
!±≡𩸽
→ 1 2 3 4
(byte nol) → 1
Null byte
Jika satu-satunya cara untuk tetap membaca input di luar byte nol adalah dengan mengetahui jumlah byte total, Anda dapat memperoleh jumlah byte dengan cara apa pun (bahkan input pengguna).
Jika bahasa Anda tidak bisa menangani byte nol sama sekali, Anda dapat menganggap bahwa input tidak mengandung null.
Jawaban:
Pyth,
97 byteTerima kasih kepada @Maltysen untuk menghemat 2 byte!
Suite uji
Mengkonversi setiap karakter dari input ke representasi binernya dan kemudian membaginya menjadi potongan-potongan dengan panjang 8. Jumlah potongan-potongan tersebut kemudian jumlah byte yang diperlukan untuk menyandikan karakter itu.
sumber
.E
pyth.herokuapp.com/...mlhc8.B
ml%8.B
(sekarangd
implisit).Python 3,
4236 bytesumber
map
.lambda x:map(len,map(str.encode,x))
C,
6865 byteTerima kasih kepada @FryAmTheEggman untuk bermain golf 3 byte!
Uji di Ideone .
sumber
APL, 15 karakter
Dalam bahasa Inggris: konversi setiap karakter ke UTF-8 (artinya: vektor representasi byte) dan dapatkan penghitungannya.
sumber
≢¨'UTF-8'∘⎕ucs¨
+⌿0 7 11 16∘.≤2⍟⎕UCS
0 7 11 16⍸2⍟⎕UCS
GolfScript, 16 byte
Cobalah online!
Latar Belakang
GolfScript tidak memiliki petunjuk apa itu Unicode; semua string (input, output, internal) terdiri dari byte. Meskipun itu bisa sangat menjengkelkan, itu sempurna untuk tantangan ini.
UTF-8 menyandikan karakter ASCII dan non-ASCII secara berbeda:
Semua poin kode di bawah 128 dikodekan sebagai
0xxxxxxx
.Semua titik kode lainnya dikodekan sebagai
11xxxxxx 10xxxxxx ... 10xxxxxx
.Ini berarti bahwa pengkodean setiap karakter Unicode berisi
0xxxxxxx
byte tunggal atau11xxxxxx
byte tunggal dan 1 hingga 510xxxxxx
byte.Dengan membagi semua byte input dengan 64 , kita berubah
0xxxxxxx
menjadi 0 atau 1 ,11xxxxxx
menjadi 3 , dan10xxxxxx
menjadi 2 .Jika kita membandingkan hasil bagi dengan 2 - mendorong 1 untuk 2 ; dan 0 untuk 0 , 1 , dan 3 - setiap karakter akan diubah menjadi 0 , diikuti oleh 1 hingga 5 1 's.
Yang tersisa adalah untuk membagi string yang dihasilkan pada kejadian 0 , hitung jumlah 1 di antara nol itu dan tambahkan satu ke jumlah tersebut.
Bagaimana itu bekerja
sumber
PowerShell v4, 58 byte
NB
OK, ini seharusnya bekerja, dan bisa dilakukan di hampir semua test case kecuali
𩸽
yang entah bagaimana dihitung seperti3,3
pada mesin saya. Karakter itu bahkan menunjukkan 7 byte di komputer saya. Saya menduga ini karena beberapa jenis bug di Windows atau versi .NET yang saya jalankan secara lokal, karena @Mego tidak memiliki masalah itu . ( Sunting: @cat menunjukkan ini karena BOM . Terima kasih telah memecahkan misteri itu, @cat! )Namun, itu masih belum memperhitungkan semua masalah. Saya rasa saya tahu dari mana beberapa masalah itu berasal. Di dalam .NET, semua string terdiri dari unit kode UTF-16 (yang merupakan tipe System.Char). Dengan typecasting sangat longgar yang menggunakan PowerShell, ada banyak casting dan konversi implisit antara jenis di latar belakang. Kemungkinan ini adalah faktor yang berkontribusi terhadap perilaku yang kita lihat - misalnya,
[system.text.encoding]::utf8.getchars([System.Text.UTF8Encoding]::UTF8.GetBytes('𩸽'))
mengembalikan dua yang tidak diinginkan, daripada satu karakter.Penjelasan
Kode yang sangat mudah. Mengambil input
$args[0]
dan secara eksplisit melemparkannya sebagai char-array sehingga kita dapat mengulang setiap komponen dari string|%{...}
. Setiap iterasi, kami menggunakan panggilan .NET[System.Text.Encoding]::UTF8.GetByteCount()
(System.
tersirat) untuk mendapatkan jumlah byte karakter saat ini$_
. Itu ditempatkan pada pipa untuk keluaran nanti. Karena itu adalah kumpulan dari[int]
s yang dikembalikan, casting ke array adalah implisit.Tes Berjalan
Diedit untuk menambahkan Ini benar-benar memperhitungkan persyaratan null-byte yang ditambahkan ke tantangan setelah saya awalnya diposting, asalkan Anda menarik data dari file teks dan pipa itu sebagai berikut:
sumber
That character even shows as 7 bytes on my computer.
Ya, itu karena Byte-Order Mark yang merupakan apa yang Anda dapatkan di Windows dengan UTF-8. Beri tahu Notepad ++ untuk digunakanUTF-8 without BOM
(karena Anda harus selalu menghindari BOM , terutama untuk kepatuhan dengan Unicies) dan Anda akan menemukan file memiliki ukuran 4 byte, karena BOM adalah 3 dan 4 + 3 = 7get-content -Encoding UTF8 .\z.txt|%{.\bytes-per-character.ps1 $_}
masih kembali3,3
.-Encoding
parameter tidak muncul harus didukung .JavaScript (ES6),
544543 byteSunting: Disimpan 2 byte dengan bantuan dari @ l4m2.
sumber
s=>[...s].map(c=>encodeURI(c).length/3-4&3)
Ruby, 33 byte
Nyaris tidak menggunakan Python, yay! Cobalah online.
sumber
Perl 6 ,
77 6963 byteKarena Perl 6 menggunakan string NFG saya harus menarik byte secara langsung, yang menghindari fitur ini.
(NFG seperti NFC kecuali itu juga membuat codepoints sintetis)
Outputnya dipisahkan oleh baris baru.
Uji:
Penjelasan:
Ini berfungsi karena byte pertama dalam multi-byte codepoint memiliki jumlah byte yang disandikan di dalamnya, dan byte lain dalam codepoint memiliki set bit tertinggi, tetapi bukan yang tertinggi berikutnya. Sementara titik byte tunggal tidak memiliki set bit tertinggi.
sumber
read:1
dan / atau/while$
sebaliknya? Dan jika itu berhasil ,if$
?while
.\n1\n1\n
, apakah itu disengaja? Pada dasarnya, apakah ini menangani byte NUL?perl -e 'print "𩸽\0𩸽"' | perl6 -e '...'
saya mendapatkan414
seperti yang saya harapkan. (Bagian tentang nuls ditambahkan setelah saya diposting)Python 3, 82 byte
Ini jauh lebih lama daripada jawaban Python yang lain, dan sebagian besar dari jawaban lainnya, tetapi menggunakan pendekatan yang melibatkan logaritma yang belum saya lihat.
Fungsi anonim yang mengambil input, melalui argumen, sebagai string dan mengembalikan daftar.
Cobalah di Ideone
Bagaimana itu bekerja
Metode ini bergantung pada cara UTF-8 mengkodekan titik kode karakter. Jika titik kode kurang dari 128, karakter dikodekan seperti pada ASCII:
di mana
x
mewakili bit dari titik kode. Namun, untuk kode-poin lebih besar dari atau sama dengan 128, byte pertama diisi dengan jumlah1
s yang sama dengan jumlah total byte, dan byte berikutnya dimulai10
. Bit-bit dari titik kode kemudian dimasukkan untuk memberikan urutan multibyte sesingkat mungkin, dan bit yang tersisa menjadi0
.Dan seterusnya.
Sekarang dapat diperhatikan bahwa untuk setiap jumlah byte
n
, batas atas untuk jumlah bit kode-titik diberikan oleh(-n+7)+6(n-1) = 5n+1
. Oleh karena itu, titik kode batas atasc
untuk masing-masingn
diberikan, dalam desimal, olehc= 2^(5n+1)
. Menyusun ulang ini memberin = (log2(c)-1)/5
. Jadi untuk titik kode apa pun, jumlah byte dapat ditemukan dengan mengevaluasi ekspresi di atas, dan kemudian mengambil plafon.Namun, ini tidak berfungsi untuk titik kode dalam rentang
64 <= c <= 127
, karena kurangnya padding1
karena pengkodean seperti ASCII untuk 1 byte karakter berarti bahwa batas atas yang salah diprediksi, danlog2
tidak ditentukan untukc = 0
, yang terjadi jika byte nol hadir dalam input. Karena itu, jikac <= 127
, nilai1
dikembalikan untuk n.Inilah yang dilakukan oleh kode; untuk setiap karakter
i
dalam stringx
, titik-kode ditemukan menggunakanord
fungsi, dan langit-langit ekspresi ditemukan dengan menggunakan integer daripada pembagian float dengan5
dan kemudian menambahkan1
. Karena tipe float Python selalu mewakili bilangan bulat sebagaix.0
, bahkan setelah pembagian bilangan bulat, hasilnya dilewatkan keint
fungsi untuk menghapus trailing nol. Jikaord(i) <= 127
, hubung-pendek logis berarti yang1
dikembalikan. Jumlah byte untuk setiap karakter disimpan sebagai elemen dalam daftar, dan daftar ini dikembalikan.sumber
Java 10,
10096956761 byte-4 byte menghapus spasi karena ini diperbolehkan dalam komentar
-1 byte berubah
UTF-8
menjadiutf8
-28 byte pergi dari Java 7 ke 8 (
a->{...}
bukanvoid c(char[]i)throws Exception{...}
)-3 byte mengambil input sebagai String-array bukan karakter-array, dan
-3 byte pergi dari Java 8 ke 10 (
var
bukanString
)Penjelasan:
Cobalah online.
sumber
Julia, 34 byte
Ini adalah fungsi anonim yang menerima string dan mengembalikan array integer. Untuk menyebutnya, tetapkan ke variabel.
Pendekatannya cukup mudah: Jika input kosong, output kosong. Kalau tidak, kita memetakan
sizeof
fungsi, yang menghitung jumlah byte dalam string, untuk setiap substring satu karakter.Cobalah online! (termasuk semua kasus uji)
sumber
s->[sizeof("$c")for c=s]
menghemat beberapa byte.split("","")
tidak kembali[]
? (JavaScript"".split("")
tidak.)split("","")
tampaknya memberi""
(tidak seperti dalam Python yang memberikan pengecualian) tapi saya tidak tahu apa-apa tentang kompatibilitas[]
dan""
di julia.split("", "") == [""]
yaitu array satu elemen yang berisi string kosong, tetapi masalahnya adalah itusizeof("") == 0
, yang menurut OP tidak diizinkan.PHP,
9257 byteSetelah dipikir-pikir, Anda bisa melakukan ini dengan lebih mudah:
Coba online, catat bahwa ini sedikit lebih lama karena menggunakan stdin daripada argumen program.
Versi ini mengharuskan Anda untuk mengabaikan pemberitahuan yang dikirim ke stderr tapi itu tidak masalah .
versi lama:
Menggunakan pendekatan yang agak berbeda dengan jawaban php lainnya. Bergantung pada kurangnya dukungan asli untuk string multi-byte di php.
sumber
<?=
Emacs Lisp,
5549 bytePertama membedah string menjadi daftar karakter dengan
(mapcar 'string s)
. Thestring
fungsi dalam Emacs Lisp mengambil daftar karakter dan membangun string dari mereka. Karena cara Emacs membagi stringmapcar
(yaitu ke dalam daftar bilangan bulat, bukan karakter atau string), konversi eksplisit ini diperlukan. Kemudian memetakanstring-bytes
fungsi ke daftar string.Contoh:
Testcases:
Jawaban lama:Tidak Terkumpul:
Testcases:
sumber
nil
jika Anda meratakan hasilnya?nil
adalah daftar kosong (dan satu-satunya cara untuk mengatakan "false" di Emacs). Meskipun tidak ada standar perataan di Emacs (Anda dapat menggunakan tanda hubung-flatten
) setiap implementasi yang mungkin akan menghilangkannya.JavaScript (Node), 27 byte
Ini mengambil input sebagai array karakter individual, dan mengembalikan array jumlah byte.
Buffer
adalah metode yang mewakili data biner mentah. Buffer.byteLength (string) memberikan jumlah byte dalam string. UTF-8 adalah penyandian default. Perhatikan bahwa hanya Node.js yang memiliki buffer, bukan browser JS. Setara browser kasar disebut Blob , yang datang pada 31 byte:Uji
Simpan file ini dan jalankan melalui node, atau coba online .
Ini seharusnya hasilnya:
sumber
Bash, 74 byte
Golf
Algoritma
string input hexdump, lipat 2 karakter per baris, potong karakter pertama saja
(4 bit orde tinggi dari setiap byte input sebagai hex hex, satu per baris)
Hapus "lanjutan byte" 0x80..0xBF
(apa yang tersisa, adalah 4 bit byte pertama dari setiap karakter unicode)
memetakan bit pertama ke dalam panjang char, menciutkan output dan mencetak
Uji
sumber
-t
pilihan untuktr
asing bagi saya, dan ternyata ekstensi GNU. Perpipaan ke substitusi perintah setelahecho
mungkin juga layak penjelasan yang sedikit lebih rinci.PHP, 126 byte
Cobalah online!
sumber
<?=($s=fgets(STDIN))?
C #,
8982 byteC # lambda sederhana yang beriterasi melalui string dan mengembalikan daftar spasi yang dipisahkan.
Sunting: disimpan 6 byte berkat beberapa komentar yang sangat bagus.
sumber
var J="";...
1121
dan1 2 1 2
keduanya OK} return J;};
using System.Text
atau sekitar itu - impor tidak gratis.Haskell, 85 byte
sumber
map$...
Pyth, 17 byte
Cobalah online!
Gunakan titik kode karakter dengan beberapa aritmatika.
sumber
C, 85 byte.
Memeriksa tinggi 4 bit setiap byte untuk menentukan encoding dan jumlah byte berikutnya untuk dilewati;
sumber
while *c
keluar pada string kosong, dan `c + = d 'melompati nulls di tengah multi-byte codepoint.char*
, sungguh) dalam C ditandai dengan byte nol. Tidak mungkin membedakan byte nol dari ujung string yang sebenarnya.Factor,
57878280 byteDijelaskan:
Tes unit:
Mereka semua lewat, sekarang. c:
sumber
Swift 2.2,
675250 byteSangat jelek. Tidak ada cara untuk mendapatkan panjang UTF-8 dari Karakter di Swift, jadi saya perlu beralih melalui string dengan karakter, konversi
Character
keString
, dan menemukancount
karakter tunggal ituString
(hei, setidaknya ada built-in metode untuk melakukan itu). Mencari optimasi, mungkin menggunakan pemindai.Revisi 1: Disimpan 15 byte dengan menggunakan
count
alih-alihunderestimateCount()
.Revisi 2: Menyimpan 2 karakter lainnya dengan menggunakan for-in loop alih-alih untuk setiap penutupan.
sumber
Rust, 53 byte
Rust memiliki primitif utf-8 char, iterators, dan lambdas, jadi ini mudah. Kode uji:
Keluaran
sumber
jq, 26 karakter
(23 karakter kode + 3 opsi opsi baris perintah)
Semoga bersaing. Meskipun
utf8bytelength
telah ditambahkan 9 ++ bulan sebelum pertanyaan ini, masih belum termasuk dalam versi yang dirilis.Contoh dijalankan:
sumber
C (gcc) , 53 byte
Cobalah online!
sumber
SmileBASIC, 69 byte
Input adalah array byte.
Jumlah byte dalam karakter UTF-8 sama dengan jumlah
1
bit terkemuka di byte pertama (kecuali tidak ada1
s, dalam hal ini karakternya adalah 1 byte). Untuk menemukan jumlah 1s terkemuka, program menemukan yang pertama0
dalam representasi biner, lalu menambahkan 1 jika ini adalah 0.sumber
F #,
595466 byteSecara teknis, s adalah urutan char, tetapi ternyata ada konversi implisit yang memungkinkan string diteruskan.
Saat menguji ini di konsol dengan
!±≡𩸽
, itu membagi kanji menjadi dua karakter, masing-masing panjangnya 3 byte. Semua test case lainnya bekerja dengan baik.Sunting: Ternyata impor namespace umum tidak tersirat. Naik 12 karakter lagi.
sumber
UTF-8 without BOM
maka ini salah dan harus diperbaiki. 3) Sepertinya F # membutuhkan pernyataan yang inginlet f(x)= ...
diakhiri;;
, seperti SML. 4) Anda dapat mengabaikan fungsi nama anonim ini, yaitu(s)=seq{for c in s->Encoding.UTF8.GetByteCount([|c|])}
.error FS0039: The namespace or module 'Encoding' is not defined
ketika mencoba menjalankan ini. Apa yang saya lakukan salah?System.Text
namespace. Saya mengasumsikan namespace terbuka dan kode entri disertakan, berasal dari jawaban C # AstroDan's.import
,#include
,open
,load
,require
,using
,USING:
dll di sini di PPCG. Jawaban AstroDan sama keliru, dan saya memberi tahu mereka tentang itu.05AB1E , 15 byte
Cobalah online.
Header
ε
digunakan untuk masing-masing atas semua kasus uji;Footer
ï]J]»
untuk mencetak daftar karakter keluaran dengan cantik (ï
: desimal dan karakter ke integer;:]
tutup jika-yang lain dan untuk masing-masingJ
;: Gabungkan digit bersama-sama}
;: tutup tajuk depan;;»
Gabung dengan baris baru).Penjelasan:
Karena 05AB1E tidak memiliki builtin untuk mengonversi karakter ke jumlah byte yang digunakan, saya gunakan
Ç
untuk mengonversi karakter ke nilai unicode mereka, dan di-masing-masing melakukan hal berikut dalam pseudo-code:Terinspirasi oleh @TheBikingViking 's Python 3 jawaban .
sumber
Zsh , 41 byte
Cobalah online!
Zsh sadar akan UTF-8, jadi kami membagi string pada karakter, lalu menonaktifkan multibyte dan mencetak panjang setiap karakter.
sumber