Impronta ecologica del codice sorgente


102

Sei appena stato assunto da una casa automobilistica tedesca. Il tuo primo compito, come ingegnere, è scrivere un programma che calcoli l'impronta ecologica delle stringhe ASCII.

L'impronta ecologica del carattere è calcolata come segue:

Scrivi il codice ASCII del personaggio in binario e conta il numero di 1.

Ad esempio, Aha un footprint di 2, ma Oè più sporco con un footprint di 5.

L'impronta globale di una stringa è la somma delle impronte dei suoi caratteri. Una stringa vuota ha un footprint pari a zero.

Il programma deve accettare una stringa ASCII come parametro (tramite riga di comando o input), calcolare la sua impronta ecologica ed emetterla. Il programma stesso deve essere codificato ASCII.

C'è un singhiozzo però. Poiché la tua azienda desidera entrare in un nuovo mercato con regole ambientali più rigorose, è necessario ottimizzare il programma in modo che si comporti diversamente in "modalità test". Così:

Il programma dovrebbe generare 0 quando riceve la stringa testcome parametro.

punteggio

Vince il codice sorgente con il minimo impatto ecologico (e sì, la risposta testè vietata!)


36
Mi dispiace, non sono stato al passo con le notizie, ma l'ho appena letto. Possiamo supporre che la casa automobilistica tedesca NON sia sicuramente chiamata Volkswagen?
Level River St

7
Per riferimento, personaggi più costosi a meno costosi:\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 È una società fittizia, ma il suo nome inizia davvero con V e ha una W da qualche parte nel mezzo. Ma qualsiasi somiglianza con la realtà è una semplice coincidenza, almeno qualcuno ci fa causa.
Mindwin,

1
Funzioni consentite (anziché programmi)?
Luis Mendo,

12
Ti stanno mentendo! 1 sono molto più ecologici di 0. Vuoi una prova? Stampa il codice sorgente in binario. 0 usano quasi il doppio dell'inchiostro rispetto a 1. E se codifichi con uno sfondo scuro, sprecano anche più elettricità per essere visualizzati sullo schermo. (Se codifichi con uno sfondo bianco, stai già sprecando elettroni che rendono tutto quel bianco, quindi chiaramente qualsiasi programmatore attento all'ambiente dovrebbe usare uno sfondo nero nel loro editor.) Per essere più eco-compatibili, dovremmo tutti scrivere Spazio bianco ...
Darrel Hoffman,

Risposte:


45

CJam, 33 31

"",AA#b:c~

Ci sono 11300000000950000000034000000011600000001010000000115000000011600000000340000000061000000003300000000420000000058000000010500000000500000000102000000009800000000490000000102000000009800000000490000000098 byte nulli tra le virgolette.

Il codice è equivalente a

11300000000950000000034000000011600000001010000000115000000011600000000340000000061000000003300000000420000000058000000010500000000500000000102000000009800000000490000000102000000009800000000490000000098
AA#b:c~

che può essere testato online .

Come funziona

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

Come funziona

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.

Questo codice sorgente ha un'impronta ecologica di 75.


3
Wow, è intelligente. Immagino che l'avvertimento sia che non potresti mai eseguirlo, dal momento che tutta la memoria del mondo non può contenere l'intero codice.
Reto Koradi,

49
Questo è un piccolo inconveniente. Non puoi dare un prezzo alla natura.
Dennis,

È un bel trucco, ma non è valido se non può essere eseguito
edc65

5
@PyRulez: Non per niente se non sarà costruito da qualcosa di diverso dalla materia e occuperà qualcosa di diverso dallo spazio.
vsz,

5
Perché non usare solo Lenguage?
jimmy23013,

40

Lenguage , 0


L'output è unario , dal momento che Lenguage / Brainfuck non ha alcun modo sano di stampare numeri interi nella base 10.

Il codice sorgente effettivo contiene

22360559967824444567791709913713659826044558304969374451791514225490473373040212332757409553558758107085015797320276213515502796255082717802632399123502087743818475438512153373406931103005017157351410347278489842099128517039634739852783737052963203448945756470632484148121769939122103257063633371522287190530269279693540898545359211009781370158317748609540216376596783541124510013448091325488601732964773653391702083563797082990404753843419895799343996435988722965711513708742853668363743953430527328863418281733901770990932025503662188187254784985474815936854540100376410040743052620419372327997519047616042603909398552951490180076364164838561112002025592431155898041427468731461614504254168899805662501979953318388813759833797929243626668399650485310047043700001093878284174322463350892654886806075148010832042248607926124030339950499631072150856939786062937034833055717723216663269161130154002679878012158315587925933383341827053312086716181702533743607685576475754259877651521989944802973721727159955208722180232955193930065862370838526521351991966172723976565264862909528310162816593997640732796289501819499741414526385058421824690665542546821941125191276568479078107133076037506211133628962099403163812267452274532219562823184225236020523509355625620557197876838014050964240952738109101849512504021041103516630358995290177306585560988278630098667702211916671663291473843258785929522017507744814910480115446168939335008597569919072874897148594826036210511162928991890818427747059833051607455121463371211282760364668765311589329918870071117807132901910082663054895226456039171170783440772764031568108965851688162729239711772886386306884508520204834432674839183166053019421652064937613583258148354531835035461504442885024563141848164279928769795684221364984104923764359842286827870778678989243517189772102669283996930513577004801536579491093711362942690905779844535371088542020595945700544234301668098553671685123172583259206072965508639556627967633275762621813851479909708616154198658896714629908456913467267354690109885368211752176196164620615081464122410029328694509842558492529684841818953632659248840216891072110853731776562597900145806210691868173380612838327841104919352821441230296200143603175486627682007399030356592930049570084097858148122367

byte nulli ed è equivalente al seguente programma Brainfuck:

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

Provalo online su brainfuck.tk .

La lunghezza del codice Brainfuck è altamente subottimale - per cominciare, ho codificato le impronte di tutti i caratteri ASCII - ma il punteggio 0 è il punteggio 0 ...


In nessun modo, Lenguage in realtà supporta byte nulli ?!
Decadimento beta

20
Sento che la risposta in questo modo non mostra rispetto per il pubblico: è barare e giocare al sistema ... Ma dopo tutto questo è il punto centrale di questa sfida. +1
edc65,

1
"L'output è unario, dal momento che Lenguage / Brainfuck non ha alcun modo sano di stampare numeri interi nella base 10." . Pensavo che parte del punto di Lenguage / Brainfuck fosse che non aveva un modo sano di fare nulla :)
Adam,

9
Questo non ha funzionato abbastanza per me quando ho provato a ricreare il tuo programma dalla definizione che hai dato. Potresti per favore pubblicare l'intera fonte di Lenguage in modo che io possa vedere dove il tuo programma differisce dal mio tentativo di ricrearlo? ;-)
Cort Ammon,

1
Ciò che mi stupisce non è che Lenguage supporti i null, ma che tu sia riuscito a realizzare un programma del genere in BF. Haunting ...
Erik the Outgolfer

12

PowerShell, 337 344 304 punti

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

Sto urlando contro di te perché è più economico!

Prende input come $A, quindi esegue il cast come char-array, quindi scorre su un for-loop su ogni carattere, utilizza il ridicolmente verboso [convert]::ToString()per convertire il carattere in quella posizione in binario, sostituisce tutti gli 0 con nulla, quindi conta la lunghezza e aggiunge quello a $B. Alla fine, utilizza un'equivalenza per indicizzare in una matrice dinamica (ovvero, se $Aè test, quindi -CEQè $TRUE, quindi indicizza al secondo elemento 0).

Modifica1 - Caso di prova corretto "TEST"
Modifica2 - Golfato un paio di punti ripetendo i caratteri stessi anziché i loro indici, e ricordando che -replacenon è necessario un secondo parametro se lo si sostituisce con nulla.


La doppia citazione " 00100010è più rispettosa dell'ambiente rispetto alla singola citazione ' 00100111.
Jacob Krall,

Restituisce un valore errato 0 per l'input"TEST"
Jacob Krall,

1
@JacobKrall Buona cattura della doppia citazione ". Anche corretto con -CEQsensibilità al maiuscolo / minuscolo. Ha alzato un po 'i punti, perché stavo erroneamente segnando il ' 'come non l'ho delimitato correttamente nei miei test.
AdmBorkBork,

9

Pyth - 52 49

Tre punti risparmiati grazie a @orlp.

*/.BQ`1nQ"test

Accetta le virgolette per salvare l'impronta.

Test Suite .


Uff, ho quasi ottenuto lo stesso di te, ma la mia risposta è troppo simile e tu l'hai postata per prima. Sostituisci @,0con *per salvare 3 :)
orlp

1
@Maltysen Dici di aver trovato tre punti ma la fonte dice ancora @,0, ti sei appena dimenticato di cambiare?
applaude il

@ConfusedMr_C yep. Ho appena cambiato il permalink e ho dimenticato la risposta effettiva.
Maltysen,

7

Lisp comune, 294 281 235

Per ridurre il punteggio, ho usato @(costo 1) e !(costo 2) come nomi di variabili (modifica: ed è ancora meglio se uso @per la variabile che si verifica maggiormente nella funzione). Sto urlando troppo perché è più economico.

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

Pretty-stampati

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

Bene, il punteggio è più simile a 294;)
Cabbie407,

@ Cabbie407 Ho perso la parte relativa al punteggio, scusa :-)
coredump

1
@ Cabbie407 Ho avuto la strana sensazione di avere un punteggio molto basso per un paio di minuti ...
coredump

1
Volevo solo farti sapere, perché conoscendo il metodo di calcolo del punteggio probabilmente guarderesti il ​​tuo codice da una prospettiva diversa. E vedo che hai già cambiato qualcosa.
Cabbie407,

1
@ Cabbie407 Ho dimenticato di ringraziarti, a proposito. Grazie.
coredump,

6

JavaScript, 279

Modifica correzione bug (non contava il bit 1 di ogni carattere)

Un programma completo, con input e output tramite popup. Testato su Firefox, dovrebbe funzionare su qualsiasi browser moderno.

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

Alcuni strumenti (testato con 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
Questa risposta non è valida - produce 17 per testinvece di 0.
ASCIIThenANSI

@ASCIIThenANSI no, non nel mio browser. Ma vado a controllare di nuovo
edc65,

È divertente ... Provandolo con il tuo contatore, ottengo 279 e testandolo con se stesso ottengo 277. Mi chiedo quale sia corretto; potrebbe avere qualcosa a che fare con le newline?
ETHproductions

@ETHproductions Ho ricontrollato e il conteggio corretto è 279. Ma non funziona con una stringa contenente una nuova riga - è un problema relativo alla promptfunzione. In Firefox, prompttraduce le newline (2 bit) negli spazi (1 bit), quindi otteniamo 277 anziché 279
edc65

@ETHproductions ... in Chrome (su Windows) la nuova riga diventa una coppia CR LF (3 bit + 2 bit) e il conteggio è nuovamente errato
edc65,

6

Julia, 254 246 232

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

La count_onesfunzione conta il numero di quelli nella rappresentazione binaria del suo input.

Ridotta la mia impronta ecologica grazie a FryAmTheEggman!


1
Nessun problema, mi interessa solo l'ambiente;)
FryAmTheEggman,

6

Python 3, 271

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

3
Molti piccoli cambiamenti mi danno 228
FryAmTheEggman

2
Perché non approfittare del fatto che i bool sono ints? z=input();print(sum(bin(ord(i)).count("1")for i in z)*(z!="test")).... @ FryAmTheEggman jinx?
NightShadeQueen

1
@NightShadeQueen Haha, significa che non posso pubblicare post per un giorno? : X Comunque è una bella sorpresa per un nuovo utente di questo sito, bel lavoro! Ad ogni modo, benvenuto in PPCG! :) Inoltre, più in tema, il punto e virgola potrebbe essere rimosso in quanto costa leggermente più di una nuova riga.
FryAmTheEggman,

5

Perl, 136 118 73

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

Sostituisci tutto @con\0

Esempio di utilizzo:

perl -p entry.pl entry.pl

5

MATLAB, 198 194 byte

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

Innanzitutto, la stringa viene letta da STDIN tramite la inputfunzione. Una volta che ciò accade, confrontiamo la stringa di input con la stringa test. Se il risultato non lo è test , convertiamo ogni carattere nel suo codice ASCII e quindi nella sua rappresentazione binaria tramite dec2bin. Una bella conseguenza di questa funzione è che se si invia una stringa, la rappresentazione binaria del suo codice ASCII viene delimitata come un carattere per riga.

Come esempio:

>> dec2bin('ABCD')

ans =

1000001
1000010
1000011
1000100

dec2bingenera un array di caratteri. Una volta che ciò accade, sottrarre per 48, che è il codice ASCII per 0 in modo che la matrice venga convertita in doublecomposta da 0 e 1. Una volta che ciò accade, una chiamata per nnzcontare il numero totale di elementi diversi da zero in questa matrice. Si noti che questo risultato viene moltiplicato per l'opposto della stringa confrontata con test. Se la stringa non dovesse essere test, otteniamo il calcolo dell'impronta. Se è uguale, la moltiplicazione risulta in 0.

Qualche esempio:

>> 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 ti è permesso usare Communications Toolbox, puoi de2biinvece usare ed evitare -48di lanciarlo in un tipo numerico (così come i 2 caratteri extra nel nome della funzione).
becher

5

bash 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

Abbastanza diretto. Fa scorrere i caratteri nell'input convertendoli prima in ascii (con printf %de il primo 'sul numero, poi in binario (con bc), rimuove gli zeri e conta il numero di caratteri.

Non è una grande risposta ma non ho ancora visto un tentativo bash.

Modificato dalla mia prima risposta ha permesso di dare la stringa di input semplicemente sulla riga di comando (cioè è diventata più parametri di input se parole multipe) ma dopo aver letto alcune altre risposte penso di poter supporre che sia quotata, quindi l'intera stringa arriva come $1


1
Benvenuto in Programmazione di puzzle e codice golf! 1. È possibile sostituire docon {e donecon }. 2. Inoltre non hai bisogno degli spazi intorno <<<. 3. È possibile sostituire \ncon un avanzamento di riga letterale.
Dennis,

Grazie @Dennis. Una delle sfide di questo sito è disimparare un sacco di "buone abitudini" :).
Adam,

3
Lo è di sicuro. Se non l'hai già fatto, ti consiglio di dare un'occhiata ai Suggerimenti per giocare a golf a Bash . È una grande risorsa.
Dennis,

3
Questa sfida è strana anche per gli standard del golf! I personaggi extra possono comunque salvare punti. Utilizzo =e ||costi 15, mentre l'utilizzo !=ed &&è solo 13! Un personaggio in più ma risparmia due punti ...
Adam,

5

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

Questo era l'originale, ungolfed:

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

Questo prende l'argomento da un parametro della riga di comando ... process.arguments è una sequenza (possibilmente vuota) di stringhe, quindi prima di usarne una, dobbiamo verificare se esiste realmente. Nell'altro caso viene emesso un messaggio di errore (ciò non è richiesto dalla domanda e verrà eliminato nelle prossime versioni).

La sumfunzione di Ceylon prende una Iterable non vuota di elementi di qualche tipo che deve soddisfare Summable, cioè ha un plusmetodo, come Integer. (Non funziona con sequenze vuote perché ogni tipo di Summable avrà il suo zero e il runtime non ha alcuna possibilità di sapere quale si intende.)

Gli elementi di una stringa o i bit di un intero non sono iterabili non vuoti. Quindi stiamo usando qui la funzione per costruire un iterabile specificando alcuni elementi, quindi una "comprensione" (che verrà valutata a zero o più elementi). Quindi nel caso dei caratteri ne stiamo aggiungendo uno (ma solo quando è impostato il bit corrispondente), nel caso della stringa stiamo aggiungendo il risultato dei caratteri. (La comprensione sarà valutata solo quando la funzione di ricezione effettivamente scorre su di essa, non quando si costruisce l'Iterable.)

Vediamo come possiamo ridurlo. Innanzitutto, ciascuna delle funzioni viene chiamata solo in un punto, quindi possiamo incorporarle. Inoltre, come menzionato sopra, sbarazzarsi del messaggio di errore. (764 punti di impronta.)

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

In realtà non abbiamo bisogno del nidificato interiore sum, possiamo renderlo una grande comprensione. (Questo ci consente di risparmiare 37 punti di impronta per sum({0,}), e alcuni di più per gli spazi bianchi, che verranno comunque eliminati alla fine.) 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 }));
        }
    }
}

Possiamo applicare un principio simile alla speciale "test"stringa racchiusa : poiché in questo caso il risultato è 0 (ovvero non viene fornito alcun contributo alla somma), possiamo semplicemente farlo come parte della somma (ma dobbiamo invertire la condizione) . Questo ci consente principalmente di risparmiare print(0);alcuni parentesi graffe e un mucchio di spazi di rientro, arrivando a un footprint di 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 }));
    }
}

Facciamo lo stesso per il primo if, con l'effetto collaterale che ora non viene fornito alcun argomento 0invece di fare nulla. (Almeno ho pensato che sarebbe successo qui, invece sembra appendere con un ciclo eterno? Strano.)

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

Possiamo effettivamente omettere il ()per la sumfunzione qui, usando una sintassi di chiamata di funzione alternativa , che utilizza {...}invece di ()e riempirà le comprensioni in argomenti iterabili. Questo ha il footprint 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 });
}

Sostituendo il nome della funzione footprint(40) con p(3) si risparmiano altri 37 punti, portandoci a 501. (I nomi delle funzioni di Ceylon devono iniziare con caratteri minuscoli, quindi non possiamo ottenere meno di 3 punti qui.)

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

Anche i nomi delle variabili s(5) e c(4), i(4) non sono ottimali. Sostituiamoli con a(argomento), d(cifra?) E b(bit-index). Footprint 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 });
}

Non vedo alcuna ottimizzazione rimanente per gli spazi non bianchi, quindi rimuoviamo gli spazi bianchi non necessari (1 punto per ogni spazio, due per ciascuna delle due interruzioni di riga):

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

Durante la navigazione dell'API, ho scoperto che Character.hash in realtà restituisce lo stesso valore del suo integerattributo. Ma ha solo 14 punti invece di 30, quindi scendiamo 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"]

modifica - ho dimenticato il caso "test" ... molto costoso.

editit - ha perso un'occasione MAIUSCOLA.

edititedit - ha incorporato i suggerimenti di commento (Grazie TimmyD).

modifica 4 - D è una variante più economica di C (2 vs. 3)

modifica 5 - Ritorno a 295 a causa del controllo della distinzione tra maiuscole e minuscole.

Passa sopra la stringa e conta gli 1 che vengono spostati dal valore ASCII dei caratteri.

Punta di cappello a TimmyD per avermi dato la lungimiranza di usare caratteri maiuscoli E di usare l'indice di array alla fine.


1
Bel approccio! Un paio di campi da golf (rimossa l'inizializzazione $ B, per impostazione predefinita a zero, rimosso un paio di parentesi, rimosso alcuni punti e virgola), lo porta a 293 PARAM($A)[CHAR[]]$A|%{$C=[INT]$_;WHILE($C){$B+=$C-BAND0X1;$C=$C-SHR1}};($B,0)[$A-EQ"TEST"]
AdmBorkBork,

Cosa significa quando leggo "Bel approccio!" e hai sentito la voce di Wii Golf? Grazie per i suggerimenti! L'inizializzazione mi stava facendo scattare durante il test nella console di PowerShell e l'ho lasciato dentro. Buono a sapersi altrimenti.
Quaranta,

Sì - se stai usando la console, è praticamente un ambiente REPL, in quanto le variabili assegnate rimangono da una riga all'altra. Se lo salvi come .ps1, allora $ B (e ogni altra variabile) viene reinizializzato, anche se premi su-freccia-invio dalla stessa shell. Ad esempio,PS C:\scripts> .\ecological-footprint.ps1
AdmBorkBork, il

Restituisce un valore errato 0 per l'input"TEST"
Jacob Krall

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

Newline (non inclusi nel punteggio) aggiunti per chiarezza. Potrebbe essere migliorato a 360 semplicemente cambiando i nomi delle variabili in maiuscolo, ma proverò a pensare a qualcosa di meglio.

L'input avviene tramite riga di comando, il che significa che segfault sull'input assente. Mi aspetto un punteggio peggiore per l'input tramite 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 Impronta ecologica (ancora molto) , 102 91 byte

Sembra che PHP sia rispettoso dell'ambiente solo in modalità test. ;)

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

Viene eseguito dalla riga di comando come:

php footprint.php hello
php footprint.php test

whileè più rispettoso dell'ambiente che foranche se condividono lo stesso numero di personaggi. Anche i nomi delle variabili maiuscole hanno un footprint migliore rispetto alle loro controparti minuscole.

modificare

  • salvato 40 punti usando nomi di funzioni maiuscoli.
  • salvato 38 punti usando decbininvece dibase_convert

1
@Adam Ecco una discussione sugli avvisi e qui sui tag di apertura di PHP . Spero che questo ti sia utile.
insertusernamehere

4

VBA, 475 418

Grazie Jacob per 57 punti

  • Converte stringa in array di byte (128 è la scorciatoia vba per "Converte la stringa da Unicode alla tabella codici predefinita del sistema" Quindi non funzionerà su Mac ....)

  • Effettua il loop della matrice di byte convertendola in binaria e concatenando tutto insieme.

  • controlla per il test
  • Stampa la lunghezza della stringa con tutti gli 0 sostituiti con nulla

VBA perché sei così cattivo nel golf ... :(

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 non fa distinzione tra maiuscole e minuscole, quindi dovresti usare maiuscole ovunque per salvare un punto per carattere minuscolo! (tranne "test"ovviamente)
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)

La doppia citazione " 00100010è più rispettosa dell'ambiente rispetto alla singola citazione ' 00100111.
Jacob Krall,

3

Pyth, 64

?qz"test"0l`sS.Bz

Verifica se l'input è test e, in caso contrario, conta il numero di 1 nella rappresentazione binaria dell'input.


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

Non c'è molto da dire qui: trasforma ogni carattere in valore ASCII ( fromEnum) e calcola la 1s (via a). Somma tutti i risultati.


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)

Questo è il mio primo tentativo di giocare a golf in JavaScript, quindi probabilmente non è molto soddisfatto.


È generalmente concordato che JavaScript golf abbia bisogno di una forma di output diversa da quella implicita. Può essere un avviso, document.write o persino un ritorno di funzione.
Mwr247,

È possibile spostare l'assegnazione rapida nelle prime 's' nell'istruzione if, racchiusa tra parentesi, per salvare un paio di byte. Puoi anche rimuovere lo '0' in charCodeAt. Inoltre, un grande risparmio che puoi fare è usare l'operatore ternario invece delle istruzioni if ​​/ else =)
Mwr247

Molte grazie! Alla fine ho usato una virgola anziché una parentesi per l'assegnazione rapida; salva un altro byte. (: @ Mwr247
Zach Gates,

s.split ('') può invece essere s.split``, risparmiando 2 byte
Dendrobium

1
Il commento di Dendrobium sopra @JacobKrall
Zach Gates,

3

Rubino, 316 313

Molto semplice, alla ricerca di altre possibilità di golf:

b=gets.chomp;b=='test'?0:b.chars.map{|i|i.ord.to_s(2).count('1')}.inject(:+)
  • Usato binvece di xsalvare 3 punti.

È possibile utilizzare $*[0]invece di gets.chomp(accetta input come argomento della riga di comando)
Mhmd

La doppia citazione " 00100010è più rispettosa dell'ambiente rispetto alla singola citazione ' 00100111.
Jacob Krall,

I nomi delle variabili maiuscole sono anche più ecologici rispetto all'equivalente minuscola. Hè meglio che Iper lo stesso motivo.
Jacob Krall,

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

Una porta della mia risposta Pyth, sopra.

L'input viene ricevuto come una stringa (con virgolette):

"ABC"

1
La doppia citazione " 00100010è più rispettosa dell'ambiente rispetto alla singola citazione ' 00100111.
Jacob Krall,

Un paio di modifiche di base portano a questo A=input();print[sum(bin(ord(H)).count("1")for H in A),0][A=="test"]con un punteggio di 243.
Kade,


2

Pyth, 96

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

Una porta della mia risposta CJam, sopra / sotto.


Solo alcune note generali di Pyth: invece di Iprovare a usare il ternario ?, ma in questo caso dato che è un bool puoi semplicemente usare *(dopo essere passato a ninvece di q), kè automaticamente ""e ssu stringhe è la stessa a jk. Spero che ti diverta ad imparare Pyth! :)
FryAmTheEggman il

Questa è stata la mia prima risposta Pyth: P È stato abbastanza difficile farlo, ah ah, divertente. Grazie per i suggerimenti! @FryAmTheEggman
Zach Gates,

2

CJam, 83 81 79 77

Meglio finora dopo aver provato una serie di varianti:

l0$"test"=!\:i2fbe_1b*

Provalo online

Spiegazione:

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

Approccio diretto in sequenza attraverso tutti i byte dell'input e tutti i bit in ciascun byte, sommando alla variabile d.

dviene inizializzato su -2 perché hcontiene l'input newline dall'input (vale 2 bit) e non vogliamo contarlo.

Allo stesso modo hconterrà testuna nuova riga finale, quindi una nuova riga deve essere inclusa nel valore di confronto.

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

Abbastanza autoesplicativo.
test:

> 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 footprint, 98 byte

Un'altra soluzione 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);}

Il modo in cui funziona è che s viene inizializzato su 0 di solito, ma diventa -17 se l'argomento della riga di comando è "test" (strcmp restituisce 0 su stringhe uguali e diverso da zero su stringhe distinte, quindi invertendo restituisce 1 se stringa è "test"). Il numero -17 è stato scelto per compensare l'impronta di 17 che verrà calcolata per il "test". Il calcolo dell'impronta è semplice con gli operatori bit a bit.

Snap! Inizialmente ho perso le "vittorie dell'impronta più corta", quindi miravo al codice più corto ... Vedrò se riesco a ridurre l '"impronta".


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 non è molto verde.

Versione non golfata:

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è dichiarato come un Integermodo per poter accedere Integeral bitCountmetodo statico in modo rispettoso dell'ambiente. Il bitCountmetodo considera la chars come numeri interi e restituisce il numero di bit impostati.


1
Interessante il confronto tra Java e Ceylon ... Java ha un certo sovraccarico a causa del boilerplate e una dichiarazione di stampa più lunga. Il bitCount aiuta, tuttavia, Ceylon non ha questo. Ceylon ha un modo più lungo per accedere ai parametri della riga di comando e deve anche controllare se sono effettivamente dati (dove il tuo programma semplicemente lancerebbe un ArrayIndexOutOfBoundsException). La funzione di somma di Ceylon è sicuramente più breve dell'aggiunta manuale in Ceylon (ma Java non ha alcuna comprensione, quindi aggiungere manualmente è meglio che costruire un Iterable da solo).
Paŭlo Ebermann,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.