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


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.