Tipps zum Code-Golfen in C #

62

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

Jcolebrand
quelle
BESTER TIPP => Verwenden Sie etwas anderes als .NET, wenn Sie die längste Antwort für die Herausforderung nicht senden möchten. .NET ist so konzipiert, dass es sehr ausführlich ist und die IDE die Eingabe übernimmt. Was eigentlich nicht so schlimm ist, wie es sich für die allgemeine Programmierung anhört, solange Sie diese IDE-Krücke haben, aber für Code-Golf ist diese Strategie mit Sicherheit ein Fehlschlag.
Krowe
Vergib mir das Bild eines Kalenders, es war alles, was ich kurzfristig finden konnte.
Undergroundmonorail

Antworten:

59

Anstatt die .ToString()Verwendung +""für Zahlen und andere Typen zu verwenden, die sicher in eine Zeichenfolge umgewandelt werden können.

.ToString() <-- 11 chars
+""         <--  3 chars
Jcolebrand
quelle
5
Dies funktioniert auch in JS.
Cyoce
1
Dies sind normalerweise 5 Zeichen, wenn Sie die Zeichenfolge später zum Einschließen der geschweiften Klammern verwenden müssen ...(1+"").DoSomethingWith1String();
TheLethalCoder
1
Wenn Sie die Zeichenfolge benötigen, speichern Sie sie normalerweise. So gut wie jede andere Verwendung kann nativ auf ToString () schließen ...
jcolebrand
1
Beachten Sie, dass dies tatsächlich das statische Element String.Concat(object)mit dem Argument und nicht den virtuellen Aufruf aufruft object.ToString(). ConcatKonvertiert explizit nullin 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).
VisualMelon
1
Alternative - String-Interpolation :$"{n}"
Andriy Tolstoy
41

Ich habe mein Programm einmal absichtlich eingefügt, namespace Systemum den Zugriff auf eine bestimmte Klasse zu verkürzen. Vergleichen Sie

using System;using M=System.Math;

zu

namespace System{using M=Math;
Joey
quelle
9
Denken Sie daran, dass es besser ist, Klassen / Funktionen vollständig zu qualifizieren, wenn eine einmalige Verwendung das Problem löst. Dies ist nur dann sinnvoll, wenn Sie etwas mehrmals aufrufen müssen, und auch dann nur für Elemente im SystemNamespace.
Nick Larsen
Sie können es auch einfach tun using System;class P....
ldam
@Logan: Es ging nicht nur using System;darum, einen Alias ​​für eine Klasse im selben Namespace zu haben, was kürzer ist, als ich es hier gezeigt habe.
Joey,
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 als using staticwenn Sie auf mehrere Klassen zugreifen müssen.
melken
@milk: Das zusätzliche staticSchlüsselwort ist oft länger als alle Einsparungen durch Weglassen M.der Methodenaufrufe, aber ja, es ist eine Option, aber es ist mit hohen Vorabkosten verbunden, für deren Amortisierung viele Anrufe erforderlich sind.
Joey
30

Verwenden Sie diese Option varzum Deklarieren und Initialisieren von (einzelnen) Variablen, um Zeichen in folgendem Typ zu speichern:

string x="abc";

wird

var x="abc";

Ist intnatürlich nicht besonders notwendig .

Joey
quelle
2
Denken Sie daran, dass vares nicht mehrere Deklaratoren geben kann, beispielsweise var x="x",y="y";ist dies nicht möglich.
Ian H.
29

Wenn Sie LINQ verwenden, können Sie eine Methode direkt an übergeben, Selectanstatt ein Lambda zu erstellen.

Also statt

foo.Select(x=>int.Parse(x))

Sie können verwenden

foo.Select(int.Parse)

direkt.

( Wurde kürzlich entdeckt, als eine der C # -Antworten von Timwi verbessert wurde .)

Joey
quelle
2
FWITW dies heißt η-Reduktion
ThreeFx
Es ist auch als "point free" -Stil bekannt
Jonathan Wilson
5
Für die Pragmatiker von uns ist es einfach kürzer : -þ
Joey
23

Denken Sie daran, dass das kleinste kompilierbare Programm in C # 29 Zeichen umfasst:

class P
{
    static void Main()
    {   
    }
}

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:

  • Reduzieren Sie ifnach Möglichkeit alle Schleifen und Anweisungen auf eine einzige Zeile, um die Klammern zu entfernen.
  • Wenn Sie die Option zwischen stdin und Kommandozeile haben, verwenden Sie immer die Kommandozeile!
Nick Larsen
quelle
Dies betrifft normalerweise auch ternär;)
jcolebrand
1
As a C# golfer, you're really competing against the language Unglaublich verwandt
Dorukayhan
1
Eigentlich stimmt das nicht. Es kompiliert auch mit static int Main()28 Zeichen.
Metoniem
1
@Metoniem Das erfordert returnetwas .
User202729
21

Anstatt von

bool a = true;
bool b = false;

machen

var a=0<1;
var b=1<0;

Wenn Sie mehrere Variablen benötigen, verwenden Sie diese (vorgeschlagen von @VisualMelon )

bool a=0<1,b=!a;
Yytsi
quelle
Beachten Sie, dass es normalerweise günstiger ist, den Typ durch ein Komma von den Deklarationen zu trennen, wenn Sie mehrere Variablen desselben Typs benötigenbool a=0<1,b=!a;
VisualMelon,
18

Ziehen Sie gegebenenfalls den ternären Operator den if.. else-Blöcken vor.

Zum Beispiel:

if(i<1)
    j=1;
else
    j=0;

ist effizienter:

j=i<1?1:0;
Nellius
quelle
15
Bin ich der einzige, der der Meinung ist, dass der zweite Fall für solche Dinge von Natur aus besser lesbar ist? Das mache ich routinemäßig. Wenn ich eine var x = input ?? "";
Nullbedingung
Es gibt Zeiten, in denen dies alles andere als die besser lesbare Option ist, insbesondere wenn i < 1es sich um eine komplexe Aussage handelt oder wenn der Name jlang ist. IMO, es kann auch nicht sehr gut Nebenwirkungen vermitteln. In dem Fall, in dem if (i < 1)etwas wie " if (SendEmail(recipient))wahr" / "falsch" zurückgegeben wird, bevorzuge ich die "wenn" / "dann" -Notation.
Nick Larsen
11
Keine Notwendigkeit für Klammern im zweiten Fall - j=i<1?1:0;ist genug.
Danko Durbić
3
Die Frage fragt nach Tipps, die etwas spezifisch für C # sind. Dies ist in den Tipps für alle Sprachen enthalten .
Peter Taylor
4
@PeterTaylor Ich habe diese Frage vor über 3 Jahren beantwortet, lange bevor der von Ihnen verknüpfte Thread erstellt wurde
Nellius
15

Effektive Nutzung von

Sie können durch using ersetzenfloat (was ein Alias ​​für ist System.Single)zz=System.Single;

Dann ersetzen Sie z=System.Single;mit z=Single;durch das Programm im Namensraum platzieren System. (Wie bei Joeys Antwort)

Dies kann für andere Werttypen (verwenden Sie einen Alias ​​für diese), Strukturen und Klassen angewendet werden

Nathan Cooper
quelle
14

Wenn Sie Console.ReadLine()Ihren Code mehrmals verwenden müssen (mindestens dreimal), können Sie Folgendes tun:

Func<string>r=Console.ReadLine;

und dann einfach benutzen

r()

stattdessen

Cristian Lupascu
quelle
Ich denke, Sie müssen ()aus der ersten Zeile entfernen .
Mellamokb
@mellamokb das stimmt, danke! Fest.
Cristian Lupascu
1
Können Sie nicht tun auto r=Console.ReadLine;?
Claudiu
2
@claudiu nein, leider nicht ideone.com/jFsVPX
Cristian Lupascu
@Claudiu, autoist ein C++Verb. varist für C#. Der Grund, warum dies nicht möglich ist, Console.ReadLineist, dass die Funktionssignatur überladen ist und angegeben werden muss, um dem Compiler mitzuteilen, welche Überladung gewünscht wird.
GreatAndPowerfulOz
14

Wenn Sie jedes Zeichen eines Befehlszeilenarguments lesen, anstatt eine Schleife bis zur Länge der Zeichenfolge auszuführen:

static void Main(string[]a){
    for(int i=0;i<a[0].Length;)Console.Write(a[0][i++]);
}

Sie können ein Zeichen speichern, indem Sie einen try / catch-Block verwenden, um das Ende zu finden:

static void Main(string[]a){
    try{for(int i=0;;)Console.Write(a[0][i++]);}catch{}
}

Dies gilt für jedes Array innerhalb eines Arrays wie:

  • string[]
  • int[][]
  • IList<IList<T>>
Hand-E-Food
quelle
7
Das ist wirklich schrecklich ... ich liebe es!
Alex Reinking
Holy Mist, das ist genial. Ich habe gerade einen Charakter gespeichert, als ich ein Array
geloopt habe
Das ist wirklich böse!
GreatAndPowerfulOz
13

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:

int s(int a,int b)=>a+b;

Dies ist kürzer als die Definition einer Funktion wie folgt:

int s(int a,int b){return a+b;}
ProgramFOX
quelle
3
C # 6 bietet eine
völlig
In C # 7 kann dies in einer anderen Funktion durchgeführt werden, um lokale Funktionen zu erstellen. Ich bezweifle, dass dies beim Golfen helfen wird, aber es ist immer noch ein guter Trick zu wissen.
TehPers
1
Das ist formal kein Lambda. Es ist ein ausdrucksstarkes Mitglied .
rekursive
13

LINQ

Anstelle von:

Enumerable.Range(0,y).Select(i=>f(i))

erhalten eine Enumerable mit dem Ergebnis der Funktion ffür jede intin [0,y]die Sie verwenden können

new int[y].Select((_,i)=>f(i))

Wenn Sie stringetwas benötigen , das Enumerablein Ihrem Programm implementiert ist , können Sie es auch verwenden

var s="I need this anyway";
s.Select((_,i)=>f(i))
rauh
quelle
Ich benutze diesen Trick in meiner Antwort für die Shamir's Secret Sharing- Herausforderung.
Aloisdg
Ich glaube nicht, dass der String-Teil ausgeführt wird, wenn Sie das unzählige mit aktivierter Optimierung nicht wiederholen. Ich bin nur gescheitert, bis ich .ToArray () ;. Davon abgesehen ein toller Tipp!
Gaspa79
Ja, Enumerables sind faul, aber das gilt für alle drei Beispiele, nicht nur für das mit der Zeichenfolge.
raggy
11

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:

class D:Dictionary<int,string>{}

und dann einfach benutzen

D d=new D{{1,"something"},{2,"something else"}};

anstatt Dictionary<int,string>für jede Instanziierung zu wiederholen .

Ich habe diese Technik in dieser Antwort verwendet

Cristian Lupascu
quelle
2
Und auch "D d" anstelle von "var d"
Zukki
@ Zukki Offensichtlich! Was habe ich gedacht? :)
Cristian Lupascu
Alternative:using D = System.Collections.Generic.Dictionary<int,string>;
Andriy Tolstoy
10

Sie können floatund doubleLiterale verwenden, um einige Bytes zu speichern.

var x=2.0;
var y=2d;         // saves 1 byte

Wenn Sie eine intArithmetik benötigen , um a zurückzugeben, floatoder doublewenn Sie die Konvertierung mithilfe der Literale erzwingen möchten.

((float)a+b)/2;  // this is no good
(a+b)/2.0;       // better
(a+b)/2f;        // best      

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.

((double)x-y)/(x*y);
(x*1d-y)/(x*y);      // saves 5 bytes
SLuck49
quelle
Noch kürzer:(x-y)*1d/x/y;
rekursiver
9

Denken Sie daran, wo private oder öffentliche inhärente Elemente vorhanden sind, z.

class Default{static void Main()

verglichen mit

public class Default { public static void Main()
Jcolebrand
quelle
5
Und immer nur einen Buchstaben für die Klasse machen :-)
Joey
2
Ach ja, und noch eine nette Sache, die hier impliziert wird: Mainbraucht keine Argumente im Gegensatz zu Java zum Beispiel.
Joey
@ Joey: und es muss auch nicht öffentlich sein.
R. Martinho Fernandes
1
@ Martinho ~ Hast du meine Antwort gelesen? ;) kein öffentliches am main
jcolebrand 31.01.11
@Joey ~ Ich habe versucht, es auf einen pro Post zu beschränken;) ... dachte, jemand anderes würde taht über Haupt- oder Klassen posten, die nur ein Buchstabe sind. Angesichts dessen, wie es sonst niemand hat, werde ich auch diesen hinzufügen.
Jcolebrand
9

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

SomeCall((x)=>{DoSomething();});

Verwenden

SomeCall(x=>DoSomething);
Juliana Peña
quelle
11
Ich schreibe niemals die Klammern für Ein-Parameter-Lambdas, auch nicht für Seriencode.
R. Martinho Fernandes
Ich benutze immer die Klammern, weil ich das Lambda zur besseren Lesbarkeit in mehrere Zeilen aufteilen möchte.
Juliana Peña
2
SomeCall(DoSomething)ist noch besser
GreatAndPowerfulOz
9

Looping:

Variablendeklarationen:

int max;
for(int i=1;i<max;i++){
}

werden:

int max,i=1;
for(;i<max;i++){
}

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:

int max,i=1;
for(;i<max;i++){
  Console.WriteLine(i);
}

zu

int max,i=1;
for(;i<max;){
  Console.WriteLine(++i);
}

Und das reduziert sich um ein Zeichen und verschleiert den Code leicht. Tun Sie das nur mit der ERSTEN iReferenz, wie folgt: (Zugegebene Ein-Zeichen-Optimierungen sind nicht viel, aber sie können helfen.)

int max,i=1;
for(;i<max;i++){
  Console.WriteLine(i + " " + i);
}

zu

int max,i=1;
for(;i<max;){
  Console.WriteLine(++i + " " + i);
}

Wenn die Schleife nicht erhöht werden muss i(umgekehrte Reihenfolge):

for(int i=MAX;--i>0;){
      Console.WriteLine(i);
}
Jcolebrand
quelle
Normalerweise füge ich das ++in solchen Fällen direkt in den Loop-Header ein: Das for(;++i<max;)ist leichter zu verfolgen und schwerer zu verwechseln.
Joey
@ Joey In diesen Fällen tendiere ich dazu, zu while (++ i <max) zu wechseln, das dieselbe Länge hat, aber leichter zu lesen ist.
ICR
ICR: Hängt davon ab, ob Sie eine andere (frühere) Anweisung in die forKopfzeile einfügen können, die dann ein Zeichen erneut speichert.
Joey
Sie können beide Deklarationen zurück in die for-Klausel verschieben, um a1 Byte zu sparen.
rekursive
Ich wechsle gerne for(;i<max;)zu while(i<max). Gleiche Anzahl von Bytes, aber für mich sieht es einfach sauberer aus.
Ayb4btu
8

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:

........10........20........30........40........50........60........70........80........90.......100.......110.......120.......130.......140.......150..
public double c(int[]b){int n,v,i=0,X=10;double t=0;while(i<19){n=b[i]+b[i+1];v=b[i+2];t+=(n<X)?n:X+v;if(b[i]>9)t+=b[i+(i>16|v!=X?3:4)];i+=2;}return t;}

Und mit einem Ausgabeparameter:

........10........20........30........40........50........60........70........80........90.......100.......110.......120.......130.......140.......
public void d(int[]b,out double t){int n,v,i=0,X=10;t=0;while(i<19){n=b[i]+b[i+1];v=b[i+2];t+=(n<X)?n:X+v;if(b[i]>9)t+=b[i+(i>16|v!=X?3:4)];i+=2;}}

Der Ausgabeparameter hier speichert insgesamt 5 Zeichen.

M_J_O_N_E_S
quelle
8

In C # dürfen wir nicht if(n%2)prüfen, ob nes sich um eine gerade Zahl handelt. Wenn wir das tun, bekommen wir eine cannot implicity convert int to bool. Ein naiver Umgang wäre:

if(n%2==0)

Ein besserer Weg ist zu verwenden:

if(n%2<1)

Ich habe diese ein Byte zu gewinnen hier .

Beachten Sie, dass dies nur für positive Zahlen funktioniert, da -1%2==-1dies auch bei dieser Methode berücksichtigt wird.

aloisdg
quelle
6

String-Interpolation

Eine wirklich einfache platzsparende Verbesserung ist die Interpolation. Anstatt von:

string.Format("The value is ({0})", (method >> 4) + 8)

Verwenden Sie einfach, $um Ausdrücke einzufügen:

$"The value is ({(method >> 4) + 8})"

Zusammen mit den neuen Ausdruckskörpern in C # 6.0 sollte dies jede einfache Zeichenfolgenberechnung in C # zum Kinderspiel werden lassen.

mınxomaτ
quelle
3
Beachten Sie auch, dass i+$" bottles of beer";kürzer ist als $"{i} bottles of beer".
Aloisdg
1
@aloisdg In diesem ersten Fall solltest du allerdings weglassen $.
Metoniem
@Metoniem In der Tat! Ich habe es zugelassen, weil ich in meinem ursprünglichen Fall zwei {i}vorne und einen in der Mitte hatte;)
aloisdg
@aloisdg Ahh, ich verstehe. Schade, Kommentare können nicht bearbeitet werden :(
Metoniem
6

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:

bool Has(string s, char c)
{
    return s.Contains(c);
}

Als Lambda werden wir schreiben

Func<string, char, bool> Has = (s, c) => s.Contains(c);

Anonymes Lambda ist ebenfalls erlaubt:

(s, c) => s.Contains(c)

Entfernen Sie alle Störungen und konzentrieren Sie sich!

Aktualisieren:

Wir können mit einem Schritt weiter verbessern currying als @TheLethalCoder Kommentar:

s => c => s.Contains(c);

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!

aloisdg
quelle
1
Ich s=>c=>...
bin
@TheLethalCoder In der Tat können wir! Ich werde die Antwort aktualisieren. Danke!
aloisdg
Können Sie in diesem Fall die eta-Reduktion verwenden? So etwas wie s=>s.Contains.
corvus_192
Beachten Sie, dass C # - und Java-Antworten der Sorte 'untyped lambda' in Ungnade fallen. Nehmen Sie möglicherweise an der Diskussion zu diesem Meta-Beitrag teil . Die vorgeschlagene Alternative ist(string s,char c)=>s.Contains(c)
VisualMelon
Diskussion über unbenannte Funktionen
aloisdg
5

Machen Sie Klassennamen nur einen Buchstaben. Verbesserung der Tipps für Code-Golfing in C #, von dem wir ausgehen

class Default{static void Main()

zu

class D{static void Main()

was in diesem Fall weitere 6 Zeichen ausschaltet.

Jcolebrand
quelle
1
Das gleiche gilt für Variablennamen
Nellius
11
Wie ist das "zumindest etwas spezifisch für C #"?
Peter Taylor
5

Das Compute Instanzmethode von System.Data.DataTable, kann ein einfacher Zeichenfolgenausdruck ausgewertet werden, z.

C # (Visual C # -Compiler) , 166 Byte

namespace System.Data
{
    class P
    {
        static void Main()
        {
            Console.Write(new DataTable().Compute("30*2+50*5/4",""));
        }
    }
}

Probieren Sie es online!

Per se nicht sehr "golfig", aber manchmal nützlich.

digEmAll
quelle
5

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:

var c=a;a=b;b=c;

Das sind 16 Bytes! Es gibt einige andere Methoden zum Tauschen, die besser sind.

//Using tuples
(a,b)=(b,a);
//Bitwise xoring 
a=a^b^(b=a);
//Addition and subtraction
a=a+b-(b=a);
//Multiplication and division
a=a*b/(b=a);

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.

Verkörperung der Ignoranz
quelle
Gilt jedoch nur für Zahlen, und selbst dann läuft alles andere als Tupel und X Gefahr, in ganzzahlige Grenzen zu geraten, wenn Sie dies auf ganze Zahlen anwenden. Gelegentlich stoßen auch andere Zahlentypen an ihre Grenzen
ASCII
4

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.

EvilFonti
quelle
.NetFiddle-Unterstützung .Dump();)
Aloisdg
4

(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

char b='5'; // b is some ASCII input
int a=(b-48)*c; // we want to find the numerical value of b, and multiply it by something ('0'==48)

Erwägen

char b='5'; // b is some ASCII input
int a=b%48*c; // only good for ASCII within 48 of '0' (positive only)!

Beispiele:

'5'%'0'*2 -> 10
'5'%'0'*-1 -> -5
'5'%'0'/2 -> 2

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 1oder -1darauf aufbauen muss, und diese gestreiften 2 Bytes.)

VisualMelon
quelle
4

Wenn Sie mehrere usings einschließen müssen, die alle aus derselben Hierarchie stammen, ist es häufig kürzer, die längste als Folgendes zu verwenden namespace:

using System;
using System.Linq;
//Some code

vs:

namespace System.Linq
{
    //Some code
}
TheLethalCoder
quelle
3

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:

class a
{
    public void b()
    {
        new c().d("input");
    }
}
class c
{
    public void d(string e)
    {
        System.Console.Write(e.Replace("in", "out"));
    }
}

Klasse mit Arbeit im Konstruktor:

class a
{
    public void b()
    {
        new c("input");
    }
}
class c
{
    public c(string e)
    {
        System.Console.Write(e.Replace("in", "out"));
    }
}

In diesem Beispiel werden 9 Zeichen gespeichert.

M_J_O_N_E_S
quelle
3

Verwenden Sie Actionlike Func, um einer Variablen eine Funktion zuzuweisen. ActionGibt nothing ( void) zurück, daher eignet es sich hervorragend zum Drucken.

Zum Beispiel:

Action<string>w=Console.WriteLine;
w("Hello World");

Diese Tipps sind inspiriert von @W0lf tollem Anwendungsbeispiel FuncmitReadLine .

aloisdg
quelle
3

Deklarieren Sie leere / übereinstimmende Zeichenfolgen zusammen

Wenn Sie mehrere leere / übereinstimmende Zeichenfolgen deklarieren müssen, können Sie einige Bytes wie folgt speichern:

string a="";string b="";string c=""; // 36 bytes
var a="";var b="";var c="";          // 27 bytes
string a="",b="",c="";               // 22 bytes
string a="",b=a,c=a;                 // 20 bytes

Ist leider var a="",b=a,c=a;illegal, wieimplicitly type variable cannot have multiple declarators

Erresen
quelle
Kannst du var a=b=c=""gerne in Javascript?
corvus_192
@ corvus_192 nein - leider nicht.
Erresen