FizzBuzz с использованием троичного условного оператора - PullRequest
8 голосов
/ 22 октября 2008

Я читал выражения в условном стиле в 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 ]

16 голосов
/ 22 октября 2008

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

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

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

11 голосов
/ 22 октября 2008

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

Напишите программу, которая печатает цифры от 1 до 100. Но для кратные три печати "Fizz" вместо числа и для кратные пяти печатать «Базз». За числа, которые кратны обоим три и пять печатать «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 ,valu_if_cond_is_true - 1, а valu_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
    }
}

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

7 голосов
/ 22 октября 2008

Для развлечения вот еще один способ:

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}
3 голосов
/ 22 октября 2008

Тройной является базовой структурой 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 )
1 голос
/ 22 октября 2008

поток:

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