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 ;)
-
\$\begingroup\$ Forgive me for the picture of a calendar, it was all I could find on short notice. \$\endgroup\$undergroundmonorail– undergroundmonorail2014年07月08日 12:44:05 +00:00Commented Jul 8, 2014 at 12:44
61 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
-
8\$\begingroup\$ This also works in JS. \$\endgroup\$Cyoce– Cyoce2016年04月05日 18:25:29 +00:00Commented Apr 5, 2016 at 18:25
-
2\$\begingroup\$ This is usually actually 5 chars if you need to use the string afterwards for including the braces...
(1+"").DoSomethingWith1String();
\$\endgroup\$TheLethalCoder– TheLethalCoder2017年05月18日 12:48:30 +00:00Commented May 18, 2017 at 12:48 -
1\$\begingroup\$ If you need the string you're usually storing it. Just about any other usage can natively infer the ToString()... \$\endgroup\$jcolebrand– jcolebrand2017年05月18日 14:38:58 +00:00Commented May 18, 2017 at 14:38
-
1\$\begingroup\$ Note that this actually calls the static
String.Concat(object)
with the argument, rather than the virtual callingobject.ToString()
.Concat
explicitly convertsnull
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). \$\endgroup\$VisualMelon– VisualMelon2017年07月11日 20:01:53 +00:00Commented Jul 11, 2017 at 20:01 -
3\$\begingroup\$ Alternative - string interpolation:
$"{n}"
\$\endgroup\$Andriy Tolstoy– Andriy Tolstoy2019年01月04日 11:24:45 +00:00Commented Jan 4, 2019 at 11:24
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;
-
10\$\begingroup\$ Just 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. \$\endgroup\$Nick Larsen– Nick Larsen2011年01月31日 14:43:19 +00:00Commented Jan 31, 2011 at 14:43 -
\$\begingroup\$ You can also just do
using System;class P...
. \$\endgroup\$ldam– ldam2015年06月05日 19:15:30 +00:00Commented Jun 5, 2015 at 19:15 -
\$\begingroup\$ @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. \$\endgroup\$Joey– Joey2015年06月05日 20:28:11 +00:00Commented Jun 5, 2015 at 20:28 -
1\$\begingroup\$ 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 thanusing static
if you need to access multiple classes. \$\endgroup\$milk– milk2016年09月01日 01:51:06 +00:00Commented Sep 1, 2016 at 1:51 -
1\$\begingroup\$ @milk: the additional
static
keyword often is longer than any savings from leaving outM.
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. \$\endgroup\$Joey– Joey2016年09月01日 05:44:59 +00:00Commented Sep 1, 2016 at 5:44
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.)
-
2\$\begingroup\$ FWITW this is called η-reduction \$\endgroup\$ThreeFx– ThreeFx2016年09月13日 11:30:23 +00:00Commented Sep 13, 2016 at 11:30
-
\$\begingroup\$ It's also known as "point free" style \$\endgroup\$Jonathan Wilson– Jonathan Wilson2017年03月02日 18:04:18 +00:00Commented Mar 2, 2017 at 18:04
-
8\$\begingroup\$ To the more pragmatic of us, it's simply shorter :-þ \$\endgroup\$Joey– Joey2017年03月03日 08:06:50 +00:00Commented Mar 3, 2017 at 8:06
-
\$\begingroup\$ Interesting! Would love to learn more. I asked a question over at softwareengineering @ThreeFx \$\endgroup\$David– David2020年06月10日 09:09:28 +00:00Commented Jun 10, 2020 at 9:09
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.
-
3\$\begingroup\$ Remember that
var
cannot have multiple declarators, for examplevar x="x",y="y";
is not possible. \$\endgroup\$Ian H.– Ian H.2017年11月22日 08:57:26 +00:00Commented Nov 22, 2017 at 8:57
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!
-
\$\begingroup\$ This does usually involve ternary as well ;) \$\endgroup\$jcolebrand– jcolebrand2011年01月31日 14:47:29 +00:00Commented Jan 31, 2011 at 14:47
-
2\$\begingroup\$
As a C# golfer, you're really competing against the language
Unbelievably related \$\endgroup\$user8397947– user83979472016年07月19日 15:07:52 +00:00Commented Jul 19, 2016 at 15:07 -
1\$\begingroup\$ Actually, that's not true. It compiles using
static int Main()
as well, which would be 28 characters. \$\endgroup\$Mika– Mika2017年02月14日 14:14:21 +00:00Commented Feb 14, 2017 at 14:14 -
2\$\begingroup\$ @Metoniem That requires a
return
something. \$\endgroup\$user202729– user2027292018年03月27日 14:54:32 +00:00Commented Mar 27, 2018 at 14:54 -
3\$\begingroup\$ Be advised that starting with C# 9 you can use top-level statements thus making the smallest compilable program exactly 0 bytes (docs.microsoft.com/en-us/dotnet/csharp/fundamentals/…) \$\endgroup\$bazzilic– bazzilic2022年02月19日 08:05:44 +00:00Commented Feb 19, 2022 at 8:05
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;
-
\$\begingroup\$ 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;
\$\endgroup\$VisualMelon– VisualMelon2017年01月13日 09:37:52 +00:00Commented Jan 13, 2017 at 9:37
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>>
-
11\$\begingroup\$ That is truly horrifying... I love it! \$\endgroup\$Alex Reinking– Alex Reinking2016年07月09日 18:19:24 +00:00Commented Jul 9, 2016 at 18:19
-
2\$\begingroup\$ holy crap this is genius, I actually just saved a character while looping an array \$\endgroup\$Gaspa79– Gaspa792017年04月09日 06:13:14 +00:00Commented Apr 9, 2017 at 6:13
-
3\$\begingroup\$ This is truly evil! \$\endgroup\$GreatAndPowerfulOz– GreatAndPowerfulOz2017年08月08日 17:17:35 +00:00Commented Aug 8, 2017 at 17:17
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
-
1\$\begingroup\$ I think you need to remove
()
from the first line. \$\endgroup\$mellamokb– mellamokb2012年04月13日 12:51:40 +00:00Commented Apr 13, 2012 at 12:51 -
1\$\begingroup\$ Can't you do
auto r=Console.ReadLine;
? \$\endgroup\$Claudiu– Claudiu2014年09月25日 16:36:19 +00:00Commented Sep 25, 2014 at 16:36 -
2\$\begingroup\$ @claudiu no, unfortunally not ideone.com/jFsVPX \$\endgroup\$Cristian Lupascu– Cristian Lupascu2014年09月25日 17:19:07 +00:00Commented Sep 25, 2014 at 17:19
-
\$\begingroup\$ @Claudiu,
auto
is aC++
verb.var
is forC#
. The reason this can't be done is becauseConsole.ReadLine
is overloaded so the function signature needs to be specified in order to tell the compiler which overload is wanted. \$\endgroup\$GreatAndPowerfulOz– GreatAndPowerfulOz2017年08月08日 17:15:20 +00:00Commented Aug 8, 2017 at 17:15 -
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;
-
17\$\begingroup\$ Am 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) \$\endgroup\$jcolebrand– jcolebrand2011年01月31日 14:31:35 +00:00Commented Jan 31, 2011 at 14:31 -
\$\begingroup\$ 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 ofj
is long. IMO, it also fails to convey side effects very well. In the case whereif (i < 1)
is something likeif (SendEmail(recipient))
which returns true/false depending on the success of the side effects, I prefer the if/then notation. \$\endgroup\$Nick Larsen– Nick Larsen2011年01月31日 15:01:59 +00:00Commented Jan 31, 2011 at 15:01 -
11\$\begingroup\$ No need for parentheses in the second case -
j=i<1?1:0;
is enough. \$\endgroup\$Danko Durbić– Danko Durbić2011年04月18日 13:28:43 +00:00Commented Apr 18, 2011 at 13:28 -
3\$\begingroup\$ The question asks for tips which are somewhat specific to C#. This is one included in the tips for all languages. \$\endgroup\$Peter Taylor– Peter Taylor2014年03月17日 20:35:17 +00:00Commented Mar 17, 2014 at 20:35
-
4\$\begingroup\$ @PeterTaylor I answered this question over 3 years ago, well before the thread you linked was created \$\endgroup\$Nellius– Nellius2014年03月18日 15:31:42 +00:00Commented Mar 18, 2014 at 15:31
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
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))
-
\$\begingroup\$ I use this trick in my answer for the Shamir's Secret Sharing challenge. \$\endgroup\$aloisdg– aloisdg2016年07月07日 20:01:11 +00:00Commented Jul 7, 2016 at 20:01
-
\$\begingroup\$ 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! \$\endgroup\$Gaspa79– Gaspa792017年04月09日 23:34:20 +00:00Commented Apr 9, 2017 at 23:34
-
\$\begingroup\$ Yes enumerables are lazy but that is true for all three examples not just the one with the string. \$\endgroup\$raggy– raggy2017年04月10日 16:39:46 +00:00Commented Apr 10, 2017 at 16:39
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.
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;}
-
3\$\begingroup\$ C#6 gives a whole new range of ability to code-golf \$\endgroup\$jcolebrand– jcolebrand2015年01月11日 23:32:40 +00:00Commented Jan 11, 2015 at 23:32
-
\$\begingroup\$ 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. \$\endgroup\$TehPers– TehPers2017年08月04日 16:38:05 +00:00Commented Aug 4, 2017 at 16:38
-
3\$\begingroup\$ That's not formally a lambda. It's an expression bodied member. \$\endgroup\$recursive– recursive2017年11月22日 22:32:13 +00:00Commented Nov 22, 2017 at 22:32
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);
}
-
\$\begingroup\$ 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. \$\endgroup\$Joey– Joey2011年03月03日 10:49:48 +00:00Commented Mar 3, 2011 at 10:49 -
\$\begingroup\$ @Joey In those cases I tend to switch to while(++i<max) which is the same length but easier to read. \$\endgroup\$ICR– ICR2011年12月07日 14:17:56 +00:00Commented Dec 7, 2011 at 14:17
-
\$\begingroup\$ ICR: depends on whether you can put another (earlier) statement into the
for
header as well, which would then save a character again. \$\endgroup\$Joey– Joey2011年12月07日 15:09:22 +00:00Commented Dec 7, 2011 at 15:09 -
\$\begingroup\$ You can move both declarations back into the for clause for a1 byte savings. \$\endgroup\$recursive– recursive2016年07月04日 03:39:08 +00:00Commented Jul 4, 2016 at 3:39
-
1\$\begingroup\$ If you won't need the variable again, you can use: while(max-->0) { foo;} \$\endgroup\$Zuabros– Zuabros2020年08月19日 20:23:40 +00:00Commented Aug 19, 2020 at 20:23
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
-
2\$\begingroup\$ And also "D d" instead of "var d" \$\endgroup\$Zukki– Zukki2015年06月04日 19:48:24 +00:00Commented Jun 4, 2015 at 19:48
-
\$\begingroup\$ @Zukki Obviously! What was I thinking? :) \$\endgroup\$Cristian Lupascu– Cristian Lupascu2015年06月05日 06:24:51 +00:00Commented Jun 5, 2015 at 6:24
-
1\$\begingroup\$ Alternative:
using D = System.Collections.Generic.Dictionary<int,string>;
\$\endgroup\$Andriy Tolstoy– Andriy Tolstoy2019年01月04日 10:58:39 +00:00Commented Jan 4, 2019 at 10:58
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);
-
13\$\begingroup\$ I never write the parentheses for one-parameter lambdas, even on production code. \$\endgroup\$R. Martinho Fernandes– R. Martinho Fernandes2011年02月02日 01:34:47 +00:00Commented Feb 2, 2011 at 1:34
-
\$\begingroup\$ I always use the brackets because I like to split the lambda into multiple lines for readability. \$\endgroup\$Juliana Peña– Juliana Peña2011年02月02日 21:02:01 +00:00Commented Feb 2, 2011 at 21:02
-
3\$\begingroup\$
SomeCall(DoSomething)
is even better \$\endgroup\$GreatAndPowerfulOz– GreatAndPowerfulOz2017年08月08日 17:18:40 +00:00Commented Aug 8, 2017 at 17:18
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
-
2\$\begingroup\$ Even shorter:
(x-y)*1d/x/y;
\$\endgroup\$recursive– recursive2019年05月21日 20:08:07 +00:00Commented May 21, 2019 at 20:08
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
.
-
2\$\begingroup\$
is GC
saves 1 byte \$\endgroup\$btnlq– btnlq2023年05月07日 11:44:15 +00:00Commented May 7, 2023 at 11:44
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()
-
6\$\begingroup\$ And always make the class one letter only :-) \$\endgroup\$Joey– Joey2011年01月29日 11:40:06 +00:00Commented Jan 29, 2011 at 11:40
-
2\$\begingroup\$ Oh, and another nice thing, implied here:
Main
does not need any arguments in contrast to Java, for example. \$\endgroup\$Joey– Joey2011年01月29日 19:10:41 +00:00Commented Jan 29, 2011 at 19:10 -
\$\begingroup\$ @Joey: and neither does it need to be public. \$\endgroup\$R. Martinho Fernandes– R. Martinho Fernandes2011年01月31日 02:36:57 +00:00Commented Jan 31, 2011 at 2:36
-
1\$\begingroup\$ @martinho ~ did you read my answer? ;) no public on main \$\endgroup\$jcolebrand– jcolebrand2011年01月31日 13:53:50 +00:00Commented Jan 31, 2011 at 13:53
-
\$\begingroup\$ @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. \$\endgroup\$jcolebrand– jcolebrand2011年01月31日 13:54:31 +00:00Commented Jan 31, 2011 at 13:54
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.
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!
-
\$\begingroup\$ One of the best tips on the page. \$\endgroup\$primo– primo2020年05月29日 17:51:44 +00:00Commented May 29, 2020 at 17:51
-
1\$\begingroup\$ With C# 7, you can sometimes save another byte with tuples:
var(a,i)=([...],[...])
. \$\endgroup\$nwellnhof– nwellnhof2020年09月30日 18:36:28 +00:00Commented Sep 30, 2020 at 18:36
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#.
-
3\$\begingroup\$ Also note that
i+$" bottles of beer";
is shorter than$"{i} bottles of beer"
. \$\endgroup\$aloisdg– aloisdg2016年07月08日 14:56:42 +00:00Commented Jul 8, 2016 at 14:56 -
1\$\begingroup\$ @aloisdg In that first case you should leave
$
out, though. \$\endgroup\$Mika– Mika2017年02月14日 14:21:39 +00:00Commented Feb 14, 2017 at 14:21 -
\$\begingroup\$ @Metoniem Indeed! I let it because in my original case I had two
{i}
one in front and one in the middle ;) \$\endgroup\$aloisdg– aloisdg2017年02月14日 14:37:38 +00:00Commented Feb 14, 2017 at 14:37 -
\$\begingroup\$ @aloisdg Ahh, I see. Yeah, shame comments can't be edited :( \$\endgroup\$Mika– Mika2017年02月14日 14:40:12 +00:00Commented Feb 14, 2017 at 14:40
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)
If you need to include multiple using
s 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
}
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",""));
}
}
}
Not very "golfy" per se, but sometimes might be useful.
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.
-
\$\begingroup\$ 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 \$\endgroup\$ASCII-only– ASCII-only2019年02月20日 03:42:46 +00:00Commented Feb 20, 2019 at 3:42
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!
-
1\$\begingroup\$ Not sure if it's anywhere else in the tips but for this example you can use currying too...
s=>c=>...
\$\endgroup\$TheLethalCoder– TheLethalCoder2017年01月09日 14:30:17 +00:00Commented Jan 9, 2017 at 14:30 -
\$\begingroup\$ @TheLethalCoder Indeed we can! I will update the answer thank you! \$\endgroup\$aloisdg– aloisdg2017年01月10日 08:43:09 +00:00Commented Jan 10, 2017 at 8:43
-
\$\begingroup\$ Can you use eta-reduction in this case? Something like this:
s=>s.Contains
. \$\endgroup\$corvus_192– corvus_1922017年01月11日 10:20:39 +00:00Commented Jan 11, 2017 at 10:20 -
\$\begingroup\$ 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)
\$\endgroup\$VisualMelon– VisualMelon2017年01月13日 09:34:31 +00:00Commented Jan 13, 2017 at 9:34 -
\$\begingroup\$ Discussion about unamed functions \$\endgroup\$aloisdg– aloisdg2017年11月24日 12:34:06 +00:00Commented Nov 24, 2017 at 12:34
Use .NET 6 Top Level Statements, File-Scoped Namespaces, and target-typed new()
Upgrade to .net 6 and you can use single file programs with no boilerplate. You can also use file-scoped namespaces like so:
namespace whatever;
Also, when you instantiate an object, if it's type can be inferred by the compiler, you can use a target-typed new()
constructor. e.g.,
class C {}
C c=new();
See (https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/tutorials/top-level-statements)
-
\$\begingroup\$ Welcome to Code Golf, and nice tip! \$\endgroup\$2022年06月14日 20:30:38 +00:00Commented Jun 14, 2022 at 20:30
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.
-
1\$\begingroup\$ ditto with variable names \$\endgroup\$Nellius– Nellius2011年01月31日 14:07:43 +00:00Commented Jan 31, 2011 at 14:07
-
13\$\begingroup\$ How is this "at least somewhat specific to C#"? \$\endgroup\$Peter Taylor– Peter Taylor2014年02月21日 17:49:12 +00:00Commented Feb 21, 2014 at 17:49
Group statements via tuples
Let's assume the simplest case: you have two statements that return a value and would like to group them into one that returns the second value (perhaps the first one has useful side effects):
(s1,o:s2).o
This can be used along with inline variable declarations via is
:
(s1 is var x,o:f(x,g(x))).o
It also works with the void -> value
transformation via is int
(although it doesn't always help):
(Print(x)is int,o:f(x)).o
-
2\$\begingroup\$
(s1 is var x,o:f(x,g(x))).o
can usually be shortened to(s1 is{}x,o:f(x,g(x))).o
now. \$\endgroup\$recursive– recursive2022年12月20日 18:40:11 +00:00Commented Dec 20, 2022 at 18:40