计算程序的字节数


21

注意2:我接受了@DigitalTrauma6字节长的答案。如果有人能击败我,我将更改接受的答案。感谢参与!

注意:我将在美国标准时间15/14/15下午6:00接受答复。感谢所有的参与!

对于尚未被问到这个问题,我感到非常惊讶(或者我搜索的不够努力)。无论哪种方式,这个挑战都非常简单:

输入:字符串形式的程序。此外,输入内容可能包含也可能不包含:

  • 前导和尾随空格
  • 尾随换行符
  • 非ASCII字符

输出:两个整数,一个代表UTF-8字符计数,一个代表字节计数,您可以选择顺序。尾随换行符是允许的。输出可以是STDOUT或从函数返回。IT可以采用任何格式,只要两个数字可以区分即可(2327是无效输出)。

笔记:

  • 您可以将换行符视为\n\r\n
  • 这是一个用于测试的不错的字节和字符计数器。另外,这是一个具有相同内容的元帖子(感谢@Zereges)。

I / O示例:( 所有输出均为形式{characters} {bytes}

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

输出: 37 37

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

输出: 17 27

输入:


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

输出: 156 156

这是代码高尔夫球-以字节为单位的最短代码获胜!

排行榜

这是一个堆栈片段,用于按语言生成常规排行榜和获胜者概述。

为确保您的答案显示出来,请使用以下Markdown模板以标题开头。

# Language Name, N bytes

N您提交的文件大小在哪里。如果您提高了分数,则可以将旧分数保留在标题中,方法是将它们打掉。例如:

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

如果要在标头中包含多个数字(例如,因为您的分数是两个文件的总和,或者您想单独列出解释器标志罚分),请确保实际分数是标头中的最后一个数字:

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

您还可以将语言名称设置为链接,然后该链接将显示在页首横幅代码段中:

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


输出必须用空格分隔吗?
Maltysen

不,它可以是任何格式,只要数字是可以区分的(2327是无效输出)
GamrCorps,2015年

难道不存在一些UTF-8字符,根据解释可以将其分解为另外两个产生相同字节值的字符吗?那我们怎么算呢?
帕特里克·罗伯茨

老实说,我不知道你的意思。因此,请随心所欲。
GamrCorps 2015年

@GamrCorps UTF-8字符包括非ASCII字符,这些字符基本上是不能用一个字节表示,但必须用两个甚至四个字节表示的字符。根据程序读取字符的方式,由程序决定如何解释字节流。例如,一个2字节的UTF-8可以解释为2个连续的ASCII字符,每个字符都由构成原始预期字符的两个字节表示。
帕特里克·罗伯茨

Answers:


32

Shell + coreutils,6

如果使用的编码不是UTF-8,则此答案无效。

wc -mc

测试输出:

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

如果严格执行输出格式(两个整数之间只有一个空格),那么我们可以这样做:

Shell + coreutils,12

echo`wc -mc`

感谢@immibis建议删除echo。之后的空格。我花了一段时间才弄清楚,shell将其扩展为echo<tab>n<tab>m,默认情况下,选项卡位于in $IFS,结果命令中的完全合法的令牌分隔符也是如此。


13
绝对是工作的正确工具。
Alex A.

1
您可以在“回声”之后删除空格吗?
user253751

@immibis是的-很好-我无法立即看到效果如何。
Digital Trauma 2015年

21

GolfScript,14个12字节

.,p{64/2^},,

Web GolfScript上在线尝试。

理念

GolfScript不知道Unicode是什么。所有字符串(输入,输出,内部)均由字节组成。尽管这可能很烦人,但对于此挑战而言却是完美的选择。

UTF-8对ASCII和非ASCII字符的编码方式不同:

  • 所有低于128的代码点均编码为0xxxxxxx

  • 所有其他代码点均编码为11xxxxxx 10xxxxxx ... 10xxxxxx

这意味着每个Unicode字符的编码包含一个0xxxxxxx字节或一个11xxxxxx字节(0到5 10xxxxxx个字节)。

通过将输入的所有字节由64,我们把0xxxxxxx0111xxxxxx3,和10xxxxxx2。剩下的就是计算商不是2的字节。

                (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字节

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

感谢Alex A.节省了两个字节。

直截了当,照他说的做。使用参数时i,先打印的长度i,然后再打印iUTF-8 的长度。请注意,为了接受多行输入,function参数应该用三引号引起来:'''

编辑:它不适用于多行输入,所以我只是使其成为一个函数。

一些测试用例(用空白换行符分隔):

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

一直以来,我一直在像sucker一样使用len()。这显然是优越的。
状态

3
由于可以从函数返回输出,因此可以通过创建this来节省一些字节lambda i:[len(i),len(i.encode('utf-8'))]
Alex A.

@AlexA。好吧,变化。以前从未接触过lambda。
The_Basset_Hound 2015年

1
您的lambda格式不正确。如果您给它一个定义,它将是f=lambda i:[len(i),len(i.encode('utf-8'))],但是由于您使用的是匿名lambda函数,因此它应该仅为lambda i:[len(i),len(i.encode('utf-8'))]
卡德2015年

1
您可以使用U8代替utf-8来保存一些字节。
Mego

5

朱莉娅,24个字节

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

这将创建一个lambda函数,该函数返回一个整数元组。该length函数在字符串上调用时,返回字符数。该sizeof函数返回输入中的字节数。

在线尝试


4

Rust,42个字节

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

3

Pyth- 12 9字节

会尝试变得更短。

lQh/l.BQ8

测试套件


对于UTF-8字节计数,这将提供过多的字节。当前floor(… / 8) + 1应为ceil(… / 8)
PurkkaKoodari

这帮助我发现了一个错误.B。另外,lQlc.BQ8我认为,在保存1个字节的同时修复了@ Pietu1998提到的错误。
isaacg '16

3

Java,241 90 89字节

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

爱您将Java压缩到100字节以下。
GamrCorps 2015年

好吧,这只是一种方法……
SuperJedi224

1
您可以更改getBytes("UTF-8")getBytes("utf8")。又为什么throws Exception呢?
RAnders00 '16

因为getBytes UnsupportedEncodingException在给它一个无效的编码名称时会引发一个。
SuperJedi224 '16

2

PowerShell,57个字节

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


2

R,47个字节

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

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

输出:

[1] 17
[2] 27

如果在“任何格式”下都不允许在输出旁边打印行号,则cat可以解决此问题:

R,52个字节

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

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

输出: 17 27


作为一个功能,39个字节:function(s)c(nchar(s,"c"),nchar(s,"b"))
Alex A.

1
也只是一些总则第高尔夫提示:您可以使用T代替TRUE=代替<-,并输入可以来自scanreadline或者function,所有这些都是比较短的commandArgs
Alex A.

1

银河1.6.2,7个字节(非竞争)

':y!^P!

说明

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

用法

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

我将其标记为不竞争,因为挑战早于语言。
Mego


1

Brainfuck,163个字节

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

带有换行符以提高可读性:

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

最重要的部分是第一行。这将计算输入的字符数。剩下的只是打印大于9的数字所需的长时间垃圾。

编辑:由于BF无法输入/输出1-255以外的ASCII数字,因此无法测量UTF-8字符。


看起来它可能会打更多。但这可能不行。+1。
wizzwizz4 2016年

0

蜂蜡, 99 87字节

一个更紧凑的版本,比第一个短12个字节:

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

一样,更容易遵循六角形布局:

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

输出为characters,然后bytecount以换行符分隔。

示例:该s行开头的小写字母只是告诉用户该程序希望使用字符串作为输入。

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

空字符串示例:

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

Beeswax将在STDIN输入的字符串的字符推入全局堆栈,编码为它们的Unicode代码点的值。

为了便于理解,以下是上面程序的未包装版本:

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

对于这个例子,该字符α被输入在STDIN(代码点U+03B1,十进制: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

基本上,此程序检查每个代码点值是否为1字节,2字节,3字节和4字节代码点限制。

如果n是codepoint值,那么正确的UTF-8字符串的这些限制是:

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

你可以找到号码745在上面的代码中的移位指令。如果检查结果0,则lstack计数器会适当增加以计算输入字符串的字节数。该@PP...@结构增加字节计数器。每次计数之后,将从gstack弹出最上面的Unicode点,直到它为空。然后将字节计数输出到STDOUT并终止程序。

没有检查不正确编码的方法,例如超长ASCII编码和超出其范围的非法代码点0x10FFFF,但我认为这很好;)


0

斯威夫特3,37

{($0.characters.count,$0.utf8.count)}//这里$0String

用法

测试

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.