litediary

<7月 2009年08月 9月>
            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      
過去の記事
2015年04月  2015年01月  2014年09月  2014年07月  2014年02月  2013年12月  2013年01月  2012年12月  2012年11月  2012年07月  2012年06月  2012年05月  2012年04月  2012年03月  2012年02月  2012年01月  2011年12月  2011年11月  2011年10月  2011年08月  2011年07月  2011年06月  2011年05月  2011年04月  2011年03月  2011年01月  2010年12月  2010年11月  2010年10月  2010年09月  2010年08月  2010年07月  2010年06月  2010年04月  2010年03月  2010年02月  2010年01月  2009年12月  2009年11月  2009年10月  2009年09月  2009年08月  2009年07月  2009年06月  2009年05月  2009年04月  2009年03月  2009年02月  2009年01月  2008年12月  2008年11月  2008年10月  2008年09月  2008年08月  2008年07月  2008年06月  2008年05月  2008年04月  2008年03月  2008年02月  2008年01月  2007年12月  2007年11月  2007年10月  2007年09月  2007年08月  2007年07月  2007年06月  2007年05月  2007年04月  2007年03月  2007年02月  2006年12月  2006年11月  2006年10月  2006年09月  2006年08月  2006年07月  2006年06月  2006年05月  2006年04月  2006年03月  2006年02月  2006年01月  2005年12月  2005年11月  2005年10月  2005年09月  2005年08月  2005年07月  2005年06月  2005年05月  2005年04月  2005年03月  2005年02月  2005年01月  2004年12月  2004年11月  2004年10月  2004年09月  2004年08月  2004年07月  2004年06月  2004年05月  2004年04月  2004年03月  2004年02月 
for-else09/08/22 00:48
キー入力処理なんかで、if-else ifでつなぐことは良くある。
同時押し回避のためにifを並べるんじゃなくてelse ifでつなぐ必要がある。

if (condX())
{
}
else if (condY())
{
}
else if (condZ())
{
}

ここで、一部だけループで処理出来そうだったりする

if (condX(0))
{
}
else if (condX(1))
{
}
else if (condX(2))
{
}
else if (condY())
{
}
else if (condZ())
{
}

そこでこんなの出来たら良いなーと思う

for(int i=0; i<3; i++)
{
    if (condX(i))
    {
        break;
    }
}
else if (condY())
{
}
else if (condZ())
{
}

condX(i)が真になってbreakされた場合はその後のelse ifはスキップされ、i<3が偽になった時だけelse ifが評価される。

実はPythonだと出来るのだ。
C系言語に導入しても問題なさそう。
まぁいまさら導入されることは無さそうなんだけどね…

もともと
while(cond()) { doanything(); }

loop:
  if (!cond()) goto end;
  doanything();
  goto loop;
end:

なので、
while(cond()) { doanything(); } else { doelse(); }


loop:
  if (!cond()) goto else;
  doanything();
  goto loop;
else:
  doelse();
end:
と問題なくいけるはず。(breakはgoto endに。)
forもほぼ同様。

妥協点としては
BOOL handled = FALSE;
for(int i=0; i<3; i++)
{
    if (condX(i))
    {
        handled = TRUE;
        break;
    }
}
if (handled) {}
else if (condY())
{
}
else if (condZ())
{
}

もしくは

for(int i=0; i<3; i++)
{
    if (condX(i))
    {
        goto break_for_else_chain;
    }
}
if (condY())
{
}
else if (condZ())
{
}
break_for_else_chain:

こうですかね
情報処理技術者試験09/08/20 04:03
申込締切でした。
締切ギリギリでネットワークを申し込んでおいた。
去年、15点足りなくて落ちたので…。
試験勉強は去年の本で大丈夫だろうか。

コミケの戦利品はとりあえず写真だけ取り終わった。
最後に積み上げてみたら、思ったより買ってた。
これも皆様のおかげです。
http://creeper.no-ip.info/c76/
C76と幸福と09/08/14 20:54
当然のように三日参加の予定だったんだけど、1日目はサークルで欲しいのがワルワル1箇所しかなかった。
というわけで、初めての企業スタート。
6時おき、シャワー浴びてのんびり出発して8時着。
11:30くらいに会場入り。
ALcot/pixiv/コミックハイ/ういんどみる
と回って終了。
ワルワルは人に頼んじゃった。

ずっと影が出来ない程度に曇ってて、屋外は風もあって涼しかった。
三日間これならいいなぁ・・・

帰りに駅前のロータリーに幸福実現党の車が止まってるのを発見。

「こんな敵だらけのとこでどうするつもりだろう」
と思ってたら、二次絵の書かれたうちわを配っていた。
最初、反応できずに貰い損ねたので戻って貰ってしまった。



1日目戦利品

VisualStudio09/08/07 15:36
C++とC#の混成プロジェクトを作っていると、Expressでは不便になってくる。
(ExpressではC#のみ、C++のみしか作れない。マルチスレッドのデバッグも貧弱)
で、Professionalがほしいなーと思った。
でも通常版が10万もする。
Amazonで調べるとアカデミックがトップに来て1万ちょいだけど…
まぁそれは置いといて

アップグレード版が5万くらい。
なにからアップグレード出来るのかというと…
http://www.microsoft.com/japan/msdn/vstudio/2008/purchase/upgrade.aspx
Expressからも出来るようだ。
通常版は意味が無い?

2010が出たら本気だそう。
Yコンビネータが理解できない09/08/06 22:53
今日はC#。

ツリービューにファイルツリーを表示するのを、
λ式で再帰的に書こうとしてみた。

 Action<string, TreeNodeCollection> func = null;
 func = (path, nodes) =>
 {
     TreeNode node = nodes.Add(Path.GetFileName(path));
     node.Tag = path;
     if (Directory.Exists(path))
     {
         Array.ForEach(
             Directory.GetDirectories(path).Concat(Directory.GetFiles(path)).ToArray(),
             child => func(child, node.Nodes));
     }
 };
 func(@"C:", treeView1.Nodes);

1行目、一度funcにnullを入れて、2行目でλ式を入れている。
こうしないと、func = の右辺ではまだfuncが未初期化なので再帰しようとしているところでコンパイルエラー。
ていうかかっこ悪い。


スマートにかけないのかと調べていると、Yコンビネータなるものにたどり着いてしまう。
よく分からないのだが、これを使うと再帰が綺麗にかけるらしい。

ぐぐった結果、こんな答えが出てきた。

 delegate Func<A, R> Recursive<A, R>( Recursive<A, R> f );

 Func<Func<Func<int, int>, Func<int, int>>, Func<int, int>> y = f =>
     ( (Recursive<int, int>)( g => a => f( g( g ) )( a ) ) )
     ( (Recursive<int, int>)( g => a => f( g( g ) )( a ) ) );

 var int120 = y( fact => n => n == 0 ? 1 : n * fact( n - 1 ) )( 5 );

5の階乗を再帰で求めている。
なるほど、確かにこれなら綺麗に書けるみたいだけど…
全く意味が分からない。

こんな感じのメソッド作っておけば…

 Func<A, R> Y<A, R>(Func<Func<A, R>, Func<A, R>> func)
 {
     Func<Func<Func<A, R>, Func<A, R>>, Func<A, R>> y = f =>
         ((Recursive<Func<A, R>>)(g => a => f(g(g))(a)))
         ((Recursive<Func<A, R>>)(g => a => f(g(g))(a)));
     return y(func);
 }
 var func = Y<int, int>( fact => n => n == 0 ? 1 : n * fact( n - 1 ) );
 func(5); // 120

もうちょっと簡略化して、
 Func<A, R> Y<A, R>(Func<Func<A, R>, Func<A, R>> f)
 {
     Recursive<Func<A, R>> rec = g => a => f(g(g))(a);
     return rec(rec);
 }
うん。これなら実用できそう。
でもやっぱり理解不能。

というわけで、この記事を書いてみている。

■シンプルな関数で考えてみる。
0...3の和を計算する。
 Y<int, int>( func => arg => arg>0 ? arg + func(arg-1) : 0 )(3);
これを展開をしてみよう

 f = { func => arg => arg>0 ? arg + func(arg-1) : 0 }
 rec = g => a => f(g(g))(a);
 rec(rec)(3);

fを展開
 rec = { g => a => { arg => arg>0 ? arg + g(g)(arg-1) : 0 }(a) };
 rec(rec)(3);

recを展開
 { g => a => { arg => arg>0 ? arg + g(g)(arg-1) : 0 }(a) }({ g => a => { arg => arg>0 ? arg + g(g)(arg-1) : 0 }(a) })(3) --- (1.1)

さて、この形がこれから何度も出てくるので
 func = { g => a => { arg => arg>0 ? arg + g(g)(arg-1) : 0 }(a) }({ g => a => { arg => arg>0 ? arg + g(g)(arg-1) : 0 }(a) });
と置こう。最初のfuncとは違うけど、同じです。
funcは展開すると
 { a => { arg => arg>0 ? arg + func(arg-1) : 0 }(a) } --- (1.2)
となる。
見ての通り再帰になっている。

funcを用いると式(1.1)は
 func(3)

式(1.2)より
 { a => { arg => arg>0 ? arg + func(arg-1) : 0 }(a) }(3)

aを3に展開
 { arg => arg>0 ? arg + func(arg-1) : 0 }(3)

argを3に展開
 3>0 ? 3 + func(3-1) : 0

3項演算子の結果が確定するので取り出す。
 3 + func(2)

もう一度funcを展開すると…
 3 + { a => { arg => arg>0 ? arg + func(arg-1) : 0 }(a) }(2)

後半部分がさっき出てきた形になっているので、以下同様に
 3 + { arg => arg>0 ? arg + func(arg-1) : 0 }(2)
 3 + 2 + { arg => arg>0 ? arg + func(arg-1) : 0 }(1)
 3 + 2 + 1 + { arg => arg>0 ? arg + func(arg-1) : 0 }(0)
argが0に展開され、0>0==falseとなるので
 3 + 2 + 1 + 0
めでたしめでたし。


■この証明を一般化してみよう。

Yに渡すfは一般に次のような形になる。
 f = func => arg => F(func, arg)
(上記の例ならF = (func, arg) => arg>0 ? arg + func(arg-1) : 0 )

Y(f)(arg)を展開していこう。
fを展開
 Y({ func => arg => F(func, arg) })(arg);

Yを展開
 rec = g => a => { func => arg => F(func, arg) }(g(g))(a);
 rec(rec)(arg);

funcを展開
 rec = g => a => { arg => F(g(g), arg) }(a)
 rec(rec)(arg);

argを展開
 rec = g => a => F(g(g), a);
 rec(rec)(arg);

recを展開
 { g => a => F(g(g), a) }({ g => a => F(g(g), a) })(arg); --- (2.1)

gを展開
 { a => F({ g => a => F(g(g), a) }({ g => a => F(g(g), a) }), a) }(arg);

aを展開
 F({ g => a => F(g(g), a) }({ g => a => F(g(g), a) }), arg); --- (2.2)

ここで、
 func = { g => a => F(g(g), a) }({ g => a => F(g(g), a) });
とおくと、
式(2.1)は次のようになる。
 func(arg);

式(2.2)は次のようになる。
 { a => F(func, a) }(arg);

argを展開
 F(func, arg);

Fでは、次のような呼び出しを行うだろう。
 func(arg_1)

するとこれは、次のように展開される。
 F(func, arg_1);

そして再帰的にFが呼ばれることになる。
 F(func, arg_n);

再帰の終了となるarg_Nが渡された時点で、Fの呼び出しが終了し、展開も終了する。

このfuncがY<A, R>()の返す式の正体だ。

ということで良いのかな。


参考:
C#λ式で再帰をやろうとしてYコンビネータに行き着くパターン(今回の自分と同じ)
http://blogs.wankuma.com/mnow/archive/2008/02/17/123545.aspx
http://blogs.msdn.com/wesdyer/archive/2007/02/02/anonymous-recursion-in-c.aspx

Yコンビネータそのものの解説
http://d.hatena.ne.jp/nowokay/20090409
C++/CLIメモ 基本的なとこいろいろ09/08/05 16:30
■文字列の変換
・managed -> unmanaged
#ifdef _UNICODE
wchar_t* ptr = (wchar_t*)Marshal::StringToHGlobalUni(str).ToPointer();
#else
char* ptr = (char*)Marshal::StringToHGlobalAnsi(str).ToPointer();
#endif
でptrが取り出せる。
Marshal::FreeHGlobal((IntPtr)ptr);
で後始末する必要がある。

・unmanaged -> managed
String^ str = gcnew String(ptr); // char*でもwchar_t*でもOK

ansi <-> uniの変換はOSのcodepageに従ってかな?
とりあえず自分の環境ではsjisで上手くいってるようだ。

■プロパティ
public ref class Hoge
{
    property int Hage
    {
        int get() { return hage; }
        void set(int value) { hage = value; }
    }
}
これは、 property int Hage; と省略可能。(Hageとしてプロパティが作成され、中身は完全に隠される)
int Hage;としておくのに比べ、将来set/getを作った時にバイナリ互換が保たれると思われる。

get/setを宣言と定義を別に書く時は、
class Hoge
{
    property int Hage
    {
        int get();
        void set(int value);
    }
};
int Hoge::Hage::get()
{
return hage;
}
void Hoge::Hage::set(int value)
{
hage = value;
}

・インデックス付きプロパティ
これはC#だと出来ない。よね?
property int Hages[int]
{
    int get(int idx);
}
hoge.Hages[0]でアクセスできる。

・デフォルトプロパティ
property int default[int]
{
    int get(int idx);
}
これはoperator[]と被る。(コンパイルエラー)
ref classではデフォルトプロパティを使ったほうが良いと思われる。

http://msdn.microsoft.com/ja-jp/library/ms235304(VS.80).aspx [プロパティの宣言]

■デストラクタ/ファイナライザ
C#では~classname()がファイナライザだが、
C++/CLIでは~classname()がデストラクタ、!classname()がファイナライザになる。
実際には次のようなコードが生成され、間接的に呼び出されるようだ。(ildasmで確認)
protected void Dispose(bool disposing)
{
    if (disposing)
    {
        ~classname();
    }
    else
    {
        !classname();
    }
}
public void Dispose()
{
    Dispose(true);
    System::GC::SuppressFinalize(this);
}
Finalize()
{
    Dispose(false);
}
GC::SuppressFinalizeされるので、デストラクタが呼ばれた場合はファイナライザは呼ばれない。
ただしデストラクタは複数呼ばれる可能性がある。(Dispose()を複数回呼んでみれば良い)

C++/CLIで
{
    Hoge hoge;
    // do something...
}
と書くと、C#で言う
try
{
    Hoge hoge = new Hoge();
    // do something...
}
finaly
{
    hoge.Dispose();
}
となる。(using)

hoge->~Hoge();
delete hoge;
この二つは、どちらもhoge.Dispose()となる。

ファイナライザはGCから呼ばれるのみで、呼び出すことは出来ない。

http://msdn.microsoft.com/ja-jp/library/fs2xkftw.aspx [Dispose メソッドの実装]
http://msdn.microsoft.com/ja-jp/library/b1yfkh5e.aspx [アンマネージ リソースをクリーンアップするための Finalize および Dispose の実装]
http://msdn.microsoft.com/ja-jp/library/ms177197.aspx [Destructors and Finalizers in Visual C++]

minibbs - テスト稼動中
creeper2012/05/03 01:28
.jpからもきてるんか…
creeper2012/05/02 10:52
誰も書き込まないのにSPAMばっかりくるようになったのでhost名制限かけました。
基本的に逆引きできて*.jpにならないと弾きます
wataru2010/12/01 11:43
GT5俺がかわりにやっといてあげますよ。
q2010/12/01 10:35
消化不良すぎ
2010/10/30 01:03
netbeansだとmakeファイル使う機会があるかもしれませんね
2010/10/05 06:04
なに書き込み不可能とか直しちゃってるのこわい
creeper2010/10/04 02:58
長いことコメント書き込み不可能になってた。直しました。
ao 2007/09/30 10:54
お、良いねぃ
creeper2007/09/16 05:18
そこまで詳しくなかったので調べてみた。Wikipedia万歳
なるほど、失敗する6号機まではかぐやと同じ3t強をSBB無しの202で上げてたんですね。
SRB-Aの出力を下げてSBB追加することでとりあえず対応していたと。

今後の予定をみると、次の燃えるのは2010年の金星探査機かー
「超高速インターネット衛星WINDS」は名前には惹かれるけど都心に引きこもってる限り関係ないなー
Wikipediaの予定だとWINDSは2024になってますね。
重量的に、2024か204か新型か…
A責ダッシュ!2007/09/15 10:11
SSB使っての打ち上げって今回が最後じゃなかったかな?
まー、今回のもSRB-Aがもともとの性能を出せてれば2022じゃなくて202で上げられたかもしれないです。LE-7Aの再生長ノズルはこなれてきたようなので、元のSRB-Aが復帰すればまたちょっとづつ色々変わっていくんじゃないのでしょうか。H-IIBも控えてますしね。
creeper2007/09/12 05:55
http://lovelove.rabi-en-rose.net/blog.php?n=256

今回はcygwinのgccつかってます。
まぁ、ソース見ての通りこの問題が1:1になるのは自明で、
かつrandの結果は偶数奇数が交互に出るようなこともなく、
おかしな偏りも無かったのでOKということで。