Question

J'ai lu des expressions de style conditionnel en ruby. Cependant, je suis tombé sur un problème que je ne comprenais pas tout à fait pour définir le problème classique de FizzBuzz. Je comprends le problème de FizzBuzz et j’ai même écrit le mien avant de trouver la solution rapide suivante qui utilise l’opérateur ternaire. Si quelqu'un peut m'expliquer comment cette chaîne fonctionne pour résoudre le problème de FizzBuzz, ce serait très apprécié:)

for i in 0...100
  puts i%3==0 ? i%5==0 ? "FizzBuzz" : "Buzz" : i%5==0 ? "Fizz" : i
end
Était-ce utile?

La solution

Certaines parenthèses peuvent aider:

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

Ainsi, si i est divisible par 3, il vérifie également si i est également divisible par 5. Si tel est le cas, il affiche "FizzBuzz". sinon, juste "Buzz". Si i n'est pas divisible par trois, il vérifie de nouveau la divisibilité par 5 et imprime "Fizz". si oui, sinon je juste.

Autres conseils

Voici une description du problème de FizzBuzz décrit dans cet article de Jeff Atwood .

  

Ecrivez un programme qui imprime le   numéros de 1 à 100. Mais pour   multiples de trois imprimés " Fizz "   au lieu du nombre et pour le   des multiples de cinq imprimer "Buzz". Pour   nombres qui sont des multiples des deux   trois et cinq impressions "FizzBuzz".

Un opérateur ternaire est une écriture abrégée pour une instruction if-else. Le format général est:

cond ? evaluate_if_cond_is_true : evaluate_if_cond_is_false

Donc si j'écris:

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

Est équivalent au code suivant:

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

Où cond est i% 2 == 0 , evalu_if_cond_is_true est 1 et evalu_if_cond_is_false est 0 .

L’avantage des opérateurs ternaires est qu’ils peuvent être combinés. Cela signifie que l'instruction à exécuter lorsque l'une des conditions est vraie ou fausse peut être un autre opérateur ternaire.

Laissons la condition entière d'une manière plus lisible:

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

Et associer cela à des instructions if-else est facile avec les règles expliquées ci-dessus:

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

Ce n'est pas un code valide, mais comme le résultat de l'opérateur ternaire est incorporé dans l'expression du résultat, il est utilisé en tant qu'entrée pour la commande put.

Pour vous amuser, voici un autre moyen:

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

Et un autre:

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

Le ternaire est une structure de base if-then.

Ce qui précède équivaut à ...

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

Ou, en utilisant quelques parens ...

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

le flux est:

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
    }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top