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.
- von Marcog's Idee entlehnt;)
Antworten:
Anstatt die
.ToString()
Verwendung+""
für Zahlen und andere Typen zu verwenden, die sicher in eine Zeichenfolge umgewandelt werden können.quelle
(1+"").DoSomethingWith1String();
String.Concat(object)
mit dem Argument und nicht den virtuellen Aufruf aufruftobject.ToString()
.Concat
Konvertiert explizitnull
in die leere Zeichenfolge ( siehe Referenzquelle ). Es gibt kein 'native Casting', Sie können so etwas konvertieren, es ist nur so, dass das Ergebnis in manchen Fällen nicht sehr nützlich sein kann! (aber das Nullverhalten kann durchaus sein).$"{n}"
Ich habe mein Programm einmal absichtlich eingefügt,
namespace System
um den Zugriff auf eine bestimmte Klasse zu verkürzen. Vergleichen Siezu
quelle
System
Namespace.using System;class P...
.using System;
darum, einen Alias für eine Klasse im selben Namespace zu haben, was kürzer ist, als ich es hier gezeigt habe.using static System.Math;
In C # 6 ist dies sogar noch kürzer (Sie können jede dieser Funktionen so verwenden, als ob sie wirklich global wären - nicht in einer Klasse). Der ursprüngliche Vorschlag ist möglicherweise noch kürzer alsusing static
wenn Sie auf mehrere Klassen zugreifen müssen.static
Schlüsselwort ist oft länger als alle Einsparungen durch WeglassenM.
der Methodenaufrufe, aber ja, es ist eine Option, aber es ist mit hohen Vorabkosten verbunden, für deren Amortisierung viele Anrufe erforderlich sind.Verwenden Sie diese Option
var
zum Deklarieren und Initialisieren von (einzelnen) Variablen, um Zeichen in folgendem Typ zu speichern:wird
Ist
int
natürlich nicht besonders notwendig .quelle
var
es nicht mehrere Deklaratoren geben kann, beispielsweisevar x="x",y="y";
ist dies nicht möglich.Wenn Sie LINQ verwenden, können Sie eine Methode direkt an übergeben,
Select
anstatt ein Lambda zu erstellen.Also statt
Sie können verwenden
direkt.
( Wurde kürzlich entdeckt, als eine der C # -Antworten von Timwi verbessert wurde .)
quelle
Denken Sie daran, dass das kleinste kompilierbare Programm in C # 29 Zeichen umfasst:
Entfernen Sie das also zunächst aus Ihrer Länge und beurteilen Sie Ihre Antwort danach, wie viel es kostet. C # kann nicht mit anderen Sprachen konkurrieren, wenn es um das Drucken oder Lesen von Eingaben geht. Dies ist das Herzstück der meisten
[code-golf]
Probleme. Machen Sie sich also keine Sorgen. Als C # -Golfer treten Sie wirklich gegen die Sprache an.Ein paar andere Dinge zu beachten:
if
nach Möglichkeit alle Schleifen und Anweisungen auf eine einzige Zeile, um die Klammern zu entfernen.quelle
As a C# golfer, you're really competing against the language
Unglaublich verwandtstatic int Main()
28 Zeichen.return
etwas .Anstatt von
machen
Wenn Sie mehrere Variablen benötigen, verwenden Sie diese (vorgeschlagen von @VisualMelon )
quelle
bool a=0<1,b=!a;
Ziehen Sie gegebenenfalls den ternären Operator den
if
..else
-Blöcken vor.Zum Beispiel:
ist effizienter:
quelle
var x = input ?? "";
i < 1
es sich um eine komplexe Aussage handelt oder wenn der Namej
lang ist. IMO, es kann auch nicht sehr gut Nebenwirkungen vermitteln. In dem Fall, in demif (i < 1)
etwas wie "if (SendEmail(recipient))
wahr" / "falsch" zurückgegeben wird, bevorzuge ich die "wenn" / "dann" -Notation.j=i<1?1:0;
ist genug.Effektive Nutzung von
Sie können durch using ersetzen
float
(was ein Alias für istSystem.Single
)z
z=System.Single;
Dann ersetzen Sie
z=System.Single;
mitz=Single;
durch das Programm im Namensraum platzierenSystem
. (Wie bei Joeys Antwort)Dies kann für andere Werttypen (verwenden Sie einen Alias für diese), Strukturen und Klassen angewendet werden
quelle
Wenn Sie
Console.ReadLine()
Ihren Code mehrmals verwenden müssen (mindestens dreimal), können Sie Folgendes tun:und dann einfach benutzen
stattdessen
quelle
()
aus der ersten Zeile entfernen .auto r=Console.ReadLine;
?auto
ist einC++
Verb.var
ist fürC#
. Der Grund, warum dies nicht möglich ist,Console.ReadLine
ist, dass die Funktionssignatur überladen ist und angegeben werden muss, um dem Compiler mitzuteilen, welche Überladung gewünscht wird.Wenn Sie jedes Zeichen eines Befehlszeilenarguments lesen, anstatt eine Schleife bis zur Länge der Zeichenfolge auszuführen:
Sie können ein Zeichen speichern, indem Sie einen try / catch-Block verwenden, um das Ende zu finden:
Dies gilt für jedes Array innerhalb eines Arrays wie:
string[]
int[][]
IList<IList<T>>
quelle
Verwenden Sie Lambdas, um eine Funktion in C # 6 zu definieren
In C # 6 können Sie ein Lambda verwenden, um eine Funktion zu definieren:
Dies ist kürzer als die Definition einer Funktion wie folgt:
quelle
LINQ
Anstelle von:
erhalten eine Enumerable mit dem Ergebnis der Funktion
f
für jedeint
in[0,y]
die Sie verwenden könnenWenn Sie
string
etwas benötigen , dasEnumerable
in Ihrem Programm implementiert ist , können Sie es auch verwendenquelle
Wenn Sie
Dictionary<TKey, TValue>
in Ihrem Code mindestens zwei Mal eine generische Klasse verwenden müssen, können Sie eine Dictionary-Klasse deklarieren, wie im folgenden Beispiel:und dann einfach benutzen
anstatt
Dictionary<int,string>
für jede Instanziierung zu wiederholen .Ich habe diese Technik in dieser Antwort verwendet
quelle
using D = System.Collections.Generic.Dictionary<int,string>;
Sie können
float
unddouble
Literale verwenden, um einige Bytes zu speichern.Wenn Sie eine
int
Arithmetik benötigen , um a zurückzugeben,float
oderdouble
wenn Sie die Konvertierung mithilfe der Literale erzwingen möchten.Wenn Sie jemals in eine Situation geraten, in der Sie eine Umwandlung vornehmen müssen, können Sie einige Bytes sparen, indem Sie stattdessen die Multiplikation verwenden.
quelle
(x-y)*1d/x/y;
Denken Sie daran, wo private oder öffentliche inhärente Elemente vorhanden sind, z.
verglichen mit
quelle
Main
braucht keine Argumente im Gegensatz zu Java zum Beispiel.Bei einzeiligen Lambda-Ausdrücken können Sie die Klammern und das Semikolon überspringen. Bei Ein-Parameter-Ausdrücken können Sie die Klammern überspringen.
Anstatt von
Verwenden
quelle
SomeCall(DoSomething)
ist noch besserLooping:
Variablendeklarationen:
werden:
Und wenn Sie die Variable i nur einmal benötigen oder damit arbeiten müssen, können Sie bei -1 (oder 0, je nach Schleifenumstand) beginnen und inline erhöhen:
zu
Und das reduziert sich um ein Zeichen und verschleiert den Code leicht. Tun Sie das nur mit der ERSTEN
i
Referenz, wie folgt: (Zugegebene Ein-Zeichen-Optimierungen sind nicht viel, aber sie können helfen.)zu
Wenn die Schleife nicht erhöht werden muss
i
(umgekehrte Reihenfolge):quelle
++
in solchen Fällen direkt in den Loop-Header ein: Dasfor(;++i<max;)
ist leichter zu verfolgen und schwerer zu verwechseln.for
Kopfzeile einfügen können, die dann ein Zeichen erneut speichert.for(;i<max;)
zuwhile(i<max)
. Gleiche Anzahl von Bytes, aber für mich sieht es einfach sauberer aus.Unter bestimmten Umständen kann ein Ausgabeparameter Zeichen speichern. Hier ist ein leicht konstruiertes Beispiel, ein 10-Pin-Bowling-Score-Algorithmus.
Mit einer Rückgabeerklärung:
Und mit einem Ausgabeparameter:
Der Ausgabeparameter hier speichert insgesamt 5 Zeichen.
quelle
In C # dürfen wir nicht
if(n%2)
prüfen, obn
es sich um eine gerade Zahl handelt. Wenn wir das tun, bekommen wir einecannot implicity convert int to bool
. Ein naiver Umgang wäre:Ein besserer Weg ist zu verwenden:
Ich habe diese ein Byte zu gewinnen hier .
Beachten Sie, dass dies nur für positive Zahlen funktioniert, da
-1%2==-1
dies auch bei dieser Methode berücksichtigt wird.quelle
String-Interpolation
Eine wirklich einfache platzsparende Verbesserung ist die Interpolation. Anstatt von:
Verwenden Sie einfach,
$
um Ausdrücke einzufügen:Zusammen mit den neuen Ausdruckskörpern in C # 6.0 sollte dies jede einfache Zeichenfolgenberechnung in C # zum Kinderspiel werden lassen.
quelle
i+$" bottles of beer";
kürzer ist als$"{i} bottles of beer"
.$
.{i}
vorne und einen in der Mitte hatte;)Verwenden Sie C # Lambda. Da PPCG Lambda für die Eingabe / Ausgabe zulässt, sollten wir sie verwenden.
Eine klassische C # -Methode sieht folgendermaßen aus:
Als Lambda werden wir schreiben
Anonymes Lambda ist ebenfalls erlaubt:
Entfernen Sie alle Störungen und konzentrieren Sie sich!
Aktualisieren:
Wir können mit einem Schritt weiter verbessern currying als @TheLethalCoder Kommentar:
Beispiel für die Aktualisierung durch @Felix Palmen: Wie wird der WPA-Schlüssel berechnet?
Es ist hilfreich, wenn Sie genau 2 Parameter haben, dann ist eine leere, nicht verwendete Variable
_
besser. Siehe Meta-Post dazu . Ich benutze diesen Trick hier . Sie müssen die Funktion etwas ändern. Beispiel: Online ausprobieren!quelle
s=>c=>...
s=>s.Contains
.(string s,char c)=>s.Contains(c)
Machen Sie Klassennamen nur einen Buchstaben. Verbesserung der Tipps für Code-Golfing in C #, von dem wir ausgehen
zu
was in diesem Fall weitere 6 Zeichen ausschaltet.
quelle
Das
Compute
Instanzmethode vonSystem.Data.DataTable
, kann ein einfacher Zeichenfolgenausdruck ausgewertet werden, z.C # (Visual C # -Compiler) , 166 Byte
Probieren Sie es online!
Per se nicht sehr "golfig", aber manchmal nützlich.
quelle
Zwei Variablen tauschen
Um zwei Variablen auszutauschen, müssen Sie normalerweise eine temporäre Variable deklarieren, um den Wert zu speichern. Es würde ungefähr so aussehen:
Das sind 16 Bytes! Es gibt einige andere Methoden zum Tauschen, die besser sind.
Die letzten drei funktionieren nur für numerische Werte, und wie nur in ASCII angegeben, können die letzten beiden zu einer ArithmeticOverflow-Ausnahme führen. Alle oben genannten Werte sind 12 Byte, was einer Einsparung von 4 Byte gegenüber dem ersten Beispiel entspricht.
quelle
Mit LinqPad haben Sie die Möglichkeit, den gesamten Programmaufwand zu reduzieren, da Sie Anweisungen direkt ausführen können. (Und es sollte in Codegolf völlig legal sein ... Niemand sagt, Sie brauchen eine .exe)
Die Ausgabe erfolgt über die
.Dump()
Erweiterungsmethode.quelle
.Dump()
;)(Ein besonderer Fall , in dem Sie die Priorität Ihres Betreibers kennen !)
Verwenden
%
für eine (etwas) begrenzte Subtraktion bei enger Bindung. Dies erspart Ihnen ein paar Klammern um eine Subtraktion, deren Ergebnis Sie multiplizieren oder durch etwas dividieren möchten. Aber seien Sie vorsichtig, es hat ernsthafte Einschränkungen.Anstatt von
Erwägen
Beispiele:
Ich habe dies gerade erst entdeckt und denke, es wird eine wertvolle Sache sein, sich daran zu erinnern, wann immer wir in Zukunft mit ASCII arbeiten. (Ich spiele gerade irgendwo Golf, wo ich ASCII für kompakte numerische Darstellungen verwende, aber mit einer anderen Bedingung multiplizieren
1
oder-1
darauf aufbauen muss, und diese gestreiften 2 Bytes.)quelle
Wenn Sie mehrere
using
s einschließen müssen, die alle aus derselben Hierarchie stammen, ist es häufig kürzer, die längste als Folgendes zu verwendennamespace
:vs:
quelle
Wird heute Abend "in den Schützengräben" entdeckt, während ein Teil des Golfcodes verbessert wird. Wenn Sie eine Klasse für Ihre Verarbeitung haben, können Sie die Arbeit im Konstruktor erledigen, um die Deklaration einer Methode zu sparen.
Ich entdeckte dies, als ich eine Konsolenanwendung reduzierte - wie es eine gab
static void Main()
, mussten alle Funktionen und Variablen als statisch deklariert werden. Ich habe eine verschachtelte Klasse mit Elementfunktionen und Variablen erstellt, wobei die Hauptarbeit im Konstruktor ausgeführt wurde. Dadurch werden auch Zeichen im aufrufenden Code gespeichert.zB Klasse mit Methode:
Klasse mit Arbeit im Konstruktor:
In diesem Beispiel werden 9 Zeichen gespeichert.
quelle
Verwenden Sie
Action
likeFunc
, um einer Variablen eine Funktion zuzuweisen.Action
Gibt nothing (void
) zurück, daher eignet es sich hervorragend zum Drucken.Zum Beispiel:
Diese Tipps sind inspiriert von @W0lf tollem Anwendungsbeispiel
Func
mitReadLine
.quelle
Deklarieren Sie leere / übereinstimmende Zeichenfolgen zusammen
Wenn Sie mehrere leere / übereinstimmende Zeichenfolgen deklarieren müssen, können Sie einige Bytes wie folgt speichern:
Ist leider
var a="",b=a,c=a;
illegal, wieimplicitly type variable cannot have multiple declarators
quelle
var a=b=c=""
gerne in Javascript?