什么测试用例会失败?谷歌foo.bar挑战bomb_baby

时间:2016-10-11 10:49:38

标签: java

所以只是为了好玩,我正在尝试一些谷歌foo.bar的挑战,而这是我坚持的一个。

有5个未公开的测试用例,我失败了2个。测试案例3和5。

有人能弄清楚我的代码是如何不符合任务要求的吗?

炸弹,宝贝!

有两种类型的炸弹:马赫炸弹(M)和法图拉炸弹(F)

炸弹通过以下两种方式之一进行自我复制: 对于每一枚马赫炸弹,都会制造一枚Facula炸弹; 或者每个Facula炸弹都会产生一个马赫炸弹。

E.g。 3枚马赫炸弹和2枚Facula炸弹可生产3枚马赫炸弹和5枚Facula炸弹,或5枚马赫炸弹和2枚Facula炸弹。每个周期都可以更改复制过程。

你从1马赫和1个法特拉炸弹开始。

写一个函数答案(M,F),其中M和F是所需的Mach和Facula炸弹的数量。返回需要通过的最少代数(作为字符串),直到达到所需目标,或字符串"不可能"如果不能这样做的话! M和F将是正整数的字符串表示,不大于10 ^ 50。

实施例

输入:     (字符串)M =" 2"     (字符串)F =" 1" 输出:     (字符串)" 1"

输入:     (字符串)M =" 4"     (字符串)F =" 7" 输出:     (字符串)" 4"

输入:     (字符串)M =" 2"     (字符串)F =" 4" 输出:     (字符串)"不可能"

import java.util.Arrays;

public class Main {

public static void main(String [] args)
{
    System.out.println("Input: " + Arrays.toString(args));
    System.out.println(answer(args[0], args[1]));
}

public static String answer(String M, String F) {

    try {
        long numM = Long.parseLong(M);
        long numF = Long.parseLong(F);

        String output = "impossible";
        long count = 0;
        while (numM > 1 || numF > 1) {

            if (!checkIsValid(numM, numF)) {
                numM = numF = 0;
            }
            else if (numM > numF) {
                numM -= numF;
                count++;
            }
            else if (numF > numM) {
                numF -= numM;
                count++;
            }

            //System.out.println("cycle: " + count + " " + numM + " " + numF);
        }

        if (numM == 1 && numF == 1) {
            output = ""+count;
        }

        return output;
    }
    catch (NumberFormatException nfe) {
        return "impossible";
    }
}

protected static boolean checkIsValid(long numM, long numF) {
    boolean valid = true;
    if (numM % 2 == 0 && numF % 2 == 0) {
        valid = false;
    }
    else if (numM == numF) {
        valid = false;
    }
    else if (numM <= 0 || numF <= 0) {
        valid = false;
    }
    else if (numM > 1 && numF % numM == 0) {
        valid = false;
    }
    else if (numF > 1 && numM % numF == 0) {
        valid = false;
    }

    return valid;
}
}

2 个答案:

答案 0 :(得分:0)

这里还有一些手工优化的范围。

看两个减法循环。在长格式伪代码中,它们可以展开为:

if numM > numF: 
  difference = numM - numF 
  multiplier = (difference / numF) + 1 // note that this is an integer division or floor
  counter += multiplier 
  numM = numM - (multiplier * numF)

显然,您必须处理numF == 1的特殊情况以防止下溢。

在我的小测试中,计数器值= 1000,这使执行时间缩短了一半以上。

答案 1 :(得分:0)

我不做Java,但我得到了适用于Python的解决方案。如果你愿意,可以随意看看。 (它通过了所有测试用例,尽管有一些特殊情况会使算法运行不尽管,但答案仍然正确)

导入副本

def answer(M,F):     M = int(M)     F = int(F)

cycles = 0

if M > F:
    maxi = M
    mini = F
else:
    maxi = F
    mini = M

while (maxi != 1 or mini != 1) and (maxi > 0 and mini > 0):

    if mini > maxi:
        hold = copy.deepcopy(maxi)
        maxi = mini
        mini = hold

    magic_number = maxi % mini

    if magic_number == 0 or magic_number == mini:
        if maxi == 1 and mini == 1:
            return str(cycles)
        else:
            maxi -= mini
            cycles += 1
    else:
        cycles += int((maxi - magic_number) / mini)
        maxi = magic_number

    print(maxi, mini)

if maxi == 0 or mini == 0:
    return 'impossible'
else:
    return str(cycles)