FizzBuzz有何解?

FizzBuzz 是先前在 coding 界最流行最時尚的東東,它是一個sense 。

事情是這樣的:

印出 1 到 100,但如果是 3 的倍數就印 Fizz,如果是 5 的倍數就印 Buzz,如果同時是 3 和 5 的倍數就印 FizzBuzz。

這個東西對於一個普通會 coding 的工程師看起來非常的容易。容易歸容易,但你必需要實做出 DRY (Do Not Repeat Yourself) 原則,也就是說用最少的 coding 行數來達成以上的結果。

FizzBuzz 搭上 DRY 就整個概念變的非常的時尚,因為,簡約就是時尚的原則啊!(茶)

一般很平常的工程師遇到這樣的問題,即馬上做這樣子的的程式碼:
[cc lang=”vb”]
Dim i

For i = 1 to 100
If (i Mod 3 = 0) And (i Mod 5 = 0) Then
WScript.Echo “FizzBuzz”
ElseIf (i Mod 3 = 0) Then
WScript.Echo “Fizz”
ElseIf (i Mod 5 = 0) Then
WScript.Echo “Buzz”
Else
Wscript.Echo i
End If
Next
[/cc]

在其它語言中,有的是這樣做的:
在 C 語言:
[cc lang=”c”]
int main() {
for( int i=1; i<=100; i++) { if(i%3==0) printf("Fizz"); if(i%5==0) printf("Buzz"); if(i%3!=0 && i%5!=0) printf("%d",i); printf("\n"); } return 0; } [/cc] 或是這樣解: [cc lang="c"] int main (int argc, const char * argv[]) { char *formats[] = { "%d\n", "fizz\n", "buzz\n", "fizzbuzz\n" }; for (int i = 1; i <= 100; i++) printf(formats[(i % 3 == 0) + 2 * (i % 5 == 0)], i); return 0; } [/cc] 在java是這樣寫:
[cc lang=”java”]
class FizzBuzzString? {
public static void main(String[] args)
{

for(int i=1; i<=100; i++) { String num=""; if(i%3==0) num+="Fizz"; if(i%5==0) num+="Buzz"; if(num.length()==0) num=Integer.toString(i); System.out.println(num); } } } [/cc] 在perl原先是這樣:
[cc lang=”perl”]
#!/usr/bin/perl

for (1..100) {
my $fizz = ($_ % 3 == 0) ? “Fizz” : “”;
my $buzz = ($_ % 5 == 0) ? “Buzz” : “”;
($fizz ne “” || $buzz ne “”) ? print “$fizz$buzz\n” : print “$_\n”;
}
[/cc]
然後還可以用一行流!
[cc lang=”perl”]
#!/usr/bin/perl
print ( ((($_ % 3) ? “” : “Fizz”) . (($_ % 5) ? “” : “Buzz”)) || $_, “\n”) for (1..100);
[/cc]
在python就這樣寫:
[cc lang=”python”]
import sys
for i in range(-50, 100):
if i%3==0:
sys.stdout.write(‘Fizz’)
if i%5==0:
sys.stdout.write(‘Buzz’)
if (i%5<>0 and i%3<>0):
print i,
print
[/cc]
php是這樣搞的:
[cc lang=”php”]
$out = ”; for ( $i=1; $i <= 100; ++$i ) { if ($f = ($i%3 == 0)) $out .= 'Fizz'; if ($b = ($i%5 == 0)) $out .= 'Buzz'; if ($f == 0 && $b == 0) $out .= $i; $out .= ', '; } echo $out; [/cc] 第二種解法 [cc lang="php"] $out = ''; for ( $i=1; $i <= $N; ++$i ) { $outp = ''; if ($i%3 == 0) $outp = 'Fizz'; if ($i%5 == 0) $outp .= 'Buzz'; if ($outp == '') $outp = $i; $out .= $outp.', '; } echo $out; [/cc] 用basic是這樣子的:
[cc lang=”basic4gl”]
for N = 1 to 100
P = 0
if N mod 3 = 0 then print “Fizz”; : P = 1
if N mod 5 = 0 then print “Buzz”; : P = 1
if P > 0 then print else print N
next N
[/cc]
用javascript也可以寫的很簡單:
[cc lang=”javascript”]
var i = 1,
f = ‘Fizz’,
b = ‘Buzz’,
out = ”;
for (; i <= 100; i++) { out = !(i % 3) ? !(i % 5)? f+b : f : !(i % 5)? b : i; console.log(out); } [/cc] 其它有兩個很威的我比較陌生的語言也可以用一行流。 用Groovy只要64個字元:
[cc lang=”groovy”]
for(i in 1..100)println(i%3+i%5?i%3?i%5?i:”Buzz”:”Fizz”:”FizzBuzz”)
[/cc]
用lo:
[cc lang=”lolcode”]
Range;1 to(100) foreach(x,if(x%15==0,writeln(“FizzBuzz”),if(x%3==0,writeln(“Fizz”),if(x%5==0,writeln(“Buzz”),writeln(x)))))
[/cc]

經過這樣子的比較有些語言確實可以達到DRY的方式來達成FizzBuzz的問題,但相對的可讀性就會大大減少,如一行流的perlgroovylo,但有趣的是這些語言除了perl是最大宗的使用者之外其餘的似乎是很Geek的層級所擁有的技能呀!

但是另一方面來說,軟體的使用者才不會管你是用什麼東西來寫軟體呢。但是,如果你要拿來應徵軟體公司的工作,我想這方面的技能還是要能搞懂比較好,必竟身為程式設計師要搞懂FizzBuzz也是正常的。

另外 ruby 也有一行的做法:
[cc lang=”ruby”]
1.upto(100) { |n| puts n % 3 == 0 ? n % 5 == 0 ? “fizzbuzz” : “buzz” : n % 5 == 0 ? “fizz” : n }
[/cc]

這不就是我正在學的語言嗎?我本來打算要投靠perl了呢,看來還可以靠它撐一下。:D

Related Posts Plugin for WordPress, Blogger...

Leave a Reply