VC#でFizzBuzz¶
Contents:
for文を使った例¶
まずはもっともシンプルな例
1using System;
2using System.Linq;
3
4class Program
5{
6 static void Main(string[] args)
7 {
8 for (var i = 0; i < 101; i++)
9 {
10 if (i % 3 == 0) Console.WriteLine("Fizz");
11 else if (i % 5 == 0) Console.WriteLine("Buzz");
12 else if (i % 15 == 0) Console.WriteLine("FizzBuzz");
13 else Console.WriteLine(i.ToString());
14 }
15 }
16}
ジェネレータを使った例¶
- yield return():
を使う。
1using System;
2using System.Linq;
3using System.Collections.Generic;
4
5class Program
6{
7 private static IEnumerable<string> fb(int m)
8 {
9 for (int i = 0; i <= m; i++)
10 {
11 if (i % 3 == 0) yield return ("Fizz");
12 else if (i % 5 == 0) yield return ("Buzz");
13 else if (i % 15 == 0) yield return ("FizzBuzz");
14 else yield return (i.ToString());
15 }
16 }
17 static void Main(string[] args)
18 {
19 foreach (var n in fb(100))
20 {
21 Console.WriteLine(n);
22 }
23 }
24}
Pythonの内包リストっぽく書く¶
かなり難しい。以下の理由であり、それぞれの解法を述べる。
標準ライブラリでは文字列の繰り返しができない
単一文字に変換し、最後にstring.replace()する
文字列のor(=空白のときの代理文字列)がつかえない
三項演算子で条件分岐する。
1using System;
2using System.Linq;
3using System.Collections.Generic;
4
5class Program
6{
7 static void Main(string[] args)
8 {
9 for(int i =0; i <= 100; i++)
10 {
11 Console.WriteLine((new string('F', i % 3 == 0 ? 1 : 0) + new string('B', i % 5 == 0 ? 1 : 0)).Replace("F", "Fizz").Replace("B", "Buzz") +
12 new string('N', ( (i % 5) * (i % 3) ) != 0 ? 1 : 0).Replace("N",i.ToString()));
13 }
14 }
15}
三項演算子を使った例¶
そもそも三項演算子を使うなら、以下の例で良い。。。
1using System;
2using System.Collections.Generic;
3
4
5class Program
6{
7 delegate bool cond(int i);
8 delegate void proc(int i);
9
10 static void Main(string[] args)
11 {
12 for (int i = 0; i <= 100; i++) Console.WriteLine(i % 15 == 0 ? "FizzBuzz" : i % 3 == 0 ? "Fizz" : i % 5 == 0 ? "Buzz" : i.ToString());
13 }
14}
KeyValuePairを使って条件分岐¶
fizzbuzzでgoogleしたところ、以下のような例を見つけた。
1// 参考: http://blogs.wankuma.com/episteme/archive/2007/11/08/106821.aspx
2using System;
3using System.Collections.Generic;
4
5
6class Program
7{
8 delegate bool cond(int i);
9 delegate void proc(int i);
10
11 static void Main(string[] args)
12 {
13 KeyValuePair<cond, proc>[] fb =
14 {
15 /*
16 * 以下のように書いてもいいらしい
17 new KeyValuePair<cond ,proc>(
18 delegate(int c) { return c % 3 != 0 && c % 5 != 0; },
19 delegate(int c) { Console.Write(c); }
20 ),
21 */
22 new KeyValuePair<cond ,proc>(
23 (c => c % 3 != 0 && c % 5 != 0),
24 (c => Console.Write(c) )
25 ),
26 new KeyValuePair<cond,proc>(
27 (c => c % 3 == 0 ),
28 (c => Console.Write("Fizz") )
29 ),
30 new KeyValuePair<cond,proc>(
31 (c => c % 5 == 0 ),
32 (c => Console.Write("Buzz") )
33 ),
34 };
35
36 for (int i = 1; i <= 100; ++i)
37 {
38 foreach (KeyValuePair<cond, proc> kv in fb)
39 if (kv.Key(i)) kv.Value(i); Console.WriteLine("");
40 }
41 }
42}
てっきり、proc(int)はラムダ式でしか書けないと思っていたのだが、 参照したページによれば delegate(int c) という書き方ができるのですね。 delegate表記で引数のcに対する型を明記するという意味で、 delegateの方が読みやすいかもしれませんね。
Reactive Extensions¶
VisualStudio2012使っているのだからRxを使いましょう。ということで以下の例。
1using System;
2using System.Linq;
3using System.Collections.Generic;
4using System.Reactive;
5using System.Reactive.Linq;
6
7
8class Program
9{
10 static void Main(string[] args)
11 {
12 var fb = Observable.Range(1, 100).Publish();
13 fb.Where(c => c % 3 == 0).Subscribe(c => Console.WriteLine("Fizz"));
14 fb.Where(c => c % 5 == 0).Subscribe(c => Console.WriteLine("Buzz"));
15 fb.Where(c => c % 3 != 0 && c % 5 != 0).Subscribe(c => Console.WriteLine(c.ToString()));
16 fb.Connect();
17 }
18}
Observable.Publish() は Connect() するまで列挙を始めないためのおまじないで、 これによって、条件分岐を定義してから列挙することが可能。 ちなみに、IEnumerableなオブジェクトは ToObservable() で 列挙オブジェクトに変換できるので、
1using System;
2using System.Linq;
3using System.Collections.Generic;
4using System.Reactive;
5using System.Reactive.Linq;
6
7
8class Program
9{
10 public static IEnumerable<int> fblist(int m)
11 {
12 for (int i = 1; i <= m; i++) yield return i;
13 }
14 static void Main(string[] args)
15 {
16 var fb = fblist(100).ToObservable().Publish();
17 fb.Where(c => c % 3 == 0).Subscribe(c => Console.WriteLine("Fizz"));
18 fb.Where(c => c % 5 == 0).Subscribe(c => Console.WriteLine("Buzz"));
19 fb.Where(c => c % 3 != 0 && c % 5 != 0).Subscribe(c => Console.WriteLine(c.ToString()));
20 fb.Connect();
21 }
22}
とすることも可能。