Tips for code-golfing in C#

65

28

What general tips do you have for golfing in C#? I'm looking for ideas that can be applied to code golf problems in general that are at least somewhat specific to C# (e.g. "remove comments" is not an answer). Please post one tip per answer.

-- borrowed from marcog's idea ;)

jcolebrand

Posted 2011-01-29T06:02:23.427

Reputation: 1 683

BEST TIP => Use something beside .NET if you don't want to submit the longest answer for the challenge. .NET is designed to be very verbose and to let the IDE do the typing. Which is actually not as bad as it sounds for general programming as long as you have that IDE crutch but for code golf that strategy is certain fail. – krowe – 2014-07-02T05:48:05.340

Forgive me for the picture of a calendar, it was all I could find on short notice. – undergroundmonorail – 2014-07-08T12:44:05.907

Answers

61

Instead of using .ToString() use +"" for numerics and other types that can be natively cast to a string safely.

.ToString() <-- 11 chars
+""         <--  3 chars

jcolebrand

Posted 2011-01-29T06:02:23.427

Reputation: 1 683

6This also works in JS. – Cyoce – 2016-04-05T18:25:29.440

@Cyoce And Java – Kevin Cruijssen – 2016-09-29T11:49:14.773

1This is usually actually 5 chars if you need to use the string afterwards for including the braces... (1+"").DoSomethingWith1String(); – TheLethalCoder – 2017-05-18T12:48:30.277

1If you need the string you're usually storing it. Just about any other usage can natively infer the ToString()... – jcolebrand – 2017-05-18T14:38:58.670

1

Note that this actually calls the static String.Concat(object) with the argument, rather than the virtual calling object.ToString(). Concat explicitly converts null to the empty string (see the reference source). There is no 'native casting' going on, you can convert anything like this, it's just that the result might not be very useful in some cases! (but the null behaviour may well be).

– VisualMelon – 2017-07-11T20:01:53.377

1

Alternative - string interpolation: $"{n}"

– Andriy Tolstoy – 2019-01-04T11:24:45.397

Yah, that just recently got added tho, compared to the 2011 post date. – jcolebrand – 2019-01-04T16:06:57.747

@jcolebrand how about something like .ToString("dddd, dd MMMM yyyy HH:mm:ss")!??? – AminM – 2019-06-16T05:39:50.327

41

I once deliberately placed my program in namespace System so I can shorten access to a specific class. Compare

using System;using M=System.Math;

to

namespace System{using M=Math;

Joey

Posted 2011-01-29T06:02:23.427

Reputation: 12 260

You can also just do using System;class P.... – ldam – 2015-06-05T19:15:30.407

@Logan: This wasn't about just using System; but also about having an alias for a class in the same namespace, which is shorter the way I've shown here. – Joey – 2015-06-05T20:28:11.580

It's even shorter to do using static System.Math; in C#6 (add you can use any of those functions as if they were truly global--not in a class). The original suggestion may still be shorter than using static if you need to access multiple classes. – milk – 2016-09-01T01:51:06.370

@milk: the additional static keyword often is longer than any savings from leaving out M. on the method calls, but yes, it's an option, but it comes at a hefty upfront cost that needs lots of calls to amortise. – Joey – 2016-09-01T05:44:59.567

9Just remember that it is better to fully qualify classes/functions when a single use solves the problem. This is only useful if you have to call something more than once, and even then only for items in the System namespace. – Nick Larsen – 2011-01-31T14:43:19.093

30

Use var for declaring and initializing (single) variables to save characters on the type:

string x="abc";

becomes

var x="abc";

Isn't particulaly necessary for int, of course.

Joey

Posted 2011-01-29T06:02:23.427

Reputation: 12 260

3Remember that var cannot have multiple declarators, for example var x="x",y="y"; is not possible. – Ian H. – 2017-11-22T08:57:26.847

29

If using LINQ you can pass a method directly to Select instead of making a lambda.

So, instead of

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

you can use

foo.Select(int.Parse)

directly.

(Discovered recently when improving on one of Timwi's C# answers.)

Joey

Posted 2011-01-29T06:02:23.427

Reputation: 12 260

2FWITW this is called η-reduction – ThreeFx – 2016-09-13T11:30:23.467

It's also known as "point free" style

– Jonathan Wilson – 2017-03-02T18:04:18.090

6To the more pragmatic of us, it's simply shorter :-þ – Joey – 2017-03-03T08:06:50.053

23

Remember that the smallest compilable program in C# is 29 characters:

class P
{
    static void Main()
    {   
    }
}

So start by removing that from your length and judge your answer on how much over that it takes. C# cannot compete with other languages when it comes to printing or reading input, which is the heart of most [code-golf] problems, so don't worry about that. As a C# golfer, you're really competing against the language.

A few other things to keep in mind:

  • Reduce all loops and if statements to a single line if possible in order to remove the brackets.
  • If given the option between stdin and command line, always use command line!

Nick Larsen

Posted 2011-01-29T06:02:23.427

Reputation: 633

1As a C# golfer, you're really competing against the language Unbelievably related – user8397947 – 2016-07-19T15:07:52.857

1Actually, that's not true. It compiles using static int Main() as well, which would be 28 characters. – Metoniem – 2017-02-14T14:14:21.107

1

@Metoniem That requires a return something.

– user202729 – 2018-03-27T14:54:32.173

This does usually involve ternary as well ;) – jcolebrand – 2011-01-31T14:47:29.770

20

Instead of

bool a = true;
bool b = false;

do

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

If you need multiple variables, use this (suggested by @VisualMelon)

bool a=0<1,b=!a;

Yytsi

Posted 2011-01-29T06:02:23.427

Reputation: 3 582

Note that if you need multiple variables of the same type it is usually cheaper to declare the type a comma separate the declarations bool a=0<1,b=!a; – VisualMelon – 2017-01-13T09:37:52.123

18

Favor the ternary operator over if..else blocks where appropriate.

For example:

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

is more efficiently:

j=i<1?1:0;

Nellius

Posted 2011-01-29T06:02:23.427

Reputation: 568

11No need for parentheses in the second case - j=i<1?1:0; is enough. – Danko Durbić – 2011-04-18T13:28:43.000

15Am I the only one that feels that the second case is inherently more readable for things like this in general? I do that routinely. In addition, if I need to avoid a null condition (like on a string) I do something like var x = input ?? ""; (I loves my coalesces) – jcolebrand – 2011-01-31T14:31:35.000

There are times when it is far from being the more readable option, particularly when i < 1 is a complex statement or when the name of j is long. IMO, it also fails to convey side effects very well. In the case where if (i < 1) is something like if (SendEmail(recipient)) which returns true/false depending on the success of the side effects, I prefer the if/then notation. – Nick Larsen – 2011-01-31T15:01:59.760

3

The question asks for tips which are somewhat specific to C#. This is one included in the tips for all languages.

– Peter Taylor – 2014-03-17T20:35:17.840

4@PeterTaylor I answered this question over 3 years ago, well before the thread you linked was created – Nellius – 2014-03-18T15:31:42.827

@NickLarsen I meant only on simple assignments, I should have clarified. Yes, for things which may have side effects or which may call functions as the (1:0) spot, I don't prefer the short way, I agree with you and prefer the long way. But for defining defaults of the order int value; if (boolean == true) {value = 1;}else{value=2;} in that style I prefer the ternary. ~~ Anyways, I know this has been gone over time and time again on the intertubes ;) – jcolebrand – 2011-02-01T15:41:18.450

15

Effective use of using

You can replace float (which is an alias for System.Single) with z using z=System.Single;

Then replace z=System.Single; with z=Single; by placing the program in the namespace System. (As with Joey's answer)

This can be applied for other value types (use what they are an alias for), structs and classes

Nathan Cooper

Posted 2011-01-29T06:02:23.427

Reputation: 617

15

When reading each character of a command line argument, rather than looping up to the string's length:

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

You can save a character by using a try/catch block to find the end:

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

This applies to any array within an array such as:

  • string[]
  • int[][]
  • IList<IList<T>>

Hand-E-Food

Posted 2011-01-29T06:02:23.427

Reputation: 7 912

7That is truly horrifying... I love it! – Alex Reinking – 2016-07-09T18:19:24.090

holy crap this is genius, I actually just saved a character while looping an array – Gaspa79 – 2017-04-09T06:13:14.323

This is truly evil! – GreatAndPowerfulOz – 2017-08-08T17:17:35.887

14

If you need to use Console.ReadLine() multiple times in your code (min 3 times), you could do:

Func<string>r=Console.ReadLine;

and then just use

r()

instead

Cristian Lupascu

Posted 2011-01-29T06:02:23.427

Reputation: 8 369

I think you need to remove () from the first line. – mellamokb – 2012-04-13T12:51:40.180

@mellamokb that's right, thanks! fixed. – Cristian Lupascu – 2012-04-13T13:50:38.600

@Claudiu, auto is a C++ verb. var is for C#. The reason this can't be done is because Console.ReadLine is overloaded so the function signature needs to be specified in order to tell the compiler which overload is wanted. – GreatAndPowerfulOz – 2017-08-08T17:15:20.723

1Can't you do auto r=Console.ReadLine;? – Claudiu – 2014-09-25T16:36:19.050

2

@claudiu no, unfortunally not http://ideone.com/jFsVPX

– Cristian Lupascu – 2014-09-25T17:19:07.813

13

Use lambdas to define a function in C# 6

In C# 6, you can use a lambda to define a function:

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

This is shorter than defining a function like this:

int s(int a,int b){return a+b;}

ProgramFOX

Posted 2011-01-29T06:02:23.427

Reputation: 8 017

3C#6 gives a whole new range of ability to code-golf – jcolebrand – 2015-01-11T23:32:40.510

In C#7, this can be done inside another function to create local functions. I doubt this will help while golfing, but it's still just a neat trick to know. – TehPers – 2017-08-04T16:38:05.563

1

That's not formally a lambda. It's an expression bodied member.

– recursive – 2017-11-22T22:32:13.180

13

LINQ

Instead of using:

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

to get an Enumerable with the result of function f for every int in [0,y] you can use

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

if you need string or anything that implements Enumerable in your program you can use them too

var s="I need this anyway";
s.Select((_,i)=>f(i))

raggy

Posted 2011-01-29T06:02:23.427

Reputation: 491

I use this trick in my answer for the Shamir's Secret Sharing challenge.

– aloisdg moving to codidact.com – 2016-07-07T20:01:11.047

I don't think that the string part will execute if you don't iterate the ienumerable with optimization on. Just failed for me until I did .ToArray();. Other than that, amazing tip! – Gaspa79 – 2017-04-09T23:34:20.127

Yes enumerables are lazy but that is true for all three examples not just the one with the string. – raggy – 2017-04-10T16:39:46.463

10

You can use float and double literals to save a few bytes.

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

When you need some int arithmetic to return a float or double you can use the literals to force the conversion.

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

If you ever run into a situation where you have to to cast you can save a few bytes by using multiplication instead.

((double)x-y)/(x*y);
(x*1d-y)/(x*y);      // saves 5 bytes

SLuck49

Posted 2011-01-29T06:02:23.427

Reputation: 901

Even shorter: (x-y)*1d/x/y; – recursive – 2019-05-21T20:08:07.627

10

If you need to use a generic Dictionary<TKey, TValue> at least two times in your code, you could declare a dictionary class, like in this example:

class D:Dictionary<int,string>{}

and then just use

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

instead of repeating Dictionary<int,string> for every instantiation.

I have used this technique in this answer

Cristian Lupascu

Posted 2011-01-29T06:02:23.427

Reputation: 8 369

2And also "D d" instead of "var d" – Zukki – 2015-06-04T19:48:24.240

@Zukki Obviously! What was I thinking? :) – Cristian Lupascu – 2015-06-05T06:24:51.503

1Alternative: using D = System.Collections.Generic.Dictionary<int,string>; – Andriy Tolstoy – 2019-01-04T10:58:39.767

9

Remember where private or public are inherent, such as the following:

class Default{static void Main()

as compared to

public class Default { public static void Main()

jcolebrand

Posted 2011-01-29T06:02:23.427

Reputation: 1 683

The example is wrong. Classes are internal by default, not public. Members are private by default, not public. – Kendall Frey – 2013-01-25T14:31:32.470

5And always make the class one letter only :-) – Joey – 2011-01-29T11:40:06.203

2Oh, and another nice thing, implied here: Main does not need any arguments in contrast to Java, for example. – Joey – 2011-01-29T19:10:41.850

@KendallFrey, I think the point was that Main is a special case or doesn't need to be public? – GreatAndPowerfulOz – 2017-08-08T17:21:36.257

@Joey: and neither does it need to be public. – R. Martinho Fernandes – 2011-01-31T02:36:57.843

1@martinho ~ did you read my answer? ;) no public on main – jcolebrand – 2011-01-31T13:53:50.600

@Joey ~ I was trying to keep it to one per post ;) ... figured someone else would post taht about main or classes only being one letter. Seeing as how nobody else has, I'll go ahead and add that one too. – jcolebrand – 2011-01-31T13:54:31.660

@drachenstern: I was constrasting it with Java, where you are forced to bow to the full signature: public static void main(String[] a). – R. Martinho Fernandes – 2011-02-02T01:29:58.217

Ohhh good point @Martinho – jcolebrand – 2011-02-02T01:30:34.557

9

Looping:

Variable declarations:

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

become:

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

And if you have a need to or work with the i variable only once, you could start at -1 (or 0 depending on the loop circumstance) and increment inline:

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

to

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

And that reduces by one character, and slightly obfuscates the code as well. Only do that to the FIRST i reference, like thus: (granted one character optimizations aren't much, but they can help)

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

to

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

when the loop does not have to increment i (reverse order loop):

for(int i=MAX;--i>0;){
      Console.WriteLine(i);
}

jcolebrand

Posted 2011-01-29T06:02:23.427

Reputation: 1 683

You can move both declarations back into the for clause for a1 byte savings. – recursive – 2016-07-04T03:39:08.317

I usually put the ++ in such cases directly into the loop header: for(;++i<max;) which is both easier to follow and harder to get wrong. – Joey – 2011-03-03T10:49:48.107

I like changing for(;i<max;) to while(i<max). Same number of bytes, but for me it just looks cleaner. – Ayb4btu – 2017-11-10T22:52:48.780

Okay so change it? – jcolebrand – 2017-11-10T23:02:24.927

@Joey In those cases I tend to switch to while(++i<max) which is the same length but easier to read. – ICR – 2011-12-07T14:17:56.730

ICR: depends on whether you can put another (earlier) statement into the for header as well, which would then save a character again. – Joey – 2011-12-07T15:09:22.573

9

For one-line lambda expressions, you can skip the brackets and semicolon. For one-parameter expressions, you can skip the parentheses.

Instead of

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

Use

SomeCall(x=>DoSomething);

Juliana Peña

Posted 2011-01-29T06:02:23.427

Reputation: 221

3SomeCall(DoSomething) is even better – GreatAndPowerfulOz – 2017-08-08T17:18:40.887

11I never write the parentheses for one-parameter lambdas, even on production code. – R. Martinho Fernandes – 2011-02-02T01:34:47.553

I always use the brackets because I like to split the lambda into multiple lines for readability. – Juliana Peña – 2011-02-02T21:02:01.627

8

There are circumstances when an output parameter can save characters. Here's a slightly contrived example, a 10 pin bowling score algorithm.

With a return statement:

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

And with an output parameter:

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

The output parameter here saves a total of 5 characters.

M_J_O_N_E_S

Posted 2011-01-29T06:02:23.427

Reputation: 161

8

In C#, we are not allowed to do if(n%2) to check if n is a even number. If we do, we get a cannot implicity convert int to bool. A naive handling would be to do:

if(n%2==0)

A better way is to use:

if(n%2<1)

I used this to gain one byte here.

note that this only works for positive numbers, as -1%2==-1, it is considered even with this method.

aloisdg moving to codidact.com

Posted 2011-01-29T06:02:23.427

Reputation: 1 767

6

String Interpolation

A really simple space-saving improvement is interpolation. Instead of:

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

just use $ to inline expressions:

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

This, together with the new expression bodies in C#6.0 should make any simple string-calculation challenge pretty golfable in C#.

mınxomaτ

Posted 2011-01-29T06:02:23.427

Reputation: 7 398

3Also note that i+$" bottles of beer"; is shorter than $"{i} bottles of beer". – aloisdg moving to codidact.com – 2016-07-08T14:56:42.033

1@aloisdg In that first case you should leave $ out, though. – Metoniem – 2017-02-14T14:21:39.323

@Metoniem Indeed! I let it because in my original case I had two {i} one in front and one in the middle ;) – aloisdg moving to codidact.com – 2017-02-14T14:37:38.573

@aloisdg Ahh, I see. Yeah, shame comments can't be edited :( – Metoniem – 2017-02-14T14:40:12.297

6

Use C# lambda. Since PPCG allows lambda for input/output we should use them.

A classic C# methods looks like this:

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

As a lambda, we will write

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

Anonymous lambda are allowed too:

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

Remove all the noise and focus!

Update:

We can improve one step more with currying as @TheLethalCoder comment:

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

Example of curring by @Felix Palmen: How compute WPA key?

It will be helpful when you have exactly 2 parameters, then a empty unused variable _ will be better. See meta post about this. I use this trick here. You will have to change a bit the function. Example: Try it online!

aloisdg moving to codidact.com

Posted 2011-01-29T06:02:23.427

Reputation: 1 767

1Not sure if it's anywhere else in the tips but for this example you can use currying too... s=>c=>... – TheLethalCoder – 2017-01-09T14:30:17.093

@TheLethalCoder Indeed we can! I will update the answer thank you! – aloisdg moving to codidact.com – 2017-01-10T08:43:09.417

Can you use eta-reduction in this case? Something like this: s=>s.Contains. – corvus_192 – 2017-01-11T10:20:39.630

Note that C# and Java answers of the 'untyped lambda' variety are falling out of favour, you might wish to join the discussion on this meta post. The suggested alternative is (string s,char c)=>s.Contains(c)

– VisualMelon – 2017-01-13T09:34:31.707

Discussion about unamed functions

– aloisdg moving to codidact.com – 2017-11-24T12:34:06.953

5

The Compute instance method of System.Data.DataTable, allows to evaluate a simple string expression, e.g. :

C# (Visual C# Compiler), 166 bytes

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

Try it online!

Not very "golfy" per se, but sometimes might be useful.

digEmAll

Posted 2011-01-29T06:02:23.427

Reputation: 4 599

5

Swapping two variables

Normally, to swap two variables, you have to declare a temporary variable to store the value. It would look like something along the lines of this:

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

That's 16 bytes! There are some other methods of swapping that are better.

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

The last three only work for numeric values, and as ASCII-only pointed out, the last two might result in an ArithmeticOverflow exception. All of the above are 12 bytes, a 4 byte saving compared to the first example.

Embodiment of Ignorance

Posted 2011-01-29T06:02:23.427

Reputation: 7 014

Only applies for numbers though, and even then anything other than tuples and xor risk running into integer limits of you're applying this to integers. Occasionally, other number types will run into limits too – ASCII-only – 2019-02-20T03:42:46.353

5

Make classnames only one letter. Enhancing on Tips for code-golfing in C# we go from

class Default{static void Main()

to

class D{static void Main()

which knocks out another 6 chars in this case.

jcolebrand

Posted 2011-01-29T06:02:23.427

Reputation: 1 683

11How is this "at least somewhat specific to C#"? – Peter Taylor – 2014-02-21T17:49:12.613

1ditto with variable names – Nellius – 2011-01-31T14:07:43.767

4

(A particular case of knowing your operator precedence!)

Use % for tight-binding (somewhat) limited subtraction. This can save you a pair of parentheses around a subtraction, the result of which you want to multiply or divide by something; but be careful, it has serious limitations.

Instead of

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)

Consider

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

Examples:

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

I've only just discovered this, and I feel like it will be valuable thing to remember whenever working with ASCII in the future. (I'm currently golfing somewhere where I'm using ASCII for compact numeric representations, but needs to multiply by 1 or -1 based on another condition, and this striped 2 bytes)

VisualMelon

Posted 2011-01-29T06:02:23.427

Reputation: 3 810

4

If you need to include multiple usings that all fall off of the same hierarchy it is often shorter to use the longest one as the namespace:

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

vs:

namespace System.Linq
{
    //Some code
}

TheLethalCoder

Posted 2011-01-29T06:02:23.427

Reputation: 6 930

4

Avoid single-statement foreach loops

If the loop's statement returns a non-int (including void!) "value", it can be replaced with LINQ:

foreach(var x in a)Console.WriteLine(F(x));
a.Any(x=>Console.WriteLine(F(x))is int);

If the value happens to be an int, you can use a condition that will always be true or always be false (for example, >0 or <n), a different type and/or All instead of Any.

my pronoun is monicareinstate

Posted 2011-01-29T06:02:23.427

Reputation: 3 111

4

Use dynamic to group declarations

dynamic is a forgotten feature that literally performs dynamic typing in C#! It has limitations (doesn't support extension methods, is bad at inferring that you want to use it, ...), but can often save bytes by merging declarations of incompatible types. Compare the following:

var a=[something of type IEnumerable<int>];var b=[something of type string];int i=x+~y^z
dynamic a=[something of type IEnumerable<int>],b=[something of type string],i=x+~y^z

That's 4 bytes of savings!

my pronoun is monicareinstate

Posted 2011-01-29T06:02:23.427

Reputation: 3 111

4

Using LinqPad will give you the possibility to remove all the program overhead as you can execute statements directly. (And it should be fully legal in codegolf... No one says you need an .exe)

Output is done using the .Dump() extension method.

EvilFonti

Posted 2011-01-29T06:02:23.427

Reputation: 301

.NetFiddle support .Dump() ;) – aloisdg moving to codidact.com – 2016-07-08T15:04:57.357

3

Declare empty/matching strings together

If you need to declare multiple empty/matching strings, you can save a few bytes with the following:

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

Unfortunately var a="",b=a,c=a; is illegal, as implicitly type variable cannot have multiple declarators

Erresen

Posted 2011-01-29T06:02:23.427

Reputation: 449

Can you do var a=b=c="" like in javascript? – corvus_192 – 2017-01-11T10:22:18.670

@corvus_192 nope - unfortunately not. – Erresen – 2017-01-11T10:41:01.727

3

Always use the alias for a type if you need to type as they are usually shorter than the full names. It also means you don't need to include

using System;

or fully qualify the type when you otherwise wouldn't need to.

For a full list of the aliases visit this SO answer:

object:  System.Object
string:  System.String
bool:    System.Boolean
byte:    System.Byte
sbyte:   System.SByte
short:   System.Int16
ushort:  System.UInt16
int:     System.Int32
uint:    System.UInt32
long:    System.Int64
ulong:   System.UInt64
float:   System.Single
double:  System.Double
decimal: System.Decimal
char:    System.Char

Note that you can also use the alias for calling static methods, consider:

System.String.Concat();

vs

string.Concat();

TheLethalCoder

Posted 2011-01-29T06:02:23.427

Reputation: 6 930

3

If you're already using Linq in your code and need to create a list use the following:

var l=new int[0].ToList();

Compared to:

var l=new System.Collections.Generic.List<int>();

You can even initialise the list with values like:

var l=new int[0]{1,2,3,4}.ToList();

TheLethalCoder

Posted 2011-01-29T06:02:23.427

Reputation: 6 930

1You can remove the 0 in your declaration. – PmanAce – 2019-02-20T19:35:23.460

3

If you want to return multiple values from a function, use C# 7 style tuples instead of out parameters:

(int,int)d(int a,int b)=>(a/b,a%b);

user82593

Posted 2011-01-29T06:02:23.427

Reputation: 31

Oh, didn't knew this was possible in C#. Thanks for sharing, +1 from me! One thing to golf in your code is by using currying input, though (a=>b=> instead of (a,b)=>). Here is your code in action, which might be useful to add as example-link to your tip. Oh, and welcome to PPCG! :)

– Kevin Cruijssen – 2018-08-31T14:53:55.133

@KevinCruijssen posted here :)

– aloisdg moving to codidact.com – 2019-01-11T09:14:32.727

3

Use Ranges and indices (C# 8)

You can use the type Index, which can be used for indexing. You can create one from an int that counts from the beginning, or with a prefix ^ operator that counts from the end:

Index i1 = 3;  // number 3 from beginning
Index i2 = ^4; // number 4 from end
int[] a = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
Console.WriteLine($"{a[i1]}, {a[i2]}"); // "3, 6"

You can also use a Range type, which consists of two Indexes, one for the start and one for the end, and can be written with a x..y range expression. You can then index with a Range in order to produce a slice:

var slice = a[i1..i2]; // { 3, 4, 5 }

source

aloisdg moving to codidact.com

Posted 2011-01-29T06:02:23.427

Reputation: 1 767

3

C# Interactive Window

AKA C# (Visual C# Interactive Compiler) on Try it Online

C# Interactive

This is a REPL for the C# language that includes many advantages to code golfing over using the traditional C# compiler.

Currently, the shortest full program to print Hello, World! using the traditional C# compiler is 67 bytes:

class P{static void Main(){System.Console.Write("Hello, World!");}}

Using the C# Interactive Window, you can do the same thing in 22 bytes:

Write("Hello, World!")

And yes, I added my answer just for this post ;)

As you can see, ceremonial class definitions are not required. Also, a whole bunch of references are included by default. The current list is as follows:

  • /r:System
  • /r:System.Core
  • /r:Microsoft.CSharp
  • /u:System
  • /u:System.IO
  • /u:System.Collections.Generic
  • /u:System.Console
  • /u:System.Diagnostics
  • /u:System.Dynamic
  • /u:System.Linq
  • /u:System.Linq.Expressions
  • /u:System.Text
  • /u:System.Threading.Tasks

The System.Linq namespace is particularly handy as it allows you to write functional style programming which often saves many bytes. Many of the older C# answers added 18 bytes or so for this advantage, simply to import the library using System.Linq;. There are other hacks where solutions created their class in the System namespace to more succinctly access the Console object. None of this is needed with the C# Interactive Window.

dana

Posted 2011-01-29T06:02:23.427

Reputation: 2 541

3

Discovered tonight "in the trenches" while improving some golf code... if you have a class for your processing, you can do the work in the constructor to save declaring a method.

I discovered this while reducing a console application - as there was a static void Main(), all functions and variables had to be declared static. I created a nested class with member functions and variables, with the main work performed in the constructor. This also saves characters in the calling code.

e.g. Class with method:

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

Class with work in the constructor:

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

This example saves 9 characters.

M_J_O_N_E_S

Posted 2011-01-29T06:02:23.427

Reputation: 161

3

Use the one character non-short-circuiting variants of logical operators where possible:

  • i>0||i<42
  • i>0|i<42

or

  • i>0&&i<42
  • i>0&i<42

The difference between the two are one byte (yeah!) and the short-circuit principle. In our first example if i>0 is true, i<42 wont be checked. We dont need it. With the bitwise, both will be evaluated.

example: Code golf to make logos for New Stack exchange sites

Learn more about them on MSDN.

aloisdg moving to codidact.com

Posted 2011-01-29T06:02:23.427

Reputation: 1 767

1

Your statement about short circuiting is incorrect, logical or (||) does indeed short circuit if the left operand is true. https://msdn.microsoft.com/en-us/library/6373h346.aspx

– None – 2016-07-11T21:56:38.380

@Phaeze Indeed I wrote the wrong one. Thank you. – aloisdg moving to codidact.com – 2016-07-11T23:55:13.007

Technically none of these are bitwise operators, they are just non-short-circuiting Boolean operators, because they are operating on Booleans. – VisualMelon – 2017-01-13T21:17:52.603

@VisualMelon MSDN uses "logical or bitwise OR" for "x | y" and "logical OR" for "x || y". What should I use? – aloisdg moving to codidact.com – 2017-01-14T15:21:49.453

1These are 'logical' (Boolean being the logic system). Bitwise would be for integer types. I like to make the distinction clear because the a lot of C# golfing can end up being a mix of both, and operator precedence can be a real pain (though they are the same for each type) – VisualMelon – 2017-01-14T17:16:36.817

@VisualMelon I am not sure about what to write. Can you made a edit on my answer? Thank you for the comments! – aloisdg moving to codidact.com – 2017-01-16T07:19:14.640

3

Use Action like Func to set a function to a variable. Action returns nothing (void) so it is great for printing.

For example:

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

This tips is inspired by @W0lf great example of use of Func with ReadLine.

aloisdg moving to codidact.com

Posted 2011-01-29T06:02:23.427

Reputation: 1 767

2

If you need to use an enum for a method it is often shorter to cast an int to it rather than using the value directly:

DayOfWeek.Sunday
(DayOfWeek)0;

TheLethalCoder

Posted 2011-01-29T06:02:23.427

Reputation: 6 930

2

If you're already using Linq in your answer and need to check for a none empty collection use Any(). Compare it to the following:

Count()>0
Length>0
Count>0
Any()

TheLethalCoder

Posted 2011-01-29T06:02:23.427

Reputation: 6 930

2

Tuple Deconstruction

It is possible to deconstruct a Tuple into variables using the following syntax:

var myTuple = (1, "red", new DateTime(2000, 1, 1));
var (i, c, d) = myTuple;

In a code-golf scenario, you could use this to pass a tuple into a function:

t=>{var(i,c,d)=t;Print(i);Print(c);Print(d);}

Try it online!

A more practical use of this is to decompose a list of tuples and iterate over them using foreach.

var myTuples = new[] {
    (1, "red", new DateTime(2000, 1, 1)),
    (2, "blue", new DateTime(2000, 1, 1))
};
foreach (var (i, c, d) in myTuples) {
    Print(i);
    Print(c);
    Print(d);
}

Or in a code-golf scenario:

t=>{foreach(var(i,c,d)in t){Print(i);Print(c);Print(d);}}

Try it online!

dana

Posted 2011-01-29T06:02:23.427

Reputation: 2 541

2

When to use a space and when you can remove it.

After []

  • int[] f(char[] a){Console.Write('a');}
  • int[]f(char[]a){Console.Write('a');}

Before $

  • return $"{a}"
  • return$"{a}"

example: Code golf to make logos for New Stack exchange sites


(Add yours in comment I will edit)

aloisdg moving to codidact.com

Posted 2011-01-29T06:02:23.427

Reputation: 1 767

2

When you want to join something to output a string without delimiter, you should use string.Concat(), instead of string.Join("",);

  • string.Join("",)
  • string.Concat()

One byte free!

example: Code golf to make logos for New Stack exchange sites

Also Concat() has a lot more signatures than Join. Check them on MSDN: Concat and Join.

aloisdg moving to codidact.com

Posted 2011-01-29T06:02:23.427

Reputation: 1 767

1

Implicitly typed arrays

If you need an array (or IEnumerable) initialized with constant data, the most naive implementation might be like so:

new int[6]{23,16,278,0,2,44}

It's well known that arrays in C# can have implicit length:

new int[]{23,16,278,0,2,44}

However, for certain data types C# will also be able to determine the base type for the array from its values, making the same declaration even shorter:

new[]{23,16,278,0,2,44}

Here is an example demonstrating that all these options create the same array.

Additionally, specifically if you are creating an array for inline declaration, the new[] can be removed as long as the declared variable is not implicitly typed, which can save some bytes:

var a=new[]{"woah"};
string[]b={"woah"};

Kamil Drakari

Posted 2011-01-29T06:02:23.427

Reputation: 3 461

That last line is worth all the weight. Excellent tips! – jcolebrand – 2017-11-15T18:58:13.067

1

Convert a string to an IEnumerable<char>

Common way would be to use .ToCharArray() (14 bytes) or even better .ToList() (11 bytes), but the best I found is to rely on .Skip(0) (8 bytes).

Most of the time you wont need anything and the string will be cast directly, but sometimes it matters:

string.Join("a","bb") // bb

vs

string.Join("a","bb".Skip(0)) // bab

aloisdg moving to codidact.com

Posted 2011-01-29T06:02:23.427

Reputation: 1 767

1wait ToSkip is a thing? – ASCII-only – 2018-04-27T07:50:08.717

@ASCII-only Skip ;) – aloisdg moving to codidact.com – 2018-04-27T11:03:55.180

Then it's no longer 10 bytes – ASCII-only – 2018-04-27T11:05:03.717

@ASCII-only yup. 8 bytes \o/ – aloisdg moving to codidact.com – 2018-04-27T11:07:05.807

1

Using Command-Line Options

Command-line options are not included in the byte count of your program, so they are very useful. However, keep in mind that when you use a command-line option, you are not competing in C# anymore, you are competing in C# with -yourflag.

The syntax for them is to put a - or a / preceding the letter, and if there are any arguments, you use : to separate the option name from the argument.

There are 3 command-line options that I know of as of right now:

  • /u or -u or /using or -using

    • Acts as a using statement. Example: /u:System.Text.RegularExpressions. You can do static imports with them by just adding the class name, like /u:System.Text.RegularExpressions.Regex. For example, if you have /u:System.String as an option, you can just use Concat(yourString) instead of string.Concat(yourString). Sadly, aliasing doesn't seem to work. You can also put multiple imports on the same line with ; as a delimiter like this: /u:System.Math;System.CodeDom.
  • /i or -i, activates REPL mode. Code from the input box is also evaluated and printed.

    • Can be useful for situations where hard-coding is allowed, e.g. if input insertRandomTermHere output 3, if input anotherRandomTerm output 4, we can just do int insertRandomTermHere=3,anotherRandomTerm=4;. Try it online!
  • /r or -r

    • Acts as an assembly reference. Allows you to use types like those in System.Numerics or System.Drawing. If you want to use BigInteger, an assembly reference is required.

Meanwhile, happy ing!

Embodiment of Ignorance

Posted 2011-01-29T06:02:23.427

Reputation: 7 014

Where did you find these flags in the docs? I can only find something about the default Roslyn flags.

– Kevin Cruijssen – 2019-01-30T10:55:30.273

1@KevinCruijssen Experimentation :) – Embodiment of Ignorance – 2019-01-30T16:19:19.150

https://github.com/dotnet/roslyn/pull/5857 – dana – 2019-01-30T20:31:09.553

1"Command-line options are not included in the byte count of your program" [citation needed] – Peter Taylor – 2019-04-17T07:04:48.497

@PeterTaylor Added relevant link to meta – Embodiment of Ignorance – 2019-04-18T02:25:50.267

1

Use the weird kind of the is operator

a is var b always defines the variable b equal to a and returns true. It is unclear how have the humans who design C# come up with this (inline variable declarations that return true for some reason seem to be beyond Javascript to me), but it works. It can sometimes be used to shorten code (this is an oversimplified example; savings can often be smaller or zero):

a=>{var b=f(a);return g(b,b);}
a=>g(f(a)is var b?b:b,b)

my pronoun is monicareinstate

Posted 2011-01-29T06:02:23.427

Reputation: 3 111

1

Use dynamic instead of types with longer names in function declarations

For example, instead of
DateTime f(int y)=>
use
dynamic f(int y)=>

Adám

Posted 2011-01-29T06:02:23.427

Reputation: 37 779

Why wouldn't I just use var here? – jcolebrand – 2020-01-08T17:38:38.927

@jcolebrand Clarified. – Adám – 2020-01-08T17:40:11.997

1

You can use the ternary operator to shorten complex if..else constructs even if you need to work on multiple or different variables in different branches. You can sometimes save some chars by doing all or part of the work in the 3rd part of a for. ...and also other "optimizations", you can find in this example, I submitted here (it increments all numbers in a string given as char array or StringBuilder):

for (int b=3, c, i=a.Length; i-->0;
    b=48>c|c>57
        ?7
        :b>2
            ?c>56?a[i]='0':++a[i]*0
            :b
) c=a[i];

In two of the branches, b isn't really set; in two branches, a[i] is set even though it says b= in the beginning; in one case a[i] and b are set simultaneously...

c>56 is shorter than c==57

i=a.Length; i-->0; is a lot shorter than i=a.Length-1; i>=0; i--

maf-soft

Posted 2011-01-29T06:02:23.427

Reputation: 261

1

One thing I just learned (which I didn't know but probably all of you do): You do not need a namespace at all. If it is a simple program which doesn't use many namespaces that you would need to shorten, just omit the namespace and start with class Foo{....

Any objections to this or hints why I shouldn't do this are very welcome, as I'm just writing up my first "golfed" (as far as I got) answer in C# ;-)

InvisiblePanda

Posted 2011-01-29T06:02:23.427

Reputation: 131

Alternately by putting the namespace as system you can omit the common using System; declaration ... – jcolebrand – 2014-10-29T16:30:41.660

1

Convert line endings from CRLF to LF before counting bytes ☺

mirabilos

Posted 2011-01-29T06:02:23.427

Reputation: 422

3This really applies to all languages, and preprocessor directives are pretty rare in C# golf, so few programs will ever need to be on more than one line. – VisualMelon – 2015-01-03T15:42:12.493

Mh but it's still non-obvious to some people. And most other languages are more often seen on LF-only environments. I don't expect it to help much, but… why not? – mirabilos – 2015-01-03T15:43:43.887

7Most of the time, just remove newlines... – aloisdg moving to codidact.com – 2016-07-08T15:04:27.700

1

ReSharper tips

If you have used ReSharper to get to the initial working solution before golfing, note that it often generates

  • readonly variables
  • static methods, if they do not use any fields

If you have R#, you want to use the inline method refactoring for methods that are only called once, since they only need the additional method declaration.

Thomas Weller

Posted 2011-01-29T06:02:23.427

Reputation: 1 925

Or Rider, which is currently in free beta (unlike R#). – mınxomaτ – 2016-07-08T15:41:26.583

1

Remember that C# uses unicode (which includes ascii). All char are int under the hood.

For example 'a' is 97.

  • n=>char.IsDigit(n)|char.IsUpper(n)
  • n=>n>47&n<58|n>64&n<91 // note that I use a bitwise comparator see

example: Code golf to make logos for New Stack exchange sites


Since char are int, you can increment them:

  • for(int x=31;x<126;)Console.Write((char)++x);
  • for(char x=' ';x<127;)Console.Write(x++);

example: Print the ASCII printable character set

Use the unicode table for reference. Be careful one byte != one character.

aloisdg moving to codidact.com

Posted 2011-01-29T06:02:23.427

Reputation: 1 767

ints are 4 bytes, but chars are only 2. – recursive – 2019-05-21T20:06:36.350