FizzBuzz с использованием тернарного условного оператора

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

for i in 0...100
  puts i%3==0 ? i%5==0 ? "FizzBuzz" : "Buzz" : i%5==0 ? "Fizz" : i
end
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Шаг 1: Создание приложения Slack Чтобы создать Slackbot, вам необходимо создать приложение Slack. Войдите в свою учетную запись Slack и перейдите на...
8
0
4 361
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

Ответ принят как подходящий

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

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

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

Большое спасибо - скобки и ваше объяснение помогли решить эту проблему.

Damian 22.10.2008 13:58

поток:

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

Тернар - это базовая структура «если-то».

Вышеупомянутое эквивалентно ...

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 )

Извиняюсь. Я просто ленился.

Jarrett Meyer 22.10.2008 17:51

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

Write a program that prints the numbers from 1 to 100. But for multiples of three print "Fizz" instead of the number and for the multiples of five print "Buzz". For numbers which are multiples of both three and five print "FizzBuzz".

тернарный оператор - это сокращенная запись для оператора 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, Assessment_if_cond_is_true - это 1, а Assessment_if_cond_is_false - это 0.

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

Давайте представим все условие в более удобочитаемом виде:

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.

Ради интереса вот еще один способ:

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}

Это не правильно. В спецификации указано, что вы должны печатать номер только в том случае, если вы не печатаете шипение или жужжание.

mxcl 27.11.2010 14:44

Просто для развлечения. Если вы хотите сделать это на C#. Вот простой способ. Он в основном начинается с вашего цикла for, который будет печатать числа от 1 до 100. Затем он спрашивает, делится ли ваш индекс «i» на 3 и 5, если он истинен, а затем выводит на консоль «FizzBuzz». В противном случае, если ваш индекс «i» делится на 3, если true, то выведите в консоль «Fizz». Иначе, если ваш индекс «i» делится на 5, если true, то выведите в консоль «Buzz». В противном случае просто распечатайте «i», которое является вашим целым числом. Я добавил табуляцию для лучшей читаемости.

for(int i = 1; i <= 100; i++) {
        string result = (i % 3 == 0 && i % 5 == 0) ? 
        "FizzBuzz" :  
            (i % 3 == 0) ? 
                "Fizz" : 
                    (i % 5 == 0) ? 
                        "Buzz" : 
                            i.ToString();
    Console.WriteLine(result);
    }

Другие вопросы по теме