Golftipps in <allen Sprachen>

81

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

ajax333221
quelle
5
"Mehrheit" nach welcher Metrik?
hörte auf,
2
@ Linksaroundabout durch die Metrik des gleichen Wortes
Ajax333221
8
Das Problem ist, dass viele Sprachen (oft kurzlebige) experimentelle Sprachen mit sehr untypischen Paradigmen sind, für die typische Programmierausdrücke überhaupt keinen Sinn ergeben. Also "Mehrheit aller Sprachen" ist es praktisch unmöglich zu erfüllen. Sie sollten es in irgendeiner Weise einschränken, zB auf "die Mehrheit der Sprachen, die regelmäßig auf codegolf.SE verwendet werden". Gegenwärtig ähneln die Antworten weitgehend "der Mehrheit der von C abgeleiteten Fremdsprachen", aber die, obwohl die überwiegende Mehrheit des gesamten geschriebenen Codes in ihnen geschrieben ist, sind nicht die Mehrheit der Sprachen .
aufgehört, gegen den Uhrzeigersinn am
3
Ich glaube, wir alle wissen, was sie ungefähr bedeuten. Hierbei handelt es sich hauptsächlich um sprachunabhängige Optimierungen, dh solche, die nicht nur in Brainfuck, sondern möglicherweise auch in Python, C, Java und Fortran gleichzeitig nützlich sind. Allgemeine Ideen, die Sie in vielen Sprachen anwenden können, die ähnlich funktionieren. Ich glaube nicht, dass es notwendig ist, Tipps und eine CW-Frage so präzise und spezifisch zu formulieren . Hier geht es darum, anderen beim Golfen zu helfen, und nicht darum, sie wütend zu machen.
Joey
14
Hoffentlich schafft niemand eine Sprache namens <all languages>...
mbomb007

Antworten:

72

Loops zusammenführen

Normalerweise können Sie zwei aufeinanderfolgende Schleifen oder zwei verschachtelte Schleifen zu einer zusammenführen.

Vor:

for (i=0; i<a; i++) foo();
for (i=0; i<b; i++) bar();

Nach:

for (i=0; i<a+b; i++) i<a?foo():bar();
ugoren
quelle
die ugoren schleifen sind immer noch nicht die gleichen. @Gaffi ist richtig.
kaoD
5
@kaoD, in beiden Fällen fooheißt aZeiten, barheißt bZeiten. Dies liegt daran, dass in "after" die Schleife a+bmal läuft , beim ersten aAufruf foo, beim nächsten Aufruf bar.
Ugoren
Ich schaue mir das noch einmal an (viel, viel später) und verstehe meine eigene Frage jetzt nicht. Ich habe die ternäre Operation vielleicht vorher nicht verstanden? So wie ich es jetzt sehe, macht es Sinn.
Gaffi
1
Woops, ich habe das sehr spät in der Nacht gelesen. Du hast recht!
kaoD
3
Sehr ähnlich: for(y=0;y<Y;++y)for(x=0;x<X;++x)oft wird for(i=0;i<X*Y;++i)mit xFassung i%Xund yersetzt durch i/X.
Lynn
62

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

Joey
quelle
12
+1 Dies ist nicht nur gut zum Golfen, sondern auch eine gute Übung für jeden Programmierer in vielen realen Situationen!
Gaffi
52

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.

Adrian McCarthy
quelle
4
Ich benutze ein Spin-off dieser Methode. Da die Probleme selbst normalerweise recht einfach sind, schreibe ich ein Programm, das die Arbeit macht. Normalerweise ist dies "lesbar Golf", so dass es prägnant ist, aber Newlines usw. sind da. Ich kopiere diese Datei an einen neuen Speicherort und spiele Golf. Von Zeit zu Zeit überprüfe ich, ob die Programme für einige ausgewählte Eingaben dieselben Werte zurückgeben. Wenn ich jemals einen Fehler gemacht habe, der mich mit einem kaputten Programm zurücklässt, keine Erinnerung an das, was ich geändert habe und kein Verständnis für mein Golfstück, habe ich etwas von einer "Spezifikation" als Referenzquelle gespeichert.
Shiona
2
Ich liebe diese Methode, was ein Grund dafür ist, dass ich für alle Probleme, die ich schreibe, umfassende Testsuiten einbeziehe.
Joey
@RubberDuck Das Do not repeat yourself Prinzip wird oft strikt befolgt.
Jonathan Frech
48

Versuchen Sie, logische Aussagen zu reduzieren

Zum Beispiel, wenn Aund BBoolesche Werte sind und Ihre Sprache Boolesche Werte bis zu einem gewissen Grad wie Zahlen behandelt A and (not B)und A>Bgleichwertig ist. Zum Beispiel in Python

if A and not B:
    foo()

ist das gleiche wie:

if A>B:
    foo()
Wrzlprmft
quelle
3
Daran hätte ich nie gedacht.
cjfaure
27
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.
Scragar
5
@scragar: Richtig, aber darum geht es in diesem Tipp nicht. (Es ist jedoch ein wertvoller unabhängiger Tipp.)
Wrzlprmft
3
@scragar, B>A or foowürde auswerten, fooob B==Adas nicht das ist, was wir wollen. (Richtig?)
msh210
2
Wenn Sie lange imbrizierte Bedingungen haben (beispielsweise mit 5/6 Parametern), können Sie eine Wahrheitstabelle und eine Karnaugh-Karte verwenden , um den kürzesten booleschen Ausdruck dafür zu finden
Katenkyo,
33

Initialisieren Sie Variablen mit Werten, die Sie bereits haben.

x=1Versuchen 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).

ugoren
quelle
4
in C können Sie argc von Haupt als 1. nachschauen: codegolf.stackexchange.com/questions/1034/reinvent-the-for-loop/...
std''OrgnlDave
1
@ std''OrgnlDave, Stimmt, aber bei dieser Frage geht es um Dinge, die allen Sprachen gemeinsam sind.
Ugoren
33

Verwenden Sie unary ~für x+1undx-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+1gleich -~x! Ebenso ist x-1gleich ~-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:

(x+1)*(y-1)     ==>    -~x*~-y
Lynn
quelle
30

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:

f () { echo a; echo b; }

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 einhalten echo.

f(){ echo a;echo b;}

In Common Lisp und PicoLisp , ()sind Metazeichen. Betrachten Sie diesen Code, um den Durchschnitt von zwei Zahlen zu ermitteln:

(/ (+ a b) 2)

Wir können 2 Plätze weg Golf spielen.

(/(+ a b)2)

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.

#!ruby -an
i=$F.map &:to_i
puts"#{i.reduce &:+} #{i.reduce &:*}"

Jeder &braucht einen Platz vor sich. In Ruby i=$F.map &:to_ibedeutet, i=$F.map(&:to_i)wo &ein Blockparameter übergeben wird. Aber i=$F.map&:to_ibedeutet i=$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.

Kernigh
quelle
1
Warum muss zwischen "{" und "echo" ein Leerzeichen stehen, nicht aber zwischen ";" und "Echo"?
Ryan
3
Ich habe die Begriffe aus dem Handbuch für OpenBSD sh (1) verwendet, die besagen, dass "{" ein reserviertes Wort ist und ";" ist ein Meta-Charakter. Aus diesem Grund ist "{echo" ein Wort, aber "; echo" sind zwei Wörter. Andere Handbücher erklären dies möglicherweise anders. Auch die Z-Shell zsh hat andere Regeln.
Kernigh
28

weisen Sie Funktionen neue Namen zu, wenn Sie diese mehrmals verwenden

x = SomeLongFunctionName
x(somedata)
x(somemoredata)
etc
Blazer
quelle
Nur wenn wir genug telefonieren x.
Elipszilon
28

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.

Ratschenfreak
quelle
8
26 für Sprachen ohne Berücksichtigung der Groß- / Kleinschreibung. :-)
Gaffi
12
Oft $und _kann als Bezeichner verwendet werden.
Griffin
4
@Gaffi: Und mehr als genug für Sprachen, die Unicode-IDs zulassen, es sei denn, die Aufgabe beschränkt Sie auf ASCII oder zählt Bytes anstelle von Zeichen.
Hammar
Wenn Sie Bytes anstelle von Unicode zählen, ist die Verwendung von Extended ASCII möglicherweise eine Möglichkeit, weitere ~ 120 Bezeichner zu verwenden, wenn Sie diese benötigen (nicht, dass Sie für ein
Golfskript
2
@ist ein gültiger Variablenname in T-SQL, verwenden Sie ihn anstelle von @a.
BradC
25

Verwenden Sie den bedingten Operator.

Ein bedingter Operator

bool ? condition_true : condition_false

ist charakterbezogen vorteilhafter als eine IF- Anweisung .

if(a>b){r=a;}else{r=b;}

kann geschrieben werden als

r=a>b?a:b;
MrZander
quelle
25
Sprachen, die kein Ternär haben, können a&&b||cstattdessen verwendet werden. Etwas länger, aber immer noch kürzer als eine if.
Michael Kohl
Andererseits können einige keine der beiden Optionen verwenden (VBA fällt mir ein), aber beide sind immer noch gute Vorschläge. :-)
Gaffi
1
Gaffi: VBA hat Iff, obwohl es eine Funktion ist, also eine Bewertung aller Argumente.
Joey
Die Verwendung von ternary in if-Anweisungen kann ebenfalls sehr hilfreich seinif(a ? b : c)
Jojodmo
4
@ MichaelKohl Hinweis, dass zurückgeben a&&b||ckann, cwenn awahr ist, wenn bfalsch ist, ein kleiner
Randfall
24

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

Laikoni
quelle
23

Ü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\nanstatt nur \roder \nwenn 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\nZeilenenden in konvertieren , \rindem Sie zu gehen Edit > 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.

Sean Latham
quelle
Ich glaube nicht, dass ich jemals einen Fall gesehen habe, in dem dies tatsächlich gezählt hat ...
Jacob
4
Ich habe dieses Problem gerade selbst gehabt (daher füge ich es hinzu).
Sean Latham
21

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.

Tobia
quelle
15
Ich denke, eine bessere Überschrift wäre hier "Behandle keine nicht benötigten Randfälle". Der Satz "Versuchen Sie, Lücken zu finden" erinnert Sie daran, wie Sie vermeiden können, das zu tun, was durch eine kunstvolle Neuinterpretation der Regeln vorgeschrieben ist, während Sie lediglich den guten Rat geben, Ihre Lösung nicht zu überimplementieren.
Jonathan Van Matre
1
Ja, aber eine kunstvolle Neuinterpretation der Regeln gehört auch zum Code-Golf! (0 Zeichen Lösungen usw.)
Tobia
8
Das wäre / sollte aber eine andere Antwort sein. Es gibt einen grundlegenden Unterschied zwischen der Implementierung einer Lösung, die nur für ints funktioniert, weil für OP keine Float-Unterstützung erforderlich ist, und einer Antwort, die den Text "Alle Primzahlen größer als 100" ausgibt, weil "Sie nicht gesagt haben, dass dies erforderlich ist eine tatsächliche Primzahl sein ".
Jonathan Van Matre
Ich denke, dass einige OPs die Meldung "Testfälle können geändert werden; Ihr Code muss nach der Änderung noch funktionieren" enthalten und sie wirklich ändern, wenn sie nur eine Antwort sehen, die die Testfälle fest codiert.
Erik der Outgolfer
20

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 , wenn xist nicht zwischen 0 und m(einschließlich), und andernfalls false. Es speichert 6 Bytes vom nächstkürzeren äquivalenten Ausdruck x>=0&&x<=m:, funktioniert aber offensichtlich nur, wenn m2 n -1 erfüllt sind .

Sean Latham
quelle
18

Funktionsparameter anstelle neuer Variablen wiederverwenden

Greif
quelle
1
Nun, in C wird Ihrer Hauptfunktion immer die Anzahl der Argumente übergeben, die an das Programm übergeben wurden (dh 1 - der Programmname - standardmäßig), sodass main(i){...Sie jetzt eine Variable mit dem Wert 1 haben, ohne dass dies erforderlich ist Aufgaben erledigen. Dort wurden 2 Zeichen gespeichert.
Griffin
6
Ich denke, es ist ziemlich spezifisch für C. Skriptsprachen benötigen keine Deklarationen, und in den meisten kompilierten Sprachen ist das Definieren einer Variablen nicht länger als das Definieren eines Parameters.
Ugoren
Wenn Sie in Java ein Array in einer Funktion benötigen, die denselben Typ wie ein Parameter hat, können Sie einige Bytes einsparen, indem Sie diesen Parameter als letzten setzen und ihn zu einem vararg-Parameter machen. (benutzte das, um einige Bytes einer Funktion zu
entfernen
18

Größer / Kleiner als, um eine Ziffer zu speichern:

//use:
if(n>9){A}else{B}
//instead of:
if(n<10){B}else{A}

Denken Sie daran, den Code von ifauf zu tauschen , elseund 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)

ajax333221
quelle
Ich bin mir nicht sicher, ob ich den Grund dafür verstehe. Wovon reduziert sich das?
Gaffi
@ Gaffi Sie einen Charakter speichern und sie tun genau das gleiche
Ajax333221
Welche Alternative? Entschuldigung, versuche nicht hartnäckig zu sein, ich verstehe es einfach nicht. (newb, hier anscheinend ...)
Gaffi
1
Ah ich sehe. Funktioniert mit jedem Integer-Übergang von 9 auf 10, 99 auf 100 usw. Tut mir leid, dass ich so lange gebraucht habe! (Ich sage nur Ganzzahl, weil ich ein Problem mit n = 9,5 sehen kann ...)
Gaffi
8
Auch in einigen Sprachen (falls unterstützt), wenn Ihre Zahlen groß / klein genug sind, kann die wissenschaftliche Notation Ihnen stattdessen Zeichen ersparen: if(n>99999)vsif(n<1e5)
scragar
16

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 mit

if(x>24&&x<51)

Ist 2 Bytes kürzer als mit

if(x>=25&&x<=50)
Jojodmo
quelle
3
Verwandte Themen: Wenn Sie sicher sind, dass ein Ergebnis nicht negativ sein kann, können Sie es <1anstelle der ==0Nullprüfung (oder >0anstelle !=0der gespiegelten Prüfung) verwenden.
Kevin Cruijssen
1
Sollten Sie keine Notiz hinzufügen, die besagt, xdass es sich um eine Ganzzahl handelt?
Zacharý
15

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.

int main() {
bool m = false;
int n = 1000;
for (int i = 0; i < n; i++) {
if (i >= 100) {
m = true;
break; // remove this line
}
} 
return 0;
}
Gaffi
quelle
5
Sie können auch die Vereinfachung der ifErklärung weg in diesen Fällen: m|=i>=100. (Und Sie können auch die in diesem Fall zu vereinfachen i>=100, i>99aber das ist hier nicht sehr relevant)
Marinus
15

Verwenden Sie -anstelle von!=

für numerische Vergleiche:

Wenn a gleich b ist, a-bergibt sich 0, was falsch ist. Alles andere als 0wahr ist; also,
wenn in einem booleschen Kontext verwendet, a-b<=>a!=b

Wenn Sie es mit if/elseoder 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

Titus
quelle
12

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

["Foo""Bar""Baz""Quux"]  # 23 chars

wird

"Foo
Bar
Baz
Quux"n/  # 20 chars

Bei einigen Sprachen ist der Schwellenwert nur eine Zeichenfolge. ZB in Java,

new String[]{"Foo"}  // 19 chars

wird

"Foo".split("~")  // 16 chars
Peter Taylor
quelle
6
Eine bemerkenswerte Ausnahme ist Rubin, die ein Array-of-strings literal bereitstellt , die auf Plätze auf Kosten von zwei Bytes automatisch Splits: %w{Foo Bar Baz Quux}.
Martin Ender
1
Perl bietet etwas Ähnliches: Es qw(Foo Bar Baz Quux)wird eine Liste von Zeichenfolgen.
BenGoldberg
12

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.

anatolyg
quelle
10

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:

  • In allen mir bekannten Sprachen haben bitweise Operatoren eine höhere Priorität als boolesche Operatoren: Sie (a&b)&&cbenötigen keine Klammern, a&b&&cgenauso wie (a*b)+cnicht.
  • a+(b<<c)kann umgeschrieben werden als a+b*2**c.
    Das speichert nichts für dieses Beispiel, aber es wird cein kleines Integer-Literal (<14) sein.
  • Bitweise Operationen haben eine niedrigere Priorität als die meisten arithmetischen Operationen. Wenn Ihre Sprache also implizit Boolesche Operationen in int umwandelt, können Sie ein Byte a<b&&c<dmit sparen a<b&c<d(es sei denn, Sie benötigen die Kurzschlussbewertung).
Titus
quelle
7

Kürzere for-Schleifen

Wenn Sie XAnweisungen {innerhalb }Ihrer for-Schleife können Sie bewegen X-1Aussagen (innerhalb )der for-Schleife nach dem zweiten Semikolon for(blah;blah;HERE)3 Bytes zu speichern. (trennen Sie die Anweisungen mit einem Komma ,)

Anstatt von

for(int i=0;i<9;){s+=s.length();println(i++);}

Sie können eine der Anweisungen in die (geschweiften Klammern der for-Schleife verschieben, )während Sie die andere weglassen

for(int i=0;i<9;println(i++))s+=s.length();

und speichere 3 Bytes (1 weiteres Byte dank @ETHProductions)


Einfach ausgedrückt,

Anstatt von

for(blah;blah;){blah 1;blah 2;...;blah X}

Verschieben Sie die Anweisungen, damit Sie am Ende damit fertig sind

for(blah;blah;blah 2,...,blah X)blah 1;

und sparen Sie 3 Bytes

Kritixi Lithos
quelle
@ ETHproductions Vielen Dank für einen Tipp zum Golfen :)
Kritixi Lithos
Und wenn das fordie letzte Aussage ist, ;wird das optional
elipszilon
7

Verwenden Sie unary ~für a-b-1unda+b+1

Zusätzlich zu @Lynns Vorschlägen zu x+1-~x; und x-1~-x können Sie auch Golf a-b-1und a+b+1.

a-b-1    // 5 bytes
a+~b     // 4 bytes

a+b+1    // 5 bytes
a-~b     // 4 bytes

Es mag wie ein Tipp aussehen, den Sie nicht so oft verwenden, ein bisschen wie das Verwenden von ~xanstelle von -x-1kommt 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.

Kevin Cruijssen
quelle
6

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:

if a>0 and a<10 and a+b==4 and a+3<1:

Wird

if all([a>0,a<10,a+b==4,a+3<1]):
LemonBoy
quelle
Das ist cool, ich muss es versuchen!
stokastic
4
Welche Sprachen haben eine all(array-of-Booleans)eingebaute?
Peter Taylor
3
Ruby hat es. [a>0,a<10,a+b==4,a+3<1].all?
Kernigh
4
Wäre dies jedoch Python, würden Sie so etwas wieif 10>a>0 and a+b==4>1>a+3:
Sp3000 29.11.14
@PeterTaylor Haskell hat auch
stolzer Haskeller
6

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

p 0=1;p x=p(x-1)+p(x-1)

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:

p 0=1;p x=(\y->y+y)$p$x-1

Aber der Compiler kann das schon für Sie tun, Sie müssen nur -Oein 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.

John Dvorak
quelle
@ETHproductions yep, sorry, ich habe
John Dvorak
Sollte das erste Beispiel nicht einfach so sein p(x-1)*2?
Cyoce
5

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

if(25<x+=y)

Anstatt von

x+=y;if(x>25)

Oder Sie möchten die Länge eines Strings nach dem Trimmen ermitteln:

strlen(s=trim(s))

Eher, als

s=trim(s);strlen(s)
orp
quelle
In welcher Sprache können Sie Aufgaben innerhalb eines Anrufs erledigen ? oder ist das ein schlüsselwort arg?
Katze
2
Ich denke, Zuweisungen sind Ausdrücke (mit dem neuen Wert der zugewiesenen Variablen als Ausdruckswert) in mindestens C, C ++, C # und Java. a = (b=c)+1;setzt bauf cund setzt dann aauf b+1.
Lynn
@Lynn Versuch a=1+b=c. Und Sie können Ihrer Liste PHP und JavaScript hinzufügen.
Titus
2
Ruby macht das am besten. Es gibt dem =Operator eine höhere Priorität auf der linken Seite als auf der rechten Seite, 1+x=2ist also gültig und wird bis zum3
Cyoce
@Cyoce afaik es ist so in allen Sprachen, in denen eine Aufgabe ein Ausdruck ist.
Titus
5

Verwenden Sie die Sprachversion / den Compiler / die Umgebungsmerkmale / die neuen Funktionen

Dies ist besonders nützlich für , 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.

programmer5000
quelle
4

Kombinieren Sie mehrere / verschachtelte, wenn möglich, Überprüfungen mit und / oder.

dh:

if (a && (b || c)) {

}

Anstatt von:

if (a) {
    if (b) {
        //Do Stuff
    } elseif (c) {
        //Do same stuff
    }
}
Gaffi
quelle
5
Verwenden Sie auch kleine Bedingungen ( &, `|), um weitere Zeichen zu entfernen.
FUZxxl
2
Obwohl die Verwendung von bitweise &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.
DollarAkshay
4

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, xals leere Zeichenfolge zu initialisieren :

x:=""

oder xals leere Rune (char) wie:

x:=''

als

var x string

und

var x rune

Die Verwendung bereits vorhandener Werte wird offensichtlich bevorzugt, ist jedoch nicht so einfach.

Katze
quelle