Contar os bytes de um programa

21

Nota 2: Aceitei @DigitalTraumaa resposta longa de 6 bytes. Se alguém puder vencer, mudarei a resposta aceita. Obrigado por jogar!

Nota: Aceitarei uma resposta às 18:00 MST em 14/10/15. Agradeço a todos por sua participação!

Estou muito surpreso que isso ainda não tenha sido solicitado (ou não pesquisei o suficiente). De qualquer forma, esse desafio é muito simples:

Entrada: um programa na forma de uma sequência. Além disso, a entrada pode ou não conter:

  • Espaços iniciais e finais
  • Trailing newlines
  • Caracteres não ASCII

Saída: Dois inteiros, um representando a contagem de caracteres UTF-8 e um representando a contagem de bytes, você pode escolher qual ordem. Novas linhas à direita são permitidas. A saída pode ser STDOUT ou retornada de uma função. A TI pode estar em qualquer formato, desde que os dois números sejam distinguíveis um do outro (2327 não é uma saída válida).

Notas:

  • Você pode considerar a nova linha como \nou \r\n.
  • Aqui está um bom contador de bytes e caracteres para seus testes. Além disso, aqui está uma meta post com a mesma coisa (obrigado a @Zereges).

E / S de amostra: (todas as saídas estão no formulário {characters} {bytes})

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

Saída: 37 37

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

Saída: 17 27

Entrada:


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

Saída: 156 156

Este é o código golf - o menor código em bytes vence!

Classificação

Aqui está um snippet de pilha para gerar uma classificação regular e uma visão geral dos vencedores por idioma.

Para garantir que sua resposta seja exibida, inicie-a com um título, usando o seguinte modelo de remarcação:

# Language Name, N bytes

onde Nestá o tamanho do seu envio. Se você melhorar sua pontuação, poderá manter as pontuações antigas no título, identificando-as. Por exemplo:

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

Se você quiser incluir vários números no cabeçalho (por exemplo, porque sua pontuação é a soma de dois arquivos ou você deseja listar as penalidades do sinalizador de intérpretes separadamente), verifique se a pontuação real é o último número no cabeçalho:

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

Você também pode transformar o nome do idioma em um link que será exibido no snippet da tabela de classificação:

# [><>](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
fonte
a saída precisa ser separada por espaço?
Maltysen 14/10/2015
não, ele pode estar em qualquer formato, desde que os números são distinguíveis uma da outra (2327 não é válido saída)
GamrCorps
Não existem alguns caracteres UTF-8 que, dependendo da interpretação, podem ser divididos em dois outros caracteres que geram os mesmos valores de bytes? Como contamos isso então?
Patrick Roberts
Honestamente, eu não sei o que você quer dizer. Portanto, conte como desejar.
GamrCorps
Os caracteres UTF-8 do @GamrCorps incluem caracteres não ASCII, que são basicamente caracteres que não podem ser representados por um byte, mas devem ser representados por dois ou até quatro bytes. Dependendo de como os caracteres são lidos por um programa, cabe ao programa escolher como interpretar o fluxo de bytes. Por exemplo, um UTF-8 de 2 bytes pode ser interpretado como 2 caracteres ASCII seqüenciais, cada um dos quais é representado pelos dois bytes que compõem o caractere originalmente pretendido.
Patrick Roberts

Respostas:

32

Shell + coreutils, 6

Esta resposta se torna inválida se uma codificação diferente de UTF-8 for usada.

wc -mc

Saída de teste:

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

Caso o formato de saída seja rigorosamente imposto (apenas um espaço separando os dois números inteiros), podemos fazer o seguinte:

Shell + coreutils, 12

echo`wc -mc`

Obrigado a @immibis por sugerir a remoção do espaço após o echo. Demorei um pouco para descobrir isso - o shell expandirá isso para echo<tab>n<tab>me as guias por padrão estão incluídas $IFS, assim como os separadores de token perfeitamente legais no comando resultante.

Trauma Digital
fonte
13
Definitivamente, a ferramenta certa para o trabalho.
Alex A.
11
Você pode remover o espaço após "eco"?
user253751
@immibis Sim - bom - eu não conseguia ver como isso funcionava imediatamente.
Digital Trauma
21

GolfScript, 14 12 bytes

.,p{64/2^},,

Experimente online no Web GolfScript .

Idéia

GolfScript não tem idéia do que é Unicode; todas as strings (entrada, saída, interna) são compostas de bytes. Embora isso possa ser muito chato, é perfeito para esse desafio.

UTF-8 codifica caracteres ASCII e não ASCII de maneira diferente:

  • Todos os pontos de código abaixo de 128 são codificados como 0xxxxxxx.

  • Todos os outros pontos de código são codificados como 11xxxxxx 10xxxxxx ... 10xxxxxx.

Isso significa que a codificação de cada caractere Unicode contém um 0xxxxxxxbyte único ou um 11xxxxxxbyte único (e de 0 a 5 10xxxxxxbytes).

Ao dividir todos os bytes da entrada por 64 , transformamos 0xxxxxxxem 0 ou 1 , 11xxxxxxem 3 e 10xxxxxxem 2 . Tudo o que resta é contar os bytes cujo quociente não é 2 .

Código

                (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
fonte
9

Python, 42 40 bytes

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

Obrigado a Alex A. pelos dois bytes de folga.

Simples, faz o que diz. Com argumento i, imprime o comprimento de i, então o comprimento de iem UTF-8. Note-se que, a fim de aceitar a entrada de várias linhas, o argumento da função deve ser cercado por aspas triplas: '''.

Edição: Não funcionou para entrada de múltiplas linhas, então apenas fiz uma função.

Alguns casos de teste (separados por novas linhas em branco):

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
fonte
E aqui todo esse tempo eu tenho usado apenas len () como um otário. Isto é claramente superior.
Status
3
Como a saída pode ser retornada de uma função, você pode salvar alguns bytes fazendo isso lambda i:[len(i),len(i.encode('utf-8'))].
Alex A.
@AlexA. Tudo bem, mudando. Nunca toquei lambda antes.
The_Basset_Hound
11
Seu lambda não está formado corretamente. Se você der uma definição, seria f=lambda i:[len(i),len(i.encode('utf-8'))], mas como você está usando uma função lambda anônima, deveria ser lambda i:[len(i),len(i.encode('utf-8'))].
Kade
11
Você pode salvar alguns bytes com em U8vez deutf-8 .
Mego
5

Julia, 24 bytes

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

Isso cria uma função lambda que retorna uma tupla de números inteiros. A lengthfunção, quando chamada em uma sequência, retorna o número de caracteres. A sizeoffunção retorna o número de bytes na entrada.

Experimente online

Alex A.
fonte
4

Ferrugem, 42 bytes

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

Pitão - 12 9 bytes

Vai tentar ficar mais curto.

lQh/l.BQ8

Conjunto de Teste .

Maltysen
fonte
Isso fornece um byte demais para a contagem de bytes UTF-8. É atualmente floor(… / 8) + 1, deve serceil(… / 8)
PurkkaKoodari
Isso me ajudou a encontrar um bug .B. Além disso, lQlc.BQ8corrige o erro que o Pietu1998 menciona enquanto economiza 1 byte, eu acho.
Isaacg
3

Java, 241 90 89 bytes

int[]b(String s)throws Exception{return new int[]{s.length(),s.getBytes("utf8").length};}
SuperJedi224
fonte
Adoro que você tenha Java com menos de 100 bytes.
GamrCorps
Bem, isso é apenas um método ...
SuperJedi224
11
Você pode mudar getBytes("UTF-8")para getBytes("utf8"). E por que throws Exception?
precisa saber é o seguinte
Porque getBytes lança um UnsupportedEncodingExceptionquando você atribui um nome de codificação inválido.
precisa saber é o seguinte
2

PowerShell, 57 bytes

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

C, 68 67 bytes

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

Isso usa a mesma idéia que minha outra resposta .

Experimente online no Ideone .

Dennis
fonte
2

R, 47 bytes

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

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

Saída:

[1] 17
[2] 27

Se a impressão de números de linhas ao lado da saída não for permitida no "qualquer formato", catpoderá corrigir o problema:

R, 52 bytes

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

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

Saída: 17 27

SnoringFrog
fonte
Como função, 39 bytes:function(s)c(nchar(s,"c"),nchar(s,"b"))
Alex A.
11
Também a apenas algumas dicas de golfe geral R: Você pode usar Tno lugar de TRUE, =em lugar de <-, e de entrada pode vir de scan, readlineou function, todos os quais são mais curtos do que commandArgs.
Alex A.
1

Via Láctea 1.6.2 , 7 bytes (não concorrente)

':y!^P!

Explicação

'        ` 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>
Zach Gates
fonte
Marquei isso como não competitivo, pois o desafio antecede o idioma.
Mego
1

Perl 6, 33 bytes

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

Com base nesta postagem no blog Perl6Advent.

gato
fonte
1

Brainfuck, 163 bytes

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

Com quebras de linha para facilitar a leitura:

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

A parte mais importante é a primeira linha. Isso conta o número de caracteres inseridos. O restante é apenas o lixo comprido necessário para imprimir um número maior que 9.

EDIT: Como o BF não pode inserir / enviar nada além de números ASCII de 1-255, não haveria como medir os caracteres UTF-8.

vasilescur
fonte
Parece que poderia ser jogado mais. Mas provavelmente não pode. +1.
wizzwizz4
0

cera de abelha, 99 87 bytes

Uma versão mais compacta, 12 bytes mais curta que a primeira:

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

O mesmo, mais fácil de seguir o layout hexagonal:

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

Saída como characters, então bytecount, separada por uma nova linha.

Exemplo: a letra minúscula sno início da linha informa ao usuário que o programa deseja uma string como entrada.

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

Exemplo de string vazia:

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

A cera de abelha envia os caracteres de uma sequência inserida no STDIN para a pilha global, codificada como os valores de seus pontos de código Unicode.

Para um entendimento mais fácil, aqui está a versão desembrulhada do programa acima:

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

Para este exemplo, o personagem αé inserido no STDIN (ponto de código U+03B1, decimal: 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

Basicamente, este programa verifica cada valor de ponto de código quanto aos limites de 1 byte, 2 bytes, 3 bytes e 4 bytes.

Se nfor o valor do ponto de código, esses limites para as seqüências UTF-8 apropriadas são:

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

Você pode encontrar os números 7, 4e 5para as instruções de mudança no código acima. Se uma verificação resultar 0, o contador lstack é incrementado adequadamente para calcular o número de bytes da string inserida. As @PP...@construções incrementam o contador de bytes. Após cada registro, o ponto Unicode mais alto é exibido no gstack até ficar vazio. Em seguida, a contagem de bytes é enviada para STDOUT e o programa é encerrado.

Não há verificações de codificação inadequada, como codificação ASCII excessiva e pontos de código ilegais além 0x10FFFF, mas acho que está bom;)

ML
fonte
0

Swift 3, 37

{($0.characters.count,$0.utf8.count)}// onde $0estáString

Uso

Teste

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

Apollonian
fonte