2008-10-22 36 views
8

He estado leyendo sobre las expresiones de estilo condicional en ruby. Sin embargo, encontré uno que no pude entender para definir el clásico problema de FizzBuzz. Entiendo el problema de FizzBuzz e incluso escribí el mío antes de encontrar la siguiente solución rápida utilizando el operador ternario. Si alguien puede explicarme cómo funciona esta cadena para satisfacer el problema FizzBuzz sería muy apreciada :)FizzBuzz usando el operador condicional ternario

for i in 0...100 
    puts i%3==0 ? i%5==0 ? "FizzBuzz" : "Buzz" : i%5==0 ? "Fizz" : i 
end 

Respuesta

16

Algunos paréntesis podrían ayudar:

puts (i%3 == 0) ? ((i%5 == 0) ? "FizzBuzz" : "Buzz") : ((i%5 == 0) ? "Fizz" : i) 

lo tanto, si i es divisible por 3 , luego verifica si también puedo dividirlo entre 5. Si es así, imprime "FizzBuzz" o simplemente "Buzz". Si no soy divisible por tres, entonces verifica la divisibilidad por 5 nuevamente e imprime "Fizz" si es así, de lo contrario solo yo.

+0

Muchas gracias - el paréntesis y su explicación se ha resuelto este problema – Damian

1

el flujo es:

if (i%3 == 0) {    // multiple of 3 
    if (i%5 == 0) {   // multiple of 3 and 5 
     puts "FizzBuzz" 
    } else {     // not multiple of 5, only of 3 
     puts "Buzz" 
    } 
} else (     // not multiple of 3 
    if (i%5 == 0) {   // multiple of 5, not of 3 
     puts "Fizz" 
    } else {     // multiple of neither 5 nor 3 
     puts i 
    } 
} 
3

El ternario es una estructura básica if-then.

Lo anterior es equivalente a ...

if i%3 ==0 
    if i%5 == 0 
     "FizzBuzz" 
    else 
     "Buzz" 
else 
    if i%5 == 0 
     "Fizz" 
    else 
     i 

O, usando algunos parens ...

puts i%3==0 ? (i%5==0 ? "FizzBuzz" : "Buzz") : (i%5==0 ? "Fizz" : i) 
+1

leer ese código sin paréntesis me está haciendo tic . – nickf

+0

Lo siento. Solo estaba siendo flojo. –

+0

Imagina que es un pseudocódigo. ;-) – Wickethewok

11

Aquí se presenta una descripción del problema FizzBuzz como se indica en este Jeff Atwood article.

escribir un programa que imprime los números del 1 al 100. Pero para múltiplos de tres impresión "Fizz" en lugar del número y de los múltiplos de cinco de impresión "zumbido". Para números que son múltiplos de tres y cinco imprimen "FizzBuzz".

A ternary operator es una escritura abreviada para una instrucción if-else. El formato general es:

 
cond ? evaluate_if_cond_is_true : evaluate_if_cond_is_false 

Así que si escribo:

int isEven = (i % 2 == 0) ? 1 : 0; 

es equivalente al siguiente código:

if (i % 2 == 0) { 
    isEven = 1; 
} else { 
    isEven = 0; 
} 

Dónde cond es i % 2 == 0, evaluate_if_cond_is_true es 1 y evaluate_if_cond_is_false es 0 .

Lo bueno de los operadores ternarios es que se pueden combinar. Esto significa que la instrucción para ejecutar cuando cualquiera de las condiciones se evalúa como verdadera o falsa puede ser otro operador ternario.

Let puso toda la condición de una forma más legible:

i%3==0 ? 
    i%5==0 ? 
     "FizzBuzz" 
     : "Buzz" 
    : i%5==0 ? 
     "Fizz" 
     : i 

y cartografía sobre esto a las declaraciones si-si no es fácil con las normas explicado anteriormente:

if (i%3==0) { 
    if (i%5==0) { 
     "FizzBuzz" 
    } else { 
     "Buzz" 
    } 
} else { 
    if (i%5==0) { 
     "Fizz" 
    } else { 
     i 
    } 
} 

Esto no es un código válido pero como el resultado del operador ternario está subrayado en la expresión de resultado, se usa como entrada para el comando puts.

7

Para la diversión, aquí está otra manera:

puts (1..100).map {|i| (fb = [["Fizz"][i%3],["Buzz"][i%5]].compact.join).empty? ? i : fb} 

Y otro:

(1..100).zip([nil,nil,"Fizz"]*34,[nil,nil,nil,nil,"Buzz"]*20).map {|a,b,c| b || c ? [b,c].join : a} 
+1

Esto está mal. La especificación establece que solo debe imprimir el número si no imprime fizz o zumbido. – mxcl

+0

Ah, es verdad. –

Cuestiones relacionadas