Compter les octets d'un programme

21

Note 2: J'ai accepté @DigitalTraumala longue réponse de 6 octets. Si quelqu'un peut battre cela, je changerai la réponse acceptée. Merci d'avoir joué!

Remarque: J'accepterai une réponse à 18h00 HNT le 14/10/15. Merci à tous ceux qui ont participé!

Je suis très surpris que cela n'ait pas encore été demandé (ou je n'ai pas cherché assez fort). Quoi qu'il en soit, ce défi est très simple:

Entrée: programme sous forme de chaîne. De plus, l'entrée peut contenir ou non:

  • Espaces de tête et de fuite
  • Traversées de nouvelles lignes
  • Caractères non ASCII

Sortie: Deux entiers, un représentant le nombre de caractères UTF-8 et l'autre représentant le nombre d'octets, vous pouvez choisir l'ordre. Les sauts de ligne sont autorisés. La sortie peut être vers STDOUT ou renvoyée par une fonction. IL peut être dans n'importe quel format tant que les deux nombres peuvent être distingués l'un de l'autre (2327 n'est pas une sortie valide).

Remarques:

Exemple d'E / S: (Toutes les sorties sont sous la forme {characters} {bytes})

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

Sortie: 37 37

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

Sortie: 17 27

Contribution:


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

Sortie: 156 156

C'est le code golf - le code le plus court en octets gagne!

Classements

Voici un extrait de pile pour générer à la fois un classement régulier et un aperçu des gagnants par langue.

Pour vous assurer que votre réponse s'affiche, veuillez commencer votre réponse avec un titre, en utilisant le modèle Markdown suivant:

# Language Name, N bytes

Nest la taille de votre soumission. Si vous améliorez votre score, vous pouvez conserver les anciens scores dans le titre, en les barrant. Par exemple:

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

Si vous souhaitez inclure plusieurs nombres dans votre en-tête (par exemple, parce que votre score est la somme de deux fichiers ou que vous souhaitez répertorier les pénalités de drapeau d'interprète séparément), assurez-vous que le score réel est le dernier numéro de l'en-tête:

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

Vous pouvez également faire du nom de la langue un lien qui apparaîtra ensuite dans l'extrait de classement:

# [><>](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
la source
ne la sortie ont à être séparés par des espaces?
Maltysen
non, il peut être dans n'importe quel format tant que les nombres peuvent être distingués les uns des autres (2327 n'est pas une sortie valide)
GamrCorps
N'y a-t-il pas des caractères UTF-8 qui, selon l'interprétation, peuvent être divisés en deux autres caractères qui génèrent les mêmes valeurs d'octets? Comment les comptons-nous alors?
Patrick Roberts
Honnêtement, je ne sais pas ce que tu veux dire. Par conséquent, comptez comme vous le souhaitez.
GamrCorps
@GamrCorps Les caractères UTF-8 comprennent des caractères non ASCII, qui sont essentiellement des caractères qui ne peuvent pas être représentés par un octet mais doivent être représentés par deux, voire quatre octets. Selon la façon dont les caractères sont lus par un programme, c'est au programme de choisir comment interpréter le flux d'octets. Par exemple, un UTF-8 à 2 octets peut être interprété comme 2 caractères ASCII séquentiels, chacun étant représenté par les deux octets constituant le caractère initialement prévu.
Patrick Roberts

Réponses:

32

Coquille + coreutils, 6

Cette réponse devient invalide si un codage autre que UTF-8 est utilisé.

wc -mc

Sortie de test:

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

Dans le cas où le format de sortie est strictement appliqué (un seul espace séparant les deux entiers), alors nous pouvons le faire:

Coquille + coreutils, 12

echo`wc -mc`

Merci à @immibis d'avoir suggéré de supprimer l'espace après le echo. Il m'a fallu un certain temps pour comprendre cela - le shell va développer cela echo<tab>n<tab>met les onglets par défaut sont dedans $IFS, tout comme les séparateurs de jetons parfaitement légaux dans la commande résultante.

Traumatisme numérique
la source
13
Certainement le bon outil pour le travail.
Alex A.
1
Pouvez-vous supprimer l'espace après "écho"?
user253751
@immibis Oui - bien - je ne pouvais pas voir comment cela fonctionnait tout de suite.
Digital Trauma
21

GolfScript, 14 12 octets

.,p{64/2^},,

Essayez-le en ligne sur Web GolfScript .

Idée

GolfScript n'a aucune idée de ce qu'est Unicode; toutes les chaînes (entrée, sortie, interne) sont composées d'octets. Bien que cela puisse être assez ennuyeux, il est parfait pour ce défi.

UTF-8 code différemment les caractères ASCII et non ASCII:

  • Tous les points de code inférieurs à 128 sont codés comme 0xxxxxxx.

  • Tous les autres points de code sont codés comme 11xxxxxx 10xxxxxx ... 10xxxxxx.

Cela signifie que le codage de chaque caractère Unicode contient soit un seul 0xxxxxxxoctet, soit un seul 11xxxxxxoctet (et 0 à 5 10xxxxxxoctets).

En divisant tous les octets de l'entrée par 64 , nous transformons 0xxxxxxxen 0 ou 1 , 11xxxxxxen 3 et 10xxxxxxen 2 . Il ne reste plus qu'à compter les octets dont le quotient n'est pas 2 .

Code

                (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
la source
9

Python, 42 40 octets

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

Merci à Alex A. pour les deux octets off.

Simple, fait ce qu'il dit. Avec argument i, affiche la longueur de i, puis la longueur de iUTF-8. Notez que pour accepter l' entrée multiligne, l'argument de fonction doit être entouré de triples guillemets: '''.

EDIT: Cela ne fonctionnait pas pour l'entrée multiligne, donc je viens d'en faire une fonction à la place.

Quelques cas de test (séparés par des sauts de ligne vides):

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
la source
Et ici, pendant tout ce temps, j'utilise juste len () comme une ventouse. C'est clairement supérieur.
Statut
3
Comme la sortie peut être renvoyée par une fonction, vous pouvez économiser quelques octets en faisant cela lambda i:[len(i),len(i.encode('utf-8'))].
Alex A.
@AlexA. D'accord, changeant. Jamais touché lambda auparavant.
The_Basset_Hound
1
Votre lambda n'est pas formée correctement. Si vous lui donnez une définition, ce serait le cas f=lambda i:[len(i),len(i.encode('utf-8'))], mais comme vous utilisez une fonction lambda anonyme, elle devrait l'être lambda i:[len(i),len(i.encode('utf-8'))].
Kade
1
Vous pouvez enregistrer quelques octets avec U8au lieu deutf-8 .
Mego
5

Julia, 24 octets

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

Cela crée une fonction lambda qui renvoie un tuple d'entiers. La lengthfonction, lorsqu'elle est appelée sur une chaîne, renvoie le nombre de caractères. La sizeoffonction renvoie le nombre d'octets dans l'entrée.

Essayez-le en ligne

Alex A.
la source
4

Rouille, 42 octets

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

Pyth - 12 9 octets

Va essayer de raccourcir.

lQh/l.BQ8

Suite de tests .

Maltysen
la source
Cela donne un octet de trop pour le nombre d'octets UTF-8. C'est actuellement floor(… / 8) + 1, devrait êtreceil(… / 8)
PurkkaKoodari
Cela m'a aidé à détecter un bug .B. En outre, lQlc.BQ8corrige le bug mentionné @ Pietu1998 tout en enregistrant 1 octet, je pense.
isaacg
3

Java, 241 90 89 octets

int[]b(String s)throws Exception{return new int[]{s.length(),s.getBytes("utf8").length};}
SuperJedi224
la source
J'adore que vous ayez Java à moins de 100 octets.
GamrCorps
Eh bien, c'est juste une méthode ...
SuperJedi224
1
Vous pourriez changer getBytes("UTF-8")pour getBytes("utf8"). Et pourquoi throws Exception?
RAnders00
Parce que getBytes lance un UnsupportedEncodingExceptionlorsque vous lui donnez un nom de codage non valide.
SuperJedi224
2

PowerShell, 57 octets

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

C, 68 67 octets

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

Cela utilise la même idée que mon autre réponse .

Essayez-le en ligne sur Ideone .

Dennis
la source
2

R, 47 octets

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

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

Sortie:

[1] 17
[2] 27

Si l'impression de numéros de ligne à côté de la sortie n'est pas autorisée sous "n'importe quel format", vous catpouvez résoudre le problème:

R, 52 octets

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

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

Sortie: 17 27

SnoringFrog
la source
En fonction, 39 octets:function(s)c(nchar(s,"c"),nchar(s,"b"))
Alex A.
1
Aussi juste quelques conseils de golf général R: Vous pouvez utiliser Tà la place TRUE, =à la place de <-, et l' entrée peuvent provenir scan, readlineou function, tous sont plus courtes que commandArgs.
Alex A.
1

Voie lactée 1.6.2 , 7 octets (non concurrent)

':y!^P!

Explication

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

Usage

./mw <path-to-code> -i <input>
Zach Gates
la source
J'ai marqué cela comme non concurrent car le défi est antérieur à la langue.
Mego
1

Perl 6, 33 octets

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

Basé sur cet article de blog sur Perl6Advent.

chat
la source
1

Brainfuck, 163 octets

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

Avec des sauts de ligne pour la lisibilité:

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

La partie la plus importante est la première ligne. Cela compte le nombre de caractères saisis. Le reste n'est que la longue jonque requise pour imprimer un nombre supérieur à 9.

EDIT: Puisque BF ne peut pas entrer / sortir autre chose que des nombres ASCII de 1-255, il n'y aurait aucun moyen de mesurer les caractères UTF-8.

vasilescur
la source
On dirait qu'il pourrait être plus joué au golf. Mais ce n'est probablement pas possible. +1.
wizzwizz4
0

cire d'abeille, 99 87 octets

Une version plus compacte, 12 octets de moins que la première:

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

De même, car il est plus facile de suivre la disposition hexagonale:

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

Sortie en tant que characters, puis bytecount, séparée par une nouvelle ligne.

Exemple: la petite lettre sau début de la ligne indique simplement à l'utilisateur que le programme veut une chaîne en entrée.

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

Exemple de chaîne vide:

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

La cire d'abeille pousse les caractères d'une chaîne qui est entrée à STDIN sur la pile globale, codée comme les valeurs de leurs points de code Unicode.

Pour une meilleure compréhension, voici la version non emballée du programme ci-dessus:

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

Pour cet exemple, le caractère αest entré à STDIN (point de code U+03B1, décimal: 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

Fondamentalement, ce programme vérifie chaque valeur de point de code pour les limites de codet 1 octet, 2 octets, 3 octets et 4 octets.

Si nest la valeur du point de code, ces limites pour les chaînes UTF-8 appropriées sont:

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

Vous pouvez trouver les numéros 7, 4et 5pour les instructions de décalage dans le code ci - dessus. Si une vérification aboutit 0, le compteur lstack est incrémenté de manière appropriée pour comptabiliser le nombre d'octets de la chaîne entrée. le@PP...@ constructions incrémentent le compteur d'octets. Après chaque décompte, le point Unicode le plus haut est extrait de la gstack jusqu'à ce qu'il soit vide. Ensuite, le nombre d'octets est émis vers STDOUT et le programme est terminé.

Il n'y a pas de vérification pour un encodage incorrect comme un encodage ASCII trop long et des points de code illégaux au 0x10FFFF- delà , mais je pense que ça va;)

ML
la source
0

Swift 3, 37

{($0.characters.count,$0.utf8.count)}// où $0estString

Usage

Tester

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

Apollonian
la source