Порахуйте байти програми


21

Примітка 2: Я прийняв @DigitalTrauma6-байтну довгу відповідь. Якщо хтось може перемогти, я зміню прийняту відповідь. Дякуємо за гру!

Примітка. Відповідь я прийму о 18:00 MST 14.10.15. Дякуємо всім, хто брав участь!

Я дуже здивований, що про це ще не питали (або я не шукав достатньо важко). У будь-якому випадку цей виклик дуже простий:

Введення: Програма у вигляді рядка. Крім того, вхід може містити або не містити:

  • Провідні та кінцеві простори
  • Зміна нових ліній
  • Не символи ASCII

Вихід: Два цілих числа, одне з яких представляє кількість символів UTF-8 і одне, що представляє кількість байтів, ви можете вибрати, який порядок. Доступні нові рядки дозволені. Вихід може бути STDOUT або повернутий з функції. ІТ може бути в будь-якому форматі до тих пір, поки два числа відрізняються один від одного (2327 не є дійсним результатом).

Примітки:

Зразок вводу / виводу: (Всі виходи у формі {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>


робить висновок повинен бути розділеними пробілами?
Мальтісен

ні, воно може бути в будь-якому форматі, якщо номери відрізняються один від одного (2327 недійсний вихід)
GamrCorps

Чи не є деякі символи UTF-8, які залежно від інтерпретації можна розділити на два інших символи, які генерують однакові байтові значення? Як ми тоді рахуємо їх?
Патрік Робертс

Чесно кажучи, я не знаю, що ти маєш на увазі. Тому рахуйте, як хочете.
GamrCorps

Символи @GamrCorps UTF-8 містять символи, що не належать до ASCII, які в основному є символами, які не можуть бути представлені одним байтом, але повинні бути представлені двома або навіть чотирма байтами. Залежно від того, як символи читаються програмою, саме програма повинна вибрати, як інтерпретувати потік байтів. Наприклад, 2-байтний UTF-8 можна інтерпретувати як 2 послідовних символи ASCII, кожен з яких представлений двома байтами, що складають початково призначений символ.
Патрік Робертс

Відповіді:


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. Мені знадобилося певний час, щоб зрозуміти, що - оболонка буде розширювати це echo<tab>n<tab>m, і вкладки за замовчуванням знаходяться $IFS, тому цілком легальні роздільники токенів у отриманій команді.


13
Однозначно правильний інструмент для роботи.
Олексій А.

1
Чи можете ви видалити пробіл після "відлуння"?
користувач253751

@immibis Так - добре - я не міг зрозуміти, як це спрацювало відразу.
Цифрова травма

21

GolfScript, 14 12 байт

.,p{64/2^},,

Спробуйте його онлайн на веб-сайті GolfScript .

Ідея

GolfScript не має поняття, що таке Unicode; всі рядки (вхідні, вихідні, внутрішні) складаються з байтів. Хоча це може бути дуже прикро, це ідеально підходить для цього виклику.

UTF-8 кодує ASCII та non-ASCII символи по-різному:

  • Всі кодові точки нижче 128 кодуються як 0xxxxxxx.

  • Усі інші кодові точки кодуються як 11xxxxxx 10xxxxxx ... 10xxxxxx.

Це означає, що кодування кожного символу Unicode містить або один 0xxxxxxxбайт, або один 11xxxxxxбайт (і від 0 до 5 10xxxxxxбайт).

Ділимо всі байти вхідного сигналу на 64 , перетворюємо 0xxxxxxxна 0 або 1 , 11xxxxxxна 3 і 10xxxxxxна 2 . Залишилося лише порахувати байти, коефіцієнт яких не 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

Пітон, 42 40 байт

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

Дякую Алексу А. за два байти.

Прямо, робить те, що говорить. За допомогою аргументу iдрукується довжина i, а потім довжина iв UTF-8. Зверніть увагу , що для того , щоб прийняти багатостроковий введення, аргумент функції повинен бути оточений потрійними лапками: '''.

EDIT: Він не працював для багатолінійного введення, тому я просто зробив це функцією замість цього.

Деякі тестові випадки (розділені порожніми новими рядками):

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

І тут увесь цей час я використовував лише len (), як присоску. Це явно вище.
Статус

3
Оскільки вихід може бути повернутий з функції, ви можете зберегти кілька байтів, зробивши це lambda i:[len(i),len(i.encode('utf-8'))].
Олексій А.

@AlexA. Добре, мінливий. Ніколи раніше не торкався лямбда.
The_Basset_Hound

1
Ваша лямбда сформована не зовсім коректно. Якщо ви дасте це визначення, це було б f=lambda i:[len(i),len(i.encode('utf-8'))], але оскільки ви використовуєте функцію анонімної лямбда, це просто має бути lambda i:[len(i),len(i.encode('utf-8'))].
Кейд

1
U8Замість цьогоutf-8 можна зберегти кілька байтів .
Мего

5

Юлія, 24 байти

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

Це створює лямбда-функцію, яка повертає набір цілих чисел. lengthФункція, при виклику на рядок, повертає кількість символів. sizeofФункція повертає число байт у вхідних даних.

Спробуйте в Інтернеті



3

Pyth - 12 9 байт

Постараємось скоротити.

lQh/l.BQ8

Тестовий сюїт .


Це дає занадто багато байтів для підрахунку байтів UTF-8. Наразі це floor(… / 8) + 1повинно бутиceil(… / 8)
PurkkaKoodari

Це допомогло мені зловити помилку .B. Також, lQlc.BQ8виправляє помилку @ Pietu1998, згадуючи, зберігаючи 1 байт, я думаю.
isaacg

3

Java, 241 90 89 байт

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

Любіть, що у вас Java набрала менше 100 байт
GamrCorps

Ну, це просто метод ...
SuperJedi224

1
Ви можете змінитись getBytes("UTF-8")на getBytes("utf8"). А чому throws Exception?
RAnders00

Тому що getBytes кидає, UnsupportedEncodingExceptionколи ви даєте йому недійсне ім'я кодування.
SuperJedi224



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"))
Алекс А.

1
Крім того, тільки деякі поради гольф загального R: Ви можете використовувати Tзамість TRUE, =замість <-, і вхід може надходити з scan, readlineабо function, все з яких коротше commandArgs.
Олексій А.

1

Milky Way 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>

Я відзначив це як неконкурентоспроможний, оскільки виклик перед мовою.
Мего


1

Brainfuck, 163 байти

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

З перевірками рядків для читабельності:

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

Найважливіша частина - перший рядок. При цьому враховується кількість введених символів. Решта - це лише довгі барахли, необхідні для друку числа, що перевищує 9.

EDIT: Оскільки BF не може вводити / виводити нічого, окрім ASCII чисел від 1-255, не можна було б виміряти символи UTF-8.


Це виглядає так, що можна було б більше пограти в гольф. Але це, мабуть, не може. +1.
wizzwizz4

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!

Бджолиний віск висуває символи рядка, введеного в 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значення кодової точки, то ці обмеження для правильних рядків 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

Ви можете знайти номери 7, 4а 5інструкції щодо зміни - у наведеному вище коді. Якщо перевірка призводить до 0, лічильник lstack збільшується відповідним чином, щоб підрахувати кількість байтів введеного рядка. У @PP...@конструкції збільшити лічильник байтів. Після кожного підрахунку найвища точка Unicode вискакує з gstack, поки вона не порожня. Потім кількість байтів виводиться в STDOUT і програма припиняється.

Немає перевірок на неправильне кодування, наприклад, надмірне кодування ASCII та незаконні кодові пункти 0x10FFFF, але я думаю, що це нормально;)


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.