2010-03-04 16 views
9

Hay un puesto de comentario en el blog de Paul codinghorror.com Jungwirth que incluye un poco de tarea de programación:¿Preguntado incorrectamente o soy estúpido?

Usted tiene los números 123456789, en ese orden. Entre cada número, debe insertar ya sea nada, un signo más o un signo de multiplicación, de modo que la expresión resultante sea igual a 2001. Escriba un programa que imprima todas las soluciones. (Hay dos.)

Aburrido, pensé, me gustaría, pero estaría condenado si puedo obtener un resultado para el año 2001. Creo que el siguiente código es correcto y creo que hay soluciones cero que resultan en 2001. Según mi código, hay dos soluciones para 2002. ¿Tengo razón o estoy equivocado?

/** 
* 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"; 
    } 
} 

Respuesta

12

Más abajo en la misma página se ha vinculado a .... =)

"Paul Jungwirth escribió:

Usted tiene los números 123456789, en ese orden Entre cada número. , debe insertar nada, un signo más , o un signo de multiplicación, por lo que que la expresión resultante es igual a 2001. Escribir un programa que imprime todas las soluciones. (Hay dos)

creo que quería decir 2002, no 2001. :)

(Sólo la corrección de cualquier otra persona como yo, que obsesivamente trata de resolver pequeños problemas "práctica" como esto uno, y después haga clic en Google cuando su resultado no coincide con la respuesta establecida. ;.) Damn, algunos de esos Perl ejemplos son feos)"

+3

Y Jungwirth confirma que quería decir 2002 algunos comentarios desde que –

+0

que es impresionante –

+2

bolas así, al menos tengo alguna práctica de revisión de código! – jah

3

El número es 2002.

solución recursiva lleva once líneas de JavaScript (excluyendo evaluación expresión de cadena, que es una función estándar de JavaScript, sin embargo, sería probablemente llevaría otros diez o más líneas de código para rodar su propia para este escenario específico):..!

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');  
Cuestiones relacionadas