Reputation: 1
I recently took a Codility test and the question was to find the first unique number in a numeric sequence. Although I get the correct result using LINQ, it is apparently too expensive computationally and not scalable enough.
How would I improve my solution?
var a = new int[] {1, 2, -3, 4, 5, -6, 0, 8, 9, 1, 2};
const int expected = -3;
var retVal = -1;
var y = a.GroupBy(z => z).Where(z => z.Count() == 1).Select(z => z.Key).ToList();
if (y.Count > 0) retVal = y[0];
Console.Write(retVal==expected);
Upvotes: 0
Views: 1838
Reputation: 1
I decided to test the various answers posted above and count the number of ticks using the StopWatch class.
Changing y.Count > 0 to y.Any() resulted in the second lowest tick count, but the largest reduction belongs to the group by comment from Baldrick
To get the average each test was run 50 times.
Ticks
Min Max Avg Actual
2 14502 584 -3 Original
2 919 40 -3 if (y.Any()) actual = y[0];
2 1423 60 -3 a.GroupBy(g => g).Where(w => w.Count() == 1)
.Select(s => s.Key)
.FirstOrDefault();
2 1553 65 -3 a.ToLookup(i => i).First(i => i.Count() == 1).Key;
2 317 15 -3 a.GroupBy(i => i).First(i => i.Count() == 1).Key;
Upvotes: 0
Reputation: 1864
try this
var result = a.GroupBy(g => g).Where(w => w.Count() == 1).Select(s => s.Key).FirstOrDefault();
Upvotes: 0
Reputation: 11840
How about this:
var result = a.ToLookup(i => i).First(i => i.Count() == 1).Key;
This should give -3.
It builds a Lookup
object with a key created using each number in the list, and a value of the same number.
In the case of duplicates, then multiple entries are created under each key. The first unique value will be the first group in the Lookup
with one entry.
(You could just as easily use GroupBy
, instead of ToLookup
. The end result will be the same.)
Upvotes: 1