Zählen Sie die Bytes eines Programms

21

Anmerkung 2: Ich habe die @DigitalTrauma6 Byte lange Antwort akzeptiert . Wenn jemand das schlagen kann, werde ich die akzeptierte Antwort ändern. Danke fürs Spielen!

Hinweis: Ich werde eine Antwort um 18:00 Uhr MEZ am 14.10.15 annehmen. Vielen Dank an alle, die teilgenommen haben!

Ich bin sehr überrascht, dass dies noch nicht abgefragt wurde (oder ich nicht hart genug gesucht habe). In jedem Fall ist diese Herausforderung sehr einfach:

Eingabe: Ein Programm in Form eines Strings. Darüber hinaus kann die Eingabe Folgendes enthalten oder nicht:

  • Führende und nachfolgende Leerzeichen
  • Zeilenumbruch
  • Nicht-ASCII-Zeichen

Ausgabe: Zwei Ganzzahlen, eine für die Anzahl der UTF-8- Zeichen und eine für die Anzahl der Bytes. Sie können die Reihenfolge auswählen. Nachgestellte Zeilenumbrüche sind zulässig. Die Ausgabe kann an STDOUT erfolgen oder von einer Funktion zurückgegeben werden. IT kann in einem beliebigen Format vorliegen, solange die beiden Zahlen voneinander unterscheidbar sind (2327 ist keine gültige Ausgabe).

Anmerkungen:

  • Sie können Newline als \noder betrachten \r\n.
  • Hier ist ein netter Byte- und Zeichenzähler für Ihre Tests. Auch hier ist ein Meta-Post mit der gleichen Sache (Danke an @Zereges).

Beispiel-E / A: (Alle Ausgaben sind in der Form {characters} {bytes})

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

Ausgabe: 37 37

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

Ausgabe: 17 27

Eingang:


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

Ausgabe: 156 156

Dies ist Code Golf - der kürzeste Code in Bytes gewinnt!

Bestenlisten

Hier ist ein Stack-Snippet, um sowohl eine reguläre Rangliste als auch eine Übersicht der Gewinner nach Sprache zu erstellen.

Um sicherzustellen, dass Ihre Antwort angezeigt wird, beginnen Sie Ihre Antwort mit einer Überschrift. Verwenden Sie dazu die folgende Markdown-Vorlage:

# Language Name, N bytes

Wo Nist die Größe Ihres Beitrags? Wenn Sie Ihren Score zu verbessern, Sie können alte Rechnungen in der Überschrift halten, indem man sich durch das Anschlagen. Zum Beispiel:

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

Wenn Sie mehrere Zahlen in Ihre Kopfzeile aufnehmen möchten (z. B. weil Ihre Punktzahl die Summe von zwei Dateien ist oder wenn Sie die Strafen für Interpreter-Flags separat auflisten möchten), stellen Sie sicher, dass die tatsächliche Punktzahl die letzte Zahl in der Kopfzeile ist:

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

Sie können den Namen der Sprache auch als Link festlegen, der dann im Leaderboard-Snippet angezeigt wird:

# [><>](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
quelle
ist der Ausgang haben Leerzeichen getrennt sein?
Maltysen
nein, es kann in jedem Format sein, solange die Zahlen voneinander unterscheidbar sind (2327 ist keine gültige Ausgabe)
GamrCorps
Gibt es nicht einige UTF-8-Zeichen, die je nach Interpretation in zwei andere Zeichen aufgeteilt werden können, die dieselben Bytewerte generieren? Wie zählen wir diese dann?
Patrick Roberts
Ehrlich gesagt, ich weiß nicht, was du meinst. Zählen Sie daher wie Sie möchten.
GamrCorps
@GamrCorps UTF-8-Zeichen enthalten Nicht-ASCII-Zeichen. Hierbei handelt es sich im Wesentlichen um Zeichen, die nicht durch ein Byte, sondern durch zwei oder sogar vier Bytes dargestellt werden können. Abhängig davon, wie die Zeichen von einem Programm eingelesen werden, kann das Programm entscheiden, wie der Bytestrom interpretiert werden soll. Beispielsweise kann ein 2-Byte-UTF-8 als 2 aufeinanderfolgende ASCII-Zeichen interpretiert werden, von denen jedes durch die zwei Bytes dargestellt wird, die das ursprünglich beabsichtigte Zeichen bilden.
Patrick Roberts

Antworten:

32

Shell + Coreutils, 6

Diese Antwort wird ungültig, wenn eine andere Codierung als UTF-8 verwendet wird.

wc -mc

Testausgang:

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

Wenn das Ausgabeformat streng erzwungen wird (nur ein Leerzeichen zwischen den beiden Ganzzahlen), können wir dies tun:

Shell + Coreutils, 12

echo`wc -mc`

Vielen Dank an @immibis für den Vorschlag, das Leerzeichen nach dem zu entfernen echo. Ich habe eine Weile gebraucht, um das herauszufinden - die Shell wird dies erweitern echo<tab>n<tab>m, und Tabulatoren sind standardmäßig aktiviert $IFS, so dass Token-Trennzeichen im resultierenden Befehl völlig legal sind.

Digitales Trauma
quelle
13
Auf jeden Fall das richtige Werkzeug für den Job.
Alex A.
1
Können Sie das Leerzeichen nach "Echo" entfernen?
user253751
@immibis Ja - nett - ich konnte nicht sehen, wie das sofort funktionierte.
Digital Trauma
21

GolfScript, 14 12 Bytes

.,p{64/2^},,

Probieren Sie es online im Web GolfScript aus .

Idee

GolfScript hat keine Ahnung, was Unicode ist. Alle Zeichenfolgen (Eingabe, Ausgabe, intern) bestehen aus Bytes. Das kann zwar ziemlich ärgerlich sein, ist aber perfekt für diese Herausforderung.

UTF-8 codiert ASCII- und Nicht-ASCII-Zeichen unterschiedlich:

  • Alle Codepunkte unter 128 werden als codiert 0xxxxxxx.

  • Alle anderen Codepunkte werden als codiert 11xxxxxx 10xxxxxx ... 10xxxxxx.

Dies bedeutet, dass die Codierung jedes Unicode-Zeichens entweder ein einzelnes 0xxxxxxxByte oder ein einzelnes 11xxxxxxByte (und 0 bis 5 10xxxxxxByte) enthält.

Indem wir alle Bytes der Eingabe durch 64 teilen , werden wir 0xxxxxxxzu 0 oder 1 , 11xxxxxxzu 3 und 10xxxxxxzu 2 . Jetzt müssen nur noch die Bytes gezählt werden, deren Quotient nicht 2 ist .

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
quelle
9

Python, 42 40 Bytes

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

Vielen Dank an Alex A. für die zwei Bytes.

Einfach, macht was es sagt. Gibt mit dem Argument idie Länge von iund dann die Länge von iin UTF-8 aus. Beachten Sie, dass , um mehrzeilige Eingaben zu akzeptieren, sollte die Funktion Argument durch dreifache Anführungszeichen gesetzt werden: '''.

EDIT: Es funktionierte nicht für mehrzeilige Eingabe, also habe ich es stattdessen zu einer Funktion gemacht.

Einige Testfälle (durch leere Zeilenumbrüche getrennt):

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
quelle
Und hier habe ich die ganze Zeit nur len () wie einen Trottel benutzt. Das ist eindeutig überlegen.
Status
3
Da die Ausgabe von einer Funktion zurückgegeben werden kann, können Sie auf diese Weise einige Bytes einsparen lambda i:[len(i),len(i.encode('utf-8'))].
Alex A.
@AlexA. Okay, wechselnd. Noch nie Lambda berührt.
The_Basset_Hound
1
Dein Lambda ist nicht ganz richtig geformt. Wenn Sie eine Definition angeben, ist dies der Fall f=lambda i:[len(i),len(i.encode('utf-8'))], aber da Sie eine anonyme Lambda-Funktion verwenden, sollte dies der Fall sein lambda i:[len(i),len(i.encode('utf-8'))].
Kade
1
Sie können ein paar Bytes mit speichern U8stattutf-8 .
Mego
5

Julia, 24 Bytes

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

Dadurch wird eine Lambda-Funktion erstellt, die ein Tupel ganzer Zahlen zurückgibt. Die lengthFunktion gibt die Anzahl der Zeichen zurück, wenn sie für eine Zeichenfolge aufgerufen wird. Die sizeofFunktion gibt die Anzahl der Bytes in der Eingabe zurück.

Probieren Sie es online aus

Alex A.
quelle
4

Rust, 42 Bytes

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

Pyth - 12 9 Bytes

Werde versuchen kürzer zu werden.

lQh/l.BQ8

Test Suite .

Maltysen
quelle
Dies gibt einem Byte zu viel für die UTF-8-Bytezahl. Es ist derzeit floor(… / 8) + 1sollteceil(… / 8)
PurkkaKoodari
Dies hat mir geholfen, einen Fehler zu finden .B. Außerdem lQlc.BQ8behebt der Bug @ Pietu1998 Erwähnungen beim Speichern von 1 Byte, denke ich.
Isaacg
3

Java, 241 90 89 Bytes

int[]b(String s)throws Exception{return new int[]{s.length(),s.getBytes("utf8").length};}
SuperJedi224
quelle
Ich liebe es, dass Sie Java unter 100 Bytes haben.
GamrCorps
Nun, es ist nur eine Methode ...
SuperJedi224
1
Du könntest wechseln getBytes("UTF-8")zu getBytes("utf8"). Und warum throws Exception?
RAnders00
Weil getBytes einen auslöst, UnsupportedEncodingExceptionwenn Sie ihm einen ungültigen Codierungsnamen geben.
SuperJedi224
2

PowerShell, 57 Byte

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

C 68 67 Bytes

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

Dies verwendet die gleiche Idee wie meine andere Antwort .

Probieren Sie es online auf Ideone .

Dennis
quelle
2

R, 47 Bytes

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

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

Ausgabe:

[1] 17
[2] 27

Wenn das Drucken von Zeilennummern neben der Ausgabe unter "Beliebiges Format" nicht zulässig ist, catkann das Problem behoben werden:

R, 52 Bytes

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

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

Ausgabe: 17 27

Schnarchfrosch
quelle
Als eine Funktion, 39 Bytes:function(s)c(nchar(s,"c"),nchar(s,"b"))
Alex A.
1
Auch nur einige allgemeine R Golf - Tipps: Sie können Tanstelle von TRUE, =anstelle von <-und Eingabe kann aus scan, readlineoder function, alle sind kürzer als commandArgs.
Alex A.
1

Milchstraße 1.6.2 , 7 Bytes (nicht konkurrierend)

':y!^P!

Erläuterung

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

Verwendung

./mw <path-to-code> -i <input>
Zach Gates
quelle
Ich habe dies als nicht konkurrierend markiert, da die Herausforderung vor der Sprache liegt.
Mego
1

Perl 6, 33 Bytes

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

Gestützt auf diesen Blogeintrag bei Perl6Advent.

Katze
quelle
1

Brainfuck, 163 Bytes

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

Mit Zeilenumbrüchen zur besseren Lesbarkeit:

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

Der wichtigste Teil ist die erste Zeile. Dies zählt die Anzahl der eingegebenen Zeichen. Der Rest ist nur der lange Müll, der benötigt wird, um eine Zahl größer als 9 zu drucken.

BEARBEITEN: Da BF nur ASCII-Zahlen von 1 bis 255 eingeben / ausgeben kann, gibt es keine Möglichkeit, die UTF-8-Zeichen zu messen.

Vasilescur
quelle
Das sieht so aus, als könnte man mehr Golf spielen. Aber wahrscheinlich kann es nicht. +1.
wizzwizz4
0

Bienenwachs, 99 87 Bytes

Eine kompaktere Version, 12 Bytes kürzer als die erste:

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

Das gleiche gilt, da das sechseckige Layout einfacher zu befolgen ist:

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

Die Ausgabe characterserfolgt dann bytecountdurch einen Zeilenumbruch getrennt.

Beispiel: Der kleine Buchstabe sam Anfang der Zeile teilt dem Benutzer lediglich mit, dass das Programm eine Zeichenfolge als Eingabe wünscht.

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

Beispiel für eine leere Zeichenfolge:

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

Beeswax überträgt die Zeichen einer Zeichenfolge, die bei STDIN eingegeben wurde, auf den globalen Stapel, codiert als die Werte ihrer Unicode-Codepunkte.

Zum leichteren Verständnis ist hier die entpackte Version des obigen Programms:

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

Für dieses Beispiel wird das Zeichen αbei STDIN eingegeben (Codepunkt U+03B1, dezimal: 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

Grundsätzlich überprüft dieses Programm jeden Codepunktwert auf die Codepunktgrenzen 1 Byte, 2 Byte, 3 Byte und 4 Byte.

Wenn nes sich um den Codepunktwert handelt, lauten die folgenden Grenzwerte für ordnungsgemäße UTF-8-Zeichenfolgen:

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

Sie können die Nummern finden 7, 4und 5oben für die Schichtanweisungen im Code. Wenn sich eine Prüfung ergibt 0, wird der Stapelzähler entsprechend erhöht, um die Anzahl der Bytes der eingegebenen Zeichenfolge zu ermitteln. Die @PP...@Konstrukte erhöhen den Bytezähler. Nach jeder Zählung wird der oberste Unicode-Punkt aus dem Stapel entfernt, bis er leer ist. Dann wird die Byteanzahl an STDOUT ausgegeben und das Programm beendet.

Es gibt keine Überprüfungen auf fehlerhafte Codierung wie überlange ASCII-Codierung und unzulässige Codepunkte darüber hinaus 0x10FFFF, aber ich denke, das ist in Ordnung;)

ML
quelle
0

Swift 3, 37

{($0.characters.count,$0.utf8.count)}// wo $0istString

Verwendung

Prüfung

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

Apollonian
quelle