Empreinte écologique du code source


102

Vous venez d'être embauché par une entreprise de construction automobile allemande. Votre première tâche, en tant qu’ingénieur, est d’écrire un programme qui calcule l’empreinte écologique des chaînes ASCII.

L'empreinte écologique de caractère est calculée comme suit:

Ecrivez le code ASCII du caractère en binaire et comptez le nombre de 1.

Par exemple, Aa une empreinte de 2, mais Oest plus sale avec une empreinte de 5.

L'empreinte globale d'une chaîne est la somme des empreintes de ses caractères. Une chaîne vide a une empreinte de zéro.

Votre programme doit accepter une chaîne ASCII en tant que paramètre (via une ligne de commande ou une entrée), calculer son empreinte écologique et la générer. Le programme lui-même doit être encodé en ASCII.

Il y a un hoquet cependant. Comme votre entreprise souhaite entrer sur un nouveau marché avec des règles environnementales plus strictes, vous devez adapter votre programme de sorte qu'il se comporte différemment en "mode test". Ainsi:

Le programme doit afficher 0 lorsqu'il reçoit la chaîne en testtant que paramètre.

Notation

Le code source ayant la plus petite empreinte écologique gagne (et oui, la réponse testest interdite!)


36
Je suis désolé, je n'ai pas suivi l'actualité, mais je viens de le lire. Pouvons-nous supposer que la société automobile allemande ne s'appelle certainement PAS Volkswagen?
Level River St

7
Pour référence, caractères les plus coûteux aux moins coûteux:\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 C'est une société fictive, mais son nom commence en effet par V et a un W quelque part au milieu. Mais toute similitude avec la réalité n'est que pure coïncidence, à moins que quelqu'un nous poursuive en justice.
Mindwin

1
Fonctions autorisées (au lieu de programmes)?
Luis Mendo

12
Ils vous mentent! Les 1 sont beaucoup plus écologiques que les 0. Vous voulez une preuve? Imprimez votre code source en binaire. Les 0 utilisent presque deux fois plus d'encre que les 1. Et si vous codez avec un arrière-plan sombre, ils gaspillent également plus d'électricité à afficher sur votre écran. (Si vous codez avec un arrière-plan blanc, vous perdez déjà des électrons qui rendent tout ce blanc. Tous les programmeurs soucieux de l'environnement devraient donc utiliser un arrière-plan noir dans leur éditeur.) Pour être plus écologique, nous devrions tous écrire Espace blanc ...
Darrel Hoffman

Réponses:


45

CJam, 33 31

"",AA#b:c~

Il y a 1130000000095000000003400000001160000000100000000115000000011600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 octets null entre les guillemets doubles.

Le code est équivalent à

11300000000950000000034000000011600000001010000000115000000011600000000340000000061000000003300000000420000000058000000010500000000500000000102000000009800000000490000000102000000009800000000490000000098
AA#b:c~

qui peut être testé en ligne .

Comment ça marche

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

Comment ça marche

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.

Ce code source a une empreinte écologique de 75.


3
Wow, c'est intelligent. Je suppose que la mise en garde est que vous ne pourriez jamais l'exécuter, car toute la mémoire du monde ne pouvait contenir le code entier.
Reto Koradi

49
C'est un inconvénient mineur. Vous ne pouvez pas mettre un prix sur la nature.
Dennis

C'est un bon tour, mais il est invalide s'il est impossible de le lancer
edc65

5
@PyRulez: Pas par quoi que ce soit, sauf si elle sera construite avec autre chose que la matière et occupera autre chose que l'espace.
vsz

5
Pourquoi ne pas simplement utiliser Lenguage?
jimmy23013

40

Lenguage , 0


La sortie est unaire , car Lenguage / Brainfuck n’a aucun moyen sensé d’imprimer des nombres entiers en base 10.

Le code source actuel contient

22360559967824444567791709913713659826044558304969374451791514225490473373040212332757409553558758107085015797320276213515502796255082717802632399123502087743818475438512153373406931103005017157351410347278489842099128517039634739852783737052963203448945756470632484148121769939122103257063633371522287190530269279693540898545359211009781370158317748609540216376596783541124510013448091325488601732964773653391702083563797082990404753843419895799343996435988722965711513708742853668363743953430527328863418281733901770990932025503662188187254784985474815936854540100376410040743052620419372327997519047616042603909398552951490180076364164838561112002025592431155898041427468731461614504254168899805662501979953318388813759833797929243626668399650485310047043700001093878284174322463350892654886806075148010832042248607926124030339950499631072150856939786062937034833055717723216663269161130154002679878012158315587925933383341827053312086716181702533743607685576475754259877651521989944802973721727159955208722180232955193930065862370838526521351991966172723976565264862909528310162816593997640732796289501819499741414526385058421824690665542546821941125191276568479078107133076037506211133628962099403163812267452274532219562823184225236020523509355625620557197876838014050964240952738109101849512504021041103516630358995290177306585560988278630098667702211916671663291473843258785929522017507744814910480115446168939335008597569919072874897148594826036210511162928991890818427747059833051607455121463371211282760364668765311589329918870071117807132901910082663054895226456039171170783440772764031568108965851688162729239711772886386306884508520204834432674839183166053019421652064937613583258148354531835035461504442885024563141848164279928769795684221364984104923764359842286827870778678989243517189772102669283996930513577004801536579491093711362942690905779844535371088542020595945700544234301668098553671685123172583259206072965508639556627967633275762621813851479909708616154198658896714629908456913467267354690109885368211752176196164620615081464122410029328694509842558492529684841818953632659248840216891072110853731776562597900145806210691868173380612838327841104919352821441230296200143603175486627682007399030356592930049570084097858148122367

null octets et équivaut au programme Brainfuck suivant:

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

Essayez-le en ligne sur brainfuck.tk .

La longueur du code Brainfuck est extrêmement sous-optimale - pour commencer, j'ai codé en dur les empreintes de tous les caractères ASCII - mais le score 0 correspond au score 0 ...


Pas du tout, Lenguage supporte réellement les octets nuls?!
Beta Decay

20
Je pense que cette réponse comme celle-ci ne montre aucun respect du public: c'est de la triche et du jeu contre le système ... Mais c'est tout l'intérêt de ce défi après tout. +1
edc65

1
"La sortie est unaire, car Lenguage / Brainfuck n’a aucun moyen sensé d’imprimer des entiers en base 10." . Je pensais que Lenguage / Brainfuck était en partie responsable du fait qu’il n’avait aucune façon sensée de faire quoi que ce soit :)
Adam

9
Cela n’a pas fonctionné pour moi lorsque j’ai essayé de recréer votre programme à partir de la définition que vous avez donnée. Pourriez-vous s'il vous plaît poster la source complète de Lenguage afin que je puisse voir en quoi votre programme diffère de ma tentative de le recréer? ;-)
Cort Ammon

1
Ce qui m'étonne, ce n'est pas que Lenguage prenne en charge les valeurs nulles, mais que vous ayez réussi à créer un tel programme en BF. Haunting ...
Erik the Outgolfer

12

PowerShell, 337 344 304 points

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

Je crie chez vous parce que c'est moins cher!

Prend l'entrée comme $A, puis transforme un tableau de caractères, puis itère sur une boucle for sur chaque caractère, utilise le mot ridiculement verbeux [convert]::ToString()pour convertir le caractère à cette position en binaire, remplace tous les 0 par rien, puis compte la longueur, et ajoute cela à $B. À la fin, utilise une équivalence pour indexer dans un tableau dynamique (c'est-à-dire, si $Aest test, alors -CEQest $TRUE, donc il indexe vers le deuxième élément, 0).

Edit1 - Cas de test corrigé "TEST"
Edit2 - Golfé quelques points en effectuant une itération sur les caractères eux-mêmes plutôt que leurs index, et en se rappelant que -replacecela ne nécessite pas un second paramètre si vous ne le remplacez par rien.


Les devis doubles " 00100010sont plus écologiques que les devis simples ' 00100111.
Jacob Krall

Retourne une valeur incorrecte 0 pour l'entrée"TEST"
Jacob Krall

1
@JacobKrall Bonne prise sur la double citation ". Également corrigé avec -CEQpour la sensibilité à la casse. Cela a un peu augmenté le nombre de points, car j’avais mal marqué le score ' 'car je ne l’avais pas délimité correctement lors de mes tests.
AdmBorkBork

9

Pyth - 52 49

Trois points économisés grâce à @orlp.

*/.BQ`1nQ"test

Prend des guillemets pour économiser l’empreinte.

Suite de test .


Ugh, j'ai presque eu la même chose que vous, mais ma réponse est trop similaire et vous avez posté en premier. Remplacer @,0par *pour économiser 3 :)
orlp

1
@Maltysen Vous dites que vous avez trouvé trois points, mais la source dit toujours: @,0avez-vous simplement oublié de changer?
applaudir le

@ConfusedMr_C yep. Je viens de changer le permalien et j'ai oublié la réponse réelle.
Maltysen

7

Common Lisp, 294 281 235

Afin de réduire le score, j'ai utilisé @(coût 1) et !(coût 2) comme noms de variables (edit: et c'est encore mieux si j'utilise @pour la variable se produisant le plus dans la fonction). Je crie trop parce que c'est moins cher.

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

Joli imprimé

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

Le score est plutôt de 294;)
Cabbie407

@ Cabbie407 J'ai raté la partie sur la notation, désolé :-)
coredump

1
@ Cabbie407 J'ai eu l'étrange sensation d'avoir un score très bas pendant quelques minutes ...
coredump

1
Je voulais simplement vous informer, car, en connaissant la méthode de scoring, vous examineriez probablement votre code sous un angle différent. Et je vois que tu as déjà changé quelque chose.
Cabbie407

1
@ Cabbie407 J'ai oublié de vous remercier, d'ailleurs. Merci.
Coredump

6

JavaScript, 279

Modifier le correctif (ne compte pas le bit 1 de chaque caractère)

Un programme complet, avec entrée et sortie via popup. Testé dans Firefox, devrait fonctionner dans n'importe quel navigateur moderne.

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

Quelques outils (testé avec 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
Cette réponse est invalide - la sortie est 17 pour testau lieu de 0.
ASCIIThenANSI

@ASCIIThenANSI pas dans mon navigateur. Mais je vais vérifier à nouveau
edc65

C'est drôle ... Testez avec votre compteur, je reçois 279, et testez avec lui-même, je reçois 277. Je me demande ce qui est correct; pourrait-il avoir quelque chose à voir avec les nouvelles lignes?
ETHproductions

@ETHproductions J'ai vérifié deux fois et le nombre correct est 279. Mais cela ne fonctionne pas avec une chaîne contenant une nouvelle ligne - c'est un problème lié à la promptfonction. Dans Firefox, prompttraduit les nouvelles lignes (2 bits) en espaces (1 bits), nous obtenons donc 277 au lieu de 279
edc65

@ETHproductions ... sous Chrome (sous Windows), la nouvelle ligne devient une paire CR LF (3 bits + 2 bits) et le décompte est de nouveau erroné
edc65

6

Julia, 254 246 232

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

La count_onesfonction compte le nombre de uns dans la représentation binaire de son entrée.

Réduction de mon empreinte écologique grâce à FryAmTheEggman!


1
Pas de problème, je tiens vraiment à l'environnement;)
FryAmTheEggman

6

Python 3, 271

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

3
Beaucoup de petits changements me donne 228
FryAmTheEggman

2
Pourquoi ne pas profiter du fait que les bools sont ints? z=input();print(sum(bin(ord(i)).count("1")for i in z)*(z!="test")).... @ FryAmTheEggman Jinx?
NightShadeQueen

1
@ NightShadeQueen Haha, cela signifie-t-il que je ne peux pas poster pendant une journée? : X Quoi qu'il en soit, c'est une très belle prise pour un nouvel utilisateur sur ce site, bon travail! Quoi qu'il en soit, bienvenue à PPCG! :) De plus, le point-virgule pourrait être supprimé car il coûte un peu plus cher qu'une nouvelle ligne.
FryAmTheEggman

5

Perl, 136 118 73

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

Remplacez tout @par\0

Exemple d'utilisation:

perl -p entry.pl entry.pl

5

MATLAB, 198 194 octets

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

Tout d'abord, la chaîne est lue à partir de STDIN via la inputfonction. Une fois que cela se produit, nous comparons la chaîne d'entrée à la chaîne test. Si le résultat n'est pas test correct, nous convertissons chaque caractère en son code ASCII, puis en sa représentation binaire via dec2bin. Une belle conséquence de cette fonction est que si vous soumettez une chaîne, la représentation binaire de son code ASCII est délimitée comme un caractère par ligne.

Par exemple:

>> dec2bin('ABCD')

ans =

1000001
1000010
1000011
1000100

dec2bingénère un tableau de caractères. Ensuite, soustrayez par 48, qui est le code ASCII pour 0 afin que la matrice soit convertie en double0 et 1. Une fois que cela se produit, un appel à nnzcompter le nombre total d'éléments non nuls dans cette matrice. Notez que ce résultat est multiplié par l'opposé de la chaîne comparée à test. Si la chaîne ne devait pas être test, nous obtenons le calcul de l'empreinte. Si c'est égal, alors la multiplication donne 0.

Quelques exemples:

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

Si vous êtes autorisé à utiliser Communications Toolbox, vous pouvez utiliser à la de2biplace et éviter d' utiliser -48un type numérique (ainsi que les 2 caractères supplémentaires du nom de la fonction).
bécher

5

Frapper 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

Assez simple. Boucle les caractères de l’entrée en convertissant d’abord en ascii (avec printf %det l’entité 'du nombre puis en binaire (avec bc)), supprime les zéros et compte le nombre de caractères.

Pas une bonne réponse mais je n’avais pas encore vu une tentative de bash.

Modifié depuis que ma première réponse permettait à la chaîne d’entrée d’être donnée simplement sur la ligne de commande (c’est-à-dire que cela devenait plusieurs paramètres d’entrée si plusieurs mots étaient utilisés), mais après avoir lu d’autres réponses, je pense pouvoir supposer qu’elle est entre guillemets. $1


1
Bienvenue dans Programming Puzzles & Code Golf! 1. Vous pouvez remplacer doavec {et doneavec }. 2. Vous n'avez également pas besoin d'espaces autour <<<. 3. Vous pouvez remplacer \npar un saut de ligne littéral.
Dennis

Merci à Dennis. L'un des défis de ce site est de désapprendre un tas de "bonnes habitudes" :).
Adam

3
Tout à fait. Si vous ne l'avez pas déjà fait, je vous recommande de consulter Conseils pour jouer au golf à Bash . C'est une excellente ressource.
Dennis

3
Ce défi est bizarre, même au niveau du golf! Les personnages supplémentaires peuvent toujours enregistrer des points. Utiliser =et ||coûte 15 € alors que l’utiliser !=et &&n’est que 13! Un personnage supplémentaire mais enregistre deux points ...
Adam

5

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

C'était l'original, non-golfé:

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

Cela prend l'argument d'un paramètre de ligne de commande ... process.arguments est une séquence de chaînes (éventuellement vide). Par conséquent, avant d'utiliser l'une d'elles, nous devons vérifier si elle existe réellement. Dans l’autre cas, nous émettons un message d’erreur (cela n’est pas requis par la question et nous le jetterons dans les prochaines versions).

La sumfonction de Ceylan prend un Iterable non vide d'éléments de quelque type que ce soit qui doit satisfaire Summable, c'est-à-dire qui a une plusméthode, comme Integer. (Cela ne fonctionne pas avec des séquences vides car chaque type Summable aura son propre zéro et le moteur d'exécution n'a aucune chance de savoir lequel est visé.)

Les éléments d'une chaîne, ou les un bits d'un entier, ne sont pas des objets itératifs non vides. Par conséquent, nous utilisons ici la fonctionnalité pour construire un élément itérable en spécifiant certains éléments, puis une "compréhension" (qui sera évaluée à zéro ou à plusieurs éléments). Ainsi, dans le cas des caractères, nous en ajoutons (mais seulement lorsque le bit correspondant est défini), dans le cas des chaînes, nous ajoutons le résultat des caractères. (La compréhension ne sera évaluée que lorsque la fonction de réception itérera réellement dessus, pas lors de la construction de l'itérable.)

Voyons comment nous pouvons réduire cela. Premièrement, chacune des fonctions n’est appelée qu’à un seul endroit, nous pouvons donc les aligner. En outre, comme mentionné ci-dessus, supprimez le message d'erreur. (764 points d'empreinte.)

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

Nous n'avons pas réellement besoin de l'imbrication interne sum, nous pouvons en faire une grande compréhension. (Cela nous évite 37 points d’empreinte sum({0,}), et quelques-uns d’autres pour les espaces, qui seront éliminés à la fin de toute façon.) Voici 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 }));
        }
    }
}

Nous pouvons appliquer un principe similaire à la "test"chaîne spéciale casée : comme dans ce cas, le résultat est 0 (rien ne contribue à la somme), nous pouvons simplement le faire dans le cadre de la somme (mais nous devons inverser la condition). . Cela nous évite principalement les print(0);, quelques accolades et un tas d'espaces d'indentation, descendant à une empreinte 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 }));
    }
}

Nous faisons la même chose pour le premier if, avec l’effet secondaire qui est de ne pas donner d’argument, mais de produire 0au lieu de ne rien faire. (Au moins, je pensais que cela arriverait ici, au lieu de cela, il semble s'accrocher à une boucle éternelle? Étrange.)

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

Nous pouvons réellement omettre le ()pour la sumfonction ici, en utilisant une syntaxe d'appel de fonction alternative , qui utilise à la {...}place de (), et complétera les compréhensions dans des arguments itérables. Cela a l'empreinte 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 });
}

Remplacer le nom de la fonction footprint(40) par p(3) enregistre 37 points supplémentaires, ce qui nous ramène à 501. (Les noms de fonctions de Ceylan doivent commencer par des lettres minuscules, nous ne pouvons donc pas obtenir moins de 3 points.)

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

Les noms de variables s(5) et c(4), i(4) ne sont pas non plus optimaux. Remplaçons-les par a(argument), d(digit?) Et b(bit-index). Empreinte 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 });
}

Je ne vois aucune optimisation restante, mais supprimons les espaces non nécessaires (1 point pour chaque espace, deux pour chacun des deux sauts de ligne):

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

Lors de la navigation dans l'API, j'ai constaté que Character.hash renvoie la même valeur que son integerattribut. Mais il n’ya que 14 points au lieu de 30, nous sommes donc 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"]

modifier - j'ai oublié le cas "test" ... tellement cher.

edité - manque une opportunité UPPERCASE.

edititedit - a incorporé les suggestions de commentaires (Merci TimmyD).

edit 4 - D est une variable moins chère que C (2 vs. 3)

edit 5 - Retour à 295 en raison de la vérification de la casse.

Boucle sur la chaîne et compte les 1 qui sont décalés de la valeur ASCII des caractères.

Chapeau-pointe à TimmyD pour m'avoir donné la prévoyance d'utiliser des caractères majuscules ET d'utiliser l'index de tableau à la fin.


1
Belle approche! Quelques golfs (suppression de l'initialisation $ B, car cette valeur est PARAM($A)[CHAR[]]$A|%{$C=[INT]$_;WHILE($C){$B+=$C-BAND0X1;$C=$C-SHR1}};($B,0)[$A-EQ"TEST"]
fixée

Qu'est-ce que cela signifie quand je lis "Belle approche!" et entendu la voix de Wii Golf? Merci pour les pointeurs! L'initialisation me faisait trébucher lorsque je l'ai testée dans la console PowerShell et je l'ai laissée. Bon à savoir, sinon.
Quarante3

Oui, si vous utilisez la console, il s’agit plutôt d’un environnement REPL, dans lequel les variables affectées restent d’une ligne à l’autre. Si vous l'enregistrez en tant que .ps1, le $ B (et toutes les autres variables) est réinitialisé, même si vous appuyez sur la touche fléchée vers le haut à partir du même shell. Par exemple,PS C:\scripts> .\ecological-footprint.ps1
AdmBorkBork

Retourne une valeur incorrecte 0 pour l'entrée"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

Les nouvelles lignes (non incluses dans le score) ont été ajoutées pour plus de clarté. Pourrait être amélioré à 360 simplement en changeant les noms de variables en majuscules, mais je vais essayer de penser à quelque chose de mieux.

L'entrée se fait via la ligne de commande, ce qui signifie qu'il segfaults sur une entrée absente. Je m'attends à un pire score pour l'entrée via 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 Empreinte écologique (encore beaucoup) , 102 91 octets

Il semble que PHP respecte l’environnement en mode test uniquement. ;)

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

Fonctionne depuis la ligne de commande comme:

php footprint.php hello
php footprint.php test

whileest plus respectueux de l’environnement que formême s’ils partagent le même nombre de personnages. De plus, les noms de variables en majuscules ont une meilleure empreinte que leurs homologues en minuscules.

Modifier

  • enregistré 40 points en utilisant des noms de fonction en majuscule.
  • enregistré 38 points en utilisant decbinau lieu debase_convert

1
@Adam Voici une discussion sur les avis et ici sur les balises d'ouverture PHP . J'espère que cela vous sera utile.
insertusernamehere

4

VBA, 475 418

Merci Jacob pour 57 points

  • Convertit chaîne en tableau d'octets (128 est un raccourci vba pour "convertit la chaîne d'Unicode en page de code par défaut du système" ne fonctionnera donc pas sur Mac ....)

  • Boucle si tableau d'octets convertir en binaire et concaténer tout ensemble.

  • vérifie pour le test
  • Imprime la longueur de la chaîne avec tous les 0 remplacés par rien

VBA pourquoi es-tu si mauvais au 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 ne fait pas la distinction entre les majuscules et les minuscules; vous devez donc utiliser l’utilisation de majuscules pour sauvegarder un point par minuscule! (sauf "test"bien sûr)
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)

Les devis doubles " 00100010sont plus écologiques que les devis simples ' 00100111.
Jacob Krall

3

Pyth, 64

?qz"test"0l`sS.Bz

Vérifie si l'entrée est test et sinon, compte le nombre de 1 dans la représentation binaire de l'entrée.


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

Rien de plus à dire ici: transformez chaque caractère en valeur ascii ( fromEnum) et calculez le 1s (via a). Résumer tous les résultats.


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)

Il s’agit de ma première tentative de golf JavaScript. C’est donc probablement très peu golfé.


Il est généralement admis que JavaScript golf nécessite une forme de sortie autre qu'implicite. Cela peut être une alerte, document.write ou même un retour de fonction.
Mwr247

Vous pouvez déplacer votre affectation d'invite dans le premier 's' de l'instruction if, entourée de parenthèses, pour enregistrer quelques octets. Vous pouvez également supprimer le "0" dans charCodeAt. En outre, vous pouvez réaliser d'importantes économies en utilisant l'opérateur ternaire au lieu des déclarations if / else =)
Mwr247

Merci beaucoup! J'ai fini par utiliser une virgule au lieu de parenthèse pour l'attribution rapide, cependant; il enregistre un autre octet. (: @ Mwr247
Zach Gates

s.split ('') peut être à la place s.split``, en économisant 2 octets
Dendrobium

1
Commentaire de Per Dendrobium ci-dessus @JacobKrall
Zach Gates

3

Ruby, 316 313

Très simple, à la recherche de plus de possibilités de golf:

b=gets.chomp;b=='test'?0:b.chars.map{|i|i.ord.to_s(2).count('1')}.inject(:+)
  • Utilisé bau lieu de xsauvegarder 3 points.

Vous pouvez utiliser $*[0]au lieu de gets.chomp(prend l’entrée comme argument de ligne de commande)
Mhmd

Les devis doubles " 00100010sont plus écologiques que les devis simples ' 00100111.
Jacob Krall

Les noms de variables en majuscules sont également plus écologiques que les minuscules équivalentes. Hest meilleur que Ipour la même raison.
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

Un portage de ma réponse Pyth, ci-dessus.

L'entrée est reçue sous forme de chaîne (avec guillemets):

"ABC"

1
Les devis doubles " 00100010sont plus écologiques que les devis simples ' 00100111.
Jacob Krall

Quelques modifications de base permettent de réduire le A=input();print[sum(bin(ord(H)).count("1")for H in A),0][A=="test"]score à 243.
Kade


2

Pyth, 96

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

Un port de ma réponse CJam, ci-dessus / ci-dessous.


Juste quelques pyth notes générales: au lieu d' Iessayer d'utiliser le ternaire ?, mais dans ce cas , car il est un bool vous pouvez simplement utiliser *(après le passage à la nplace de q), kest automatiquement ""et ssur les chaînes est le même un jk. J'espère que vous aurez du plaisir à apprendre pyth! :)
FryAmTheEggman

C’était ma première réponse Pyth: P C’était déjà assez difficile d’obtenir ça, haha, c’est amusant. Merci pour les conseils! @FryAmTheEggman
Zach Gates

2

CJam, 83 81 79 77

Mieux vaut jusqu'ici après avoir essayé plusieurs variantes:

l0$"test"=!\:i2fbe_1b*

Essayez-le en ligne

Explication:

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

Approche directe en boucle sur tous les octets de l'entrée et sur tous les bits de chaque octet, en faisant la somme d'une variable d.

dest initialisé à -2 car hcontient la nouvelle ligne de terminaison de l'entrée (d'une valeur de 2 bits) et nous ne voulons pas compter cela.

De même h, contiendra testavec un retour à la ligne de fin, donc un retour à la ligne doit être inclus dans la valeur de comparaison.

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

Assez explicite.
Tests:

> 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, empreinte 378, 98 octets

Une autre solution 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);}

La façon dont cela fonctionne est que s est généralement initialisé à 0, mais devient -17 si l'argument de ligne de commande est "test" (strcmp renvoie 0 pour des chaînes égales et non nul pour des chaînes distinctes. Inverser le résultat donne donc 1 si chaîne est "test"). Le nombre -17 a été choisi pour compenser l'empreinte au sol de 17 qui sera calculée pour "test". Le calcul de l'empreinte est facile avec les opérateurs au niveau des bits.

Claquer des doigts! Au départ, j'avais raté les «gains d'empreinte les plus courts», alors je visais le code le plus court ... Je vais voir si je peux réduire l'empreinte.


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'est pas très vert.

Version non-golfée:

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

Dest déclaré comme un moyen Integerpermettant d Integer' accéder à la bitCountméthode statique de manière respectueuse de l' environnement. La bitCountméthode considère le chars comme un entier et renvoie le nombre de bits définis.


1
Intéressant en comparant Java avec Ceylan ... Java a des frais généraux dus au passe-partout, et une instruction print plus longue. Le bitCount aide, cependant, Ceylan n'a pas ceci. Ceylan a un moyen plus long d’accéder aux paramètres de ligne de commande et doit également vérifier s’ils sont réellement spécifiés (votre programme lirait simplement une exception ArrayIndexOutOfBoundsException). La fonction de somme de Ceylan est certainement plus courte que l'ajout manuel à Ceylan (mais Java n'a aucune compréhension, aussi l'ajout manuel est préférable à la construction d'un Iterable vous-même).
Paŭlo Ebermann le
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.