Javascript Brainteaser - 反向数字确定

时间:2011-05-08 03:46:17

标签: javascript

假设我有以下表格中的数字列表(忽略|他们在那里形成帮助。)

00|00|xx
00|xx|00
xx|00|00
etc.

规则: XX可以是1到50之间的任何数字。没有XX值可以相同。

现在,我从符合上述格式的列表中选择一组随机数字(无重复项),并随机添加和减去它们。例如

000011 - 002400 - 230000 = -232389

如何确定原始数字以及是否仅从 -232389 添加或减去这些数字?我很难过。

谢谢!

修改 我正在寻找一个功能所以我最终不得不做一个。它只是一个概念证明函数,因此变量名称是丑陋的http://jsfiddle.net/jPW8A/

以下实现中存在错误,并且无法在十几个方案中工作。检查下面的选定答案。

function reverse_add_subtract(num){
    var nums = [];

    while(num != 0){
        var str = num.toString(),
            L = Math.abs(num).toString().length,
            MA = str.match(/^(-?[0-9]?[0-9])([0-9][0-9])([0-9][0-9])*$/);
        if(MA){
            var num1 = MA[1],
                num2 = MA[2];
        }else{
            var num1 = num,
                num2 = 0;
        }
        if(L%2)L++;
        if( num2 > 50){
            if(num < 0) num1--;
            else num1++;
        }
        nums.push(num1);
        var add = parseInt(num1 + Array(--L).join(0),10);
        num = (num-add);
    }
    return nums;
}
reverse_add_subtract(-122436);

3 个答案:

答案 0 :(得分:1)

首先,你的数学错了。您的前导零将前两个数字转换为八进制数。如果这是意图,这篇文章的其余部分并不完全适用,但可以进行调整。

11-2400-230000 = -232389

现在最后一个数字很简单,在这种情况下,它始终是前两位数,23。删除:

-232389 + 230000 = -2389

您的第二个号码是下面的100,在这种情况下是-2400。你的最终号码很简单:

-2389 + 2400 = 11

答案 1 :(得分:1)

首先请注意,每个xx组都受到[1,50]的约束。这意味着数量中[50,99]范围内的每个关联对实际上都是100 - xx,这意味着它“从”向左“借”。 (这也意味着只有一组标准化数字和一个解决方案,如果有的话。)

所以给定输入23|23|89(来自xx的初始-232389点),将其标准化 - 即,从右边开始,如果值>> 50,获得100 - 价值并向右移动100(必须平衡)。示例:(23 * 100) + 89 = 2300 * 89 = 2400 - 11 = 2389。并且示例表明,如果它是唯一改变的东西是负面的并不重要:(-23 * 100) - 89 = -2300 - 89 = -2400 + 11 = -2389

(注意:请记住,在23组中添加1以使其成为24:在此步骤中实际上未考虑组的符号,数学只是为了显示它的示例好的!可以使用此步骤来确定符号并避免下面的额外数学,但此解决方案只是尝试在此步骤中找到候选数字。如果在此步骤之后有数字组的重复,那么那里没有解决方案;否则存在解决方案。)

归一化后的候选数字是23|24|11(假设这是aa|bb|cc,如下所示)。现在已知所有xx值,只需查找e * (aa * 10000) + f * (bb * 100) + g * (cc * 1) = -232389组合即可。值aabbcc从上面已知,efg将为1或-1,分别


解决方案警告:在水平分隔符下方提供了一种在给定确定数字(上面确定)的情况下找到加法或减法的方法。在决定是否需要额外的“提示”之前,请休息并反思上述部分。


然后可以通过利用所有xx组在归一化之后不依赖的事实来解决这个问题。 (在每一步,尝试使下一步的输入数接近零。)

示例:

  1. -232389 + (23 * 10000) = -2389e为-1,因为它撤消了我们刚才所做的+

  2. -2389 + (24 * 100) = 11(同样,f为-1)

  3. 11 - (11 * 1) = 0(0 =胜利!g为1,解决方案为(-1 * 23 * 10000) + (-1 * 24 * 100) + (1 * 11 * 1) = -232389

  4. 快乐的家庭工作。

答案 2 :(得分:0)

噢!有人发布了一个答案,说“蛮力”,我正要回应:

function find(num){for(var i=1;i<50;i++){for(var o1=0;o1<2;o1++){for(var j=1;j<50;j++){for(var o2=0;o2<2;o2++){for(var k=1;k<50;k++){var eq;if(eval(eq=(i+(o1?'+':'-')+j+'00'+(o2?'+':'-')+k+'0000'))==num){ return eq; }}}}}}}

他们删除了它...... :(

它会在评论中出现,但这里的格式更清晰:

function find(num){
    for(var i=1;i<50;i++){
        for(var o1=0;o1<2;o1++){
            for(var j=1;j<50;j++){
                for(var o2=0;o2<2;o2++){
                    for(var k=1;k<50;k++){
                        var eq;
                        if(eval(eq=(i+(o1?'+':'-')+j+'00'+(o2?'+':'-')+k+'0000'))==num){ return eq; }
                    }
                }
            }
        }
    }
}