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