Suppose you have numbers = {0,..,9}.
Suppose you have an input , which is a subset of digits with a capacity of at least 2.
Consider all possible pairs of as many as 10 bases a and b , so that each input element is used once in a or b and without a lead 0(the actual value 0is fine, though).
The algorithm Solvefinds the minimum value of the absolute value of the difference of all valid pairs from the input.
For example, if you enter = { 0, 1, 2, 4, 6, 7 }.
There are many possible pairs that use each digit exactly once, for example a = 210and b = 764and a = 204and b = 176.
As it turned out, the second pair has a minimum difference in absolute values ( 28).
the input will be provided to a method staticcalled Solvein the form of a string with each digit divided by one space in ascending order. You can assume that the input is valid and sorted.
Question: What is the correct C # implementation Solvehas the best execution time (without preliminary calculation / hard coding of each solution ~2^10)?
, , ( , ). , , "" , "" .):
class Program
{
static void Main(string[] args)
{
var input = "0 1 2 4 6 7";
var result = Solve(input);
}
private static int Solve(string input)
{
var digits = input.Split(' ').Select(i => int.Parse(i)).ToArray();
return GetSmallestDifference(digits) ?? -1;
}
public static int? GetSmallestDifference(IEnumerable<int> input)
{
var validInput = ValidateInput(input);
var candidates = GenerateCandidates(validInput);
int? best = null;
foreach (var candidate in candidates)
{
var current = Math.Abs(candidate.Item1 - candidate.Item2);
if (current < (best ?? int.MaxValue))
{
best = current;
}
}
return best;
}
private static IEnumerable<Tuple<int, int>> GenerateCandidates(int[] validInput)
{
var found = new HashSet<string>();
var nonZeroDigits = validInput.Except(new[] { 0 });
var max = int.Parse(string.Join("", nonZeroDigits.OrderByDescending(i => i)));
for (int i = 0; i <= max; i++)
{
var potential = i;
var complements = GetComplements(potential, validInput);
if (complements != null)
{
foreach (var complement in complements)
{
var signature = GetSignature(potential, complement);
if (!found.Contains(signature))
{
found.Add(signature);
yield return Tuple.Create(potential, complement);
}
}
}
}
}
private static string GetSignature(int potential, int complement)
{
var key = new[] { potential, complement }.OrderBy(i => i).ToArray();
var formatted = string.Format("{0} {1}", key[0], key[1]);
return formatted;
}
private static List<int> GetComplements(int potential, int[] validInput)
{
var remaining = validInput.ToList();
var digits = potential.ToString().Select(c => int.Parse(c.ToString())).ToArray();
foreach (var d in digits)
{
if (!remaining.Contains(d))
{
return null;
}
remaining.Remove(d);
}
if (remaining.Count == 0)
{
return null;
}
else
{
var complements = new List<int>();
Scramble(complements, "", remaining);
return complements;
}
}
private static void Scramble(List<int> complements, string result, IEnumerable<int> remaining)
{
if (remaining.Any())
{
foreach (var i in remaining)
{
var childResult = result + i;
var childRemaining = remaining.Except(new[] { i });
Scramble(complements, childResult, childRemaining);
}
}
else
{
if (!result.StartsWith("0") || result.Length == 1)
{
var intResult = int.Parse(result);
complements.Add(intResult);
}
}
}
private static int[] ValidateInput(IEnumerable<int> input)
{
if (input == null || input.Count() < 2)
{
throw new Exception();
}
var result = input.Distinct().ToArray();
if (result.Min() < 0 || result.Max() > 9)
{
throw new Exception();
}
return result;
}
}
( , , , , , , SO . , .)