困难的算法:徽章平衡,数学分布

I have a quite interesting problem that's making my head twist. I'm working on a small system consisting of users and awards (called badges). There is a special badge that is awarded to users depending on the following criteria: 10 bronze badges, 5 silver badges and 1 gold badge. That is pretty simple, however, if an user has 8 bronze badges, 7 silver badges and 1 gold badge, he can use his 2 additional silver badges as bronze ones.

This happens everytime the user has available "higher" badges to distribute. Again, for example, if he has 8 bronze badges, 4 silver badges and 4 gold badges, he can "transform" 2 of his gold badges into bronze and 1 to silver, in order to earn the special badge.

I have absolutely no idea of how to do this. I've tried with various loops, ifs, but i can never distribute properly. Maybe someone can help me out?

The user needs at least 1 gold badge, at least 6 badges that are either silver or gold, and at least 16 badges that are bronze, silver or gold.

The pseudocode is

count(gold) >= 1
&& count(gold) + count(silver) >= 6
&& count(gold) + count(silver) + count(bronze) >= 16

If you also have a diamond medal that can swap for a gold, silver or bronze then include that as well, like

count(diamond) + count(gold) >= 1
&& count(diamond) + count(gold) + count(silver) >= 6
// etc

Or you could use a 'medal rank' so that you can do something simpler like

count(rank of gold or higher) >= 1
&& count(rank of silver or higher) >= 6
&& count(rank of bronze or higher) >= 16
$bank['g'] -= $price['g'];
$bank['s'] -= $price['s'];
$bank['b'] -= $price['b'];
if ($bank['b'] < 0) {
    $bank['s'] += $bank['b'];
    $bank['b'] = 0;
}
if ($bank['s'] < 0) {
    $bank['g'] += $bank['s'];
    $bank['s'] = 0;
}
if ($bank['g'] < 0) {
    //not enough cash
} else {
    //ok
}

One way would be to start with the "highest" badge, subtract the number that are required, and convert the rest to the next badge. So:

  1. Take away one gold badge.
  2. Convert all remaining gold badges to silver.
  3. Take away five silver badges.
  4. Convert all remaining silver badges to bronze.
  5. Take away 10 bronze badges.

If any of the "take away" steps fails, then they don't qualify for the badge. This is simple and it's trivial to modify it for other badge quantities or exchange rates.