Hitung byte dari suatu program

21

Catatan 2: Saya menerima @DigitalTraumajawaban panjang 6-byte. Kalau ada yang bisa mengalahkan itu saya akan mengubah jawaban yang diterima. Terima kasih sudah bermain!

Catatan: Saya akan menerima jawaban pada pukul 18:00 MST pada 10/14/15. Terima kasih untuk semua yang berpartisipasi!

Saya sangat terkejut bahwa ini belum ditanyakan (atau saya tidak mencari cukup keras). Bagaimanapun, tantangan ini sangat sederhana:

Input: Program dalam bentuk string. Selain itu, input mungkin mengandung atau tidak:

  • Ruang depan dan belakang
  • Mengejar baris baru
  • Karakter non-ASCII

Output: Dua bilangan bulat, satu mewakili jumlah karakter UTF-8 dan satu mewakili jumlah byte, Anda dapat memilih urutan mana. Trailing newlines diizinkan. Output dapat berupa STDOUT atau dikembalikan dari suatu fungsi. TI dapat dalam format apa pun asalkan kedua angka tersebut dapat dibedakan satu sama lain (2327 bukan keluaran yang valid).

Catatan:

Contoh I / O: (Semua output dalam bentuk {characters} {bytes})

Memasukkan: void p(int n){System.out.print(n+5);}

Keluaran: 37 37

Memasukkan: (~R∊R∘.×R)/R←1↓ιR

Keluaran: 17 27

Memasukkan:


friends = ['john', 'pat', 'gary', 'michael']
for i, name in enumerate(friends):
    print "iteration {iteration} is {name}".format(iteration=i, name=name)

Keluaran: 156 156

Ini adalah kode golf - kode terpendek dalam byte menang!

Papan peringkat

Berikut ini adalah Stack Snippet untuk menghasilkan leaderboard biasa dan gambaran umum pemenang berdasarkan bahasa.

Untuk memastikan bahwa jawaban Anda muncul, silakan mulai jawaban Anda dengan tajuk utama, menggunakan templat Penurunan harga berikut:

# Language Name, N bytes

di mana Nukuran kiriman Anda. Jika Anda meningkatkan skor Anda, Anda bisa menyimpan skor lama di headline, dengan mencoretnya. Contohnya:

# Ruby, <s>104</s> <s>101</s> 96 bytes

Jika Anda ingin memasukkan beberapa angka dalam tajuk Anda (mis. Karena skor Anda adalah jumlah dari dua file atau Anda ingin membuat daftar hukuman penterjemah secara terpisah), pastikan bahwa skor sebenarnya adalah angka terakhir di tajuk:

# Perl, 43 + 2 (-p flag) = 45 bytes

Anda juga dapat membuat tautan nama bahasa yang kemudian akan muncul di cuplikan papan peringkat:

# [><>](http://esolangs.org/wiki/Fish), 121 bytes

var QUESTION_ID=60733,OVERRIDE_USER=36670;function answersUrl(e){return"http://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(e,s){return"http://api.stackexchange.com/2.2/answers/"+s.join(";")+"/comments?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){e.comments=[];var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),e.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){e.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),e.has_more?getComments():more_answers?getAnswers():process()}})}function getAuthorName(e){return e.owner.display_name}function process(){var e=[];answers.forEach(function(s){var r=s.body;s.comments.forEach(function(e){OVERRIDE_REG.test(e.body)&&(r="<h1>"+e.body.replace(OVERRIDE_REG,"")+"</h1>")});var a=r.match(SCORE_REG);a&&e.push({user:getAuthorName(s),size:+a[2],language:a[1],link:s.share_link})}),e.sort(function(e,s){var r=e.size,a=s.size;return r-a});var s={},r=1,a=null,n=1;e.forEach(function(e){e.size!=a&&(n=r),a=e.size,++r;var t=jQuery("#answer-template").html();t=t.replace("{{PLACE}}",n+".").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SIZE}}",e.size).replace("{{LINK}}",e.link),t=jQuery(t),jQuery("#answers").append(t);var o=e.language;/<a/.test(o)&&(o=jQuery(o).text()),s[o]=s[o]||{lang:e.language,user:e.user,size:e.size,link:e.link}});var t=[];for(var o in s)s.hasOwnProperty(o)&&t.push(s[o]);t.sort(function(e,s){return e.lang>s.lang?1:e.lang<s.lang?-1:0});for(var c=0;c<t.length;++c){var i=jQuery("#language-template").html(),o=t[c];i=i.replace("{{LANGUAGE}}",o.lang).replace("{{NAME}}",o.user).replace("{{SIZE}}",o.size).replace("{{LINK}}",o.link),i=jQuery(i),jQuery("#languages").append(i)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;getAnswers();var SCORE_REG=/<h\d>\s*([^\n,]*[^\s,]),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/,OVERRIDE_REG=/^Override\s*header:\s*/i;
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr></thead> <tbody id="answers"> </tbody> </table> </div><div id="language-list"> <h2>Winners by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr></thead> <tbody id="languages"> </tbody> </table> </div><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table>

GamrCorps
sumber
apakah output harus dipisahkan dengan ruang?
Maltysen
tidak, itu bisa dalam format apa pun asalkan jumlahnya dapat dibedakan satu sama lain (2327 bukan keluaran yang valid)
GamrCorps
Bukankah ada beberapa karakter UTF-8 yang tergantung pada interpretasi dapat dibagi menjadi dua karakter lain yang menghasilkan nilai byte yang sama? Bagaimana kita menghitungnya?
Patrick Roberts
Jujur, saya tidak tahu apa yang Anda maksud. Karena itu, hitung sesuai keinginan.
GamrCorps
@GamrCorps Karakter UTF-8 termasuk karakter non-ASCII, yang pada dasarnya adalah karakter yang tidak dapat diwakili oleh satu byte tetapi harus diwakili oleh dua atau bahkan empat byte. Bergantung pada bagaimana karakter dibaca oleh suatu program, terserah pada program untuk memilih bagaimana menafsirkan aliran byte. Sebagai contoh, 2 byte UTF-8 dapat diartikan sebagai 2 karakter ASCII berurutan yang masing-masing diwakili oleh dua byte yang membentuk karakter yang dimaksudkan semula.
Patrick Roberts

Jawaban:

32

Shell + coreutils, 6

Jawaban ini menjadi tidak valid jika digunakan penyandian selain UTF-8.

wc -mc

Output tes:

$ printf '%s' "(~R∊R∘.×R)/R←1↓ιR" | ./count.sh 
     17      27
$ 

Jika format output benar-benar diberlakukan (hanya satu ruang yang memisahkan kedua bilangan bulat), maka kita dapat melakukan ini:

Shell + coreutils, 12

echo`wc -mc`

Terima kasih kepada @immibis karena menyarankan untuk menghapus spasi setelah echo. Butuh beberapa saat untuk mencari tahu - shell akan memperluas ini ke echo<tab>n<tab>m, dan tab secara default di $IFS, jadi pemisah token hukum yang sempurna dalam perintah yang dihasilkan.

Trauma Digital
sumber
13
Jelas alat yang tepat untuk pekerjaan itu.
Alex A.
1
Bisakah Anda menghapus ruang setelah "gema"?
user253751
@immibis Ya - bagus - Saya tidak bisa melihat bagaimana itu bekerja segera.
Digital Trauma
21

GolfScript, 14 12 byte

.,p{64/2^},,

Cobalah online di Web GolfScript .

Ide

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 0xxxxxxxbyte tunggal atau 11xxxxxxbyte tunggal (dan 0 hingga 5 10xxxxxxbyte).

Dengan membagi semua byte input dengan 64 , kita berubah 0xxxxxxxmenjadi 0 atau 1 , 11xxxxxxmenjadi 3 , dan 10xxxxxxmenjadi 2 . Yang tersisa adalah menghitung byte yang hasil bagi bukan 2 .

Kode

                (implicit) Read all input and push it on the stack.
.               Push a copy of the input.
 ,              Compute its length (in bytes).
  p             Print the length.
   {     },     Filter; for each byte in the original input:
    64/           Divide the byte by 64.
       2^         XOR the quotient with 2.
                If the return is non-zero, keep the byte.
           ,    Count the kept bytes.
                (implicit) Print the integer on the stack.
Dennis
sumber
9

Python, 42 40 byte

lambda i:[len(i),len(i.encode('utf-8'))]

Terima kasih kepada Alex A. untuk dua byte mati.

Terus terang, lakukan apa yang dikatakannya. Dengan argumen i, mencetak panjang i, lalu panjang idalam UTF-8. Perhatikan bahwa dalam rangka untuk menerima masukan multiline, argumen fungsi harus dikelilingi oleh tiga tanda kutip: '''.

EDIT: Ini tidak berfungsi untuk input multiline, jadi saya hanya membuatnya menjadi fungsi saja.

Beberapa kasus uji (dipisahkan oleh baris baru yang kosong):

f("Hello, World!")
13 13

f('''
friends = ['john', 'pat', 'gary', 'michael']
for i, name in enumerate(friends):
    print "iteration {iteration} is {name}".format(iteration=i, name=name)
''')
156 156

f("(~R∊R∘.×R)/R←1↓ιR")
17 27
The_Basset_Hound
sumber
Dan di sini selama ini saya telah menggunakan hanya len () seperti pengisap. Ini jelas lebih unggul.
Status
3
Karena output dapat dikembalikan dari suatu fungsi, Anda dapat menyimpan beberapa byte dengan membuatnya lambda i:[len(i),len(i.encode('utf-8'))].
Alex A.
@AlexA. Baiklah, berubah. Belum pernah menyentuh lambda sebelumnya.
The_Basset_Hound
1
Lambda Anda tidak terbentuk dengan benar. Jika Anda memberikan definisi, itu akan menjadi f=lambda i:[len(i),len(i.encode('utf-8'))], tetapi karena Anda menggunakan fungsi lambda anonim, seharusnya begitu lambda i:[len(i),len(i.encode('utf-8'))].
Kade
1
Anda dapat menyimpan beberapa byte dengan U8bukanutf-8 .
Mego
5

Julia, 24 byte

s->(length(s),sizeof(s))

Ini menciptakan fungsi lambda yang mengembalikan tupel bilangan bulat. The lengthfungsi, saat dipanggil pada string, mengembalikan jumlah karakter. The sizeoffungsi mengembalikan jumlah byte dalam input.

Cobalah online

Alex A.
sumber
4

Karat, 42 byte

let c=|a:&str|(a.chars().count(),a.len());
jus1in
sumber
3

Pyth - 12 9 byte

Akan mencoba menjadi lebih pendek.

lQh/l.BQ8

Test Suite .

Maltysen
sumber
Ini memberikan byte terlalu banyak untuk hitungan byte UTF-8. Saat ini floor(… / 8) + 1, seharusnyaceil(… / 8)
PurkkaKoodari
Ini membantu saya menangkap bug di .B. Juga, lQlc.BQ8memperbaiki bug @ Pietu1998 menyebutkan sambil menyimpan 1 byte, saya pikir.
isaacg
3

Java, 241 90 89 byte

int[]b(String s)throws Exception{return new int[]{s.length(),s.getBytes("utf8").length};}
SuperJedi224
sumber
Senang bahwa Anda punya Java di bawah 100 byte.
GamrCorps
Ya, itu hanya sebuah metode ...
SuperJedi224
1
Anda bisa berubah getBytes("UTF-8")menjadi getBytes("utf8"). Dan mengapa throws Exception?
RAnders00
Karena getBytes melempar UnsupportedEncodingExceptionketika Anda memberinya nama penyandian yang tidak valid.
SuperJedi224
2

PowerShell, 57 byte

$args|%{$_.Length;[Text.Encoding]::UTF8.GetByteCount($_)}
Andrew
sumber
2

C, 68 67 byte

b,c;main(t){for(;t=~getchar();b++)c+=2!=~t/64;printf("%d %d",c,b);}

Ini menggunakan ide yang sama dengan jawaban saya yang lain .

Cobalah online di Ideone .

Dennis
sumber
2

R, 47 byte

a<-commandArgs(TRUE);nchar(a,"c");nchar(a,"b")

Memasukkan: (~R∊R∘.×R)/R←1↓ιR

Keluaran:

[1] 17
[2] 27

Jika mencetak nomor baris di samping keluaran tidak diizinkan di bawah "format apa pun" maka cat dapat memperbaiki masalah:

R, 52 byte

a<-commandArgs(TRUE);cat(nchar(a,"c"),nchar(a,"b"))

Memasukkan: (~R∊R∘.×R)/R←1↓ιR

Keluaran: 17 27

SnoringFrog
sumber
Sebagai fungsi, 39 byte:function(s)c(nchar(s,"c"),nchar(s,"b"))
Alex A.
1
Juga hanya beberapa tips umum R golf: Anda dapat menggunakan Tdi tempat TRUE, =di tempat <-, dan masukan bisa berasal dari scan, readlineatau function, yang semuanya lebih pendek dari commandArgs.
Alex A.
1

Milky Way 1.6.2 , 7 byte (tidak bersaing)

':y!^P!

Penjelasan

'        ` read input from the command line
 :       ` duplicate the TOS
  y      ` push the length of the TOS
   !  !  ` output the TOS
    ^    ` pop the TOS
     P   ` push the length of the TOS in bytes

Pemakaian

./mw <path-to-code> -i <input>
Zach Gates
sumber
Saya menandai ini sebagai non-bersaing karena tantangan mendahului bahasa.
Mego
1

Perl 6, 33 byte

$x=get;say $x.chars," ",$x.codes;

Berdasarkan posting blog ini di Perl6Advent.

kucing
sumber
1

Brainfuck, 163 byte

,[>+<,]>[>>+>+<<<-]>>>[<<<+>>>-]<<+>[<->[>++++++++++<[->-[>+>>]>[+[-<+>]>+>>]<<<<<]>[-]++++++++[<++++++>-]>[<<+>>-]>[<<+>>-]<<]>]<[->>++++++++[<++++++>-]]<[.[-]<]<

Dengan linebreak untuk keterbacaan:

,[>+<,]>
[>>+>+<<<-]>>>[<<<+>>>-]<<+>[<->[
>++++++++++<[->-[>+>>]>[+[-<+>]>.
+>>]<<<<<]>[-]++++++++[<++++++>-
]>[<<+>>-]>[<<+>>-]<<]>]<[->>+++++
+++[<++++++>-]]<[.[-]<]<

Bagian terpenting adalah baris pertama. Ini menghitung jumlah karakter yang dimasukkan. Sisanya hanyalah sampah panjang yang diperlukan untuk mencetak angka lebih dari 9.

EDIT: Karena BF tidak dapat memasukkan / mengeluarkan apa pun selain nomor ASCII dari 1-255, tidak akan ada cara untuk mengukur karakter UTF-8.

vasilescur
sumber
Ini sepertinya bisa lebih golf. Tapi mungkin tidak bisa. +1.
wizzwizz4
0

lilin lebah, 99 87 byte

Versi yang lebih ringkas, 12 byte lebih pendek dari yang pertama:

p~5~q")~4~p")~7~g?<
>)'qq>@PPq>@Pp>Ag'd@{
     >@PPPq  @dNp"?{gAV_
     >@PPPP>@>?b>N{;

Sama, karena lebih mudah untuk mengikuti tata letak heksagonal:

 p ~ 5 ~ q " ) ~ 4 ~ p " ) ~ 7 ~ g ? <
> ) ' q q > @ P P q > @ P p > A g ' d @ {
         > @ P P P q     @ d N p " ? { g A V _ 
        > @ P P P P > @ > ? b > N { ;

Keluaran sebagai characters, kemudian bytecount, dipisahkan oleh baris baru.

Contoh: huruf kecil sdi awal baris hanya memberi tahu pengguna bahwa program menginginkan string sebagai input.

julia> beeswax("utf8bytecount.bswx")
s(~R∊R∘.×R)/R←1↓ιR
17
27
Program finished!

Contoh string kosong:

julia> beeswax("utf8bytecount.bswx")
s
0
0
Program finished!

Beeswax mendorong karakter string yang dimasukkan di STDIN ke tumpukan global, dikodekan sebagai nilai poin kode Unicode mereka.

Untuk pemahaman yang lebih mudah, berikut adalah versi yang belum dibuka dari program di atas:

             >@{;    >@P@p >@PP@p>@P p
_VAg{?"pN>Ag"d?g~7~)"d~4~)"d~5~)"d@PPp
    ;{N< d?              <      < @PP<

Untuk contoh ini, karakter αdimasukkan di STDIN (titik kodeU+03B1 , desimal: 945)

                                        gstack     lstack

_VA                                     [945,1]•   [0,0,0]•    enter string, push stack length on top of gstack
   g                                               [0,0,1]•    push gstack top value on top of local stack (lstack)
    {                                                          lstack 1st value to STDOUT (num. of characters)
     ?                                  [945]•                 pop gstack top value
      "                                                        skip next if lstack 1st >0
        N>                                                     print newline, redirect to right
          Ag                            [945,1]•   [0,0,1]•    push gstack length on top of gstack, push that value on lstack.
            "                                                  skip if lstack 1st > 0
              ?                         [945]•                 pop gstack top value
               g                                   [0,0,945]•  push gstack top value on lstack
                ~                                  [0,945,0]•  flip lstack 1st and 2nd
                 7                                 [0,945,7]•  lstack 1st=7
                  ~                                [0,7,945]•  flip lstack 1st and 2nd
                   )                               [0,7,7]•    lstack 1st = lstack 1st >>> 2nd  (LSR by 7)
                    "                                          skip next if top >0
                      ~4~)                         [0,0,0]•            flip,1st=4,flip,LSR by 4
                          "d                                   skip next if top >0... redirect to upper right
                           >@                                  redirect to right, flip lstack 1st and 3rd
                             PP@                   [2,0,0]•    increment lstack 1st twice, flip 1st and 3rd
                                p                              redirect to lower left
                                "                              (ignored instruction, not relevant)
         d?              <      <       []•                       redirect to left... pop gstack, redirect to upper right

         >Ag"d                          [0]•       [2,0,0]•    redir. right, push gstack length on gstack
                                                               push gstack top on lstack, skip next if lstack 1st > 0
                                                               redir. to upper right.
         >@                                        [0,0,2]•    redir right, flip lstack 1st/3rd
           {;                                                  output lstack 1st to STDOUT, terminate program

Pada dasarnya, program ini memeriksa setiap nilai codepoint untuk batas codepoint 1-byte, 2-byte, 3-byte, dan 4-byte.

Jika n nilai codepoint, maka batas-batas ini untuk string UTF-8 yang tepat adalah:

codepoint 0...127         1-byte: n>>>7 = 0
          128...2047      2-byte: n>>>11= 0  → n>>>7>>>4
          2048...65535    3-byte: n>>>16= 0  → n>>>7>>>4>>>5
          65535...1114111 4-byte: the 3 byte check result is >0

Anda dapat menemukan nomornya 7, 4dan5 untuk instruksi shift dalam kode di atas. Jika hasil cek di 0, penghitung lstack bertambah tepat untuk menghitung jumlah byte dari string yang dimasukkan. The @PP...@konstruksi kenaikan byte counter. Setelah setiap penghitungan, titik Unicode paling atas muncul dari gstack sampai kosong. Kemudian jumlah byte adalah output ke STDOUT dan program diakhiri.

Tidak ada pemeriksaan untuk pengkodean yang tidak benar seperti terlalu lama pengkodean ASCII dan poin kode ilegal di luar 0x10FFFF, tapi saya pikir itu bagus;)

ML
sumber
0

Swift 3, 37

{($0.characters.count,$0.utf8.count)} // dimana $0 adalahString

Pemakaian

Uji

{($0.characters.count,$0.utf8.count)}("Hello, world")

Apolonia
sumber