I wrote a terrible function to map E.161 keys to letter strings.
I think the logic could be simplified using a recursive function; however I have never been good at recursive methods. Any suggestions are welcomed.
My Code:
#LINQPad optimize+
void Main()
{
var summary = BenchmarkRunner.Run<MyClass>();
summary.Dump();
}
public class MyClass
{
[Params("2", "24", "247", "2474", "24747")]
public string DTMF_Input { get; set; }
List<char> DTMFtoString(char c)
{
return c switch
{
'2' => new List<char>() { 'A', 'B', 'C' },
'3' => new List<char>() { 'D', 'E', 'F' },
'4' => new List<char>() { 'G', 'H', 'I' },
'5' => new List<char>() { 'J', 'K', 'L' },
'6' => new List<char>() { 'M', 'N', 'O' },
'7' => new List<char>() { 'P', 'Q', 'R', 'S' },
'8' => new List<char>() { 'T', 'U', 'V' },
'9' => new List<char>() { 'W', 'X', 'Y', 'Z' },
_ => throw new ArgumentOutOfRangeException($"The specified character '{c}' is not supported."),
};
}
[Benchmark]
public void GetCombosFromDTMF()
{
var Tones = new System.Collections.Generic.Stack<char>(DTMF_Input.ToCharArray().Reverse());
var MyPrefixes = new List<string>();
while (Tones.Any())
{
var Combos = new List<string>();
var entries = DTMFtoString(Tones.Pop());
if (MyPrefixes.Any())
{
foreach (var existing in MyPrefixes)
{
foreach (var newTone in entries)
{
Combos.Add(existing + newTone);
}
}
}
else
{
Combos = entries.Select(c => Char.ToString(c)).ToList();
}
MyPrefixes = Combos;
}
MyPrefixes.OrderBy(r => r).ToList();
}
}
Benchmarks
| Method | DTMF_Input | Mean | Error | StdDev |
|------------------ |----------- |-------------:|------------:|------------:|
| GetCombosFromDTMF | 2 | 671.0 ns | 11.26 ns | 10.54 ns |
| GetCombosFromDTMF | 24 | 1,537.1 ns | 25.25 ns | 21.09 ns |
| GetCombosFromDTMF | 247 | 8,690.2 ns | 160.62 ns | 134.12 ns |
| GetCombosFromDTMF | 2474 | 30,870.3 ns | 557.15 ns | 762.63 ns |
| GetCombosFromDTMF | 24747 | 168,660.9 ns | 3,008.75 ns | 3,344.22 ns |