Das Ziel dieses Beitrags ist es, alle Golftipps zu sammeln, die einfach <all languages>
und nicht nur für einen bestimmten angewendet werden können .
Schreiben Sie nur Antworten, deren Logik auf die meisten Sprachen angewendet werden kann
Bitte einen Tipp pro Antwort
<all languages>
...Antworten:
Loops zusammenführen
Normalerweise können Sie zwei aufeinanderfolgende Schleifen oder zwei verschachtelte Schleifen zu einer zusammenführen.
Vor:
Nach:
quelle
foo
heißta
Zeiten,bar
heißtb
Zeiten. Dies liegt daran, dass in "after" die Schleifea+b
mal läuft , beim erstena
Aufruffoo
, beim nächsten Aufrufbar
.for(y=0;y<Y;++y)for(x=0;x<X;++x)
oft wirdfor(i=0;i<X*Y;++i)
mitx
Fassungi%X
undy
ersetzt durchi/X
.Nur um das Offensichtliche zu erwähnen:
Stellen Sie Ihre Wahl des Algorithmus in Frage und probieren Sie etwas völlig Neues aus.
Beim Golfen (besonders bei schwereren Problemen, die zu längeren Programmen führen) bleiben Sie möglicherweise allzu oft auf dem Weg, den Sie zuerst gewählt haben, ohne andere grundlegende Optionen auszuprobieren. Natürlich können Sie eine oder mehrere Linien gleichzeitig oder einen Teil der Gesamtidee mikro-golf spielen, aber oftmals versuchen Sie es nicht mit einer völlig anderen Lösung.
Dies machte sich insbesondere in Hitting 495 (Kaprekar) bemerkbar, wo die Abweichung vom tatsächlichen Algorithmus und die Suche nach Mustern, die Sie anwenden können, um zum gleichen Ergebnis zu gelangen, in vielen Sprachen kürzer waren (nur nicht J).
Der Nachteil ist, dass Sie möglicherweise ein halbes Dutzend Mal dasselbe lösen. Aber es funktioniert in wirklich allen Sprachen außer HQ9 + (wo die Suche nach einem anderen Weg zur Ausgabe von Hello World etwas sinnlos wäre).
quelle
Verwenden Sie testgetriebene Entwicklung
Wenn der Code mit verschiedenen Eingaben umgehen muss, schreiben Sie umfassende Tests und machen Sie es einfach, sie alle sehr schnell auszuführen. Auf diese Weise können Sie riskante Transformationen Schritt für Schritt ausprobieren. Golfen wird dann wie ein Refactoring mit perverser Absicht.
quelle
Versuchen Sie, logische Aussagen zu reduzieren
Zum Beispiel, wenn
A
undB
Boolesche Werte sind und Ihre Sprache Boolesche Werte bis zu einem gewissen Grad wie Zahlen behandeltA and (not B)
undA>B
gleichwertig ist. Zum Beispiel in Pythonist das gleiche wie:
quelle
B>A or foo()
wäre ein noch kürzerer Weg, dies auszudrücken, nutzen Sie die verzögerte Auswertung von Booleschen Ausdrücken, um sicherzustellen, dass Dinge nur berechnet werden, wenn es nötig ist.B>A or foo
würde auswerten,foo
obB==A
das nicht das ist, was wir wollen. (Richtig?)Initialisieren Sie Variablen mit Werten, die Sie bereits haben.
x=1
Versuchen Sie stattdessen , nach etwas zu suchen, das bereits 1 entspricht.Beispiel: Der Rückgabewert einer Funktion:
printf("..");x=0;
->x=!printf("..");
. Mit 0 ist es am einfachsten, weil Sie immer negieren können oder wenn Sie nur den richtigen Wahrheitswert benötigen (und es ist egal, ob es 1 oder 19 ist).quelle
Verwenden Sie unary
~
fürx+1
undx-1
Dieser Trick gilt für Sprachen mit einem unären bitweisen Negationsoperator
~
und einem unären regulären Negationsoperator-
.Wenn Ihr Programm zufällig den Ausdruck enthält
-x-1
, können Sie ihn durch ersetzen~x
, um Bytes zu sparen. Dies kommt nicht allzu oft vor, aber sehen Sie, was passiert, wenn wir-
beide Ausdrücke negieren ( ):x+1
gleich-~x
! Ebenso istx-1
gleich~-x
. (Überlegen Sie, in welche Richtung die Tilde zeigt: rechts ist+
, links ist-
.)Dies ist nützlich, da in allen Sprachen, die ich mir vorstellen kann, diese Operatoren eine höhere Priorität haben als die meisten Operatoren. Auf diese Weise können Sie in Klammern speichern. Sehen Sie hier, wie wir vier Bytes sparen:
quelle
Whitespace drücken
Kennen Sie die Regeln für Leerzeichen in Ihrer Sprache. Einige Satzzeichen oder andere Zeichen benötigen möglicherweise kein umgebendes Leerzeichen. Betrachten Sie diese Bourne-Shell- Funktion:
In der Bourne-Shell
();
sind Metazeichen und benötigen keine umgebenden Leerzeichen. Es handelt sich jedoch{}
um Wörter, die Leerzeichen benötigen, sofern sie nicht neben Metazeichen stehen. Wir können 4 Felder daneben weggolfen();
, müssen aber den Abstand zwischen{
und einhaltenecho
.In Common Lisp und PicoLisp ,
()
sind Metazeichen. Betrachten Sie diesen Code, um den Durchschnitt von zwei Zahlen zu ermitteln:Wir können 2 Plätze weg Golf spielen.
Einige Sprachen haben seltsame und subtile Regeln für Leerzeichen. Betrachten Sie dieses Ruby-Programm, das die Summe und das Produkt einer Reihe von ganzen Zahlen ausgibt.
Jeder
&
braucht einen Platz vor sich. In Rubyi=$F.map &:to_i
bedeutet,i=$F.map(&:to_i)
wo&
ein Blockparameter übergeben wird. Aberi=$F.map&:to_i
bedeuteti=$F.map.&(:to_i)
wo&
ist ein binärer Operator.Diese Verrücktheit tritt in Sprachen wie Perl oder Ruby auf, die mehrdeutige Interpunktion verwenden. Verwenden Sie im Zweifelsfall eine REPL oder schreiben Sie kurze Programme, um die Whitespace-Regeln zu testen.
quelle
weisen Sie Funktionen neue Namen zu, wenn Sie diese mehrmals verwenden
quelle
x
.Variablennamen mit einem Buchstaben
Sie haben 52 von ihnen; benutze sie alle! Haben Sie keine Angst, verschiedene Ansätze auszuprobieren und Längen zu vergleichen. Kennen Sie die Sprache und die spezifischen verfügbaren Verknüpfungen / Bibliotheksfunktionen.
quelle
$
und_
kann als Bezeichner verwendet werden.@
ist ein gültiger Variablenname in T-SQL, verwenden Sie ihn anstelle von@a
.Verwenden Sie den bedingten Operator.
Ein bedingter Operator
ist charakterbezogen vorteilhafter als eine IF- Anweisung .
kann geschrieben werden als
quelle
a&&b||c
stattdessen verwendet werden. Etwas länger, aber immer noch kürzer als eineif
.Iff
, obwohl es eine Funktion ist, also eine Bewertung aller Argumente.if(a ? b : c)
a&&b||c
kann,c
wenna
wahr ist, wennb
falsch ist, ein kleinerSchreiben Sie eine Erklärung Ihres Codes
Das Schreiben einer Erklärung zwingt Sie dazu, jeden Teil Ihres Codes noch einmal gründlich zu betrachten und Ihre Gedanken und Entscheidungen beim Schreiben einer bestimmten Passage explizit zu treffen. Dabei stellen Sie möglicherweise fest, dass verschiedene Ansätze möglich sind, mit denen einige Bytes eingespart werden können, oder dass Sie unbewusst Annahmen getroffen haben, die nicht unbedingt zutreffen.
Dieser Tipp ähnelt der Frage nach dem Algorithmus Ihrer Wahl und probieren Sie etwas völlig Neues aus . Ich habe jedoch festgestellt, dass der Schritt des tatsächlichen Aufschreibens, wie jedes Teil funktionieren soll, manchmal entscheidend ist, um Alternativen zu erkennen.
Als Bonus sind Antworten mit einer Erklärung für andere Benutzer interessanter und werden daher eher positiv bewertet.
quelle
Überprüfe die Anzahl deiner Charaktere
Klingt wie ein Kinderspiel, aber wenn Sie vorsichtig sind, können Sie möglicherweise ein paar Zeichen "speichern", indem Sie nichts tun!
Wenn Sie Windows verwenden, geben Sie möglicherweise ein,
\r\n
anstatt nur\r
oder\n
wenn Sie die Eingabetaste drücken, und fügen ein zusätzliches Byte pro Zeile hinzu! Drehen Sie die Steuerzeichen, um zu überprüfen, ob Sie dies nicht tun.In Notepad ++ können Sie alle
\r\n
Zeilenenden in konvertieren ,\r
indem Sie zu gehenEdit > EOL Conversion > UNIX/OSX Format
.Stellen Sie außerdem sicher, dass Sie in Ihrer Zeichenzahl kein abschließendes Leerzeichen einfügen! Der Zeilenvorschub in der untersten Zeile Ihres Codes spielt ebenfalls keine Rolle, sodass er auch nicht gezählt werden muss.
quelle
Lesen Sie die Frage sorgfältig durch
Beim Code-Golfen geht es genauso darum, die Frage zu verstehen (was gefragt wird und was nicht , auch wenn dies in einer anderen Umgebung impliziert wird), wie Code zu produzieren, der (möglicherweise) nur das erfüllt, was gefragt wird.
Andere Eingaben als die explizit angeforderten müssen nicht verarbeitet werden. Wenn es einige Testfälle und keine allgemeinen Anforderungen gibt, funktioniert Ihr Code möglicherweise nur in diesen Fällen. Usw.
quelle
Verwenden Sie bitweise Operationen zum Überprüfen von Zahlen zwischen 0 und 2 n -1
Könnte ein bisschen ein Randfall sein, aber es könnte sich manchmal als nützlich erweisen. Es beruht auf der Tatsache, dass für alle Zahlen, für die m = 2 n –1 gilt, die am weitesten rechts liegenden n Bits auf 1 gesetzt sind.
Also, 7 10 == 00000111 2 , 15 10 == 00001111 2 , 31 10 == 00011111 2 und so weiter.
Der Trick ist
x&~m
. Dies wird true zurück , wennx
ist nicht zwischen 0 undm
(einschließlich), und andernfalls false. Es speichert 6 Bytes vom nächstkürzeren äquivalenten Ausdruckx>=0&&x<=m
:, funktioniert aber offensichtlich nur, wennm
2 n -1 erfüllt sind .quelle
Funktionsparameter anstelle neuer Variablen wiederverwenden
quelle
main(i){...
Sie jetzt eine Variable mit dem Wert 1 haben, ohne dass dies erforderlich ist Aufgaben erledigen. Dort wurden 2 Zeichen gespeichert.Größer / Kleiner als, um eine Ziffer zu speichern:
Denken Sie daran, den Code von
if
auf zu tauschen ,else
und sie werden genau dasselbe tun (oder die Seiten der Ungleichung vertauschen )!Hinweis: Dies kann mit jeder Potenz von 10 und ihren Negativen angewendet werden:
...-100, -10, 10, 100...
(Quelllink)
quelle
if(n>99999)
vsif(n<1e5)
Verwenden Sie> und <anstelle von> = und <=
Verwenden Sie bei der Prüfung auf fest codierte Ganzzahlwerte
>
und<
anstelle von>=
und,<=
wo dies möglich ist. Zum Beispiel mitIst 2 Bytes kürzer als mit
quelle
<1
anstelle der==0
Nullprüfung (oder>0
anstelle!=0
der gespiegelten Prüfung) verwenden.x
dass es sich um eine Ganzzahl handelt?Vermeiden Sie vorzeitige Unterbrechungen der Schleife
Wenn Sie eine Schleife durchlaufen, um nach einer oder mehreren Instanzen einer Booleschen Prüfung zu suchen, kann dies dazu führen, dass ein effizienteres Programm die Schleife beim ersten wahren Wert verlässt. Das Entfernen der Unterbrechung und das Durchlaufen aller Iterationen ermöglichen jedoch kürzeren Code.
quelle
if
Erklärung weg in diesen Fällen:m|=i>=100
. (Und Sie können auch die in diesem Fall zu vereinfacheni>=100
,i>99
aber das ist hier nicht sehr relevant)Verwenden Sie
-
anstelle von!=
für numerische Vergleiche:
Wenn a gleich b ist,
a-b
ergibt sich0
, was falsch ist. Alles andere als0
wahr ist; also,wenn in einem booleschen Kontext verwendet,
a-b
<=>a!=b
Wenn Sie es mit
if/else
oder mit dem ternären Operator verwenden, können Sie auch ein Byte für die Gleichheit sparen:a==b?c:d
<=>a-b?d:c
quelle
Split-Strings für lange Arrays
Die meisten Sprachen haben die Möglichkeit, eine Zeichenfolge in eine Reihe von Zeichenfolgen um ein Token herum aufzuteilen. Dies ist zwangsläufig kürzer als ein Array-Literal, sobald die Länge einen sprachabhängigen Schwellenwert erreicht, da der zusätzliche Overhead pro Zeichenfolge eine Kopie eines Ein-Zeichen-Tokens ist und nicht (mindestens) zwei Zeichenfolgenbegrenzer.
ZB in GolfScript
wird
Bei einigen Sprachen ist der Schwellenwert nur eine Zeichenfolge. ZB in Java,
wird
quelle
%w{Foo Bar Baz Quux}
.qw(Foo Bar Baz Quux)
wird eine Liste von Zeichenfolgen.Verstehe, was andere Leute getan haben
Wenn Sie sich den Code anderer ansehen, können Sie nicht nur Spaß machen, sondern auch einen guten Algorithmus entdecken, über den Sie nicht nachgedacht haben, oder einen Trick (manchmal einen offensichtlichen), den Sie übersehen.
Manchmal gibt es eine Antwort, die Sie in eine andere Sprache übersetzen und von den Vorteilen der anderen Sprache profitieren können.
quelle
Kennen Sie Ihre Operator-Priorität
Wenn Sie mehrere Ausdrücke kombinieren, überprüfen Sie die Operator-Rangfolge-Tabelle für Ihre Sprache, um festzustellen, ob Sie die Reihenfolge ändern können, um Klammern zu speichern.
Beispiele:
(a&b)&&c
benötigen keine Klammern,a&b&&c
genauso wie(a*b)+c
nicht.a+(b<<c)
kann umgeschrieben werden alsa+b*2**c
.Das speichert nichts für dieses Beispiel, aber es wird
c
ein kleines Integer-Literal (<14) sein.a<b&&c<d
mit sparena<b&c<d
(es sei denn, Sie benötigen die Kurzschlussbewertung).quelle
Kürzere for-Schleifen
Wenn Sie
X
Anweisungen{
innerhalb}
Ihrer for-Schleife können Sie bewegenX-1
Aussagen(
innerhalb)
der for-Schleife nach dem zweiten Semikolonfor(blah;blah;HERE)
3 Bytes zu speichern. (trennen Sie die Anweisungen mit einem Komma,
)Anstatt von
Sie können eine der Anweisungen in die
(
geschweiften Klammern der for-Schleife verschieben,)
während Sie die andere weglassenund speichere 3 Bytes (1 weiteres Byte dank @ETHProductions)
Einfach ausgedrückt,
Anstatt von
Verschieben Sie die Anweisungen, damit Sie am Ende damit fertig sind
und sparen Sie 3 Bytes
quelle
for
die letzte Aussage ist,;
wird das optionalVerwenden Sie unary
~
füra-b-1
unda+b+1
Zusätzlich zu @Lynns Vorschlägen zu
x+1
→-~x
; undx-1
→~-x
können Sie auch Golfa-b-1
unda+b+1
.Es mag wie ein Tipp aussehen, den Sie nicht so oft verwenden, ein bisschen wie das Verwenden von
~x
anstelle von-x-1
kommt nur selten vor, aber ich habe ihn oft genug verwendet, um ihn hier als nützlichen Tipp anzusehen. Insbesondere bei der Array-Indizierung können Sie diese oben in einigen Fällen verwenden.quelle
Komprimieren Sie oder / und Streifen
Ein einfacher Trick, den ich mir ausgedacht habe, als ich versucht habe, eine lange Reihe von Zuständen, die durch ands (oder ors) verkettet sind, zu überwinden. In diesem Fall ersetzen Sie einfach 'all' durch 'any'.
Z.B:
Wird
quelle
all(array-of-Booleans)
eingebaute?[a>0,a<10,a+b==4,a+3<1].all?
if 10>a>0 and a+b==4>1>a+3:
Verlassen Sie sich auf den Compiler, um die erforderliche Leistung zu erbringen.
Stellen Sie sicher, dass Sie wissen, welche Optimierungen vom Compiler garantiert werden und auf welchen Optimierungsstufen, und verwenden Sie sie großzügig. Und selbst wenn die Leistung kein
Problem darstellt, können Sie sie mit eingeschalteten Optimierungen testen und dann nur ein Zeichen rabattieren, da Ihr Code noch technisch ist ohne das Compiler-Flag gültig ist.Betrachten Sie die folgende Haskell-Funktion, um 2 ^ n zu berechnen (ignorieren Sie die Tatsache, dass Haskell bereits einen oder drei Exponentiationsoperatoren enthält) (23 Zeichen):
Das Problem ist - es ist schrecklich langsam, es läuft in exponentieller Zeit. Dies kann dazu führen, dass Ihr Code nicht mehr getestet werden kann oder die in der Frage angegebenen Leistungseinschränkungen nicht erfüllt werden. Sie könnten versucht sein, eine temporäre Variable oder ein sofort aufgerufenes Funktionsliteral zu verwenden, um wiederholte Funktionsaufrufe (25 Zeichen) zu vermeiden:
Aber der Compiler kann das schon für Sie tun, Sie müssen nur
-O
ein Compiler-Flag setzen! Anstatt ein paar zusätzliche Zeichen pro Site zu verwenden, um häufig verwendete Unterausdrücke manuell zu entfernen, müssen Sie den Compiler lediglich anweisen, grundlegende Optimierungen für eine Gesamtsumme von ein oder zwei Zeichen im gesamten Programm vorzunehmen.quelle
p(x-1)*2
?Vielleicht etwas offensichtlich, aber ...
Verwenden Sie Operator-Rückgabewerte
Beachten Sie, dass der Zuweisungsoperator einen Wert zurückgibt!
Wenn Sie beispielsweise y zu x hinzufügen und dann prüfen möchten, ob x größer als etwas ist, können Sie dies tun
Anstatt von
Oder Sie möchten die Länge eines Strings nach dem Trimmen ermitteln:
Eher, als
quelle
a = (b=c)+1;
setztb
aufc
und setzt danna
aufb+1
.a=1+b=c
. Und Sie können Ihrer Liste PHP und JavaScript hinzufügen.=
Operator eine höhere Priorität auf der linken Seite als auf der rechten Seite,1+x=2
ist also gültig und wird bis zum3
Verwenden Sie die Sprachversion / den Compiler / die Umgebungsmerkmale / die neuen Funktionen
Dies ist besonders nützlich für Mehrsprachige , kann aber auch auf andere Herausforderungen angewendet werden. Manchmal kann ein Compiler-Fehler ein Byte weiterspielen, ein Implementierungs-Fehler kann es Ihnen ermöglichen, ein paar Zeichen zu sparen, oder eine wirklich brandneue Funktion kann Ihre Punktzahl verbessern.
quelle
Kombinieren Sie mehrere / verschachtelte, wenn möglich, Überprüfungen mit und / oder.
dh:
Anstatt von:
quelle
&
, `|), um weitere Zeichen zu entfernen.&
anstelle des&&
Entfernens von 1 Zeichen in einigen Fällen die Operatorpräzision verschlechtert und Sie Klammern setzen müssen, damit es funktioniert. Verwenden Sie es mit Bedacht.Finden Sie bessere Möglichkeiten, um Ihre Variablen zu initialisieren
Einige andere Antworten haben dies bereits erwähnt, aber in vielen (streng getippten?) Sprachen ist es kürzer,
x
als leere Zeichenfolge zu initialisieren :oder
x
als leere Rune (char) wie:als
und
Die Verwendung bereits vorhandener Werte wird offensichtlich bevorzugt, ist jedoch nicht so einfach.
quelle