<p>Convert a non-negative integer <code>num</code> to its English words representation.</p>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>

<pre>
<strong>Input:</strong> num = 123
<strong>Output:</strong> &quot;One Hundred Twenty Three&quot;
</pre>

<p><strong class="example">Example 2:</strong></p>

<pre>
<strong>Input:</strong> num = 12345
<strong>Output:</strong> &quot;Twelve Thousand Three Hundred Forty Five&quot;
</pre>

<p><strong class="example">Example 3:</strong></p>

<pre>
<strong>Input:</strong> num = 1234567
<strong>Output:</strong> &quot;One Million Two Hundred Thirty Four Thousand Five Hundred Sixty Seven&quot;
</pre>

<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
	<li><code>0 &lt;= num &lt;= 2<sup>31</sup> - 1</code></li>
</ul>

class Solution {
public:
    string numberToWords(const int num) const {
        if(num == 0) {
            return "Zero";
        }
        std::stringstream str;

        const auto single = [&](const auto n) {
            static constexpr std::array<const char*, 10> lookup{
                "",
                "One ",
                "Two ",
                "Three ",
                "Four ",
                "Five ",
                "Six ",
                "Seven ",
                "Eight ",
                "Nine ",
            };
            str << lookup[n];
        };

        const auto tens = [&](const auto t, const auto o){
            if(t == 1) {
                static constexpr std::array<const char*, 10> lookup{
                    "Ten ",
                    "Eleven ",
                    "Twelve ",
                    "Thirteen ",
                    "Fourteen ",
                    "Fifteen ",
                    "Sixteen ",
                    "Seventeen ",
                    "Eighteen ",
                    "Nineteen ",
                };
                str << lookup[o];
            }
            else {
                static constexpr std::array<const char*, 10> lookup{
                    "",
                    "",
                    "Twenty ",
                    "Thirty ",
                    "Forty ",
                    "Fifty ",
                    "Sixty ",
                    "Seventy ",
                    "Eighty ",
                    "Ninety ",
                };
                str << lookup[t];
            }
        };

        const auto strip = [](const auto n, const auto divisor){
            const auto amt = n / divisor;
            const auto adj = amt / 1000;
            return amt - (adj * 1000);
        };

        const auto stripunit = [](const auto n){
            const auto h = n / 100;
            const auto t = abs((h*10) - (n / 10));
            const auto o = n - (h*100) - (t*10);
            return std::make_tuple(h, t, o);
        };

        constexpr auto billion = 1'000'000'000;
        if(num >= billion) {
            const auto amt = strip(num, billion);
            single(amt);
            str << "Billion ";
        }

        const auto parse = [&](const auto num, const auto divisor, const auto& prefix){
            const auto units = strip(num, divisor);
            if(units > 0) {
                const auto [h, t, o] = stripunit(units);
                if(h > 0) {
                    single(h);
                    str << "Hundred ";
                }
                if(t > 0) {
                    tens(t, o);
                }
                if((t > 1 && o > 0) || (t == 0 && o > 0)) {
                    single(o);
                }
                if(strlen(prefix) > 0) {
                    str << prefix << " ";
                }
            }
        };

        constexpr auto million = 1'000'000;
        if(num >= million) {
            parse(num, million, "Million");
        }
        constexpr auto thousand = 1'000;
        if(num >= thousand) {
            parse(num, thousand, "Thousand");
        }
        constexpr auto hundred = 1;
        if(num >= 1) {
            parse(num, hundred, "");
        }

        auto res = str.str();
        res.erase(res.size()-1);
        return res;
    }
};
8800