- using System;
- using System.Collections;
- using System.Collections.Generic;
- namespace FlattenTest
- {
- public static class ExtensionMethods
- {
- /// Ref.: Flatten Ruby method in C# - Stack Overflow
- /// http://stackoverflow.com/questions/197081/flatten-ruby-method-in-c
- private static IEnumerable FlattenAux(this IEnumerable array)
- {
- foreach (var item in array)
- {
- if (item is IEnumerable)
- {
- foreach (var subitem in FlattenAux((IEnumerable)item))
- {
- yield return subitem;
- }
- }
- else
- {
- yield return item;
- }
- }
- }
- /// Returns a one-dimensinal flattening of given array.
- public static System.Array Flatten(this System.Array array)
- {
- var al = new ArrayList(array.Length);
- foreach (var v in FlattenAux(array))
- al.Add(v);
- return al.ToArray(al[0].GetType());
- }
- }
- class Program
- {
- static void Main(string[] args)
- {
- float[, ,] p0 = new float[3,2,2];
- float[][][] p1 = new float[3][][] {
- new float[2][] { new float[2], new float[2] },
- new float[2][] { new float[2], new float[2] },
- new float[2][] { new float[2], new float[2] }
- };
- for (int i = 0; i < 3; ++i)
- for (int j = 0; j < 2; ++j)
- for (int k = 0; k < 2; ++k)
- p0[i, j, k] = p1[i][j][k] = 100 * i + 10 * j + k;
- float[] fp0 = (float[])p0.Flatten();
- for (int i = 0; i < fp0.Length; ++i)
- Console.Write("{0} ", fp0[i]);
- Console.WriteLine();
- float[] fp1 = (float[])p1.Flatten();
- for (int i = 0; i < fp1.Length; ++i)
- Console.Write("{0} ", fp1[i]);
- Console.WriteLine();
- }
- }
- }
Jun 6, 2010
C# : Flatten()のようなもの
RubyでいうArray#flattenに相当するメソッドがC#には無いということで、似たものを書いてみたのがこちら。System.Arrayに対する拡張メソッドとなっています。
May 16, 2010
乱数生成アルゴリズム WELL
Mersenne Twister (MT) の作者らによる比較的新しいアルゴリズム・ WELL (Well Equidistributed Long-period Linear) についてのメモです。
- 原著はこちら:L'Ecuyer, Pierre; Panneton, François; Matsumoto, Makoto (2006), Improved Long-Period Generators Based on Linear Recurrences Modulo 2
- 論文の訂正表はこちら。シフト演算の部分に関する誤りが訂正されているので必ず参考に。
- Game Programming Gems 7 で紹介されています。記事を書いた Chris Lomont 氏 (http://www.lomont.org/) のサイトで原文が公開されています:
- アルゴリズムの特徴は:
- MTより計算が少しだけ重い。
- MTは初期状態のビットパターンに0を多く含んでいると、出力する乱数のビットパターンにもしばらく0が多く含まれてしまう傾向がある。WELLはこのような状態からの脱出がMTに比べて早い。
- C# (VS 2010) で周期 2^1024 バージョンの WELL を書いてみました:
- http://sites.google.com/site/ltsevenscore/archives/WELL-20100516.zip
- テストコードは Monobit テストを10000回実行して合格した回数を表示するものです。
- Monobit テスト: 20000ビット分の乱数に含まれる1の数が10000個から大きく離れていないかどうかをチェックする検定方法。
- 参考:http://csrc.nist.gov/publications/fips/fips140-2/fips1402.pdf
- 10000回の Monobit テストに対して不合格となるのは1〜2回程度。優秀だと思います。
- System.Random を使ったら Monobit テスト 10000回に対して3000〜4000回しか合格しないケースがあることにびっくりです。
Apr 30, 2010
Vista : シンボリック リンクでフォルダを別ドライブへ移設
Windows Vista 以降からは mklink コマンドで「シンボリックリンク」を作成することができる。
これによりファイル/ディレクトリの実体をドライブをまたいで配置することが可能となっている。
この機能を利用して C:\Program Files\Adobe を D:\Program Files\Adobe へ移設する方法は次のようになる:
1. 管理者権限でコマンドプロンプトを起動
(※「すべてのプログラム>アクセサリ>コマンド プロンプト」を右クリックし「管理者として実行」)
2. コマンドラインでの作業:
Windows Vista/7 ならば Robocopy が標準で使えるので下記のほうがいいかも。
"C:\ProgramData\Microsoft"にある "Windows Defender" を D:\ProgramData\Microsoft に移すものとして:
これによりファイル/ディレクトリの実体をドライブをまたいで配置することが可能となっている。
この機能を利用して C:\Program Files\Adobe を D:\Program Files\Adobe へ移設する方法は次のようになる:
1. 管理者権限でコマンドプロンプトを起動
(※「すべてのプログラム>アクセサリ>コマンド プロンプト」を右クリックし「管理者として実行」)
2. コマンドラインでの作業:
C:\Windows\system32> cd "c:\Program Files"(2013-01-22 追記)
C:\Program Files> xcopy /E /H /I /K /X Adobe "D:\Program Files\Adobe"
...
C:\Program Files> ren Adobe Adobe___
C:\Program Files> mklink /D Adobe "D:\Program Files\Adobe"
Adobe <<===>> D:\Program Files\Adobe のシンボリック リンクが作成されました
C:\Program Files> rmdir /S Adobe___
Windows Vista/7 ならば Robocopy が標準で使えるので下記のほうがいいかも。
"C:\ProgramData\Microsoft"にある "Windows Defender" を D:\ProgramData\Microsoft に移すものとして:
- 「Win+R(ファイル名を指定して実行)」で "cmd /f:on [Ctrl+Shift+Enter, 管理者権限で実行]"
- コマンドラインから下記の順に実行
C:\ProgramData\Microsoft>robocopy "Windows Defender" "D:\ProgramData\Microsoft\Windows Defender" *.* /copyall /dcopy:t /mir
C:\ProgramData\Microsoft>ren "Windows Defender" "___Windows Defender"
C:\ProgramData\Microsoft>mklink /D "Windows Defender" "D:\ProgramData\Microsoft\Windows Defender"
C:\ProgramData\Microsoft>rmdir /S "___Windows Defender"
Apr 23, 2010
LINQ to XML メモ
- <version="1.0" encoding="utf-8"?>
<game_consoles> - <ip_address_map>
<name="Xbox 360">192.168.11.2> <name="PlayStation 3">192.168.11.3> <name="Wii">192.168.11.4> <name="3DO Real">192.168.11.5> <name="DreamCast">192.168.11.6> - </ip_address_map>
- <game_consoles>
- using System;
- using System.Linq;
- using System.Xml.Linq;
- // ...
- XDocument config_xml = XDocument.Load(@".\config.xml");
-
var query = from c in config_xml.Descendants("target") - where c.Attribute("name").Value.Contains("3")
- select c.Attribute("name").Value + " " + c.Value;
- foreach (var q in query)
- {
- Console.WriteLine("{0}", q);
- }
from/where/selectのあたりが LINQ (Language INtegrated Query) to XML と呼ばる仕組みを使っている部分。C# 3.0 (.NET Framework 3.5 以降) で利用可能。
ハッシュテーブルなど、別なデータ構造に入れる場合の例はこんな感じでいける:
- var platform_map = new Dictionary<string, string>();
- XDocument config_xml = XDocument.Load(@".\config.xml");
- var query = from c in config_xml.Descendants("target")
- where c.Attribute("name").Value.Contains("3")
- select new KeyValuePair<string, string>(c.Attribute("name").Value, c.Value);
- foreach (var q in query)
- {
- platform_map[q.Key] = q.Value;
- }
- XDocument doc = new XDocument(
- new XElement("game_consoles",
- new XElement("ip_address_map",
- new XElement("target", new XAttribute("name", "Xbox 360"), "192.168.11.2"),
- new XElement("target", new XAttribute("name", "PlayStation 3"), "192.168.11.3"),
- new XElement("target", new XAttribute("name", "Wii"), "192.168.11.4"),
- new XElement("target", new XAttribute("name", "3DO Real"), "192.168.11.5"),
- new XElement("target", new XAttribute("name", "DreamCast"), "192.168.11.6")
- )
- )
- );
- doc.Save(@".\config.xml");
Subscribe to:
Posts (Atom)