Again, out of fun on Saturday night, I decided to solve the following problem from CodeEval.
The challenge is finding the index of the lowest unique number.
There is a game where each player picks a number from 1 to 9, writes it on a paper and gives to a guide. A player wins if his number is the lowest unique. We may have 10-20 players in our game.
Input sample:
Your program should accept as its first argument a path to a filename.
You're a guide and you're given a set of numbers from players for the round of game. E.g. 2 rounds of the game look this way:
3 3 9 1 6 5 8 1 5 3 9 2 9 9 1 8 8 8 2 1 1
Output sample:
Print a winner's position or 0 in case there is no winner. In the first line of input sample the lowest unique number is 6. So player 5 wins.
5 0
Suppose you're given a set of numbers from players for the round of game. E.g. 2 rounds of the game look this way:
3 3 9 1 6 5 8 1 5 3 9 2 9 9 1 8 8 8 2 1 1
The output is the winner's position, or 0 in case there is no winner. In the first line of input sample the lowest unique number is 6, so player 5 wins (it was player number 5 who threw number 6). And in the second set there is no unique number, so the output will be 0.
So, the overall output will be:
5 0
I solved this problem correctly using Linq in the following code, but the performance is not that great at 255 ms for about 100 data points. Any suggestion for improving performance or perhaps another novel solution? The data have to be read from a text file in CodeEval, so my code is structured around that way.
static void Main(string[] args)
{
using (StreamReader reader = File.OpenText(args[0]))
{
while (!reader.EndOfStream)
{
var linevalue = reader.ReadLine();
if (!string.IsNullOrEmpty(linevalue))
{
var numbers = linevalue.Split(' ');
var groups = numbers.GroupBy(x => x).Select(g => new
{
number = g.Key,
freq = g.Count()
});
var nonRepeated = groups.Where(x => x.freq == 1).ToList();
if (nonRepeated.Count() != 0)
{
var singles = nonRepeated.Select(x => x.number).ToList();
var smallest = singles.Min();
var playerNumber = Array.IndexOf(numbers, smallest);
Console.WriteLine(playerNumber + 1);
}
else
{
Console.WriteLine("0");
}
}
}
}
}