Исходный код экологического следа


102

Вы только что были наняты немецкой автомобильной компанией. Ваша первая задача как инженера - написать программу, которая вычисляет экологический след строк ASCII.

Экологический след персонажа рассчитывается следующим образом:

Запишите ASCII-код символа в двоичном виде и сосчитайте количество единиц.

Например, Aимеет размер 2, но Oболее грязный с размером 5.

Глобальный след строки представляет собой сумму следов ее символов. Пустая строка имеет нулевой след.

Ваша программа должна принять строку ASCII в качестве параметра (через командную строку или ввод), вычислить ее экологический след и вывести ее. Сама программа должна быть в кодировке ASCII.

Есть сбой, хотя. Поскольку ваша компания желает выйти на новый рынок с более строгими экологическими правилами, вам необходимо настроить свою программу так, чтобы она работала по-другому в «тестовом режиме». Таким образом:

Программа должна вывести 0, когда получит строку в testкачестве параметра.

счет

Исходный код с наименьшим экологическим следом выигрывает (и да, ответ testзапрещен!)


36
Извините, я не следил за новостями, но только что прочитал. Можно ли предположить, что немецкая автомобильная компания определенно НЕ называется Volkswagen?
— Уровень Река

7
Для справки: от самых дорогих до менее дорогих персонажей:\x7F}~_?{ow7yvu/s\x1F;=znm>k|OW[]^gc\x1Ex\x1D\eef\\'ZY+-VU.St\x173iNM5K6r\x0FG9:q<ljQ\x15\x13pC\aEF8IJL4\x0E21\x16RTh,X*)\x19\v&%\x1A#d\x1C\rab`!\"$(\x180\x05A\x14B\x12\x11DHP\x03\f\x06\n\t\x80\x10\x01@\x04\b\x02 \x00
— Caridorc

19
@steveverrill Это вымышленная компания, но ее название действительно начинается с V и где-то в середине. Но любое сходство с реальностью является простым совпадением, хотя бы кто-то подал на нас в суд.
— Миндвин

1
Функции разрешены (вместо программ)?
— Луис Мендо

12
Они лгут тебе! 1 гораздо более экологичны, чем 0. Хотите доказательства? Распечатайте ваш исходный код в двоичном виде. 0 используют почти вдвое больше чернил, чем 1. И если вы кодируете с темным фоном, они также тратят больше электричества на отображение на вашем экране. (Если вы кодируете с белым фоном, вы уже тратите впустую электроны, делая все это белым, поэтому любой программист, заботящийся об окружающей среде, должен использовать черный редактор в своем редакторе.) Чтобы быть более экологичными, мы все должны писать в Пробел ...
— Даррел Хоффман

Ответы:


45

CJam, 33 31

"",AA#b:c~

Есть 113000000009500000000340000000116000000010100000001150000000116000000000000160000610000000000006100000000000000000000000000000000000105000000000000000000000000000000000000000000000000000000000000000000000000000000000000000049000000000049000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

Код эквивалентен

11300000000950000000034000000011600000001010000000115000000011600000000340000000061000000003300000000420000000058000000010500000000500000000102000000009800000000490000000102000000009800000000490000000098
AA#b:c~

который может быть проверен онлайн .

Как это работает

"",  e# Push the length of the string.
AA#  e# Push 10000000000.
b    e# Turn the length into the array of its base-10000000000 digits.
:c   e# Cast each digit to character. This pushes the following:
     e# q_"test"=!*:i2fb1fb1b
~    e# Evaluate the string.

Как это работает

q_     e# Read all input and push a copy.
"test" e# Push the string "test".
=!*    e# Check for inequality and repeat the string 0 or 1 times.
       e# This replaces input "test" with the empty string.
:i     e# Cast each character to integer
2fb    e# Replace each integer by the array of its base-2 digits.
1fb    e# Replace each array of base-2 digits by the sum of its digits.
1b     e# Add the sums of digits.

Этот исходный код имеет экологический след 75.


3
Вау, это умно. Я предполагаю, что предостережение заключается в том, что вы никогда не сможете запустить его, поскольку вся память в мире не может содержать весь код.
— Рето Коради,

49
Это незначительное неудобство. Вы не можете установить цену на природу.
— Деннис

Это хороший трюк, но он недействителен, если не может быть запущен
— edc65

5
@PyRulez: Ничего, если только он не будет построен из чего-то другого, кроме материи, и займет что-то другое, чем пространство.
— вс

5
Почему бы просто не использовать Lenguage?
— jimmy23013

40

Ленгуаг , 0


Вывод унарный , так как Lenguage / Brainfuck не имеет нормального способа печати целых чисел в базе 10.

Фактический исходный код содержит

22360559967824444567791709913713659826044558304969374451791514225490473373040212332757409553558758107085015797320276213515502796255082717802632399123502087743818475438512153373406931103005017157351410347278489842099128517039634739852783737052963203448945756470632484148121769939122103257063633371522287190530269279693540898545359211009781370158317748609540216376596783541124510013448091325488601732964773653391702083563797082990404753843419895799343996435988722965711513708742853668363743953430527328863418281733901770990932025503662188187254784985474815936854540100376410040743052620419372327997519047616042603909398552951490180076364164838561112002025592431155898041427468731461614504254168899805662501979953318388813759833797929243626668399650485310047043700001093878284174322463350892654886806075148010832042248607926124030339950499631072150856939786062937034833055717723216663269161130154002679878012158315587925933383341827053312086716181702533743607685576475754259877651521989944802973721727159955208722180232955193930065862370838526521351991966172723976565264862909528310162816593997640732796289501819499741414526385058421824690665542546821941125191276568479078107133076037506211133628962099403163812267452274532219562823184225236020523509355625620557197876838014050964240952738109101849512504021041103516630358995290177306585560988278630098667702211916671663291473843258785929522017507744814910480115446168939335008597569919072874897148594826036210511162928991890818427747059833051607455121463371211282760364668765311589329918870071117807132901910082663054895226456039171170783440772764031568108965851688162729239711772886386306884508520204834432674839183166053019421652064937613583258148354531835035461504442885024563141848164279928769795684221364984104923764359842286827870778678989243517189772102669283996930513577004801536579491093711362942690905779844535371088542020595945700544234301668098553671685123172583259206072965508639556627967633275762621813851479909708616154198658896714629908456913467267354690109885368211752176196164620615081464122410029328694509842558492529684841818953632659248840216891072110853731776562597900145806210691868173380612838327841104919352821441230296200143603175486627682007399030356592930049570084097858148122367

нулевые байты и эквивалентны следующей программе Brainfuck:

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

Попробуйте это онлайн на brainfuck.tk .

Длина кода Brainfuck весьма неоптимальна - для начала я жестко закодировал следы всех символов ASCII - но счет 0 равен 0 ...


Нет, Lenguage на самом деле поддерживает нулевые байты ?!
— Бета-распад

20
Я чувствую, что такой ответ, как этот, не проявляет никакого уважения публики: это обман и игра в систему ... Но в этом-то и весь смысл этой проблемы. +1
— edc65,

1
«Вывод одинарный, поскольку у Lenguage / Brainfuck нет нормального способа печати целых чисел в базе 10.» , Я думал, что отчасти Lenguage / Brainfuck заключался в том, что у него не было нормального способа что-либо делать :)
— Адам,

9
Это не совсем сработало для меня, когда я попытался воссоздать вашу программу из определения, которое вы дали. Не могли бы вы опубликовать полный исходный код Lenguage, чтобы я мог увидеть, чем ваша программа отличается от моей попытки ее воссоздания? ;-)
— Cort Ammon

1
Меня поражает не то, что Lenguage поддерживает нули, а то, что вам удалось создать такую ​​программу в BF. Призраки ...
— Эрик Outgolfer

12

PowerShell, 337 344 304 балла

PARAM([CHAR[]]$A)$A|%{$B+=([CONVERT]::TOSTRING(+$_,2)-REPLACE0).LENGTH};($B,0)[-JOIN$A-CEQ"test"]

Я кричу на тебя, потому что это дешевле!

Принимает input как $A, затем [convert]::ToString()преобразуется в массив char, затем перебирает цикл for для каждого символа, использует смехотворно многословный для преобразования символа в этой позиции в двоичный, заменяет все 0 на ноль, затем подсчитывает длину и добавляет это к $B. В конце использует эквивалентность для индексации в динамический массив (т. Е. Если $Aесть test, то -CEQесть $TRUE, поэтому он индексирует второй элемент, 0).

Edit1 - исправленный тестовый пример. "TEST"
Edit2 - отыграл пару моментов, перебирая сами символы, а не их индексы, и помня, что -replaceвторой параметр не требуется, если вы заменяете его ничем.


Двойная кавычка " 00100010более экологична, чем одинарная ' 00100111.
— Джейкоб Кралл

Возвращает неверное значение 0 для ввода"TEST"
— Джейкоб Кралл,

1
@JacobKrall Хорошо поймать двойную кавычку ". Также с поправкой -CEQна чувствительность к регистру. Это немного повысило баллы, потому что я неправильно оценивал, так ' 'как не правильно разграничил его в своих тестах.
— AdmBorkBork

9

Пиф - 52 49

Три очка сэкономить благодаря @orlp.

*/.BQ`1nQ"test

Принимает ввод в кавычках, чтобы сохранить площадь.

Тестовый пакет .


Тьфу, я почти получил то же, что и ты, но мой ответ слишком похож, и ты отправил первым. Заменить @,0с , *чтобы сохранить 3 :)
— orlp

1
@ Maltysen Вы говорите, что вы нашли три пункта, но источник все еще говорит @,0, вы просто забыли изменить?
— хлопнуть

@ConfusedMr_C да. Я просто изменил постоянную ссылку и забыл фактический ответ.
— Maltysen

7

Обыкновенный Лисп, 294 281 235

Чтобы уменьшить оценку, я использовал @(стоимость 1) и !(стоимость 2) в качестве имен переменных (правка: и даже лучше, если я использую @переменную, встречающуюся чаще всего в функции). Я кричу TOO , потому что это дешевле.

(LAMBDA(@)(IF(STRING="test"@)0(LOOP FOR ! ACROSS @ SUM(LOGCOUNT(CHAR-CODE !)))))

Довольно отпечатанных

(LAMBDA (@)
  (IF (STRING= "test" @) 0
      (LOOP FOR ! ACROSS @ SUM (LOGCOUNT (CHAR-CODE !)))))

Ну, счет больше похож на 294;)
— Cabbie407

@ Cabbie407 Я пропустил часть о выигрыше, извините :-)
— coredump

1
@ Cabbie407 У меня было странное чувство, что в течение нескольких минут у
— меня

1
Просто хотел, чтобы вы знали, потому что, зная о методе скоринга, вы, вероятно, посмотрите на свой код под другим углом. И я вижу, ты уже что-то изменил.
— Cabbie407

1
@ Cabbie407 Я забыл поблагодарить тебя, кстати. Благодарю.
— coredump

6

JavaScript, 279

Исправлена ​​ошибка редактирования (не учитывался бит 1 каждого символа)

Полная программа, с вводом и выводом через всплывающее окно. Протестировано в Firefox, должно работать в любом современном браузере.

B=(P=prompt)(H=D=0)
while(B!="test"&&(A=B.charCodeAt(H++)))while(A)D+=A&1,A>>=1
P(D)

Некоторые инструменты (протестировано с Firefox)

w=c=>c.toString(2).split('').reduce(function(a,b){return a- -b})

t=[[],[],[],[],[],[],[],[],[]]
u=[[],[],[],[],[],[],[],[],[]]
for(c=1;c<256;c++)
  c<33|c>126&c<161 ? t[w(c)].push('\\'+c) : u[w(c)].push('&#'+c+';')
for(i=0; i++<8;)       
  T.innerHTML+=i+': '+u[i].concat(t[i]).join(' ')+'\n'

function Calc()
{
  var r='', t=0, b
  I.value.split('').forEach(function(c) {
    c = c.charCodeAt(), r += '\n&#'+c+' '+((256+c).toString(2).slice(1))+' : '
    for(b=0;c;c>>=1) b += c&1
    r += b, t += b
  })
  R.innerHTML='Total '+t+'\nDetail'+r
}
#I { width: 400px }
<b>Weight table</b><pre id=T></pre><br>
<b>Counter</b><br><textarea id=I></textarea><button onclick="Calc()">-></button> <pre id=R></pre>


1
Этот ответ недействителен - testвместо 0
— выводится

@ASCIIThenANSI нет, это не в моем браузере. Но я собираюсь проверить еще раз
— edc65

Забавно ... Тестируя это со своим счетчиком, я получаю 279, и проверяя это с собой, я получаю 277. Интересно, что правильно; это может иметь какое-то отношение к переводу строки?
— ETHproductions

@ETHproductions Я дважды проверил, и правильный счет равен 279. Но он не работает со строкой, содержащей символ новой строки - это проблема, связанная с promptфункцией. В Firefox promptпереводит переводы строки (2 бита) в пробелы (1 бит), поэтому мы получаем 277 вместо 279
— edc65

@ETHproductions ... в Chrome (в Windows) символ новой строки становится парой CR LF (3 бита + 2 бита), и счет снова неверен
— edc65

6

Юлия, 254 246 232

P=readline()
print(P=="test"?0:sum([count_ones(1*A)for A=P]))

count_onesФункция подсчитывает количество единиц в двоичном представлении его ввода.

Снижение моего экологического следа благодаря FryAmTheEggman!


1
Нет проблем, я просто очень
— заботюсь

6

Питон 3, 271

z=input();print([sum([bin(ord(i)).count("1")for i in z]),0][z=="test"])

3
Много маленьких изменений дает мне 228
— FryAmTheEggman

2
Почему бы не воспользоваться преимуществами, что bools являются целыми числами? z=input();print(sum(bin(ord(i)).count("1")for i in z)*(z!="test")).... @ FryAmTheEggman сглаз?
— NightShadeQueen

1
@ NightShadeQueen Хаха, это значит, что я не могу публиковать сообщения в течение дня? : X В любом случае, это очень хороший улов для нового пользователя на этом сайте, отличная работа! В любом случае, добро пожаловать в PPCG! :) Кроме того, больше по теме, точка с запятой может быть удалена, так как стоит немного больше, чем перевод строки.
— FryAmTheEggman

5

Perl, 136 118 73

$_=unpack"B*";$_=y@1@@

Заменить все @на\0

Пример использования:

perl -p entry.pl entry.pl

5

MATLAB, 198 194 байта

A=input('','s');~strcmp('test',A)*nnz(dec2bin(A)-48)

Сначала строка считывается из STDIN через inputфункцию. Как только это происходит, мы сравниваем входную строку со строкой test. Если результата нет test , мы конвертируем каждый символ в его код ASCII, а затем через его двоичное представление dec2bin. Прекрасным следствием этой функции является то, что если вы отправляете строку, двоичное представление ее кода ASCII ограничивается одним символом в строке.

В качестве примера:

>> dec2bin('ABCD')

ans =

1000001
1000010
1000011
1000100

dec2binвыводит массив символов. Как только это произойдет, вычтите на 48, что является кодом ASCII для 0, так что матрица преобразуется в doubleсостоящий из 0 и 1. Как только это произойдет, вызовnnz подсчитывает общее количество ненулевых элементов в этой матрице. Обратите внимание, что этот результат умножается на значение, противоположное строке сравнения test. Если строка не будет test, мы получаем расчет след. Если он равен, то умножение приводит к 0.

Некоторые примеры:

>> A=input('','s');~strcmp('test',A)*nnz(dec2bin(A)-48)
A

ans =

     2

>> A=input('','s');~strcmp('test',A)*nnz(dec2bin(A)-48)
O

ans =

     5

>> A=input('','s');~strcmp('test',A)*nnz(dec2bin(A)-48)
test

ans =

     0


>> A=input('','s');~strcmp('test',A)*nnz(dec2bin(A)-48)
  %// Note - no characters were added here.  Simply pushed Enter

ans =

     0

Если вам разрешено использовать Communications Toolbox, вы можете использовать de2biвместо него и избегать -48приведения его к числовому типу (а также к 2 дополнительным символам в имени функции).
— мензурка

5

удар 440 430 412 405 403

A=0
[ test != "$1" ]&&for((D=0;D<${#1};D++)){
A=$((A+`bc<<<$(printf "obase=2;%d" "'${1:$D:1}")|tr -d "0
"|wc -m`))
}
echo $A

Довольно просто. Зацикливает символы на входе, преобразуя сначала в ascii (с printf %dи ведущим 'на числе, затем в двоичный (с bc), удаляет нули и подсчитывает количество символов.

Не очень хороший ответ, но еще не видел попытки bash.

Изменено, поскольку мой первый ответ позволял вводить строку ввода просто в командной строке (т. Е. Она превращалась в несколько входных параметров при многократных словах), но после прочтения некоторых других ответов я думаю, что могу предположить, что она заключена в кавычки, поэтому вся строка выглядит как $1


1
Добро пожаловать в Программирование Пазлов и Код Гольф! 1. Вы можете заменить doна {и doneс }. 2. Вам также не нужны места вокруг <<<. 3. Вы можете заменить \nбуквальный перевод строки.
— Деннис

Спасибо @Dennis. Одной из проблем на этом сайте является отмена «хороших привычек» :).
— Адам

3
Это точно так. Если вы еще этого не сделали, я рекомендую ознакомиться с советами по игре в гольф в Баше . Это отличный ресурс.
— Деннис

3
Эта задача странная даже по меркам гольфа! Дополнительные персонажи могут сохранять очки. Использование =и ||стоит 15, тогда как использование !=и &&только 13! Дополнительный персонаж, но экономит два очка ...
— Адам

5

Цейлон, 1431 , 764 , 697 , 571 , 547 , 538 , 501 , 493 , 467 , 451

shared void p(){print(sum{0,if(exists a=process.arguments[0])if(a!="test")for(c in a)for(b in 0..7)if(c.hash.get(b))1});}

Это был оригинал, без гольфа

Integer footprintCharacter(Integer b) {
    return sum({0, for(i in 0..7) if(b.get(i)) 1 });
}
Integer footPrintString(String s) {
    if(s == "test") {return 0;}
    return sum({0, for(c in s) footprintCharacter(c.integer)});
}
shared void footprint() {
     if(exists s = process.arguments[0]) {
         print(footPrintString(s));
     } else {
         print("This program needs at least one parameter!");
     }
}

Это берет аргумент из параметра командной строки ... process.arguments является (возможно, пустой) последовательностью строк, поэтому перед использованием одной из них нам нужно проверить, существует ли она на самом деле. В другом случае мы выводим сообщение об ошибке (это не требуется вопросом и будет выброшено в следующих версиях).

sumФункция Цейлона принимает непустую Iterable элементов некоторого типа, который должен удовлетворять Summable, т.е. имеет plusметод, такой как Integer. (Он не работает с пустыми последовательностями, потому что у каждого типа Summable будет свой ноль, и у среды выполнения нет шансов узнать, какой из них имеется в виду.)

Элементы строки или один бит целого числа не являются непустыми итерациями. Поэтому мы используем эту возможность для создания итерируемого, указав некоторые элементы, а затем «понимание» (которое будет оценено как ноль или более элементов). Таким образом, в случае символов мы добавляем их (но только когда установлен соответствующий бит), в случае строк мы добавляем результат символов. (Понимание будет оцениваться только тогда, когда принимающая функция фактически итерирует по нему, а не при построении Iterable.)

Давайте посмотрим, как мы можем уменьшить это. Во-первых, каждая из функций вызывается только в одном месте, поэтому мы можем встроить их. Также, как уже упоминалось выше, избавьтесь от сообщения об ошибке. (764 следа.)

shared void footprint() {
    if (exists s = process.arguments[0]) {
        if (s == "test") {
            print(0);
        } else {
            print(sum({ 0, for (c in s) sum({ 0, for (i in 0..7) if (c.integer.get(i)) 1 }) }));
        }
    }
}

Нам на самом деле не нужно внутреннее вложенное sum, мы можем сделать это одно большое понимание. (Это экономит нам 37 баллов sum({0,})и еще несколько пробелов, которые в конце концов будут устранены.) Это 697:

shared void footprint() {
    if (exists s = process.arguments[0]) {
        if (s == "test") {
            print(0);
        } else {
            print(sum({ 0, for (c in s) for (i in 0..7) if (c.integer.get(i)) 1 }));
        }
    }
}

Мы можем применить аналогичный принцип к специальной "test"строковой строке: так как в этом случае результат равен 0 (т.е. ничего не вносится в сумму), мы можем просто сделать это как часть суммирования (но мы должны инвертировать условие) , Это, в основном, спасает нас print(0);, некоторые скобки и кучу отступов, которые сводятся к 571:

shared void footprint() {
    if (exists s = process.arguments[0]) {
        print(sum({ 0, if (s != "test") for (c in s) for (i in 0..7) if (c.integer.get(i)) 1 }));
    }
}

Мы делаем то же самое для первого if, с побочным эффектом, который теперь не дает аргументов и выводит 0вместо того, чтобы ничего не делать. (По крайней мере, я думал, что это произойдет здесь, вместо этого, кажется, висит с вечной петлей? Странно.)

shared void footprint() {
    print(sum({ 0, if (exists s = process.arguments[0]) if (s != "test") for (c in s) for (i in 0..7) if (c.integer.get(i)) 1 }));
}

Мы можем на самом деле опустить ()для sumфункции здесь, используя альтернативный синтаксис вызова функции , которая использует {...}вместо (), и заполним постижения в Iterable аргументов. Это имеет след 538:

shared void footprint() {
    print(sum{ 0, if (exists s = process.arguments[0]) if (s != "test") for (c in s) for (i in 0..7) if (c.integer.get(i)) 1 });
}

Замена имени функции footprint(40) на p(3) экономит еще 37 баллов, в результате чего мы получаем 501. (Имена функций Цейлона должны начинаться с символов нижнего регистра, поэтому мы не можем получить здесь менее 3 баллов.)

shared void p() {
    print(sum{ 0, if (exists s = process.arguments[0]) if (s != "test") for (c in s) for (i in 0..7) if (c.integer.get(i)) 1 });
}

Имена переменных s(5) и c(4), i(4) также не оптимальны. Давайте заменим их на a(аргумент), d(цифра?) И b(бит-индекс). След 493:

shared void p() {
    print(sum{ 0, if (exists a = process.arguments[0]) if (a != "test") for (c in a) for (b in 0..7) if (c.integer.get(b)) 1 });
}

Я не вижу оставшейся оптимизации без пробелов, поэтому давайте удалим ненужные пробелы (1 точка для каждого пробела, две для каждого из двух разрывов строк):

shared void p(){print(sum{0,if(exists a=process.arguments[0])if(a!="test")for(c in a)for(b in 0..7)if(c.integer.get(b))1});}

Просматривая API, я обнаружил, что Character.hash фактически возвращает то же значение, что и его integerатрибут. Но у него всего 14 очков вместо 30, поэтому мы опустились до 451!

shared void p(){print(sum{0,if(exists a=process.arguments[0])if(a!="test")for(c in a)for(b in 0..7)if(c.hash.get(b))1});}

4

PowerShell, 273 336 328 324 293 288 295

PARAM($A)[CHAR[]]$A|%{$D=[INT]$_;WHILE($D){$B+=$D-BAND0X1;$D=$D-SHR1}};($B,0)[$A-CEQ"test"]

редактировать - забыл «тестовый» случай ... так дорого.

editedit - упустил возможность UPPERCASE.

editeditedit - включены комментарии предложения (спасибо TimmyD).

редактировать 4 - D дешевле, чем C (2 против 3)

изменить 5 - Вернуться к 295 из-за проверки чувствительности к регистру.

Зацикливает строку и считает 1, которые сдвигаются со значения ASCII символов.

Подсказка к TimmyD за то, что дал мне возможность использовать заглавные буквы И использовать индекс массива в конце.


1
Хороший подход! Пара гольфов (убрала инициализацию $ B, так как она по умолчанию обнуляется, удалила пару паренов, удалила несколько точек с запятой), опустила ее до 293 PARAM($A)[CHAR[]]$A|%{$C=[INT]$_;WHILE($C){$B+=$C-BAND0X1;$C=$C-SHR1}};($B,0)[$A-EQ"TEST"]
— AdmBorkBork

Что это значит, когда я читаю "Хороший подход!" а слышал голос от Wii Golf? Спасибо за указатели! Инициализация сбила меня с толку при тестировании в консоли PowerShell, и я оставил это. Хорошо знать иначе.
— Сорок3

Да - если вы используете консоль, это в значительной степени среда REPL, в которой назначенные переменные остаются от одной строки к следующей. Если вы сохраните его как .ps1, то $ B (и любая другая переменная) будет повторно инициализирован, даже если вы нажмете стрелку вверх-enter из той же оболочки. Например,PS C:\scripts> .\ecological-footprint.ps1
— AdmBorkBork

Возвращает неверное значение 0 для ввода"TEST"
— Джейкоб Кралл,

1
281PARAM($A)(([CHAR[]]$A|%{$B=$_;0..9|?{[INT]$B-SHR$_-BAND1}}).LENGTH,0)[("TEST"-EQ$A)]
— Томканди


4

С, 374

Новые строки (не включены в счет) добавлены для ясности. Можно улучшить до 360, просто изменив имена переменных в верхний регистр, но я постараюсь придумать что-нибудь получше.

Ввод осуществляется через командную строку, что означает, что при отсутствии ввода происходит сбой. Я ожидаю худшего результата для ввода через стандартный ввод.

i,t;
main(int c,char**v){
for(;c=v[i][i/8];i++)t+=(c>>i%8)&1;
printf("%d",strcmp(v[1],"test")?t:0);
}

4

PHP, 377 337 299 Экологический след (все еще много) , 102 91 байт

Кажется, что PHP безопасен для окружающей среды только в тестовом режиме. ;)

WHILE($D<STRLEN($A=$argv[1]))$B+=SUBSTR_COUNT(DECBIN(ORD($A[$D++])),1);ECHO"test"!=$A?$B:0;

Запускается из командной строки, как:

php footprint.php hello
php footprint.php test

whileявляется более дружественным к окружающей среде, чем, forхотя они имеют одинаковое количество символов. Также имена переменных в верхнем регистре имеют лучшую площадь, чем их аналоги в нижнем регистре.

редактировать

  • сохранено 40 баллов с использованием заглавных имен функций.
  • сэкономил 38 баллов, используя decbinвместоbase_convert

1
@ Adam Здесь обсуждаются уведомления, а здесь - открывающие теги PHP . Надеюсь, это полезно для вас.
— вставить имя пользователя здесь

4

VBA, 475 418

Спасибо Джейкобу за 57 очков

  • Преобразует строку в массив байтов (128 - это ярлык vba для «Преобразование строки из Unicode в кодовую страницу системы по умолчанию», поэтому не будет работать на Mac ....)

  • Циклы, хотя байтовый массив преобразовывает в двоичный и объединяет все вместе.

  • проверяет на тест
  • Выводит длину строки со всеми нулями, замененными ничем

VBA, почему ты так плохо играешь в гольф ... :(

SUB A(D)
DIM B() AS BYTE
B=STRCONV(D,128)
FOR P=0 TO UBOUND(B)
H=H+APPLICATION.DEC2BIN(B(P))
NEXT
IF D="test" THEN H=0
MSGBOX LEN(REPLACE(H,0,""))
ENDSUB

4
VBA нечувствителен к регистру, поэтому вы должны использовать везде верхний регистр, чтобы сохранить точку на символ нижнего регистра! (кроме, "test"конечно)
— Джейкоб Кралл


3

Пиф, 64

?qz"test"0l`sS.Bz

Проверяет, является ли ввод тестовым, а если нет, подсчитывает количество единиц в двоичном представлении ввода.


3

Хаскелл, 292

a 0=0
a b=rem b 2+a(div b 2)
b"test"=0
b d=sum$map(a.fromEnum)d
main=interact$show.b

Здесь особо нечего сказать: превратите каждый символ в значение ascii ( fromEnum) и вычислите 1s (через a). Подведите все результаты.


3

JavaScript (ES6), 521 478 458 449 473 465

alert(((A=prompt(),A!="test")&&(A!=""))?(A.split``.map(H=>(H.charCodeAt().toString(2).match(/1/g)||[]).length)).reduce((A,B)=>A+B):0)

Это моя первая попытка в JavaScript-гольфе, так что это, вероятно, очень нелегко.


Общепринято, что JavaScript-гольф нуждается в какой-либо форме вывода, отличной от неявной. Это может быть предупреждение, document.write или даже возврат функции.
— Mwr247

Вы можете переместить назначение приглашения в первые 's' в операторе if, заключив их в круглые скобки, чтобы сохранить пару байтов. Вы также можете удалить «0» в charCodeAt. Кроме того, вы можете сэкономить, используя троичный оператор вместо операторов if / else =)
— Mwr247

Большое спасибо! В конце концов я использовал запятую вместо скобок для быстрого назначения; это сохраняет другой байт. (: @ Mwr247
— Зак Гейтс,

Вместо этого s.split ('') может быть s.split``, экономя 2 байта
— Dendrobium

1
За комментарий Дендробиума выше @JacobKrall
— Зак Гейтс

3

Рубин, 316 313

Очень просто, ища еще несколько возможностей для игры в гольф:

b=gets.chomp;b=='test'?0:b.chars.map{|i|i.ord.to_s(2).count('1')}.inject(:+)
  • Используется bвместо xсохранения 3 балла.

Вы можете использовать $*[0]вместо gets.chomp(принимает ввод как аргумент командной строки)
— Mhmd

Двойная кавычка " 00100010более экологична, чем одинарная ' 00100111.
— Джейкоб Кралл,

Имена переменных в верхнем регистре также более экологичны, чем эквивалентные строчные. Hлучше, чем Iпо той же причине.
— Джейкоб Кралл

3

Python 2, 294 281 269 266

A=input()
print sum(format(ord(H),"b").count("1")for H in A)if A!="test"else 0

Порт моего Pyth ответа, выше.

Ввод получен в виде строки (с кавычками):

"ABC"

1
Двойная кавычка " 00100010более экологична, чем одинарная ' 00100111.
— Джейкоб Кралл

Пара базовых модификаций сводится к этому A=input();print[sum(bin(ord(H)).count("1")for H in A),0][A=="test"]со счетом 243.
— Kade


2

Пиф, 96

Iqz"test"0.q)/j""m.BdmCdz\1

Порт моего ответа CJam, выше / ниже.


Просто некоторые общие замечания Pyth: вместо того, Iчтобы пытаться использовать троичный ?, но в этом случае, поскольку это bool, вы можете просто использовать *(после переключения nвместо q), kавтоматически ""и sна строках то же самое a jk. Надеюсь, вам весело изучать Pyth! :)
— FryAmTheEggman

Это был мой первый ответ Pyth: P Было достаточно сложно получить это, ха-ха, хотя весело. Спасибо за советы! @FryAmTheEggman
— Зак Гейтс

2

CJam, 83 81 79 77

Лучше всего, если вы попробуете несколько вариантов:

l0$"test"=!\:i2fbe_1b*

Попробуйте онлайн

Объяснение:

l       Get input. Other options like q and r are the same number of bits.
0$      Copy input for comparison. This saves 2 bits over _.
"test"  Push special case string.
=       Compare.
!       Negate so that we have 0 for special case, 1 for normal case.
\       Swap input string to top.
:i      Convert characters to integers.
2fb     Apply conversion to base 2 to all values.
e_      Flatten array.
1b      Sum up the bits. This is 2 bits shorter than :+.
*       Multiply with result from special case test.

2

Руби, 247

Простой подход, циклически проходящий через все байты ввода и все биты в каждом байте, суммируя с переменной d .

d инициализируется до -2, потому что h содержит завершающий символ новой строки из ввода (стоит 2 бита), и мы не хотим это считать.

Точно так же hбудет содержаться testс завершающей новой строкой, поэтому новая строка должна быть включена в значение сравнения.

d=-2
h=gets
h.bytes{|a|8.times{|b|d+=a>>b&1}}
p h=='test
'?0:d

2

R 279

sum(as.integer(rawToBits(charToRaw(if((s=readline())=='test')''else s))))

Довольно понятно.
тесты:

> sum(as.integer(rawToBits(charToRaw(if((s=readline())=='test')''else s))))
sum(as.integer(rawToBits(charToRaw(if((s=readline())=='test')''else s))))
[1] 279
> sum(as.integer(rawToBits(charToRaw(if((s=readline())=='test')''else s))))
A
[1] 2
> sum(as.integer(rawToBits(charToRaw(if((s=readline())=='test')''else s))))
O
[1] 5
> sum(as.integer(rawToBits(charToRaw(if((s=readline())=='test')''else s))))
test
[1] 0
> sum(as.integer(rawToBits(charToRaw(if((s=readline())=='test')''else s))))
OAO
[1] 12

2

C, 378 следов, 98 байт

Другое решение C:

s;main(c,a)char**a;{for(s=-17*!strcmp(a[1],"test");c=*a[1]++;)for(;c;s+=c&1,c/=2);printf("%d",s);}

Это работает так, что s обычно инициализируется в 0, но становится -17, если аргумент командной строки равен «test» (strcmp возвращает 0 в одинаковых строках и ненулевое значение в разных строках, поэтому инвертирование дает 1, если строка это "тест"). Число -17 было выбрано, чтобы компенсировать след 17, который будет рассчитан для «теста». Вычисление занимаемой площади легко с побитовыми операторами.

Щелчок! Первоначально я пропустил «кратчайшие выигрыши», поэтому я стремился к самому короткому коду ... Я посмотрю, смогу ли я уменьшить «след».


2

Ява, 594

class A{public static void main(String[]P){Integer D,H;for(D=H=0;D<P[0].length();)H+=D.bitCount(P[0].charAt(D++));System.out.print(P[0].equals("test")?0:H);}}

Ява не очень зеленая.

Безголовая версия:

class A {
    public static void main(String[]P) {
        Integer D,H;
        for(D=H=0;D<P[0].length();)
            H+=D.bitCount(P[0].charAt(D++));
        System.out.print(P[0].equals("test")?0:H);
    }
}

Dобъявлен как Integerтак, чтобы мы могли получить доступ Integerк статическому bitCountметоду экологически сознательным образом. bitCountМетод рассматривает charS как целые числа и возвращает число установленных бит.


1
Интересно сравнить Java с Ceylon ... Java имеет некоторые накладные расходы из-за шаблонного и более длинного оператора печати. Хотя bitCount помогает, у Цейлона этого нет. Цейлон имеет более длинный способ доступа к параметрам командной строки, а также должен проверить, действительно ли они заданы (где ваша программа просто выдаст исключение ArrayIndexOutOfBoundsException). Функция суммирования в Цейлоне, безусловно, короче, чем добавление ее вручную в Цейлоне (но у Java нет понимания, поэтому ручное добавление лучше, чем создание Iterable самостоятельно).
— Паŭло Эберманн,
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.