using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
/// <summary>
/// 指定した範囲内の度数分布表を作成します。
/// </summary>
/// <remarks>
/// <paramref name="buckets"/>は1以上の値が与えられるものとします。
/// <paramref name="max"/>は<paramref name="min"/>より大きな値が与えられるものとします。
/// </remarks>
/// <param name="data">度数分布表を作成するデータ。</param>
/// <param name="buckets">作成する度数分布表の階級数(区間の数)。</param>
/// <param name="min">作成する度数分布表の最小値。
/// この値以上のデータを集計し、この値未満のデータは無視します。</param>
/// <param name="max">作成する度数分布表の最大値。
/// この値未満のデータを集計し、この値以上のデータは無視します。</param>
/// <returns>累積度数の配列。長さは<paramref name="buckets"/>。</returns>
private static int[] CreateHistogram(IEnumerable<double> data, int buckets, double min, double max)
{
// 累積度数の配列を作成。
int[] results = new int[buckets];
// 階級幅の逆数を計算。
double multiplier = buckets / (max - min);
foreach (double datum in data)
{
// 幅で割って(=幅の逆数を掛けて)整数化。
int index = (int)((datum - min) * multiplier);
// 度数分布表の範囲に収まっていたら度数をカウントアップ。
if (0 <= index && index < buckets)
results[index] += 1;
}
return results;
}
static void Main()
{
var r = new Random();
// 0以上100未満のランダムな数を100000個生成。
var data = Enumerable.Repeat(0, 100000).Select(x => 100.0d * r.NextDouble());
// 10以上20未満の区間を10個に分割した度数分布表を作成。
var hist = CreateHistogram(data, 10, 10.0d, 20.0d);
for (var i = 0; i < hist.Length; i++)
Console.WriteLine("{0,2}: {1}", i, hist[i]);
}
}
dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYzsKdXNpbmcgU3lzdGVtLkxpbnE7CgpjbGFzcyBQcm9ncmFtCnsKICAgIC8vLyA8c3VtbWFyeT4KICAgIC8vLyDmjIflrprjgZfjgZ/nr4Tlm7LlhoXjga7luqbmlbDliIbluIPooajjgpLkvZzmiJDjgZfjgb7jgZnjgIIKICAgIC8vLyA8L3N1bW1hcnk+CiAgICAvLy8gPHJlbWFya3M+CiAgICAvLy8gPHBhcmFtcmVmIG5hbWU9ImJ1Y2tldHMiLz7jga8x5Lul5LiK44Gu5YCk44GM5LiO44GI44KJ44KM44KL44KC44Gu44Go44GX44G+44GZ44CCCiAgICAvLy8gPHBhcmFtcmVmIG5hbWU9Im1heCIvPuOBrzxwYXJhbXJlZiBuYW1lPSJtaW4iLz7jgojjgorlpKfjgY3jgarlgKTjgYzkuI7jgYjjgonjgozjgovjgoLjga7jgajjgZfjgb7jgZnjgIIKICAgIC8vLyA8L3JlbWFya3M+CiAgICAvLy8gPHBhcmFtIG5hbWU9ImRhdGEiPuW6puaVsOWIhuW4g+ihqOOCkuS9nOaIkOOBmeOCi+ODh+ODvOOCv+OAgjwvcGFyYW0+CiAgICAvLy8gPHBhcmFtIG5hbWU9ImJ1Y2tldHMiPuS9nOaIkOOBmeOCi+W6puaVsOWIhuW4g+ihqOOBrumajue0muaVsO+8iOWMuumWk+OBruaVsO+8ieOAgjwvcGFyYW0+CiAgICAvLy8gPHBhcmFtIG5hbWU9Im1pbiI+5L2c5oiQ44GZ44KL5bqm5pWw5YiG5biD6KGo44Gu5pyA5bCP5YCk44CCCiAgICAvLy8g44GT44Gu5YCk5Lul5LiK44Gu44OH44O844K/44KS6ZuG6KiI44GX44CB44GT44Gu5YCk5pyq5rqA44Gu44OH44O844K/44Gv54Sh6KaW44GX44G+44GZ44CCPC9wYXJhbT4KICAgIC8vLyA8cGFyYW0gbmFtZT0ibWF4Ij7kvZzmiJDjgZnjgovluqbmlbDliIbluIPooajjga7mnIDlpKflgKTjgIIKICAgIC8vLyDjgZPjga7lgKTmnKrmuoDjga7jg4fjg7zjgr/jgpLpm4boqIjjgZfjgIHjgZPjga7lgKTku6XkuIrjga7jg4fjg7zjgr/jga/nhKHoppbjgZfjgb7jgZnjgII8L3BhcmFtPgogICAgLy8vIDxyZXR1cm5zPue0r+epjeW6puaVsOOBrumFjeWIl+OAgumVt+OBleOBrzxwYXJhbXJlZiBuYW1lPSJidWNrZXRzIi8+44CCPC9yZXR1cm5zPgogICAgcHJpdmF0ZSBzdGF0aWMgaW50W10gQ3JlYXRlSGlzdG9ncmFtKElFbnVtZXJhYmxlPGRvdWJsZT4gZGF0YSwgaW50IGJ1Y2tldHMsIGRvdWJsZSBtaW4sIGRvdWJsZSBtYXgpCiAgICB7CiAgICAgICAgLy8g57Sv56mN5bqm5pWw44Gu6YWN5YiX44KS5L2c5oiQ44CCCiAgICAgICAgaW50W10gcmVzdWx0cyA9IG5ldyBpbnRbYnVja2V0c107CiAgICAgICAgLy8g6ZqO57Sa5bmF44Gu6YCG5pWw44KS6KiI566X44CCCiAgICAgICAgZG91YmxlIG11bHRpcGxpZXIgPSBidWNrZXRzIC8gKG1heCAtIG1pbik7CiAgICAgICAgZm9yZWFjaCAoZG91YmxlIGRhdHVtIGluIGRhdGEpCiAgICAgICAgewogICAgICAgICAgICAvLyDluYXjgaflibLjgaPjgabvvIjvvJ3luYXjga7pgIbmlbDjgpLmjpvjgZHjgabvvInmlbTmlbDljJbjgIIKICAgICAgICAgICAgaW50IGluZGV4ID0gKGludCkoKGRhdHVtIC0gbWluKSAqIG11bHRpcGxpZXIpOwogICAgICAgICAgICAvLyDluqbmlbDliIbluIPooajjga7nr4Tlm7Ljgavlj47jgb7jgaPjgabjgYTjgZ/jgonluqbmlbDjgpLjgqvjgqbjg7Pjg4jjgqLjg4Pjg5fjgIIKICAgICAgICAgICAgaWYgKDAgPD0gaW5kZXggJiYgaW5kZXggPCBidWNrZXRzKQogICAgICAgICAgICAgICAgcmVzdWx0c1tpbmRleF0gKz0gMTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdHM7CiAgICB9CgogICAgc3RhdGljIHZvaWQgTWFpbigpCiAgICB7CiAgICAgICAgdmFyIHIgPSBuZXcgUmFuZG9tKCk7CiAgICAgICAgLy8gMOS7peS4ijEwMOacqua6gOOBruODqeODs+ODgOODoOOBquaVsOOCkjEwMDAwMOWAi+eUn+aIkOOAggogICAgICAgIHZhciBkYXRhID0gRW51bWVyYWJsZS5SZXBlYXQoMCwgMTAwMDAwKS5TZWxlY3QoeCA9PiAxMDAuMGQgKiByLk5leHREb3VibGUoKSk7CiAgICAgICAgLy8gMTDku6XkuIoyMOacqua6gOOBruWMuumWk+OCkjEw5YCL44Gr5YiG5Ymy44GX44Gf5bqm5pWw5YiG5biD6KGo44KS5L2c5oiQ44CCCiAgICAgICAgdmFyIGhpc3QgPSBDcmVhdGVIaXN0b2dyYW0oZGF0YSwgMTAsIDEwLjBkLCAyMC4wZCk7CiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBoaXN0Lkxlbmd0aDsgaSsrKQogICAgICAgICAgICBDb25zb2xlLldyaXRlTGluZSgiezAsMn06IHsxfSIsIGksIGhpc3RbaV0pOwogICAgfQp9