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 sum
fonction 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 plus
mé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 0
au 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 sum
fonction 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 integer
attribut. 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});}