public class Solution {
    private enum Bill {
        FIVE,
        TEN,
        TWENTY
    }

    private static Bill FromNumeric(int bill) => bill switch {
        5 => Bill.FIVE,
        10 => Bill.TEN,
        20 => Bill.TWENTY,
        _ => throw new ArgumentOutOfRangeException(nameof(bill), "Invalid bill"),
    };

    public bool LemonadeChange(int[] bills) {
        var counters = new Dictionary<Bill, int> {
            { Bill.FIVE, 0 },
            { Bill.TEN, 0 },
            { Bill.TWENTY, 0 }
        };

        foreach (var numericBill in bills) {
            var bill = FromNumeric(numericBill);
            ++counters[bill];

            switch (bill) {
                case Bill.FIVE:
                    /* no-op */
                    break;
                case Bill.TEN:
                    if (counters[Bill.FIVE] <= 0) {
                        return false;
                    }
                    --counters[Bill.FIVE];
                    break;
                case Bill.TWENTY:
                    if (counters[Bill.TEN] > 0 && counters[Bill.FIVE] > 0) {
                        --counters[Bill.FIVE];
                        --counters[Bill.TEN];
                    } else if (counters[Bill.FIVE] >= 3) {
                        counters[Bill.FIVE] -= 3;
                    } else {
                        return false;
                    }
                    break;
            }
        }

        return true;
    }
}