Thursday, April 16, 2009

my solution to Eric Lippert's quiz

Eric posted a quiz a few days ago, it generated quite a number of responses, so I thought I would answer with the shortest possible C# answer (with my previous team we used to kinda compete on refactoring), so here it is (Justin and Paul, bring it on!):
The problem:
Write me a function that takes a non-null IEnumerable and returns a string with the following characteristics:

(1) If the sequence is empty then the resulting string is "{}".
(2) If the sequence is a single item "ABC" then the resulting string is "{ABC}".
(3) If the sequence is the two item sequence "ABC", "DEF" then the resulting string is "{ABC and DEF}".
(4) If the sequence has more than two items, say, "ABC", "DEF", "G", "H" then the resulting string is "{ABC, DEF, G and H}". (Note: no Oxford comma!)


My solution:

static string JoinStrings(IEnumerable<string> strings) {

int len = strings.Count();

return "{"+(

(len > 1) ?

strings.Take(len - 1)

.Aggregate((string head, string tail) => head+", "+tail)+

" and " +strings.Last()

: (len == 1) ?

strings.First()

: "")+

"}";

}

2 comments:

danio said...

I find the double use of the ternary operator makes the code more unreadable than it need be.

You basically have:
return "{" + (len>1 ? a : len==1 ? b : c) + "}";

For clarity I would go for:
string inside;
if (len > 1)
inside = a;
else if (len == 1)
inside = b;
return "{" + inside + "}";

Note that you can get rid of the result I labelled c from the original double ternary because it just creates "" which inside will default to.

Looking at some of the answers on Eric's blog I'm amazed at how complicated they have managed to make it. If they're doing it for efficiency reasons it seems to be a huge case of premature optimisation (There was no performance requirement in the spec).

BlackTigerX said...

I just reformatted the code to make it look more like what you proposed, except for the "if". you're right, the code is not readable, but my particular challenge was to make it as short as possible.

And I looked at the solutions people came up with and... wow!, I guess people went for additional challenges like I did (faster, smaller, uglier, etc)