3

显而易见的解决方案是:

if (x % 15 == 0) println("fizzbuzz");
else if (x % 3 == 0) println ("fizz");
else if (x % 5 == 0) println ("buzz");

那么你可以说诀窍是连接嘶嘶声和嗡嗡声:

if (x % 3 == 0) print("fizz");
if (x % 5 == 0) print("buzz");
if (x % 15 == 0) println();

或者

print("%s%s%s", x % 3 == 0 ? "fizz" : "", x % 5 == 0 ? "buzz" : "", x % 15 == 0 ? "\r\n" : "");

所以问题是换行符,在上述所有情况下,我们都在执行 3 次检查。

假设在“fizz”或“buzz”之后需要换行,如何仅使用 2 次检查来完成?

4

5 回答 5

23

没有支票怎么办?

string[] output = { "fizzbuzz", "", "", "fizz", "", "buzz", "fizz", "", "", "fizz", "buzz", "", "fizz", "", "" };
print("%s", output[x % 15]);

请注意,这当然只会从此代码中删除if语句。底层代码很可能包含一两条跳转指令。

如果你想让它更清楚发生了什么,你可以创建两个数组:

string[] fizz = { "fizz", "", "" };
string[] buzz = { "buzz", "", "", "", "" };
print("%s%s", fizz[x % 3], buzz[x % 5]);

请注意,这两种实现都不会处理负数,这里有一个版本:

string[] fizz = { "fizz", "", "" };
string[] buzz = { "buzz", "", "", "", "" };
print("%s%s", fizz[((x % 3) + 3) % 3], buzz[((x % 5) + 5) % 5]);

请注意,我巧妙地跳过了您在代码中添加的换行符。如果您愿意,我相信您可以弄清楚如何以相同的方式修改上述代码以添加它:)

更重要的是:请注意,这实际上并没有通过“官方” fizzbuzz 测试,它只回答了您的问题。

fizzbuzz 测试是这样的:

  • 写出从 1 到 100 的所有数字,除了数字是 3 的倍数,你应该写出“fizz”,而对于 5 的倍数,你应该写出“嗡嗡声”而不是数字。如果一个数字同时是3 和 5 的倍数,请写出“fizzbuzz”而不是数字。

由于您的问题没有以任何方式处理“而不是数字”部分,因此我的回答也没有。

因此,如果我们跳过循环通常需要“检查”这一事实,我们是否可以编写整个 fizzbuzz 测试而不使用 if 语句?

有点神奇,是的,我们可以,这是 C# 代码中的循环,您可以使用LINQPadIdeone验证这一点:

void Main()
{
    string[] fizzbuzz = new[]
    {
        "fizzbuzz", "{0}", "{0}", "fizz", "{0}", "buzz", "fizz",
        "{0}", "{0}", "fizz", "buzz", "{0}", "fizz", "{0}", "{0}"
    };
    for (int index = 1; index <= 100; index++)
    {
        Debug.WriteLine(string.Format(fizzbuzz[index % 15], index));
    }
}

在这里,我依赖于这样一个事实,即发送到的格式字符串string.Format实际上不必包含对参数的任何引用。

编辑:如评论中所述,我曾经在参数??中获取并将数组中的条目保留在,但确实是变相的 if 语句,因此将其编辑掉。"{0}"string.Formatnull??

于 2013-07-06T12:36:25.987 回答
1

有点代码高尔夫,但它有效

for x in range(1,101):print"Fizz"[x%3*4:]+"Buzz"[x%5*4:]or x

资料来源: http: //maxburstein.com/blog/python-shortcuts-for-the-python-beginner/

于 2013-07-06T20:30:07.693 回答
1

这是一种没有用 c 编写的任何条件表达式的解决方案。(短路评估除外)

#include <stdio.h>
int fizzbuzz(int i)
{
    const char* f[]={"%i\n","fizz\n","buzz\n","fizbuzz\n"};
    return i&&fizzbuzz(i-1)&&printf(f[!(i%3)|!(i%5)*2],i)||1;
}
int main()
{
    return fizzbuzz(100); 
}
于 2013-07-07T11:03:26.173 回答
1

“只有两次检查”可能是针对这样一个事实,即如果一个数字可以被 3 和 5 整除,这意味着该数字可以被 15 整除。

利用它的示例代码(只有一次检查):

var words = ["fizzbuzz", "buzz", "fizz"];
var index = Math.min(x % 3, 1) + Math.min(x % 5, 1) * 2;
if (index < words.length) println(words[index]);

请注意,Lasse 的 "How about no checks" 答案仍然打印空字符串,这似乎与原始代码不同,也是问题中所述的主要问题之一。

如果可以在文本中包含换行符而不是使用 println(),则无需检查即可完成工作:

print(["fizzbuzz\n", "buzz\n", "fizz\n", ""]
         [Math.min(x % 3, 1) + Math.min(x % 5, 1) * 2]);

附言

由于您要求进行两次检查:

print(["fizzbuzz\n", "buzz\n", "fizz\n", ""]
         [(x % 3 == 0 ? 0 : 1) + (x % 5 == 0 ? 0 : 2)]);

PP:

完整的 FizzBu​​zz(包括打印数字)的 jsfiddle:http: //jsfiddle.net/QxDfh/

于 2013-07-06T19:17:47.247 回答
1

当我做 FizzBu​​zz 时,这就是我想做的,这就是我想出的:

        string[] p = { "", "Fizz", "Buzz", "FizzBuzz" };
        int n = 0;
        for (int i = 1; i <= 100; i++)
        {
            p[0] = i.ToString();
            if (i % 3 == 0)
                n += 1;
            if (i % 5 == 0)
                n += 2;
            Console.WriteLine(p[n]);
            n = 0;
        }

这个想法是通过为 Fizz 添加 1 和为 Buzz 添加 2 来打印数组中的正确字符串,因此如果两者都正确,则在数组中给出 FizzBu​​zz 得到 3。这样,单词可以是任何东西,而不仅仅是前两个单词的组合。假设您想要 Fizz、Buzz 和 FizzieBuzzie,只需更改数组中的 [3] 即可。同样,每次通过循环时,我都会将 [0] 更改为当前数字,如果没有添加任何内容,则会打印出来。

我在这里写了一篇关于我的思考过程的更深入的博客文章:

http://tomasforsman.com/blog/2018/04/19/fizzbuzz-challenge-in-c/

于 2018-04-19T01:16:51.570 回答