Contare i byte di un programma


21

Nota 2: ho accettato la @DigitalTraumarisposta lunga a 6 byte. Se qualcuno può batterlo, cambierò la risposta accettata. Grazie per aver giocato!

Nota: accetterò una risposta alle 18:00 MST il 14/10/15. Grazie a tutti quelli che hanno partecipato!

Sono molto sorpreso che non sia stato ancora chiesto (o non ho cercato abbastanza duramente). In entrambi i casi, questa sfida è molto semplice:

Input: un programma sotto forma di una stringa. Inoltre, l'input può contenere o meno:

  • Spazi iniziali e finali
  • Newline finali
  • Caratteri non ASCII

Output: due numeri interi, uno che rappresenta il conteggio dei caratteri UTF-8 e uno che rappresenta il conteggio dei byte, è possibile scegliere quale ordine. Sono consentite nuove righe finali. L'output può essere su STDOUT o restituito da una funzione. L'IT può essere in qualsiasi formato purché i due numeri siano distinguibili l'uno dall'altro (2327 non è un output valido).

Gli appunti:

I / O di esempio: (tutte le uscite sono nel modulo {characters} {bytes})

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

Produzione: 37 37

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

Produzione: 17 27

Ingresso:


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

Produzione: 156 156

Questo è il codice golf - vince il codice più corto in byte !

Classifiche

Ecco uno snippet di stack per generare sia una classifica regolare che una panoramica dei vincitori per lingua.

Per assicurarti che la tua risposta venga visualizzata, ti preghiamo di iniziare la risposta con un titolo, utilizzando il seguente modello Markdown:

# Language Name, N bytes

dov'è Nla dimensione del tuo invio. Se si migliora il punteggio, è possibile mantenere i vecchi punteggi nel titolo, colpendoli. Per esempio:

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

Se si desidera includere più numeri nell'intestazione (ad es. Perché il punteggio è la somma di due file o si desidera elencare separatamente le penalità del flag dell'interprete), assicurarsi che il punteggio effettivo sia l' ultimo numero nell'intestazione:

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

Puoi anche rendere il nome della lingua un collegamento che verrà quindi visualizzato nello snippet della classifica:

# [><>](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>


l'output deve essere separato dallo spazio?
Maltysen,

no, può essere in qualsiasi formato purché i numeri siano distinguibili tra loro (2327 non è un output valido)
GamrCorps

Non ci sono alcuni caratteri UTF-8 che a seconda dell'interpretazione possono essere divisi in altri due caratteri che generano gli stessi valori di byte? Come contiamo quelli allora?
Patrick Roberts,

Onestamente, non so cosa intendi. Pertanto, conta come desideri.
GamrCorps,

I caratteri UTF-8 di @GamrCorps includono caratteri non ASCII, che sono fondamentalmente caratteri che non possono essere rappresentati da un byte ma devono essere rappresentati da due o anche quattro byte. A seconda di come i caratteri vengono letti da un programma, spetta al programma scegliere come interpretare il flusso di byte. Ad esempio, un UTF-8 a 2 byte può essere interpretato come 2 caratteri ASCII sequenziali ciascuno dei quali sono rappresentati dai due byte che compongono il carattere originariamente previsto.
Patrick Roberts,

Risposte:


32

Shell + coreutils, 6

Questa risposta non è valida se viene utilizzata una codifica diversa da UTF-8.

wc -mc

Uscita di prova:

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

Nel caso in cui il formato di output sia rigorosamente applicato (solo uno spazio che separa i due numeri interi), allora possiamo farlo:

Shell + coreutils, 12

echo`wc -mc`

Grazie a @immibis per aver suggerito di rimuovere lo spazio dopo il echo. Mi ci è voluto un po 'di tempo per capirlo - la shell lo espanderà a echo<tab>n<tab>m, e le schede di default sono in $IFS, quindi ci sono separatori di token perfettamente legali nel comando risultante.


13
Sicuramente lo strumento giusto per il lavoro.
Alex A.

1
Riesci a rimuovere lo spazio dopo "eco"?
user253751

@immibis Sì, bello. Non riuscivo a vedere come funzionasse immediatamente.
Trauma digitale,

21

GolfScript, 14 12 byte

.,p{64/2^},,

Provalo online su Web GolfScript .

Idea

GolfScript non ha idea di cosa sia Unicode; tutte le stringhe (input, output, internal) sono composte da byte. Anche se può essere piuttosto fastidioso, è perfetto per questa sfida.

UTF-8 codifica i caratteri ASCII e non ASCII in modo diverso:

  • Tutti i punti di codice inferiori a 128 sono codificati come 0xxxxxxx.

  • Tutti gli altri punti di codice sono codificati come 11xxxxxx 10xxxxxx ... 10xxxxxx.

Ciò significa che la codifica di ciascun carattere Unicode contiene un singolo 0xxxxxxxbyte o un singolo 11xxxxxxbyte (e da 0 a 5 10xxxxxxbyte).

Dividendo tutti i byte dell'input per 64 , trasformiamo 0xxxxxxxin 0 o 1 , 11xxxxxxin 3 e 10xxxxxxin 2 . Non resta che contare i byte il cui quoziente non è 2 .

Codice

                (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.

9

Python, 42 40 byte

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

Grazie ad Alex A. per i due byte di sconto.

Semplice, fa quello che dice. Con argomento i, stampa la lunghezza di i, quindi la lunghezza di iin UTF-8. Si noti che, al fine di accettare l'input più righe, l'argomento della funzione deve essere racchiuso tra virgolette triple: '''.

EDIT: non ha funzionato per l'input multilinea, quindi l'ho solo fatto una funzione.

Alcuni casi di test (separati da righe vuote):

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

E qui per tutto questo tempo ho usato solo len () come una ventosa. Questo è chiaramente superiore.
Stato

3
Poiché l'output può essere restituito da una funzione, è possibile salvare alcuni byte eseguendo questa operazione lambda i:[len(i),len(i.encode('utf-8'))].
Alex A.

@AlexA. Va bene, cambiando. Non ho mai toccato lambda prima.
The_Basset_Hound

1
La tua lambda non è formata abbastanza correttamente. Se gli dai una definizione, lo sarebbe f=lambda i:[len(i),len(i.encode('utf-8'))], ma dato che stai usando una funzione lambda anonima, dovrebbe esserlo lambda i:[len(i),len(i.encode('utf-8'))].
Kade,

1
È possibile salvare alcuni byte con U8invece diutf-8 .
Mego

5

Julia, 24 byte

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

Questo crea una funzione lambda che restituisce una tupla di numeri interi. La lengthfunzione, quando chiamata su una stringa, restituisce il numero di caratteri. La sizeoffunzione restituisce il numero di byte nell'input.

Provalo online


4

Ruggine, 42 byte

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

3

Pyth - 12 9 byte

Proverà ad accorciarti.

lQh/l.BQ8

Test Suite .


Ciò fornisce un byte in eccesso per il conteggio dei byte UTF-8. Attualmente è floor(… / 8) + 1, dovrebbe essereceil(… / 8)
PurkkaKoodari il

Questo mi ha aiutato a individuare un bug .B. Inoltre, lQlc.BQ8corregge il bug menzionato da Pietu1998 durante il salvataggio di 1 byte, credo.
isaacg,

3

Java, 241 90 89 byte

int[]b(String s)throws Exception{return new int[]{s.length(),s.getBytes("utf8").length};}

Adoro il fatto che Java abbia meno di 100 byte.
GamrCorps,

Bene, è solo un metodo ...
SuperJedi224,

1
Potresti cambiare getBytes("UTF-8")in getBytes("utf8"). E perchè throws Exception?
RAnders00,

Perché getBytes genera un UnsupportedEncodingExceptionquando gli dai un nome di codifica non valido.
SuperJedi224,

2

PowerShell, 57 byte

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


2

R, 47 byte

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

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

Produzione:

[1] 17
[2] 27

Se la stampa dei numeri di riga accanto all'output non è consentita in "qualsiasi formato", è catpossibile risolvere il problema:

R, 52 byte

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

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

Produzione: 17 27


Come funzione, 39 byte:function(s)c(nchar(s,"c"),nchar(s,"b"))
Alex A.

1
Anche solo alcuni suggerimenti di golf generali R: È possibile utilizzare Tal posto di TRUE, =al posto di <-, e l'input possono provenire da scan, readlineo function, che sono tutti più corta commandArgs.
Alex A.

1

Via Lattea 1.6.2 , 7 byte (non competitiva)

':y!^P!

Spiegazione

'        ` 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

uso

./mw <path-to-code> -i <input>

Ho contrassegnato questo come non competitivo poiché la sfida precede la lingua.
Mego


1

Brainfuck, 163 byte

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

Con interruzioni di riga per la leggibilità:

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

La parte più importante è la prima riga. Questo conta il numero di caratteri immessi. Il resto è solo la spazzatura lunga richiesta per stampare un numero maggiore di 9.

EDIT: Dal momento che BF non può inserire / emettere nient'altro che numeri ASCII da 1-255, non ci sarebbe modo di misurare i caratteri UTF-8.


Sembra che potrebbe essere golfato di più. Ma probabilmente non può. +1.
wizzwizz4,

0

cera d'api, 99 87 byte

Una versione più compatta, 12 byte più corta della prima:

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

Lo stesso, più facile da seguire layout esagonale:

 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 { ;

Output come characters, quindi bytecount, separato da una nuova riga.

Esempio: la piccola lettera sall'inizio della riga indica all'utente che il programma vuole una stringa come input.

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

Esempio di stringa vuota:

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

La cera d'api spinge i caratteri di una stringa immessa in STDIN nello stack globale, codificati come i valori dei loro punti di codice Unicode.

Per una comprensione più semplice, ecco la versione da scartare del programma sopra:

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

Per questo esempio, il carattere αviene immesso STDIN (punto di codice U+03B1, decimale: 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

Fondamentalmente, questo programma controlla ogni valore di punti di codice per i limiti di punti di codice a 1 byte, 2 byte, 3 byte e 4 byte.

Se nè il valore del punto di codice, questi limiti per le stringhe UTF-8 appropriate sono:

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

Puoi trovare i numeri e 7, per le istruzioni del turno, nel codice sopra. Se si verifica un controllo , il contatore lstack viene incrementato in modo appropriato per calcolare il numero di byte della stringa immessa. I costrutti incrementano il contatore di byte. Dopo ogni conteggio, il punto Unicode più in alto viene spuntato dal gstack fino a quando non è vuoto. Quindi il conteggio dei byte viene inviato a STDOUT e il programma termina.450@PP...@

Non ci sono controlli per codifica errata come codifica ASCII troppo lunga e punti di codice illegale oltre 0x10FFFF, ma penso che vada bene;)


0

Swift 3, 37

{($0.characters.count,$0.utf8.count)}// dove $0èString

uso

Test

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

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.