I am in the middle of an interview process with a company I am very excited about. The position is for a Junior Developer for C# applications. I have a year of experience at my current position as well as a year of co-op placements while in school. I have made it to the final interview. For one part of the process I had to submit a program based on the following requirements:
Please write a program that generates a list of 10,000 numbers in random order each time it is run. Each number in the list must be unique and be between 1 and 10,000 (inclusive).
The HR manager let me know that in the final interview developers would be asking me questions related to the program that I submitted.
Here is the program I submitted:
public static class Program
{
private static Random random = new Random();
/// <summary>
/// Shuffles a list of generic objects randomly using the Fisher-Yates algorithm.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="list"></param>
public static void Randomize<T>(this IList<T> list)
{
int size = list.Count;
while (size > 1)
{
size--;
int index = random.Next(size + 1);
T value = list[index];
list[index] = list[size];
list[size] = value;
}
}
/// <summary>
/// Asserts uniqueness of a generic list.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="list"></param>
/// <returns></returns>
public static bool TestUnique<T>(IList<T> list)
{
return list.Distinct().Count() == list.Count();
}
/// <summary>
/// Asserts that a generic list size equals an expected size.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="list"></param>
/// <param name="count"></param>
/// <returns></returns>
public static bool TestCount<T>(IList<T> list, int count)
{
return list.Count == count;
}
/// <summary>
/// Asserts that the original list is in a different order.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="original"></param>
/// <param name="randomized"></param>
/// <returns></returns>
public static bool TestOrder<T>(IList<T> original, IList<T> randomized)
{
return original != randomized;
}
static void Main(string[] args)
{
// User starting sequence.
Console.WriteLine("Welcome to Shuffle. This program is written to randomly shuffle a list.");
Console.WriteLine("To test, lets shuffle some numbers. Please enter a range of integers you wish to shuffle (Example: 1 - 10000)");
int min, max;
bool proceed = true;
string response;
do
{
do
{
// Range is not valid.
if (!proceed)
{
Console.WriteLine("Invalid range. Please make sure the minimum integer is greater than the maximum integer.");
}
// Get the minimum range value.
Console.Write("\nPlease enter the minimum integer: ");
// Check if input is an integer.
while (!int.TryParse(Console.ReadLine(), out min))
{
Console.Write("Invalid input. We are only testing for integers at the moment. Please enter a valid minimum integer: ");
}
// Get the minimum range value.
Console.Write("Please enter the maximum integer: ");
// Check if input is an integer
while (!int.TryParse(Console.ReadLine(), out max))
{
Console.Write("Invalid input. We are only testing for integers at the moment. Please enter a valid maximum integer: ");
}
// Check if range is valid.
proceed = (min < max) ? true : false;
} while (!proceed);
Console.WriteLine("Testing shuffle for a range of {0} to {1}...\n", min, max);
// Create a list.
List<int> numbers = new List<int>(Enumerable.Range(min, max));
// Assert list size.
Debug.Assert(TestCount<int>(numbers, (max - min + 1)));
// Assert uniqueness.
Debug.Assert(TestUnique<int>(numbers));
#if DEBUG
// Copy original list of numbers only in debug mode.
List<int> originalNumbers = new List<int>(numbers);
#endif
// Randomize the list.
numbers.Randomize();
// Re-assert uniqueness.
Debug.Assert(TestUnique<int>(numbers));
// Assert random order.
Debug.Assert(TestOrder(originalNumbers, numbers));
// Output the list.
numbers.ForEach(num => Console.Write("[{0}], ", num));
// User input to re-run test.
Console.Write("\n\nWould you like to run another test? (y|n): ");
response = Console.ReadLine();
while(response.ToLower() != "y" && response.ToLower() != "n")
{
Console.Write("Invalid response. Please use 'y' or 'n'. Would you like to run another test? ");
response = Console.ReadLine();
}
} while (response == "y");
}
}
I was wondering if anyone could critique my program and submit questions that they may ask me in regards to it. I am not looking for the answers, I just want to be prepared for some questions they may ask me.
Some of the things I could think of would be to improve the user interface. Integrate with a logging library like log4net.
Thanks for your time and any suggestions or submissions would be greatly appreciated.
size + 1
, then for the first iteration, there is the remote possibility of retrieving value at list[10000]. This kind of bug is evil because it fails only once every so often. ;) \$\endgroup\$