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