Pegada ecológica do código fonte


102

Você acabou de ser contratado por uma empresa alemã de fabricação de automóveis. Sua primeira tarefa, como engenheiro, é escrever um programa que calcule a pegada ecológica das seqüências de caracteres ASCII.

A pegada ecológica do caractere é calculada da seguinte forma:

Escreva o código ASCII do caractere em binário e conte o número de 1s.

Por exemplo, Atem uma pegada de 2, mas Oé mais sujo com uma pegada de 5.

A pegada global de uma string é a soma das pegadas de seus caracteres. Uma cadeia vazia tem uma área de cobertura zero.

Seu programa deve aceitar uma string ASCII como parâmetro (por linha de comando ou entrada), calcular sua pegada ecológica e produzi-la. O próprio programa deve ser codificado em ASCII.

Há um soluço embora. Como sua empresa deseja entrar em um novo mercado com regras ambientais mais rígidas, você precisa ajustar seu programa para que ele se comporte de maneira diferente no "modo de teste". Portanto:

O programa deve gerar 0 quando receber a string testcomo parâmetro.

Pontuação

O código fonte com a menor pegada ecológica vence (e sim, a resposta testé proibida!)


36
Sinto muito, não acompanhei as notícias, mas acabei de ler. Podemos assumir que a montadora alemã definitivamente NÃO se chama Volkswagen?
Level River St

7
Para referência, os caracteres mais caros para os menos caros:\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 É uma empresa fictícia, mas seu nome realmente começa com V e tem um W em algum lugar no meio. Mas qualquer semelhança com a realidade é mera coincidência, pelo menos alguém nos processa.
Mindwin

1
Funções permitidas (em vez de programas)?
Luis Mendo

12
Eles estão mentindo para você! 1s são muito mais ecologicamente corretos que 0s. Quer prova? Imprima seu código fonte em binário. Os zeros usam quase o dobro da tinta que os zeros. E se você codifica com um fundo escuro, eles também gastam mais eletricidade para exibir na tela. (Se você codifica com fundo branco, já está desperdiçando elétrons tornando todo branco, então, claramente, qualquer programador ambientalmente consciente deve usar um fundo preto em seu editor.) Para ser mais ecologicamente correto, todos devemos escrever em Espaço em branco ...
Darrel Hoffman

Respostas:


45

CJam, 33 31

"",AA#b:c~

Existem 113000000009500000000340000000116000000010100000001150000000116000000003400000000610000000033000000004200000000580000000105000000005000000001020000005000000005000000001020000000098000000004900000001020000000098490000000102000000009800000000109800000000989800000000109800000000980000000049000000001098000000004900000001000000000989800000000109800000000980000000049000000010000000009800000000109800000000980000000049000000010000000009800000000109800000000980000000049000000010000000009898000000001098000000009898000000004949000000009898

O código é equivalente a

11300000000950000000034000000011600000001010000000115000000011600000000340000000061000000003300000000420000000058000000010500000000500000000102000000009800000000490000000102000000009800000000490000000098
AA#b:c~

que pode ser testado online .

Como isso funciona

"",  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.

Como isso funciona

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.

Esse código-fonte tem uma pegada ecológica de 75.


3
Uau, isso é inteligente. Eu acho que a ressalva é que você nunca poderia executá-lo, já que toda a memória do mundo não podia conter o código inteiro.
Reto Koradi

49
Isso é um pequeno inconveniente. Você não pode colocar um preço na natureza.
Dennis

Isso é um truque bom, mas é inválido se não pode ser executado
edc65

5
@ PyRulez: Não por nada, a menos que seja construído a partir de algo diferente da matéria e ocupe algo diferente do espaço.
vsz

5
Por que não usar apenas o Lenguage?
precisa saber é o seguinte

40

Linguagem , 0


A saída é unária , pois o Lenguage / Brainfuck não possui uma maneira sensata de imprimir números inteiros na base 10.

O código fonte real contém

22360559967824444567791709913713659826044558304969374451791514225490473373040212332757409553558758107085015797320276213515502796255082717802632399123502087743818475438512153373406931103005017157351410347278489842099128517039634739852783737052963203448945756470632484148121769939122103257063633371522287190530269279693540898545359211009781370158317748609540216376596783541124510013448091325488601732964773653391702083563797082990404753843419895799343996435988722965711513708742853668363743953430527328863418281733901770990932025503662188187254784985474815936854540100376410040743052620419372327997519047616042603909398552951490180076364164838561112002025592431155898041427468731461614504254168899805662501979953318388813759833797929243626668399650485310047043700001093878284174322463350892654886806075148010832042248607926124030339950499631072150856939786062937034833055717723216663269161130154002679878012158315587925933383341827053312086716181702533743607685576475754259877651521989944802973721727159955208722180232955193930065862370838526521351991966172723976565264862909528310162816593997640732796289501819499741414526385058421824690665542546821941125191276568479078107133076037506211133628962099403163812267452274532219562823184225236020523509355625620557197876838014050964240952738109101849512504021041103516630358995290177306585560988278630098667702211916671663291473843258785929522017507744814910480115446168939335008597569919072874897148594826036210511162928991890818427747059833051607455121463371211282760364668765311589329918870071117807132901910082663054895226456039171170783440772764031568108965851688162729239711772886386306884508520204834432674839183166053019421652064937613583258148354531835035461504442885024563141848164279928769795684221364984104923764359842286827870778678989243517189772102669283996930513577004801536579491093711362942690905779844535371088542020595945700544234301668098553671685123172583259206072965508639556627967633275762621813851479909708616154198658896714629908456913467267354690109885368211752176196164620615081464122410029328694509842558492529684841818953632659248840216891072110853731776562597900145806210691868173380612838327841104919352821441230296200143603175486627682007399030356592930049570084097858148122367

bytes nulos e é equivalente ao seguinte programa Brainfuck:

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

Experimente online no brainfuck.tk .

O comprimento do código Brainfuck é altamente abaixo do ideal - para iniciantes, eu codifiquei as pegadas de todos os caracteres ASCII - mas a pontuação 0 é a pontuação 0 ...


De jeito nenhum, o Lenguage realmente suporta bytes nulos ?!
Beta Decay

20
Sinto que uma resposta como essa não mostra respeito pelo público: é trapacear e enganar o sistema ... Mas esse é o objetivo desse desafio, afinal. +1
edc65 26/09/15

1
"A saída é unária, já que o Lenguage / Brainfuck não tem uma maneira sensata de imprimir números inteiros na base 10." . Eu pensei que parte do ponto de Lenguage / Brainfuck era que ele não tinha uma maneira sensata de fazer qualquer coisa :)
Adam

9
Isso não funcionou para mim quando tentei recriar seu programa a partir da definição que você deu. Você poderia postar a fonte completa do Lenguage para que eu possa ver onde o seu programa difere da minha tentativa de recriá-lo? ;-)
Cort Ammon

1
O que me surpreende não é que o Lenguage suporte nulos, mas que você conseguiu criar esse programa no BF. Assombrando ...
Erik the Outgolfer

12

PowerShell, 337 344 304 pontos

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

Estou gritando com você porque é mais barato!

Recebe a entrada como $A, depois lança como uma matriz de caracteres, itera sobre um loop for em cada caractere, usa o ridiculamente prolixo [convert]::ToString()para converter o caractere naquela posição em binário, substitui todos os 0 por nada, depois conta o comprimento e acrescenta isso a $B. No final, usa uma equivalência para indexar em uma matriz dinâmica (ou seja, se $Afor test, então -CEQé $TRUE, então indexa para o segundo elemento 0).

Edit1 - Caso de teste corrigido "TEST"
Edit2 - Golpeou alguns pontos repetindo os caracteres em vez de seus índices e lembrando que -replacenão é necessário um segundo parâmetro se você o substituir por nada.


As aspas duplas " 00100010são mais ecológicas que as aspas simples ' 00100111.
Jacob Krall 25/09

Retorna o valor incorreto 0 para entrada"TEST"
Jacob Krall

1
@JacobKrall Boa captura de aspas duplas ". Também corrigido com diferenciação entre -CEQmaiúsculas e minúsculas. Isso aumentou um pouco os pontos, porque eu estava pontuando incorretamente porque ' 'não os delimitei corretamente nos meus testes.
AdmBorkBork 25/09

9

Pitão - 52 49

Economize três pontos graças ao @orlp.

*/.BQ`1nQ"test

É necessário inserir aspas para economizar espaço.

Conjunto de Teste .


Quase consegui o mesmo que você, mas minha resposta é muito semelhante e você postou primeiro. Substitua @,0por *para salvar 3 :)
orlp

1
@ Maltysen Você diz que encontrou três pontos, mas a fonte ainda diz @,0: você esqueceu de mudar?
clap

@ConfusedMr_C sim. Acabei de alterar o link permanente e esqueci a resposta real.
Maltysen 27/09/15

7

Lisp comum, 294 281 235

Para reduzir a pontuação, usei @(custo 1) e !(custo 2) como nomes de variáveis ​​(edit: e é ainda melhor se eu usar @a variável que mais ocorre na função). ESTOU GRITANDO DEMAIS porque é mais barato.

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

Pretty-impresso

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

Bem, a pontuação é mais parecida com 294;)
Cabbie407 25/09/2015

@ Cabbie407 eu perdi a parte sobre a pontuação, desculpe :-)
coredump

1
@ Cabbie407 tive a estranha sensação de ter uma pontuação muito baixa para um par de minutos ...
coredump

1
Só queria que você soubesse, porque, conhecendo o método de pontuação, você provavelmente veria seu código de um ângulo diferente. E vejo que você já mudou alguma coisa.
precisa saber é o seguinte

1
@ Cabbie407 Eu esqueci de agradecer, aliás. Obrigado.
Coredump

6

JavaScript, 279

Editar correção de bug (não contava o bit 1 de cada caractere)

Um programa completo, com entrada e saída via pop-up. Testado no Firefox, deve funcionar em qualquer navegador moderno.

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

Algumas ferramentas (testadas com o 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
Esta resposta é inválido - ele gera 17 para test, em vez de 0.
ASCIIThenANSI

@ASCIIThenANSI não está no meu navegador. Mas eu vou verificar novamente
edc65

Isso é engraçado ... Testando com seu contador, recebo 279, e testando com ele mesmo, recebo 277. Gostaria de saber qual é o correto; poderia ter algo a ver com as novas linhas?
ETHproductions

@ETHproductions verifiquei duas vezes e a contagem certa é 279. Mas não funciona com uma string que contém uma nova linha - é um problema relacionado à promptfunção. No Firefox, prompttraduz as novas linhas (2bit) em espaços (1bit), então temos 277 em vez de 279
edc65

@ETHproductions ... no Chrome (no Windows) a nova linha torna-se um par CR LF (3bit + 2bit) ea contagem está errado de novo
edc65

6

Julia, 254 246 232

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

A count_onesfunção conta o número de unidades na representação binária de sua entrada.

Reduzi minha pegada ecológica graças a FryAmTheEggman!


1
Não tem problema, eu realmente me importo com o meio ambiente;)
FryAmTheEggman 25/09/2015

6

Python 3, 271

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

3
Um monte de pequenas mudanças me dá 228
FryAmTheEggman 25/15

2
Por que não aproveitar que os bools são ints? z=input();print(sum(bin(ord(i)).count("1")for i in z)*(z!="test")).... @ FryAmTheEggman jinx?
NightShadeQueen

1
@NightShadeQueen Haha, isso significa que não posso postar por um dia? : X De qualquer forma, é uma boa ideia para um novo usuário neste site, bom trabalho! De qualquer forma, bem-vindo ao PPCG! :) Além disso, mais sobre o tópico, o ponto e vírgula pode ser removido, pois custa um pouco mais do que uma nova linha.
FryAmTheEggman # 25/15

5

Perl, 136 118 73

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

Substitua tudo @por\0

Exemplo de uso:

perl -p entry.pl entry.pl

5

MATLAB, 198 194 bytes

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

Primeiro, a string é lida em STDIN através da inputfunção Quando isso acontece, comparamos a string de entrada com a string test. Se o resultado não for test , convertemos cada caractere em seu código ASCII e, em seguida, em sua representação binária via dec2bin. Uma conseqüência bonita dessa função é que, se você enviar uma string, a representação binária de seu código ASCII será delimitada como um caractere por linha.

Como um exemplo:

>> dec2bin('ABCD')

ans =

1000001
1000010
1000011
1000100

dec2bingera uma matriz de caracteres. Quando isso acontecer, subtraia por 48, que é o código ASCII para 0, para que a matriz seja convertida em doubleconsistindo em 0s e 1s. Quando isso acontece, uma chamada para nnzcontar o número total de elementos diferentes de zero nesta matriz. Observe que esse resultado é multiplicado pelo oposto da string comparada com test. Caso a string não seja test, obtemos o cálculo da pegada. Se for igual, a multiplicação resultará em 0.

Alguns exemplos:

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

Se você tiver permissão para usar o Communications Toolbox, poderá usá-lo de2bie evitar -48convertê-lo em um tipo numérico (além dos 2 caracteres extras no nome da função).
beaker

5

Bater 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

Bem direto. Faz um loop dos caracteres na entrada, convertendo primeiro em ascii (com printf %de o principal 'no número e depois em binário (com bc)), retira os zeros e conta o número de caracteres.

Não é uma ótima resposta, mas ainda não tinha visto uma tentativa de festa.

Modificada desde a minha primeira resposta, a string de entrada pode ser dada simplesmente na linha de comando (ou seja, tornou-se vários parâmetros de entrada, se houver várias palavras), mas depois de ler algumas outras respostas, acho que posso supor que ela esteja entre aspas, portanto, toda a string aparece como $1


1
Bem-vindo à programação de quebra-cabeças e código de golfe! 1. Você pode substituir dopor {e donecom }. 2. Você também não precisa dos espaços ao redor <<<. 3. Você pode substituir \npor um avanço de linha literal.
Dennis

Obrigado @Dennis. Um dos desafios deste site é desaprender vários "bons hábitos" :).
Adam

3
Com certeza é. Se ainda não o fez, recomendo conferir as dicas para jogar golfe no Bash . É um ótimo recurso.
Dennis

3
Este desafio é estranho, mesmo para os padrões de golfe! Caracteres extras ainda podem economizar pontos. Usando =e ||custa 15 enquanto usando !=e &&é apenas 13! Um caractere extra, mas economiza dois pontos ...
Adam /

5

Ceilão, 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});}

Este era o original, não destruído:

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!");
     }
}

Isso leva o argumento a partir de um parâmetro da linha de comando ... process.arguments é uma sequência de sequências (possivelmente vazias); portanto, antes de usar uma delas, precisamos verificar se ela realmente existe. No outro caso, emitimos uma mensagem de erro (isso não é requerido pela pergunta e será descartado nas próximas versões).

A sumfunção do Ceilão pega um Iterável não vazio de elementos de algum tipo que precisa satisfazer Summable, ou seja, possui um plusmétodo, como Inteiro. (Ele não funciona com sequências vazias porque cada tipo de Summable terá seu próprio zero e o tempo de execução não tem chance de saber qual é o significado.)

Os elementos de uma string ou os bits de um número inteiro não são iteráveis ​​não vazios. Portanto, estamos usando aqui o recurso para criar uma iterável especificando alguns elementos, depois uma "compreensão" (que será avaliada como zero ou mais elementos). Portanto, no caso de caracteres, estamos adicionando uns (mas somente quando o bit correspondente é definido), no caso de string, estamos adicionando o resultado dos caracteres. (A compreensão será avaliada apenas quando a função de recebimento realmente iterar sobre ela, não ao criar o Iterable.)

Vamos ver como podemos diminuir isso. Primeiro, cada uma das funções é chamada apenas em um local, para que possamos incorporá-las. Além disso, como mencionado acima, livre-se da mensagem de erro. (764 pontos de pegada).

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 }) }));
        }
    }
}

Na verdade, não precisamos do interior aninhado sum, podemos fazer uma grande compreensão. (Isso economiza 37 pontos de pegada para sum({0,}), e mais alguns, para espaços em branco, que serão eliminados no final de qualquer maneira.) Isso é 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 }));
        }
    }
}

Podemos aplicar um princípio semelhante à "test"sequência especial : como nesse caso o resultado é 0 (ou seja, nada é contribuído para a soma), podemos fazer isso como parte da soma (mas temos que inverter a condição) . Isso nos poupa principalmente print(0);, algumas chaves e um monte de espaços de recuo, chegando a uma pegada de 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 }));
    }
}

Fazemos o mesmo para o primeiro if, com o efeito colateral que agora não gera argumentos também gera, em 0vez de não fazer nada. (Pelo menos eu pensei que isso iria acontecer aqui, em vez disso, parece travar com um laço eterno? Estranho.)

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 }));
}

Na verdade, podemos omitir o ()para a sumfunção aqui, usando uma sintaxe de chamada de função alternativa , que usa {...}em vez de (), e irá preencher compreensões em argumentos iteráveis. Isso tem pegada 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 });
}

Substituir o nome da função footprint(40) por p(3) economiza outros 37 pontos, levando-nos para 501. (Os nomes das funções do Ceilão precisam começar com caracteres minúsculos, portanto, não podemos obter menos de 3 pontos aqui.)

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 });
}

Os nomes das variáveis s(5) e c(4), i(4) também não são ótimos. Vamos substituí-los por a(argumento), d(dígito?) E b(índice de bits). Pegada 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 });
}

Não vejo nenhuma otimização restante de espaço em branco, portanto, vamos remover o espaço em branco não necessário (1 ponto para cada espaço, dois para cada uma das duas quebras de linha):

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});}

Ao navegar na API, descobri que Character.hash realmente retorna o mesmo valor que seu integeratributo. Mas tem apenas 14 pontos em vez de 30, então chegamos a 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"]

editar - esqueci o caso 'teste' ... muito caro.

edited - perdeu uma oportunidade de MAIÚSCULAS.

edititedit - incorporou as sugestões de comentários (Obrigado TimmyD).

editar 4 - D é uma variável mais barata que C (2 vs. 3)

editar 5 - Voltar para 295 devido à verificação de distinção entre maiúsculas e minúsculas.

Faz um loop na string e conta os 1s que são deslocados do valor ASCII dos caracteres.

Dica para TimmyD por me dar a previsão de usar caracteres maiúsculos E usar o índice de matriz no final.


1
Boa abordagem! Um par de campos de golfe (removido da inicialização $ B, uma vez que será o padrão para zero, removido um par de parênteses, removido algumas vírgulas), traz para baixo a 293 PARAM($A)[CHAR[]]$A|%{$C=[INT]$_;WHILE($C){$B+=$C-BAND0X1;$C=$C-SHR1}};($B,0)[$A-EQ"TEST"]
AdmBorkBork

O que significa quando leio "Boa abordagem!" e ouviu a voz do Wii Golf? Obrigado pelas indicações! A inicialização estava me atrapalhando ao testá-lo no console do PowerShell e eu o deixei. É bom saber o contrário.
precisa saber é o seguinte

Sim - se você estiver usando o console, é praticamente um ambiente REPL, pois as variáveis ​​atribuídas permanecem de uma linha para a outra. Se você salvá-lo como .ps1, o $ B (e todas as outras variáveis) será reinicializado, mesmo se você pressionar a tecla de seta para cima e entrar no mesmo shell. Por exemplo,PS C:\scripts> .\ecological-footprint.ps1
AdmBorkBork

Retorna o valor incorreto 0 para entrada"TEST"
Jacob Krall 25/15

1
281PARAM($A)(([CHAR[]]$A|%{$B=$_;0..9|?{[INT]$B-SHR$_-BAND1}}).LENGTH,0)[("TEST"-EQ$A)]
tomkandy

4

Matlab, 320

A=(input('','s'));nnz(floor(rem(bsxfun(@times,[A 0],2.^(-7:0)'),2)))*~strcmp(A,'test')

4

C, 374

Novas linhas (não incluídas na pontuação) adicionadas para maior clareza. Poderia ser aprimorado para 360 apenas alterando os nomes das variáveis ​​para maiúsculas, mas tentarei pensar em algo melhor.

A entrada é via linha de comando, o que significa segfaults na entrada ausente. Espero uma pontuação pior para entrada através de stdin.

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 Pegada Ecológica (ainda muito) , 102 91 Bytes

Parece que o PHP é favorável ao meio ambiente apenas no modo de teste. ;)

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

Executa a partir da linha de comando como:

php footprint.php hello
php footprint.php test

whileé mais favorável ao meio ambiente do que formesmo que eles compartilhem a mesma contagem de caracteres. Também nomes de variáveis ​​em maiúsculas têm uma pegada melhor do que seus equivalentes em minúsculas.

Editar

  • economizou 40 pontos usando nomes de funções em maiúsculas.
  • economizou 38 pontos usando em decbinvez debase_convert

1
@ Adam Aqui está uma discussão sobre os avisos e aqui sobre as tags de abertura do PHP . Espero que isso seja útil para você.
insertusernamehere

4

VBA, 475 418

Obrigado Jacob por 57 pontos de desconto

  • Converte seqüência de caracteres em matriz de bytes (128 é o atalho vba para "Converte a seqüência de caracteres de Unicode na página de código padrão do sistema", portanto, não funciona no Mac ....)

  • Loops embora matriz de bytes convertendo em binário e concatenando tudo juntos.

  • verifica se há teste
  • Imprime o comprimento da string com todos os 0s substituídos por nada

VBA por que você é tão ruim no golfe ... :(

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
O VBA não diferencia maiúsculas de minúsculas; portanto, você deve usar maiúsculas em todos os lugares para salvar um ponto por caractere minúsculo! (exceto, é "test"claro)
Jacob Krall

4

JavaScript, 418 410

A=prompt();B=0;!A||A=="test"?0:A.split("").forEach(D=>B+=D.charCodeAt().toString(2).match(/1/g).length);alert(B)

As aspas duplas " 00100010são mais ecológicas que as aspas simples ' 00100111.
Jacob Krall 25/09

3

Pyth, 64

?qz"test"0l`sS.Bz

Verifica se a entrada é teste e, se não, conta o número de 1s na representação binária da entrada.


3

Haskell, 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

Não há muito o que dizer aqui: transforme cada caractere em valor ASCII ( fromEnum) e calcule os 1(via a). Soma todos os resultados.


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)

Esta é a minha primeira tentativa de jogar golfe em JavaScript, por isso é provavelmente muito não-destruído.


É geralmente aceito que o golfe JavaScript precisa de alguma forma de saída que não seja implícita. Pode ser um alerta, document.write ou até um retorno de função.
precisa saber é o seguinte

Você pode mover sua atribuição de prompt para os primeiros 's' na instrução if, entre parênteses, para salvar alguns bytes. Você também pode remover o '0' em charCodeAt. Além disso, uma grande economia que você pode fazer é usar o operador ternário em vez dos comandos if / else =)
Mwr247

Muito obrigado! Acabei usando uma vírgula em vez de entre parênteses para a tarefa rápida; ele salva outro byte. (: @ Mwr247
Zach Gates

s.split ('') pode ser s.split``, economizando 2 bytes
Dendrobium

1
Comentário de Per Dendrobium acima @JacobKrall
Zach Gates

3

Ruby, 316 313

Muito simples, procurando mais possibilidades de golfe:

b=gets.chomp;b=='test'?0:b.chars.map{|i|i.ord.to_s(2).count('1')}.inject(:+)
  • Utilizado em bvez de xeconomizar 3 pontos.

Você pode usar $*[0]em vez de gets.chomp(leva de entrada como um argumento de linha de comando)
Mhmd

As aspas duplas " 00100010são mais ecológicas que as aspas simples ' 00100111.
Jacob Krall 25/09

Os nomes de variáveis ​​em maiúsculas também são mais ecologicamente corretos que os em minúsculas equivalentes. Hé melhor do que Ipela mesma razão.
Jacob Krall 25/09

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

Um porto da minha resposta Pyth, acima.

A entrada é recebida como uma sequência (entre aspas):

"ABC"

1
As aspas duplas " 00100010são mais ecológicas que as aspas simples ' 00100111.
Jacob Krall 25/09

Algumas modificações básicas obter este até A=input();print[sum(bin(ord(H)).count("1")for H in A),0][A=="test"]com uma pontuação de 243.
Kade


2

Pyth, 96

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

Uma porta da minha resposta CJam, acima / abaixo.


Apenas algumas notas gerais do Pyth: em vez de Itentar usar o ternário ?, mas neste caso, como é um bool que você pode usar *(depois de alternar para em nvez de q), ké automaticamente ""e snas strings é o mesmo a jk. Espero que você se divirta aprendendo pyth! :)
FryAmTheEggman

Esta foi a minha primeira resposta Pyth: P Foi difícil o suficiente para conseguir isso, haha, divertido. Obrigado pelas dicas! @FryAmTheEggman
Zach Gates

2

CJam, 83 81 79 77

Melhor até agora, depois de tentar várias variações:

l0$"test"=!\:i2fbe_1b*

Experimente online

Explicação:

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

Ruby, 247

Abordagem direta, percorrendo todos os bytes da entrada e todos os bits em cada byte, somando a variável d.

dé inicializado como -2 porque hcontém a nova linha final da entrada (vale 2 bits) e não queremos contar isso.

Da mesma forma, hele conterá testuma nova linha à direita, portanto, uma nova linha deve ser incluída no valor de comparação.

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))))

Bastante auto-explicativo.
Testes:

> 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, pegada 378, 98 bytes

Outra solução 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);}

A maneira como isso funciona é que s é inicializado como 0 normalmente, mas se torna -17 se o argumento da linha de comando for "test" (strcmp retorna 0 em cadeias iguais e diferente de zero em cadeias distintas, portanto, invertendo, fornece 1 se cadeia de caracteres é "teste"). O número -17 foi escolhido para compensar a pegada de 17 que será calculada para "teste". O cálculo da área ocupada é fácil com os operadores bit a bit.

Snap! Inicialmente, eu perdi as "vitórias mais baixas", então estava buscando o código mais curto ... Vou ver se posso diminuir a "pegada".


2

Java, 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);}}

Java não é muito verde.

Versão não destruída:

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é declarado como um Integerpara que possamos acessar Integero bitCountmétodo estático de uma maneira ambientalmente consciente. O bitCountmétodo trata os charcomo números inteiros e retorna o número de bits definidos.


1
Interessante comparar Java com Ceilão ... O Java tem alguma sobrecarga devido ao clichê e uma declaração de impressão mais longa. O bitCount ajuda, porém, o Ceilão não tem isso. O Ceilão tem uma maneira mais longa de acessar os parâmetros da linha de comando e também precisa verificar se eles são realmente fornecidos (onde seu programa simplesmente lançaria uma ArrayIndexOutOfBoundsException). A função soma do Ceilão é certamente mais curta do que adicioná-la manualmente no Ceilão (mas o Java não tem compreensão, portanto, adicionar manualmente é melhor do que construir você mesmo um Iterable).
Paŭlo Ebermann
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.