What general tips do you have for golfing in D? I'm looking for ideas that can be applied to code golf problems in general that are at least somewhat specific to D (e.g. "remove comments" is not an answer). Please post one tip per answer.
9 Answers
Look, no parens!
D's functions and template functions can be called as values, methods (won't help), and properties.
I can't believe no one has said this yet. I'll list the ones that save bytes:
fun()
andfun!()()
shorten tofun
(assuming there is no variablefun
).fun(par)
shortens topar.fun
(assumingpar
has no property/methodfun
, as well aspar
not being an expression like5+2
).fun!(T)()
shortens tofun!T
fun!(T)(par)
shortens topar.fun!T
(assumingpar
has no property/methodfun
)
And with objects:
new cls()
shortens tonew cls
(More JavaScript anyone?)obj.fun()
andobj.fun!()()
shorten toobj.fun
obj.fun!(T)()
shortens toobj.fun!T
One final thing, use old versions. It allows you to use deprecated features that shorten your code. That said, best advice: D isn't good for code-golf. It is a great language, just not for code-golf.
-
-
\$\begingroup\$ Yeah, good to know there's still fans of D here. \$\endgroup\$– AdalynnCommented Dec 27, 2016 at 22:38
D is JavaScript.
Obviously not. But, when dealing with float
, double
and real
, nan
is a value which must be handled, and, as specified by IEEE 754, NaN does not compare equal with itself.
writeln(double.nan == double.nan); // false
Meaning,
writeln(value!=value); // only true for nan
is way shorter than
import std.math;
writeln(isNaN(value));
Obviously, always use math.isNaN
for real code. ;)
D has type inference and an auto
keyword. If the object is not int
, then auto
is probably shorter.
-
\$\begingroup\$ Does
auto
work when building an associative array with theKeyType[ValueType]
syntax? \$\endgroup\$– Alex A.Commented Feb 27, 2016 at 23:30 -
\$\begingroup\$ @AlexA.
auto asd = ["a":1, "b": 2];
works, but sinceKeyType[ValueType]
would go in the place of theauto
keyword, I don't know if that will always work with types for which literals can't be constructed \$\endgroup\$– catCommented Feb 27, 2016 at 23:39 -
\$\begingroup\$ @AlexA.
auto arr = ["a": true, "b": 6];
works, the keys and values must be of compatible types \$\endgroup\$– catCommented Feb 28, 2016 at 16:43
D is great at method chaining, but:
str.toLower.strip().split("").sort();
is the same as
sort(split(strip(str.toLower),""));
and usually the non-chained one is shorter, which I just realised, which lets me shorten my answer to Manage Trash So :D
D, as a multiparadigm (Object Functional) systems programming language, seems to embrace TIMTOWTDI, or There Is More Than One Way To Do It.
Case in point, writing the program's argv:
import std.stdio, std.array, std.algorithm;
void main(string[] args) {
for(int i=0;i<args.length;writeln(args[i++])){};
foreach(a;args)writeln(a);
each!writeln(args);
}
Note the C-style for-loop requires {}
as the empty block and will not accept a semicolon or nothing as a blank statement, in this case. Usually, or
;
are no-ops.
-
\$\begingroup\$ Can you use
char*
in place ofstring
to save a byte? \$\endgroup\$– Alex A.Commented Feb 28, 2016 at 1:36 -
\$\begingroup\$ @AlexA.
function D main parameters must be main() or main(string[] args)
moreover,char
is literally one character,char*
is a pointer to literally one character andchar[]
is an array of character literals (strings are different). D != C || C++ \$\endgroup\$– catCommented Feb 28, 2016 at 1:40 -
1\$\begingroup\$ OIC. Never used D, just guessing. \$\endgroup\$– Alex A.Commented Feb 28, 2016 at 1:41
D has a few types of C#-style lambda expressions, which can be assigned and stand alone:
(int a,int b)=>a*b;
auto a=(int a,int b)=>a*b;
However, unlike C#, the signature's types are still needed because D doesn't have Haskell-level type inferencing.
-
\$\begingroup\$ Function templates for golfing the types?
T f(T)(T a,T b){return a + b}
should infer T as int inf(5);
\$\endgroup\$– fede s.Commented May 5, 2016 at 19:35 -
\$\begingroup\$ @fedes. Hello, friend! Yes, you are exactly correct (but I think/hope "untyped" lambdas will be shorter than typed function expressions). \$\endgroup\$– catCommented May 5, 2016 at 19:48
-
\$\begingroup\$ Ah, ofc! When I decide to take yet another look on D, who do I find? :D I objectively declare you have good taste on languages \$\endgroup\$– fede s.Commented May 5, 2016 at 19:52
-
\$\begingroup\$ @fedes. Aw, why thank you! :P that implies you do too (but I haven't spent enough time in front of Smalltalk, yet anyways :) ) \$\endgroup\$– catCommented May 5, 2016 at 20:01
If the question requires a full program, the module
declaration is surprisingly unnecessary.
*cough* Java, anyone? *clears throat* Actually, D's module
system is older than Java's.
Like C/C++, main
can be int
or void
, but void main(){}
will always be shorter than int main(){return my_func_returning_int;}
.
-
\$\begingroup\$ If the question ask to output an integer wouldn't
int main(){return output}
be shorter? \$\endgroup\$ Commented Feb 28, 2016 at 1:44 -
\$\begingroup\$ @dev-null if the question asks for a full program writing an integer to stdout then
import std.stdio;void main(){write(7);}
is what's needed. I doubt a question would mandate the program return a number because many languages can't set return codes \$\endgroup\$– catCommented Feb 28, 2016 at 1:45 -
\$\begingroup\$ @dev-null however, yes, in that case that it should not be written to stdout but returned, it would be shorter \$\endgroup\$– catCommented Feb 28, 2016 at 1:45
-
3\$\begingroup\$ Usually you are allowed to return / output the most convenient way for your language. But I guess D only support exit codes from 0-255? \$\endgroup\$ Commented Feb 28, 2016 at 1:48
-
\$\begingroup\$ @dev-null actually, POSIX only supports exit codes up to 255. I don't know about Windows, but on Unix / Linux an exit code over 255 wraps around, because of overflow. \$\endgroup\$– catCommented Feb 28, 2016 at 1:50
Calling a function on an object with no other arguments
reverse(x);
can nearly always be shortened to
x.reverse;
to shave a byte or more.
This is because the .
makes the LHS an implicit first argument, and templating lets us choose the right function for the args.