Wskazówki do gry w golfa w C #

62

Jakie masz ogólne wskazówki na temat gry w golfa w C #? Szukam pomysłów, które można by zastosować do problemów z golfem w kodzie, które są przynajmniej nieco specyficzne dla C # (np. „Usuń komentarze” nie jest odpowiedzią). Proszę zamieścić jedną wskazówkę na odpowiedź.

- zapożyczone z pomysłu marcog;)

jcolebrand
źródło
NAJLEPSZA WSKAZÓWKA => Użyj czegoś obok .NET, jeśli nie chcesz przesyłać najdłuższej odpowiedzi na wyzwanie. .NET został zaprojektowany tak, aby był bardzo szczegółowy i pozwalał IDE na pisanie. Co tak naprawdę nie jest tak złe, jak się wydaje w przypadku ogólnego programowania, o ile masz kulę IDE, ale w przypadku golfa kodowego strategia ta na pewno się nie powiedzie.
krowe
Wybacz mi zdjęcie kalendarza, to było wszystko, co mogłem znaleźć w krótkim czasie.
undergroundmonorail

Odpowiedzi:

59

Zamiast .ToString()używać +""liczb i innych typów, które można bezpiecznie rzutować na łańcuch.

.ToString() <-- 11 chars
+""         <--  3 chars
jcolebrand
źródło
5
Działa to również w JS.
Cyoce
1
Zwykle jest to w rzeczywistości 5 znaków, jeśli trzeba później użyć ciągu do włączenia nawiasów klamrowych ...(1+"").DoSomethingWith1String();
TheLethalCoder
1
Jeśli potrzebujesz sznurka, zwykle go przechowujesz. Prawie każde inne użycie może natywnie wywnioskować ToString () ...
jcolebrand
1
Zauważ, że tak naprawdę wywołuje to String.Concat(object)argument statyczny , a nie wirtualne object.ToString(). Concatjawnie konwertuje nullna pusty ciąg ( patrz źródło odwołania ). Nie ma „rodzimego castingu”, możesz przekonwertować coś takiego, po prostu wynik może być w niektórych przypadkach niezbyt użyteczny! (ale zachowanie zerowe może równie dobrze być).
VisualMelon,
1
Alternatywa - interpolacja ciągów :$"{n}"
Andrij Tołstoj
41

Kiedyś celowo umieściłem swój program, namespace Systemaby móc skrócić dostęp do określonej klasy. Porównać

using System;using M=System.Math;

do

namespace System{using M=Math;
Joey
źródło
9
Pamiętaj tylko, że lepiej jest w pełni zakwalifikować klasy / funkcje, gdy jednorazowe użycie rozwiąże problem. Jest to przydatne tylko wtedy, gdy musisz zadzwonić do czegoś więcej niż raz, a nawet wtedy tylko dla elementów w Systemprzestrzeni nazw.
Nick Larsen
Możesz też po prostu zrobić using System;class P....
ldam
@Logan: Nie chodziło tylko using System;o alias klasy w tej samej przestrzeni nazw, co jest krótsze niż pokazałem tutaj.
Joey,
Jest jeszcze krótszy using static System.Math;w C # 6 (dodaj, że możesz użyć dowolnej z tych funkcji tak, jakby były naprawdę globalne - nie w klasie). Oryginalna sugestia może być jeszcze krótsza niż w using staticprzypadku konieczności uzyskania dostępu do wielu klas.
mleko
@ mleko: dodatkowe staticsłowo kluczowe często jest dłuższe niż jakiekolwiek oszczędności wynikające z pominięcia M.wywołań metod, ale tak, jest to opcja, ale wiąże się z wysokimi kosztami początkowymi, które wymagają dużej liczby połączeń w celu amortyzacji.
Joey,
30

Służy vardo deklarowania i inicjowania (pojedynczych) zmiennych w celu zapisywania znaków na typie:

string x="abc";

staje się

var x="abc";

intOczywiście nie jest to szczególnie konieczne .

Joey
źródło
2
Pamiętaj, że varnie może mieć wielu deklaratorów, na przykład var x="x",y="y";nie jest możliwe.
Ian H.
29

Jeśli używasz LINQ, możesz przekazać metodę bezpośrednio do Selectzamiast tworzenia lambda.

Więc zamiast

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

możesz użyć

foo.Select(int.Parse)

bezpośrednio.

(Odkryto niedawno podczas ulepszania jednej z odpowiedzi C # Timwi .)

Joey
źródło
2
FWITW nazywa się to redukcją η
ThreeFx
Jest również znany jako styl „bez punktów”
Jonathan Wilson
5
Dla bardziej pragmatycznych z nas jest to po prostu krótsze : -þ
Joey
23

Pamiętaj, że najmniejszy program do kompilacji w C # ma 29 znaków:

class P
{
    static void Main()
    {   
    }
}

Zacznij więc od usunięcia tego z długości i oceń swoją odpowiedź na temat tego, ile to zajmie. C # nie może konkurować z innymi językami, jeśli chodzi o drukowanie lub czytanie, co jest sercem większości [code-golf]problemów, więc nie martw się o to. Jako golfista C # naprawdę konkurujesz z językiem.

Kilka innych rzeczy, o których należy pamiętać:

  • ifJeśli to możliwe, zmniejsz wszystkie pętle i instrukcje do jednej linii, aby usunąć nawiasy.
  • Jeśli podano opcję pomiędzy stdin a wierszem poleceń, zawsze używaj wiersza poleceń!
Nick Larsen
źródło
Zwykle dotyczy to również
trójki
1
As a C# golfer, you're really competing against the language Niewiarygodnie powiązane
dorukayhan,
1
W rzeczywistości to nie jest prawda. Kompiluje również przy użyciu static int Main(), który miałby 28 znaków.
Metoniem
1
@Metoniem To wymaga returnczegoś .
user202729
21

Zamiast

bool a = true;
bool b = false;

zrobić

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

Jeśli potrzebujesz wielu zmiennych, użyj tego (sugerowane przez @VisualMelon )

bool a=0<1,b=!a;
Yytsi
źródło
Zauważ, że jeśli potrzebujesz wielu zmiennych tego samego typu, zwykle taniej jest zadeklarować typ przecinka oddzielając deklaracjebool a=0<1,b=!a;
VisualMelon 13.01.17
18

Preferuj operatora trójskładnikowego nad if... elseblokami, gdzie to stosowne.

Na przykład:

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

jest bardziej wydajnie:

j=i<1?1:0;
Nellius
źródło
15
Czy jestem jedynym, który uważa, że ​​drugi przypadek jest z natury bardziej czytelny dla takich rzeczy w ogóle? Robię to rutynowo. Ponadto, jeśli chcę uniknąć warunku zerowego (jak na sznurku), robię coś takiego var x = input ?? "";(uwielbiam moje koalescencje)
jcolebrand 31.01.11
Są chwile, kiedy dalekie jest od bycia bardziej czytelną opcją, szczególnie gdy i < 1jest to złożone zdanie lub gdy nazwa jjest długa. IMO również nie przenosi bardzo dobrze skutków ubocznych. W przypadku, gdy if (i < 1)coś takiego if (SendEmail(recipient))zwraca true / false w zależności od powodzenia efektów ubocznych, wolę notację if / then.
Nick Larsen
11
W drugim przypadku nie potrzeba nawiasów - j=i<1?1:0;wystarczy.
Danko Durbić
3
Pytanie dotyczy wskazówek, które są nieco specyficzne dla C #. Jest to jeden ze wskazówek dla wszystkich języków .
Peter Taylor
4
@PeterTaylor Odpowiedziałem na to pytanie ponad 3 lata temu, na długo przed utworzeniem wątku, który
dowiązałeś
15

Efektywne korzystanie z

Możesz zastąpić float (który jest aliasem System.Single) za zpomocąz=System.Single;

Następnie zastąpić z=System.Single;z z=Single;umieszczając program w przestrzeni nazw System. (Jak w przypadku odpowiedzi Joey'a)

Można to zastosować do innych typów wartości (użyj aliasu), struktur i klas

Nathan Cooper
źródło
14

Jeśli musisz użyć Console.ReadLine()wielokrotnie w kodzie (co najmniej 3 razy), możesz:

Func<string>r=Console.ReadLine;

a następnie po prostu użyj

r()

zamiast

Cristian Lupascu
źródło
Myślę, że musisz usunąć ()z pierwszego wiersza.
mellamokb
@mellamokb to prawda, dzięki! naprawiony.
Cristian Lupascu,
1
Nie można zrobić auto r=Console.ReadLine;?
Claudiu
2
@claudiu nie, niestety nie ideone.com/jFsVPX
Cristian Lupascu
@Claudiu, autojest C++czasownikiem. varjest dla C#. Nie można tego zrobić, ponieważ Console.ReadLinejest przeciążony, dlatego należy podać podpis funkcji, aby poinformować kompilator o żądanym przeciążeniu.
GreatAndPowerfulOz
14

Podczas odczytywania każdego znaku argumentu wiersza poleceń zamiast zapętlania do długości łańcucha:

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

Możesz zapisać postać, używając bloku try / catch, aby znaleźć koniec:

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

Dotyczy to dowolnej tablicy w obrębie tablicy, takiej jak:

  • string[]
  • int[][]
  • IList<IList<T>>
Hand-E-Food
źródło
7
To naprawdę przerażające ... Uwielbiam to!
Alex Reinking
cholera, to geniusz, właściwie właśnie uratowałem postać, zapętlając tablicę
Gaspa79
To jest naprawdę złe!
GreatAndPowerfulOz
13

Użyj lambdas, aby zdefiniować funkcję w C # 6

W C # 6 możesz użyć lambda do zdefiniowania funkcji:

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

Jest to krótsze niż zdefiniowanie takiej funkcji:

int s(int a,int b){return a+b;}
ProgramFOX
źródło
3
C # 6 daje zupełnie nowy zakres umiejętności gry w golfa
jcolebrand
W C # 7 można to zrobić wewnątrz innej funkcji, aby utworzyć funkcje lokalne. Wątpię, żeby to pomogło podczas gry w golfa, ale wciąż jest to fajna sztuczka.
TehPers
1
To nie jest formalnie lambda. To wyrazisty członek .
rekurencyjny
13

LINQ

Zamiast używać:

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

Aby otrzymać Enumerable z wynikiem funkcji fdla każdego intz [0,y]was może używać

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

jeśli potrzebujesz stringlub cokolwiek, co implementuje Enumerablew twoim programie, możesz ich również użyć

var s="I need this anyway";
s.Select((_,i)=>f(i))
obdarty
źródło
Używam tej sztuczki w mojej odpowiedzi na wyzwanie Shamir's Secret Sharing .
aloisdg
Nie sądzę, że część strunowa zostanie wykonana, jeśli nie wykonasz iteracji licznika z włączoną optymalizacją. Po prostu mi się nie udało, dopóki nie zrobiłem .ToArray () ;. Poza tym niesamowita wskazówka!
Gaspa79
Tak, wyliczenia są leniwe, ale dotyczy to wszystkich trzech przykładów, nie tylko tego z ciągiem znaków.
obdarty
11

Jeśli potrzebujesz użyć Dictionary<TKey, TValue>kodu generycznego co najmniej dwa razy w kodzie, możesz zadeklarować klasę słownika, jak w tym przykładzie:

class D:Dictionary<int,string>{}

a następnie po prostu użyj

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

zamiast powtarzać Dictionary<int,string>dla każdej instancji.

Użyłem tej techniki w tej odpowiedzi

Cristian Lupascu
źródło
2
A także „D d” zamiast „var d”
Zukki
@Zukki Oczywiście! Co ja sobie myślałem? :)
Cristian Lupascu,
Alternatywnie:using D = System.Collections.Generic.Dictionary<int,string>;
Andrij Tołstoj
10

Możesz użyć floati doubleliterałów, aby zaoszczędzić kilka bajtów.

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

Gdy potrzebujesz trochę intarytmetyki, aby zwrócić a, floatlub doublemożesz użyć literałów, aby wymusić konwersję.

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

Jeśli kiedykolwiek spotkasz się z sytuacją, w której musisz rzucić, możesz zapisać kilka bajtów, używając zamiast tego mnożenia.

((double)x-y)/(x*y);
(x*1d-y)/(x*y);      // saves 5 bytes
SLuck49
źródło
Jeszcze krótszy:(x-y)*1d/x/y;
rekurencyjny
9

Pamiętaj, gdzie są prywatne lub publiczne, na przykład:

class Default{static void Main()

w porównaniu do

public class Default { public static void Main()
jcolebrand
źródło
5
I zawsze pisz tylko jedną literę klasy :-)
Joey
2
Aha, i jeszcze jedna miła rzecz, sugerowana tutaj: Mainnie potrzebuje żadnych argumentów w przeciwieństwie na przykład do Javy.
Joey
@Joey: i nie musi być publiczny.
R. Martinho Fernandes,
1
@martinho ~ czy przeczytałeś moją odpowiedź? ;) brak publicznego w serwisie głównym
jcolebrand 31.01.11
@Joey ~ Starałem się, aby jeden był na post;) ... pomyślałem, że ktoś inny opublikuje taht o głównym lub klasach, które są tylko jedną literą. Widząc, jak nikt inny tego nie zrobi, dodam też to.
jcolebrand
9

W przypadku jednowierszowych wyrażeń lambda możesz pominąć nawiasy i średnik. W przypadku wyrażeń jednoparametrowych można pominąć nawiasy.

Zamiast

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

Posługiwać się

SomeCall(x=>DoSomething);
Juliana Peña
źródło
11
Nigdy nie piszę nawiasów dla lambda jednoparametrowego, nawet w kodzie produkcyjnym.
R. Martinho Fernandes
Zawsze używam nawiasów, ponieważ lubię dzielić lambda na wiele wierszy w celu zwiększenia czytelności.
Juliana Peña
2
SomeCall(DoSomething)jest jeszcze lepszy
GreatAndPowerfulOz
9

Pętla:

Deklaracje zmienne:

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

stają się:

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

A jeśli potrzebujesz lub pracujesz ze zmienną i tylko raz, możesz zacząć od -1 (lub 0 w zależności od okoliczności pętli) i zwiększyć inline:

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

do

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

I to zmniejsza się o jeden znak, a także nieznacznie zaciemnia kod. Rób to tylko w iodniesieniu do PIERWSZEJ referencji, w ten sposób: (przyznane optymalizacje jednej postaci to niewiele, ale mogą pomóc)

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

do

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

gdy pętla nie musi zwiększać i(pętla odwrotna):

for(int i=MAX;--i>0;){
      Console.WriteLine(i);
}
jcolebrand
źródło
++W takich przypadkach zwykle umieszczam bezpośrednio w nagłówku pętli: for(;++i<max;)co jest łatwiejsze do naśladowania i trudniejsze do popełnienia błędu.
Joey,
@Joey W takich przypadkach zwykle przełączam się na while (++ i <max), który ma tę samą długość, ale jest łatwiejszy do odczytania.
ICR
ICR: zależy od tego, czy możesz wstawić także inną (wcześniejszą) instrukcję do fornagłówka, co spowoduje zapisanie znaku ponownie.
Joey,
Możesz przenieść obie deklaracje z powrotem do klauzuli for dla oszczędności 1 bajta.
rekurencyjny
I jak zmienia for(;i<max;)się while(i<max). Ta sama liczba bajtów, ale dla mnie wygląda po prostu czystiej.
Ayb4btu,
8

Istnieją okoliczności, w których parametr wyjściowy może zapisać znaki. Oto nieco wymyślony przykład, 10-pinowy algorytm kręgli.

Ze zwrotem:

........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;}

I z parametrem wyjściowym:

........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;}}

Tutaj parametr wyjściowy zapisuje w sumie 5 znaków.

M_J_O_N_E_S
źródło
8

W języku C # nie wolno if(n%2)nam sprawdzać, czy njest liczbą parzystą. Jeśli to zrobimy, otrzymamy cannot implicity convert int to bool. Naiwne postępowanie polegałoby na:

if(n%2==0)

Lepszym sposobem jest użycie:

if(n%2<1)

Użyłem tego, aby zyskać jeden bajt tutaj .

zwróć uwagę, że działa to tylko dla liczb dodatnich, ponieważ -1%2==-1jest rozważane nawet przy tej metodzie.

aloisdg
źródło
6

Interpolacja ciągów

Naprawdę prostym ulepszeniem zajmującym mało miejsca jest interpolacja. Zamiast:

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

wystarczy użyć $do wstawienia wyrażeń:

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

To, wraz z nowymi ciałami wyrażeń w C # 6.0, powinno sprawić, że każde proste obliczenie ciągu znaków będzie łatwe do gry w C #.

mınxomaτ
źródło
3
Zauważ też, że i+$" bottles of beer";jest on krótszy niż $"{i} bottles of beer".
aloisdg
1
@aloisdg W tym pierwszym przypadku powinieneś jednak pominąć $.
Metoniem
@Metoniem Rzeczywiście! Pozwoliłem na to, ponieważ w moim pierwotnym przypadku miałem dwa {i}jeden z przodu i jeden w środku;)
aloisdg
@aloisdg Ahh, rozumiem. Tak, wstydliwych komentarzy nie można edytować :(
Metoniem
6

Użyj C # lambda. Ponieważ PPCG pozwala na wejście / wyjście lambda, powinniśmy ich użyć.

Klasyczne metody C # wygląda następująco:

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

Jako lambda napiszemy

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

Dozwolone są również anonimowe lambda:

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

Usuń cały hałas i skup się!

Aktualizacja:

Możemy poprawić jeden krok więcej z currying jak @TheLethalCoder komentarz:

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

Przykład curringowania @Felix Palmen: Jak obliczyć klucz WPA?

Będzie to pomocne, gdy masz dokładnie 2 parametry, wtedy _lepsza będzie pusta, nieużywana zmienna . Zobacz meta post na ten temat . Używam tej sztuczki tutaj . Trzeba będzie nieco zmienić funkcję. Przykład: Wypróbuj online!

aloisdg
źródło
1
Nie jestem pewien, czy jest to nigdzie indziej we wskazówkach, ale w tym przykładzie można również użyć s=>c=>...
curry
@TheLethalCoder Rzeczywiście możemy! Zaktualizuję odpowiedź, dziękuję!
aloisdg,
Czy w tym przypadku można zastosować redukcję eta? Coś takiego: s=>s.Contains.
corvus_192
Zauważ, że odpowiedzi w języku C # i Java na odmianę „bez typu lambda” nie są przychylne, możesz dołączyć do dyskusji na temat tego postu . Sugerowana alternatywa to(string s,char c)=>s.Contains(c)
VisualMelon,
Dyskusja o funkcjach bez
nazw
5

Twórz nazwy klas tylko jedną literą. Ulepszając wskazówki dotyczące gry w golfa w C #, z której pochodzimy

class Default{static void Main()

do

class D{static void Main()

co w tym przypadku nokautuje kolejne 6 znaków.

jcolebrand
źródło
1
to samo z nazwami zmiennych
Nellius 31.01.11
11
W jaki sposób jest to „przynajmniej nieco specyficzne dla C #”?
Peter Taylor
5

Metoda Computeinstancji System.Data.DataTablepozwala ocenić proste wyrażenie łańcuchowe, np .:

C # (kompilator Visual C #) , 166 bajtów

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

Wypróbuj online!

Niezbyt „golfowy” jako taki, ale czasem może być przydatny.

digEmAll
źródło
5

Zamiana dwóch zmiennych

Zwykle, aby zamienić dwie zmienne, musisz zadeklarować zmienną tymczasową do przechowywania wartości. Wyglądałoby to tak:

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

To 16 bajtów! Istnieją inne metody zamiany, które są lepsze.

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

Trzy ostatnie działają tylko w przypadku wartości liczbowych i, jak wskazano tylko w ASCII, dwie ostatnie mogą spowodować wyjątek ArithmeticOverflow. Wszystkie powyższe mają 12 bajtów, co oznacza 4 bajty oszczędności w porównaniu z pierwszym przykładem.

Wcielenie ignorancji
źródło
Dotyczy to tylko liczb, a nawet wtedy cokolwiek innego niż krotki i xor ryzykujesz, że osiągniesz limity liczb całkowitych, jeśli zastosujesz to do liczb całkowitych. Czasami inne typy liczb również napotkają ograniczenia
tylko ASCII
4

Korzystanie z LinqPad da ci możliwość usunięcia całego narzutu programu, ponieważ możesz wykonywać polecenia bezpośrednio. (I to powinno być w pełni legalne w codegolf ... Nikt nie mówi, że potrzebujesz .exe)

Dane wyjściowe są wykonywane przy użyciu .Dump()metody rozszerzenia.

EvilFonti
źródło
Wsparcie .NetFiddle .Dump();)
aloisdg
4

(Szczególny przypadek znajomości priorytetu operatora !)

Użyj %do ścisłego (nieco) ograniczonego odejmowania. Może to zaoszczędzić parę nawiasów wokół odejmowania, w wyniku czego chcesz coś pomnożyć lub podzielić; ale bądź ostrożny, ma poważne ograniczenia.

Zamiast

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)

Rozważać

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

Przykłady:

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

Dopiero co to odkryłem i wydaje mi się, że warto będzie pamiętać o każdej pracy z ASCII w przyszłości. (Obecnie gram w golfa gdzieś, gdzie używam ASCII do kompaktowych reprezentacji numerycznych, ale trzeba pomnożyć przez 1lub w -1oparciu o inny warunek, a to pasiaste 2 bajty)

VisualMelon
źródło
4

Jeśli chcesz dołączyć wiele usings, które wypadają z tej samej hierarchii, często najdłuższym jest użycie najdłuższego jako namespace:

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

vs:

namespace System.Linq
{
    //Some code
}
TheLethalCoder
źródło
3

Odkryte dziś „w okopach” przy jednoczesnym ulepszaniu kodu golfowego ... jeśli masz klasę do przetwarzania, możesz wykonać pracę w konstruktorze, aby zapisać deklarację metody.

Odkryłem to, redukując aplikację konsolową - ponieważ tak było static void Main(), wszystkie funkcje i zmienne musiały zostać zadeklarowane jako statyczne. Utworzyłem zagnieżdżoną klasę z funkcjami i zmiennymi składowymi, z główną pracą wykonywaną w konstruktorze. Zapisuje to również znaki w kodzie wywołującym.

np. Klasa z metodą:

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

Klasa z pracą w konstruktorze:

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

Ten przykład zapisuje 9 znaków.

M_J_O_N_E_S
źródło
3

Użyj Actionlike, Funcaby ustawić funkcję na zmienną. Actionnie zwraca nic ( void), więc świetnie nadaje się do drukowania.

Na przykład:

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

Te wskazówki są inspirowane przez @ W0lf świetny przykład użycia FunczReadLine .

aloisdg
źródło
3

Deklaruj puste / pasujące ciągi razem

Jeśli chcesz zadeklarować wiele pustych / pasujących ciągów, możesz zapisać kilka bajtów za pomocą:

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

Niestety var a="",b=a,c=a;jest nielegalne, jakimplicitly type variable cannot have multiple declarators

Erresen
źródło
Czy potrafisz robić var a=b=c=""w javascript?
corvus_192
@ corvus_192 nope - niestety nie.
Erresen,