Cuenta los bytes de un programa

21

Nota 2: acepté @DigitalTraumala respuesta larga de 6 bytes. Si alguien puede vencer eso, cambiaré la respuesta aceptada. ¡Gracias por jugar!

Nota: aceptaré una respuesta a las 6:00 pm MST del 14/10/15. ¡Gracias a todos los participantes!

Estoy muy sorprendido de que esto aún no se haya preguntado (o no he buscado lo suficiente). De cualquier manera, este desafío es muy simple:

Entrada: un programa en forma de cadena. Además, la entrada puede o no contener:

  • Espacios iniciales y finales
  • Nuevas líneas finales
  • Caracteres no ASCII

Salida: Dos enteros, uno que representa el recuento de caracteres UTF-8 y otro que representa el recuento de bytes, puede elegir qué orden. Se permiten nuevas líneas al final. La salida puede ser STDOUT o devuelta desde una función Puede estar en cualquier formato siempre que los dos números sean distinguibles entre sí (2327 no es una salida válida).

Notas:

Muestra de E / S: (Todas las salidas están en el formulario {characters} {bytes})

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

Salida: 37 37

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

Salida: 17 27

Entrada:


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

Salida: 156 156

Este es el código de golf: ¡el código más corto en bytes gana!

Tablas de clasificación

Aquí hay un fragmento de pila para generar una tabla de clasificación regular y una descripción general de los ganadores por idioma.

Para asegurarse de que su respuesta se muestre, comience con un título, utilizando la siguiente plantilla de Markdown:

# Language Name, N bytes

¿Dónde Nestá el tamaño de su envío? Si mejora su puntaje, puede mantener los puntajes antiguos en el título, tachándolos. Por ejemplo:

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

Si desea incluir varios números en su encabezado (por ejemplo, porque su puntaje es la suma de dos archivos o desea enumerar las penalizaciones de la bandera del intérprete por separado), asegúrese de que el puntaje real sea el último número en el encabezado:

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

También puede hacer que el nombre del idioma sea un enlace que luego aparecerá en el fragmento de la tabla de clasificación:

# [><>](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
fuente
¿la salida tiene que estar separada por espacios?
Maltysen
no, puede estar en cualquier formato siempre que los números sean distinguibles entre sí (2327 no es una salida válida)
GamrCorps
¿No hay algunos caracteres UTF-8 que, según la interpretación, se pueden dividir en otros dos caracteres que generan los mismos valores de bytes? ¿Cómo contamos esos entonces?
Patrick Roberts
Honestamente, no sé a qué te refieres. Por lo tanto, cuente como desee.
GamrCorps
Los caracteres @GamrCorps UTF-8 incluyen caracteres que no son ASCII, que son básicamente caracteres que no pueden representarse con un byte pero deben representarse con dos o incluso cuatro bytes. Dependiendo de cómo un programa lee los caracteres, depende del programa elegir cómo interpretar el flujo de bytes. Por ejemplo, un UTF-8 de 2 bytes se puede interpretar como 2 caracteres ASCII secuenciales, cada uno de los cuales está representado por los dos bytes que forman el carácter originalmente deseado.
Patrick Roberts

Respuestas:

32

Shell + coreutils, 6

Esta respuesta deja de ser válida si se usa una codificación distinta de UTF-8.

wc -mc

Prueba de salida:

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

En caso de que el formato de salida se aplique estrictamente (solo un espacio que separa los dos enteros), entonces podemos hacer esto:

Shell + coreutils, 12

echo`wc -mc`

Gracias a @immibis por sugerir eliminar el espacio después de echo. Me tomó un tiempo darme cuenta: el shell expandirá esto echo<tab>n<tab>m, y las pestañas por defecto están dentro $IFS, por lo que son separadores de tokens perfectamente legales en el comando resultante.

Trauma digital
fuente
13
Definitivamente la herramienta adecuada para el trabajo.
Alex A.
1
¿Puedes eliminar el espacio después de "echo"?
user253751
@immibis Sí, bien, no pude ver cómo funcionaba de inmediato.
Trauma digital
21

GolfScript, 14 12 bytes

.,p{64/2^},,

Pruébelo en línea en Web GolfScript .

Idea

GolfScript no tiene idea de qué es Unicode; Todas las cadenas (entrada, salida, interna) están compuestas de bytes. Si bien eso puede ser bastante molesto, es perfecto para este desafío.

UTF-8 codifica los caracteres ASCII y no ASCII de manera diferente:

  • Todos los puntos de código por debajo de 128 están codificados como 0xxxxxxx.

  • Todos los demás puntos de código están codificados como 11xxxxxx 10xxxxxx ... 10xxxxxx.

Esto significa que la codificación de cada carácter Unicode contiene un solo 0xxxxxxxbyte o un solo 11xxxxxxbyte (y de 0 a 5 10xxxxxxbytes).

Al dividir todos los bytes de la entrada por 64 , nos convertimos 0xxxxxxxen 0 o 1 , 11xxxxxxen 3 y 10xxxxxxen 2 . Todo lo que queda es contar los bytes cuyo cociente no es 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
fuente
9

Python, 42 40 bytes

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

Gracias a Alex A. por los dos bytes de descuento.

Directo, hace lo que dice. Con argumento i, imprime la longitud de i, luego la longitud de ien UTF-8. Tenga en cuenta que para aceptar entradas de varias líneas, el argumento de la función debe estar rodeado de comillas triples:''' .

EDITAR: No funcionó para la entrada multilínea, así que simplemente lo convertí en una función.

Algunos casos de prueba (separados por líneas nuevas en blanco):

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
fuente
Y aquí todo este tiempo he estado usando solo len () como un imbécil. Esto es claramente superior.
Estado del
3
Como la salida puede ser devuelta desde una función, puede guardar algunos bytes haciendo esto lambda i:[len(i),len(i.encode('utf-8'))].
Alex A.
@AlexA. Muy bien, cambiando. Nunca toqué lambda antes.
The_Basset_Hound
1
Tu lambda no está formada correctamente. Si le das una definición, lo sería f=lambda i:[len(i),len(i.encode('utf-8'))], pero como estás usando una función lambda anónima, debería serlo lambda i:[len(i),len(i.encode('utf-8'))].
Kade
1
Puede guardar algunos bytes con en U8lugar deutf-8 .
Mego
5

Julia, 24 bytes

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

Esto crea una función lambda que devuelve una tupla de enteros. La lengthfunción, cuando se llama en una cadena, devuelve el número de caracteres. La sizeoffunción devuelve el número de bytes en la entrada.

Pruébalo en línea

Alex A.
fuente
4

Óxido, 42 bytes

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

Pyth - 12 9 bytes

Intentará acortarse.

lQh/l.BQ8

Test Suite .

Maltysen
fuente
Esto da un byte demasiado para el recuento de bytes UTF-8. Actualmente es floor(… / 8) + 1, debería serceil(… / 8)
PurkkaKoodari
Esto me ayudó a atrapar un error .B. Además, lQlc.BQ8creo que corrige el error que menciona @ Pietu1998 al guardar 1 byte.
isaacg
3

Java, 241 90 89 bytes

int[]b(String s)throws Exception{return new int[]{s.length(),s.getBytes("utf8").length};}
SuperJedi224
fuente
Me encanta que tengas Java a menos de 100 bytes.
GamrCorps
Bueno, es solo un método ...
SuperJedi224
1
Podrías cambiarte getBytes("UTF-8")a getBytes("utf8"). Y por qué throws Exception?
RAnders00
Porque getBytes arroja un UnsupportedEncodingExceptioncuando le das un nombre de codificación no válido.
SuperJedi224
2

PowerShell, 57 bytes

$args|%{$_.Length;[Text.Encoding]::UTF8.GetByteCount($_)}
Andrés
fuente
2

C, 68 67 bytes

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

Esto usa la misma idea que mi otra respuesta .

Pruébelo en línea en Ideone .

Dennis
fuente
2

R, 47 bytes

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

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

Salida:

[1] 17
[2] 27

Si la impresión de números de línea junto con la salida no está permitida en "cualquier formato", catpuede solucionar el problema:

R, 52 bytes

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

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

Salida: 17 27

Ronquidos
fuente
Como función, 39 bytes:function(s)c(nchar(s,"c"),nchar(s,"b"))
Alex A.
1
También sólo algunos consejos de golf generales R: Se puede utilizar Ten lugar de TRUE, =en lugar de <-, y la entrada pueden provenir de scan, readlineo function, todo lo cual es más corto que commandArgs.
Alex A.
1

Vía Láctea 1.6.2 , 7 bytes (no competitiva)

':y!^P!

Explicación

'        ` 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>
Puertas de Zach
fuente
Marqué esto como no competitivo ya que el desafío es anterior al idioma.
Mego
1

Brainfuck, 163 bytes

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

Con saltos de línea para facilitar la lectura:

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

La parte más importante es la primera línea. Esto cuenta el número de caracteres ingresados. El resto es solo la basura larga requerida para imprimir un número mayor que 9.

EDITAR: Dado que BF no puede ingresar / emitir nada más que números ASCII del 1-255, no habría forma de medir los caracteres UTF-8.

vasilescur
fuente
Parece que se podría jugar más al golf. Pero probablemente no pueda. +1.
wizzwizz4
0

cera de abejas, 99 87 bytes

Una versión más compacta, 12 bytes más corta que la primera:

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

Lo mismo, ya que es más fácil seguir el diseño 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 { ;

Salida como characters, entoncesbytecount , separada por una nueva línea.

Ejemplo: la letra minúscula sal comienzo de la línea solo le dice al usuario que el programa quiere una cadena como entrada.

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

Ejemplo de cadena vacía:

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

La cera de abejas empuja los caracteres de una cadena que se ingresa en STDIN en la pila global, codificada como los valores de sus puntos de código Unicode.

Para una comprensión más fácil, aquí está la versión sin envolver del programa anterior:

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

Para este ejemplo, el personaje αse introduce en STDIN (punto de código U+03B1, decimales: 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

Básicamente, este programa verifica cada valor de punto de código para los límites de punto de código de 1 byte, 2 byte, 3 byte y 4 byte.

Si nes el valor del punto de código, estos límites para las cadenas UTF-8 adecuadas son:

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

Puede encontrar los números 7, 4y 5de las instrucciones de cambio en el código de seguridad. Si se produce una verificación 0, el contador lstack se incrementa adecuadamente para contar el número de bytes de la cadena ingresada. los@PP...@ construcciones incrementan el contador de bytes. Después de cada recuento, el punto Unicode superior se saca del gstack hasta que esté vacío. Luego, el recuento de bytes se envía a STDOUT y el programa finaliza.

No hay comprobaciones de codificación incorrecta, como codificación ASCII demasiado larga y puntos de código ilegales más allá 0x10FFFF, pero creo que está bien;)

ML
fuente
0

Swift 3, 37

{($0.characters.count,$0.utf8.count)}// donde $0estaString

Uso

Prueba

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

apolíneo
fuente