验证骰子组合

时间:2019-06-24 09:00:35

标签: java android algorithm validation dice

我正在Android上开发名为Thirty Throws的应用程序,但我完全陷入困境 经过我的验证。 在“三十掷”中,您得到4、5、6、7、8、9、10、11、12和6的得分。 每个回合包括3个掷骰,用户可以选择每个掷骰之间希望保留的骰子。 例如,假设用户抛出了4,4,3,5,1,5,那么他可以选择分数11,因为4 + 4 +3 = 11和5 +1 + 5 = 11或如果用户抛出了2,2 ,2他可以选择6。

我正在努力验证分数。我目前拥有的代码最多可以验证。我想念什么?

我一直在这里寻找一些递归解决方案,但是由于我必须返回一个布尔值,所以它们似乎并不是我想要的。

public static boolean isValidResult(ArrayList<Integer> score, int selectedPoints)
{
    ArrayList<Integer> notReadyNumbers = new ArrayList<>();

    for (int i: score) {
        if (i == selectedPoints) {
            continue;
        }

        if (CalcSum(notReadyNumbers) + i == selectedPoints) {
            notReadyNumbers.clear();
        } else {
            boolean isDone = false;
            if (notReadyNumbers.size() > 0) {
                for (int z: notReadyNumbers) {
                    if (z + i == selectedPoints) {
                        isDone = true;
                    }
                }
            }
            if (isDone) {
                notReadyNumbers.clear();
            } else {
                notReadyNumbers.add(i);
            }
        }
    }
    return notReadyNumbers.size() == 0 ? true : false;
}

2 个答案:

答案 0 :(得分:1)

您应该从任何位置获取所有可能的数字。因此,为了获得所有可能的结果,您可以使用这些数字的置换来对数字进行序列化。另一种方法是在递归中使用位掩码。 这是您的问题的解决方案。 (基于位掩码递归)。

public static boolean isValidResult(ArrayList<Integer> score, int selectedPoints)
{
    return canMakeValid(score, selectedPoints, 0, 0); // first 0 is for masking, second 0 is for summation.
}

public static boolean canMakeValid(ArrayList<Integer> score, int selectedPoints, int mask, int sum) 
{
    if(sum > selectedPoints) return false;
    sum %= selectedPoints;
    int sz = score.size();
    if(mask == ((1<<sz)-1)) {
        if(sum == 0) return true;
        return false;
    }
    boolean ret = false;
    for(int i = 0; i < sz; i++) {
        if((mask&(1<<i)) == 0) {
            ret = ret | canMakeValid(score, selectedPoints, mask | (1<<i), sum + score.get(i));
        }
    }
    return ret;
}

您可以通过以下链接了解位屏蔽:https://discuss.codechef.com/t/a-small-tutorial-on-bitmasking/11811/3

答案 1 :(得分:0)

实际上,有一些递归解决方案。

public static boolean isValidResult(List<Integer> score, int selectedPoints) {
    score.sort();
    return isValidResultRec(score, selectedPoints, 0);
}

/**
 * @param scoreI the first position to consider to add or not add.
 */
private static boolean isValidResultRec(List<Integer> score, int selectedPoints, int scoreI) {
    while (!score.isEmpty() && scoreI < score.size()) {
        int index = Collections.binarySearch(score, selectedPoints);
        if (index >= 0) {
           return true;
        }
        // Now ~index is the insert position;
        // i >= ~index are values > selectedPoints.
        score = score.subList(~index, score.size());
        for (int i = scoreI; i < ~index; ++i) {
            int value = score[i]; // value < selectedPoints.
            score.remove(i); // Do step.
            if (isValidResultRec(score, selectedPoints - value, scoreI + 1) {
                return true;
            }
            score.add(i, value); // Undo step.
        }
    }
    return false;
}

此处使用排序;使用降序Comparator.reversed()for --i会采取更大的步骤。

递归应添加第i th 个骰子值,也可以不添加。

这里的代码可以写得更好。