错误地问或我是傻瓜?

时间:2010-03-04 23:19:09

标签: php

Paul Jungwirth对codinghorror.com发表评论,其中包括一些编程任务:

  

您的号码是123456789。在每个数字之间,您必须插入任何内容,加号或乘法符号,以便生成的表达式等于2001.编写一个打印所有解决方案的程序。 (有两个。)

无聊,我想,我有一个去,但如果我能得到2001年的结果,我会被诅咒。我认为下面的代码是合理的,我认为2001年会有零解决方案。根据我的代码,2002年有两种解决方案。我是对还是错了?

/**
 * Take the numbers 123456789 and form expressions by inserting one of ''
 * (empty string), '+' or '*' between each number.
 * Find (2) solutions such that the expression evaluates to the number 2001
 */

$input = array(1,2,3,4,5,6,7,8,9);

// an array of strings representing 8 digit, base 3 numbers
$ops = array();
$numOps = sizeof($input)-1; // always 8
$mask = str_repeat('0', $numOps); // mask of 8 zeros for padding

// generate the ops array
$limit = pow(3, $numOps) -1;
for ($i = 0; $i <= $limit; $i++) {
    $s = (string) $i;
    $s = base_convert($s, 10, 3);
    $ops[] = substr($mask, 0, $numOps - strlen($s)) . $s;
}

// for each element in the ops array, generate an expression by inserting
// '', '*' or '+' between the numbers in $input.  e.g. element 11111111 will
// result in 1+2+3+4+5+6+7+8+9
$limit = sizeof($ops);
$stringResult = null;
$numericResult = null;
for ($i = 0; $i < $limit; $i++) {
    $l = $numOps;
    $stringResult = '';
    $numericResult = 0;
    for ($j = 0; $j <= $l; $j++) {
        $stringResult .= (string) $input[$j];
        switch (substr($ops[$i], $j, 1)) {
            case '0':
                break;
            case '1':
                $stringResult .= '+';
                break;
            case '2':
                $stringResult .= '*';
                break;
            default :
        }
    }

    // evaluate the expression

    // split the expression into smaller ones to be added together
    $temp = explode('+', $stringResult);
    $additionElems = array();
    foreach ($temp as $subExpressions)
    {
        // split each of those into ones to be multiplied together
        $multplicationElems = explode('*', $subExpressions);
        $working = 1;
        foreach ($multplicationElems as $operand) {
            $working *= $operand;
        }
        $additionElems[] = $working;
    }
    $numericResult = 0;
    foreach($additionElems as $operand)
    {
        $numericResult += $operand;
    }

    if ($numericResult == 2001) {
        echo "{$stringResult}\n";
    }
}

2 个答案:

答案 0 :(得分:12)

再往下链接到.... =)

的同一页面
  

“Paul Jungwirth写道:

     

你的号码是123456789,in   那个命令。在每个号码之间,你   必须插入任何东西,加号   标志,或乘法标志,所以   结果表达式等于   2001.编写一个打印所有解决方案的程序。 (有两个。)

     

我认为你的意思是2002年,而不是2001年。:)

     

(正好纠正其他人喜欢   我痴迷地试图解决   像这样的小“练习”问题   一,然后打谷歌时他们的   结果与陈述不符   回答。 ;)该死的,其中一些是Perl   例子很难看。)“

答案 1 :(得分:3)

这个数字是2002年。

递归解决方案需要11行JavaScript(不包括字符串表达式评估,这是一个标准的JavaScript函数,但是对于这个特定的场景,它可能需要另外十行代码来自行编写):

function combine (digit,exp) {                    
     if (digit > 9) {                             
        if (eval(exp) == 2002) alert(exp+'=2002');
        return;                                   
     }                                            
     combine(digit+1,exp+'+'+digit);              
     combine(digit+1,exp+'*'+digit);              
     combine(digit+1,exp+digit);                  
     return;                                      
}                                                 
combine(2,'1');