FizzBuzz, используя тернарный условный оператор

Я читал о выражениях условного стиля в ruby. Однако я наткнулся на один, который я не мог понять, чтобы определить классическую проблему FizzBuzz. Я понимаю проблему FizzBuzz и даже написал свой собственный, прежде чем найти следующее быстрое решение с использованием тернарного оператора. Если кто-то может объяснить мне, как эта цепочка работает, чтобы удовлетворить проблему FizzBuzz, это было бы очень оценено :)

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

5 ответов


некоторые скобки могут помочь:

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

Итак, если i делится на 3, то он проверяет, делится ли i также на 5. Если это так, он печатает "FizzBuzz", иначе просто "Buzz". Если i не делится на три, то он снова проверяет делимость на 5 и печатает "Fizz", если это так, иначе просто i.


Вот описание проблемы FizzBuzz, как указано в этой Джефф Этвуд статьи.

напишите программу, которая печатает числа от 1 до 100. Но для кратные три печати " Fizz" вместо номера и кратные пять печати "Buzz". Для числа, кратные обоим три и пять печатают "FizzBuzz".

A тернарный оператор стенография для if-else заявление. Общий формат:

cond ? evaluate_if_cond_is_true : evaluate_if_cond_is_false

Итак, если я напишу:

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

эквивалентно следующему коду:

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

где cond i % 2 == 0, evaluate_if_cond_is_true составляет 1 и evaluate_if_cond_is_false является 0.

хорошая вещь о троичных операторах заключается в том, что их можно комбинировать. Это означает, что оператор для выполнения, когда одно из условий оценивается как true или false, может быть другим тернарным оператор.

пусть поставить все условие в более читаемом виде:

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

и сопоставление этого с операторами if-else легко с правилами, описанными выше:

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

это недопустимый код, но поскольку результат тернарного оператора встроен в выражение результата, он используется в качестве входных данных для команды puts.


для удовольствия, вот еще один способ:

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

и еще:

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

Троица является базовой структурой if-then.

выше эквивалентно...

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

или, используя скобки...

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

расход:

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
    }
}