Welche allgemeinen Tipps haben Sie zum Golfen in C ++? Ich bin auf der Suche nach Ideen, die sich auf Code-Golf-Probleme im Allgemeinen anwenden lassen, die zumindest etwas spezifisch für C ++ sind (z. B. "Kommentare entfernen" ist keine Antwort). Bitte posten Sie einen Tipp pro Antwort.
48
Antworten:
Der ternäre Bedingungsoperator
?:
kann oft als in für einfachen Stand verwendet werdenif
-else
Aussagen zu erheblichen Einsparungen.Dies ist insofern von besonderem Wert, als damit alternative Werte wie in ausgewählt werden können
quelle
e
undo
. Beachten Sie, dass sich dies von der Funktionsweise dieses Operators in c unterscheidet, in dem dieser Trick nicht funktioniert, da er kein Wert sein kann.std::endl
mit'\n'
dem spart 5 ZeichenManchmal können Sie zwei Zeichen speichern, indem Sie die Tatsache verwenden, dass statische Speicherdauervariablen (die insbesondere alle globalen Bereichsvariablen umfassen) zu Beginn automatisch auf Null gesetzt werden (im Gegensatz zu automatischen Variablen, für die Sie keine solche Garantie haben). Also statt
Du kannst schreiben
quelle
Einige Compiler (zB GCC) unterstützen Konstanten mit mehreren Zeichen . Dies kann einige Zeichen sparen, wenn ein großer ganzzahliger Wert erforderlich ist. Beispiel:
Der Wert ist implementierungsspezifisch. In der Regel der Wert
'ab'
ist256*'a'+'b'
oder'a'+256*'b'
. Sie können bis zu 4 Zeichen in Anführungszeichen setzen.quelle
Eines, das ich als nützlich empfand:
Unter Ausnutzung der Tatsache , dass Nicht-Null - Werte zu bewerten
true
in Booleschen Ausdrücken, und dassx&&y
auswertet , um ,x*y
wenn sie mit booleans Umgangbewertet zu
Sie müssen sich nur der Überläufe bewusst sein, wie unten ausgeführt.
quelle
x!=0 && y!=0
. Bei der Verwendung der Multiplikation müssen Sie jedoch vorsichtig mit Überläufen umgehen. Bei Verwendung von 32-Bit-Ganzzahlen würde x = y = 65536 (und mehrere andere Kombinationen von Zweierpotenzen) ebenfalls x * y = 0 ergeben .&&
ein Kurzschlussverhalten*
fehlt. Zum Beispiel können Sie nicht ersetzeni++!=0&&j++!=0
miti++*j++
.Verwenden Sie die folgenden Typen:
Verwenden Sie für sich wiederholende Wörter / Typen
#defines
:Es lohnt sich nur, wenn Sie
while
viel verwenden, um die zusätzlichen 10 Zeichen auszugleichen. ( Ungefähr 4. )quelle
Wenn Sie bereit sind, C ++ 0x zu verwenden, können Sie neue Funktionen wie Lambdas verwenden .
quelle
Wenn möglich, ändern
&&
und||
zu&
und|
ist.Bei Verwendung von einfachen if-Anweisungen:
kann geändert werden in:
was einen Charakter speichert.
quelle
Anstatt zu benutzen
while(1)
, benutzefor(;;)
, speichere ein Zeichen :)quelle
Die Verwendung des Komma-Operators anstelle von öffnenden und schließenden Klammern kann einige Zeichen sparen, wenn Ihre Klauseln mehr als eine Anweisung enthalten:
gegen
Zwei Zeichen auf einer einfachen IF oder drei insgesamt für eine IF / ELSE gespeichert.
Zur Unterscheidung zwischen C und C ++ kann das Ergebnis eines Kommaausdrucks in C ++ als Ganzes als Wert ... FWIW verwendet werden.
quelle
Da Array-Elemente direkt hintereinander im Speicher abgelegt werden, anstatt wie folgt:
Sie können so etwas tun:
Aus Gründen der Lesbarkeit ist keines der oben genannten Elemente Golf. Die explizite Verwendung von Zeigern kann jedoch viel Platz einsparen.
quelle
for(int* i=array; i<array+25*25; i++)
? Dann müssen Sie nur noch eine Variable im Auge behalten.Es liegt auf der Hand, aber wenn Sie einen Großteil der Standardbibliothek verwenden,
using namespace std;
können einige Zeichen gespeichert werden.quelle
using std::name;
kürzer sein.std::
fünf oder mehr Mal verwenden.Es ist nützlich, sich daran zu erinnern, dass dies
a[i]
dasselbe ist wie*(a+i)
.Ersetzen Sie
a[0]
durch,*a
um zwei Zeichen zu sparen. Aucha[i][0]
ist gleichbedeutend mit*a[i]
unda[0][i]
schrumpft aufi[*a]
. Wenn Sie also einen0
Index in Ihrem Array fest codieren , gibt es wahrscheinlich einen besseren Weg.quelle
Anstatt große Zehnerpotenzen zu schreiben, verwenden Sie die e-Notation . Zum Beispiel
a=1000000000
ist länger alsa=1e9
. Dies kann auf andere Zahlen erweitert werden, wiea=1e9+24
es besser ist alsa=1000000024
.quelle
1e9/x
ist nicht dasselbe wie1000000000/x
oderint(1e9)/x
.Sie können den ternären Operator
?:
ohne Ausdrücke im True-Block verwenden (es wird ein Byte gespeichert).Überprüfen Sie es hier
quelle
Kürzere Kopfzeile
Dies ist GCC-spezifisch und möglicherweise auf andere Compiler erweiterbar.
Vorkompilierter Header.
In G ++
bits/stdc++.h
besteht der vorkompilierte Header aus allen anderen Headern. Wenn Sieimport
zwei verschiedene benötigen, können Sie diese einfach verwenden.Kürzere Kopfzeile.
Dies sind alle unter http://en.cppreference.com/w/cpp/header aufgelisteten Überschriften :
Code-Snippet anzeigen
in aufsteigender Reihenfolge der Länge sortiert.
Einige von ihnen sind bereits länger als
bits/stdc++.h
, und einige von ihnen erfordern C ++ 17-Unterstützung. Einige andere werden von TIO G ++ nicht unterstützt (aus mir unbekannten Gründen). Filtern Sie sie heraus, die wir haben:Code-Snippet anzeigen
Es kann vorkommen, dass einige von ihnen durch kürzere ersetzt werden können. Nur binäre Suche, ob das, was Sie brauchen, ersetzt werden kann. Speziell:
quelle
#import
anstatt#include
dir ein weiteres Byte zu geben.Außerdem muss das Leerzeichen zwischen
#import
und header nicht unbedingt sein:Und wenn Sie etwas aus dem
stdlib
Header benötigen , können Sie jeden Header mit STL-Container (vorzuziehenset
odermap
) anstelle von importierencstdlib
.quelle
Arithmetische Operationen mit Booleschen Werten:
Obwohl
ist besser als
es ist nicht so gut wie
Verwenden Sie #define auch für alles, was häufig verwendet wird. Sie ist oft kürzer als die Verwendung von Funktionen, da Typnamen nicht erforderlich sind.
Kombiniere die Dinge so oft wie möglich:
ist das gleiche wie
quelle
x
lvalue undx++
rvalue verwenden. undefiniertes Verhalten und SequenzpunkteVerwenden Sie generische Lambdas als billige Vorlagen
Bei anderen Typen
int
kann die Verwendung als Funktionsargumente teuer sein. Es wurden jedoch generische Lambdas eingeführt (in C ++ 14?), Die es jedem Lambda erlauben, eine Vorlage zu sein - mitauto
den Argumenttypen können Bytes gespart werden. Vergleichen Sie:Generische Lambdas sind auch sehr praktisch, um Iteratoren zu akzeptieren - wahrscheinlich ist die beste Methode, um Array-Eingaben in C ++ zu akzeptieren
[](auto a, auto z)
, woa
undz
wiebegin()
undend()
vom Array / vector / list / etc übergeben werden.quelle
Bei meinem ersten Versuch, Golf für die Aufgabe "Subtrahiere die nächsten Zahlen" zu codieren, bin ich von der Funktion ausgegangen (58 Bytes)
dann sichere 5 Bytes mit Verschiebung nach Lambda und Verschieben der Initialisierung aus
for
(53)und schließlich nach dem Wechsel von
for
zuwhile
bekam ich 51 Bytes:Der ungolfed Testcode ist so etwas wie:
AKTUALISIEREN:
for
Kann tatsächlich die gleiche Länge erreichen wiewhile
:quelle
Irgendwann zu spät zur Party, denke ich ...
Wenn Sie einen Ausdruck in -1 und 1 anstelle von 0 und 1 umwandeln möchten, gehen Sie stattdessen wie folgt vor:
mach das:
Je nach Verwendung können einige Bytes eingespart werden.
quelle
int x=(a*10>5)*2-1;
Sie das nichtint x=a*10>5?1:-1;
, was 1 Byte kürzer ist?Wenn Sie zwei ganzzahlige Variablen a und b vertauschen möchten,
kann verwendet werden und 5 Zeichen als die Standardmethode speichern
quelle
,t
bei den zuvor erstellten intst=a;a=b;b=t;
wäre das dann schon 3 bytes kürzer gewesen als beima+=b;b=a-b;a-=b;
. Trotzdem ist deinea^=b^=a^=b;
noch kürzer, also +1 von mir. Ich kenne C ++ nicht, aber es funktioniert tatsächlich . Als Java-Code-Golfer bin ich traurig, dass es dort anscheinend nicht funktioniert . :(a^=b;b^=a;a^=b;
es funktioniert gut in Java.a^=b;b^=a;a^=b;
funktioniert zwar, ist aber länger als das,t
+t=a;a=b;b=t;
. Es tut mir leid, Java erwähnt zu haben, da es hier nicht zum Thema gehört. Aber netter Tipp für C ++ Codegolfspieler!Verwenden Sie GCC-Builtins, anstatt sie zu importieren
Wenn Sie einen GCC-Compiler verwenden, ist es manchmal hilfreich, die darin enthaltenen Funktionen wie
__builtin_puts
oder zu verwenden__builtin_clz
. Zum Beispiel,44 Bytes:
50 Bytes:
quelle
Wenn Sie C ++ 11 oder neuer verwenden (was jetzt immer der Fall sein sollte), verwenden Sie
auto
Option nach Möglichkeit für komplexe Typen.Beispiel: 54 Bytes statt 66
Da die Leistung keine Rolle spielt, kann es bei einigen Herausforderungen auch
std::list
sein, dass der Job nur um ein paar Bytes weniger erledigt wird :quelle
Funktionen
<algorithm>
erfordert oft beiläufiga.begin(),a.end()
die wirklich lang ist, stattdessen können Sie mit&a[0],&*end(a)
3 Bytes speichern , wenna
istvector
oderstring
.quelle
Nicht benutzen
string("")
, benutzen""
. Das spart 8 Bytes.quelle
"" + 'a'
istchar* + char
, die Zeiger hinaus ist, währendstd::string("") + 'a'
iststd::string + char
- String - Verkettung.string()
würde funktionieren.