Pergunta

Out of curiosity, I wrote a program that calculates different number of combinations of Ski Ball roles that produce a certain score. The holes have values [0,10,20,30,40,50,100] that are held as enumerated values. There are also nine ball rolls. I treated each roll as recursively calling the next roll while looping through the values of each roll:

private static void scoreCalc(int targetScore, int score, int ballNumber)
{
    for(SkiBallHoles hole : SkiBallHoles.values())
    {
        score += hole.getValue();
        ballNumber--;
        if (ballNumber > 0) {
            scoreCalc(targetScore, score, ballNumber);
        }
        if (ballNumber == 0 && score == targetScore) {
            frequency++;
        }
        ballNumber++;
        score -= hole.getValue();
    }
}

The scores themselves are fed to this function from a for loop in the main function into a chain of set up functions:

while(score <= 900){
    writer.println(calculateFrequency(score));
    score += 10;
}

private static String calculateFrequency(int targetScore)
{
    frequency = 0;
    scoreCalc(targetScore);
    return targetScore + ": " + frequency;
}

private static void scoreCalc(int targetScore)
{
     scoreCalc(targetScore, 0, BALLCOUNT);
}

The problem with this approach, is that is does not count the number of unique solutions. i.e. 0 0 0 0 0 0 0 0 10 is counted as different from 10 0 0 0 0 0 0 0 0 while they are really the same combination of values to produce a score.

How can I modify my approach to only count unique solutions?

Thanks =)

Foi útil?

Solução 2

Thank you @omer681, you pointed me in the right direction.

My fix involved changing the Hole values from enums to ints in an array. Then, the in recursion, an 'itter' int was passed where the for loop would start. In recursion, this number was inherited from the for loop. This way, each step in a for loop would limit the number of steps in the loops below. This works for any number of balls and score holes.

    private static void scoreCalc(int targetScore, int score, int ballNumber,
    int itter)
{
    for(int i = itter; i < HOLEVALUES.length; i++)
    {
     ...
     if (ballNumber > 0) {
         scoreCalc(targetScore, score, ballNumber, i);
     ...
    }
}

private static void scoreCalc(int targetScore)
{
    scoreCalc(targetScore, 0, BALLCOUNT, 0);
}

Outras dicas

By sorting the holes by value you can iterate only over the sorted solutions (0 0 0 0 0 0 0 0 10, 0 0 0 0 0 0 0 10 20, etc).

Does your solution iterate over different permutations of the same holes? (i.e. iterates twice for 0 0) If so, you can just divide the result by n!. However this approach will be slower.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top