Calculating optimal video capture card configuration based on channels needed I have to calculate the configuration of hardware that uses the least number of capture cards based on the number of channels desired. The cards are available in 4, 8, and 16 channel varieties.

It's important to note that the least number of cards is the first priority, and the second priority is using the cheaper (lower channel) cards when possible. Therefore, a 22-channel request could be filled with 2 16-channel cards, however using a 16 and an 8-channel card is more desirable as it uses the same number of physical cards while utilizing a cheaper 8-channel card instead of two 16-channels.

var card_16 = "US-HDVRC2-16-480D";
var card_8 = "US-HDVRC2-8-240D";
var card_4 = "US-HDVRC2-4-120D";

function getCardObject(channels) {
    var cards = {}
    var remainder = channels%16;
    if (channels/16 &gt;= 1) //if there are at least 16 channels
    {
        cards[card_16] = Math.floor(channels/16);
        if (remainder != 0)
        {
            if (remainder &gt; 8)
                cards[card_16] = cards[card_16] + 1;
            else if (remainder &gt; 4)
                cards[card_8] = 1;
            else
                cards[card_4] = 1;
        }
    }
    else if (channels/8 &gt;= 1)  { //if there aren't 16 but at least 8
        if (remainder != 0)
        {
            if (remainder &gt; 8)
                cards[card_16] = 1;
            else if (remainder &gt; 4)
                cards[card_8] = 1;
            else
                cards[card_4] = 1;
        }
    }
    else if (channels/4 &gt;= 1) { //if there are at least 4
        if (remainder != 0)
        {
            if (remainder &gt; 4)
                cards[card_8] = 1;
            else
                cards[card_4] = 1;
        }
    }
    else //if there are less than 4
        cards[card_4] = 1;
    return cards;
};
Your own answer is pretty good.  I would tighten it up a bit.  In particular,


It's not immediately clear, based on the variable name, what answer represents.  Furthermore, since you are only interested in Math.floor(channels/16), I would compute it in a more succinct and efficient way: var sixteens = channels &gt;&gt; 4;.
I don't like reassigning cards["US-HDVRC2-16-480D"] or recomputing remainder &gt; 8.
To cast a boolean as 1 or 0, you can use the unary + operator.
Consider creating the cards object in a single statement.  That means you may get some members whose value is 0 — I don't know if that is acceptable to you.




function getCardObject(channels) {
    var sixteens = channels &gt;&gt; 4;   // Math.floor(channels / 16)
    var remainder = channels &amp; 15;  // channels % 16
    return {
        "US-HDVRC2-16-480D": sixteens + (8 &lt; remainder),
        "US-HDVRC2-8-240D": +(4 &lt; remainder &amp;&amp; remainder &lt;= 8),
        "US-HDVRC2-4-120D": +(0 &lt; remainder &amp;&amp; remainder &lt;= 4),
    };
}




For comparison, here's a single-expression version using explicit formulas for everything.  I don't think that it is better than what you have — it's certainly not easy to understand.

function getCardObject(channels) {
    return {
        // Use a 4-channel card if  1 &lt;= (channels % 16) &lt;= 4
        'US-HDVRC2-4-120D':  +(((channels - 1) &amp; 15) &lt;  4),

        // Use an 8-channel card if  5 &lt;= (channels % 16) &lt;= 8
        'US-HDVRC2-8-240D':  +(((channels - 1) &amp; 12) == 4),

        // 16-channel cards for the rest
        'US-HDVRC2-16-480D': (channels &gt;&gt; 4) + ((channels &amp; 15) &gt; 8),
    };
}