I'm not really a fan of making the code as short as possible, since the goal here is to make it "as understandable as possible", just like when you're writing production code in the industry. I believe interviewers would also appreciate this rather than collapsing as many instructions as possible in the same line/function.

Here's my solution using stack:

```
public class Solution {
public Dictionary<int, string> mapDigits = new Dictionary<int, string>()
{
{ 1, " One" },
{ 2, " Two" },
{ 3, " Three" },
{ 4, " Four" },
{ 5, " Five" },
{ 6, " Six" },
{ 7, " Seven" },
{ 8, " Eight" },
{ 9, " Nine" },
{ 10, " Ten" },
{ 11, " Eleven" },
{ 12, " Twelve" },
{ 13, " Thirteen" },
{ 14, " Fourteen" },
{ 15, " Fifteen" },
{ 16, " Sixteen" },
{ 17, " Seventeen" },
{ 18, " Eighteen" },
{ 19, " Nineteen" },
};
public Dictionary<int, string> mapTens = new Dictionary<int, string>()
{
{ 2, " Twenty" },
{ 3, " Thirty" },
{ 4, " Forty" },
{ 5, " Fifty" },
{ 6, " Sixty" },
{ 7, " Seventy" },
{ 8, " Eighty" },
{ 9, " Ninety" },
};
public Dictionary<int, string> mapK = new Dictionary<int, string>()
{
{ 1, "" },
{ 2, " Thousand" },
{ 3, " Million" },
{ 4, " Billion" },
{ 5, " Trillion" },
};
public string NumberToWords(int num)
{
if(num == 0)
return "Zero";
int k = 0;
Stack<int> stack = new Stack<int>();
string res = string.Empty;
while (num > 0)
{
stack.Push(num % 1000);
num /= 1000;
++k;
}
while (stack.Count > 0)
{
int currTriple = stack.Pop();
string currTripleStr = ConvertTripleToStr(currTriple);
res += currTripleStr + (String.IsNullOrEmpty(currTripleStr) ? "" : mapK[k]);
--k;
}
return res.Trim();
}
public string ConvertTripleToStr(int n)
{
string res = string.Empty;
if (n >= 100)
{
res += mapDigits[n / 100] + " Hundred";
n %= 100;
}
if (n >= 20)
{
res += mapTens[n / 10];
n %= 10;
}
if (n > 0)
{
res += mapDigits[n];
}
return res;
}
}
```