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});}
Dies war das Original, 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!");
}
}
Das Argument stammt aus einem Befehlszeilenparameter ... process.arguments ist eine (möglicherweise leere) Folge von Zeichenfolgen. Bevor Sie eine dieser Zeichenfolgen verwenden, müssen Sie überprüfen, ob sie tatsächlich vorhanden sind. Im anderen Fall geben wir eine Fehlermeldung aus (diese wird von der Frage nicht benötigt und wird in den nächsten Versionen weggeworfen).
Ceylons sum
Funktion nimmt eine nicht leere Iterable von Elementen eines Typs an, die erfüllt sein müssen Summable
, dh eine plus
Methode wie Integer haben müssen. (Es funktioniert nicht mit leeren Sequenzen, da jeder Summable-Typ eine eigene Null hat und die Laufzeit keine Chance hat, zu wissen, welche gemeint ist.)
Die Elemente einer Zeichenfolge oder die Bits einer Ganzzahl sind keine nicht leeren iterierbaren Elemente. Aus diesem Grund verwenden wir hier die Funktion, um eine Iteration zu erstellen, indem Sie einige Elemente und dann ein "Verständnis" angeben (das mit null oder mehr Elementen bewertet wird). Im Zeichenfall addieren wir also Einsen (aber nur, wenn das entsprechende Bit gesetzt ist), im Zeichenfall addieren wir das Ergebnis der Zeichen. (Das Verständnis wird nur bewertet, wenn die Empfangsfunktion tatsächlich darüber iteriert, nicht wenn die Iterable erstellt wird.)
Mal sehen, wie wir das reduzieren können. Erstens wird jede der Funktionen nur an einer Stelle aufgerufen, damit wir sie einbinden können. Beseitigen Sie auch, wie oben erwähnt, die Fehlermeldung. (764 Footprint-Punkte.)
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 }) }));
}
}
}
Wir brauchen das Verschachtelte nicht wirklich sum
, wir können dies zu einem großen Verständnis machen. (Dies erspart uns 37 Footprint-Punkte sum({0,})
und noch mehr für Whitespace, was am Ende sowieso beseitigt wird.) Dies ist 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 }));
}
}
}
Wir können ein ähnliches Prinzip auf die Sonderzeichenfolge anwenden "test"
: Da in diesem Fall das Ergebnis 0 ist (dh es wird nichts zur Summe beigetragen), können wir dies nur als Teil der Summierung tun (aber wir müssen die Bedingung invertieren). . Dies erspart uns hauptsächlich die print(0);
, einige Klammern und eine Reihe von Einrückungsräumen, die sich auf eine Stellfläche von 571 reduzieren:
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 }));
}
}
Das Gleiche machen wir zum ersten Mal if
, mit dem Nebeneffekt, dass jetzt kein Argument mehr ausgegeben wird, 0
anstatt nichts zu tun. (Zumindest dachte ich, dass das hier passieren würde, stattdessen scheint es mit einer ewigen Schleife zu hängen? Seltsam.)
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 }));
}
Wir können das ()
für die sum
Funktion hier weglassen , indem wir eine alternative Funktionsaufrufsyntax verwenden , die {...}
anstelle von verwendet wird ()
, und Verständnis in iterierbare Argumente eintragen. Das hat 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 });
}
Das Ersetzen des Funktionsnamens footprint
(40) durch p
(3) spart weitere 37 Punkte und bringt uns auf 501. (Ceylon-Funktionsnamen müssen mit Kleinbuchstaben beginnen, daher können wir hier nicht weniger als 3 Punkte erhalten.)
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 });
}
Die Variablennamen s
(5) und c
(4), i
(4) sind ebenfalls nicht optimal. Ersetzen wir sie durch a
(Argument), d
(Ziffer?) Und b
(Bit-Index). Stellfläche 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 });
}
Ich sehe keine verbleibende Nicht-Leerzeichen-Optimierung. Entfernen wir also das nicht benötigte Leerzeichen (1 Punkt für jedes Leerzeichen, zwei für jeden der beiden Zeilenumbrüche):
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});}
Beim Durchsuchen der API stellte ich fest, dass Character.hash tatsächlich denselben Wert wie sein integer
Attribut zurückgibt . Aber es hat nur 14 statt 30 Punkte, also kommen wir auf 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});}