匿名メソッドで再帰を実装する時

通常匿名メソッドを実装する時は、宣言と代入が同じになるパターンが多い。

例えば、下記のコードのように。

public void 匿名メソッドで再帰()
{
Func<int, bool> カウントダウン = (x) =>
{
if (x == 0)
{
return true;
}
Console.WriteLine(x);
x--;
return カウントダウン(x);
};
カウントダウン(40);
}

しかし、上記のコードだと、

未割り当てのローカル変数 'カウントダウン' が使用されました。

と言われてコンパイルエラーになる。

では、どうしたら良いかというと、先に匿名メソッドを代入する変数を宣言しておけばよい。

下記のコードならコンパイルエラーにならないで正しく動作する。

public void 匿名メソッドで再帰()
{
Func<int, bool> カウントダウン = null;
カウントダウン = (x) =>
{
if (x == 0)
{
return true;
}
Console.WriteLine(x);
x--;
return カウントダウン(x);
};
カウントダウン(40);
}
Share

パズル:nまでの整数を二つの組に分けて合計した結果が同じ時のnについて見つけた法則の実証をバイナリサーチで

なんでそうなのかをコンピュータによる実証以外に証明する事ができないので、ドラクエで言うと、まだ冒険の書を作ったところ。

いや、冒険の書すら作れていないのか。

nまでの整数を二つの組に分けて合計した結果が同じ時のnについて見つけた法則 – NAL-6295の舌先三寸

最近、続けている話題ですが、とりあえず見つけた法則が正しいのかどうかを実証するために法則を見つける前のコードをPCで実行させてみたら、さすがに死ぬほど時間がかかって800000に辿りつくまでですら一晩かかったので、バイナリサーチで書き直してみた。

配列なら、Array.BinarySearchがあるのだけれども・・・。

バイナリサーチにしたら、intの幅に関しては、1時間20分くらいで、戻ってくるようになった。

アルゴリズム一つでぜんぜん違うという事を改めて(今更ながら)実感。

public void nまでの整数を二つの組に分けて合計した結果が同じだった数字リスト実証()
{
Func<int, bool> 奇数が奇数個ある = x => ((x / 2) + (x % 2)) % 2 != 0;
//Enumerable.Select().Sum()は使わない方向で
Func<long, long, long> xからyまでの計 = (x, y) => ((x + y) * ((y - x + 1) / 2)) + (((y + x) / 2) * ((y - x + 1) % 2));
Func<int, long,long,long, bool> nまでの数字の合計の半分とnを二つの組にした合計が同じものがある = null;
nまでの数字の合計の半分とnを二つの組にした合計が同じものがある = (n, 総和の半分, 始点, 終点) =>
{
long 探索点 = (終点 + 始点) / 2;
long 総和 = xからyまでの計(探索点, (long)n);
if (総和 == 総和の半分)
{
return true;
}
if (始点 == 終点)
{
return false;
}
if (総和 > 総和の半分)
{
始点 = 探索点;
}
else
{
終点 = 探索点;
}
if (始点 + 1 == 終点)
{
if (総和 > 総和の半分)
{
始点++;
}
else
{
終点--;
}
}
return nまでの数字の合計の半分とnを二つの組にした合計が同じものがある(n, 総和の半分, 始点, 終点);
};
var 該当するnのリスト = Enumerable
.Range(2, int.MaxValue - 2)
.Where(n => !奇数が奇数個ある(n) && nまでの数字の合計の半分とnを二つの組にした合計が同じものがある(n, xからyまでの計(1, n) / 2, 1, n))
.Select(n => n);
foreach (var n in 該当するnのリスト)
{
Console.WriteLine(n);
}
}
Share
カテゴリー: C#

実力があっても生かせないのなら、会社にとっては実力が無いのと同じ

いろいろと、勿体ないけど、実力があってもそれを利用して仕事に生かせないのなら会社にとっては実力が無いのと同じだ。

炊飯する実力はあるのに炊飯ボタンが無い炊飯器のようなもん。

つまり、インタフェースが無くちゃ駄目だということ。

本当に実力がある人はちゃんと報われているはず。

ちなみに実力があるということと、知識が豊富ということは必ずしもイコールではない。

道具を持ってしまったばかりに、道具に使われちゃう人もいますからね。

Share

10のコーディングルール

以前、コードの10戒と題して、犬の10戒をまねしたコーディングルールを掲載しました。

しかし、若干カジュアルすぎるため仕事に適用するには文体を改修する必要があるかもしれません。

長いコーディング標準は、読むのも守るのもメンテするのも大変です。

なので、短いけど守ってほしい事と理由を犬の10戒の真似をしてまとめてみました。

コードの10戒 – NAL-6295の舌先三寸

そこで今回は、これを少しフォーマルなものにしてみました。

  • 1.識別子(名前)は分かりやすいものにすること。
    参画するメンバーにより理解してもらうために分かりやすい名前にすること。
    メソッド名等が文章になってもかまわない。
    何をしようとしているのかを明示すること。
    全ての識別子はその存在理由が明確である必要がある。
    また、その存在理由以外の目的で利用しないこと。
  • 2.”共通"とか"common"といった名前を利用しないこと。
    共通で利用するメソッドや定数やクラスも、必ず存在理由がある。
    その役割にあった場所に配置すること。
  • 3.事前条件、事後条件を利用すること。
    メソッドの処理に入る前に引数がとりえる範囲を事前条件として指定し、範囲外であれば例外を飛ばして排除すること。
    そうすることで処理中で考えなくてはいけない範囲を狭く出来る。
  • 4.スコープは最小にすること。
    複数の問題が同時に存在していると、ミスリードしてバグを誘発する可能性が高くなる。
    変数のスコープだけではなく、処理、問題等全てのスコープを最小にすること。
  • 5.「将来のため」のコードを残さないこと。
    不必要なコードを「将来のため」といった理由で作りこまないこと。
    必要になってから作ったコードは使われるが、
    「将来のため」に作ったコードは使うかもしれないし、使わないかもしれない。
  • 6.作るときにチューニングをしないこと。
    チューニングは非機能要求にそった計測後、足りていない部分においてのみ行う事。
    コードの調和の取れた構成をできるだけ崩さないようにするため。
  • 7.レビューを行うこと。
    コードは必ずレビューをすること。
    また、レビューにおいて指摘された点は速やかに修正すること。
    複数の視点で見たコードはより分かりやすくなるため。
  • 8.テストをすること。
    コードは思いどおりには動かない。
    自分が思ったとおりにコードを書いているかテストして確認すること。
    そして思い通りに動かないときは、まず自分を疑うこと。
  • 9.バージョン管理は構成管理ツールに任せること。
    コードをコメントにして残さないこと。
    修正履歴をコメントで残さないこと。
    その全てを構成管理ツールに任せること。
  • 10.保守で修正する前に、必要な範囲の構成について理解すること。
    修正する箇所だけではなく、その周辺の構成に理解したうえで、その秩序を乱さないように修正すること。
Share

nまでの整数を二つの組に分けて合計した結果が同じ時のnについて見つけた法則

私以外、誰も楽しくない話題ですが・・・

前回のエントリで、

出力された値を眺めていたら、どうも法則があることが分かった。

3は例外として、それ以降の値については、常に前回値×6-(前々回値-2)となるっぽい。

多分、知っている人には当たり前の事なんだろうなと思いつつ。

パズル:nまでの整数を二つの組に分けて合計した結果が同じだった2番目と3番目を出力する その2 – NAL-6295の舌先三寸

という法則を見つけて

N¥tiny nを任意の整数とし

N¥tiny 0¥large =-1

N¥tiny 1¥large =0

としたとき、

N¥tiny n+1¥large=N¥tiny n ¥large 6-(N¥tiny n-1 ¥large -2)

となる。

としていたが、どうも、会社の人に教えてもらったペル数列という数列の偶数番目の時の総和が同じだと言うこともわかった。

ペル数列というのは、

ペル数(ぺるすう、Pell number)は自然数で、n番目のペル数を Pn とおいて以下の式で定義される数列にある項のことである。

P¥tiny 1¥large =1

P¥tiny 2¥large =2

P¥tiny n¥large=P¥tiny n-1 ¥large 2 + P¥tiny n-2

ペル数 – Wikipedia

というものらしい。

で、数列自体は

1, 2, 5, 12, 29, 70, 169, 408, 985, 2378, 5741

となる。

nが偶数の時の総和が

1+2=3

1+2+5+12=20

1+2+5+12+29+70=119

といった具合に、このパズルの正解と同じになる。

とはいえ、なんでそうなのかをコンピュータによる実証以外に証明する事ができないので、ドラクエで言うと、まだ冒険の書を作ったところ。

いや、冒険の書すら作れていないのか。

月曜日には飽きていそうだけど、高校を普通科か理数科にしておけば良かったな。

Share

試しにサンプルアプリにはてブアイコンを追加してみた。

下記の記事でアップロードしてあったサンプルアプリにはてブアイコンを追加してみた。

ブログとは違ってurlが可変じゃないから、ただリンクを貼っただけだから簡単なんだけど。

過去の記事で下記のようなものを作成した。

このサンプルの見た目を、JavaScriptやCSSの勉強もかねて、デザインだけ変更してアップしてみた。

あと、

・入力検証

・ログインしなくてもゲストとして使える

という仕様変更を行った。

http://nal6295test.appspot.com/

やっとアプリケーションをデプロイできるようになったので、過去のサンプルをアップしてみた – NAL-6295の舌先三寸

Share

パズル:nまでの整数を二つの組に分けて合計した結果が同じだった2番目と3番目を出力する その2

問題:1からnまでの整数を二つの組に分けて合計した結果が同じだった2番目と3番目を出力する。

パズル:nまでの整数を二つの組に分けて合計した結果が同じだった2番目と3番目を出力する – NAL-6295の舌先三寸

出力された値を眺めていたら、どうも法則があることが分かった。

3は例外として、それ以降の値については、常に前回値×6-(前々回値-2)となるっぽい。

多分、知っている人には当たり前の事なんだろうなと思いつつ。

数式にするとこんな感じ?勉強していないので表記が間違っているかもしれませんが・・・

N¥tiny nを任意の整数とし

N¥tiny 0¥large =-1

N¥tiny 1¥large =0

としたとき、

N¥tiny n+1¥large=N¥tiny n ¥large 6-(N¥tiny n-1 ¥large -2)

となる。

初めて、texというのをつかったけど、こんなんで良いのかな?

間違っていたら教えてください。

でも、なんで成り立つのか分からないな。

03
20 3*6-(0-2)
119 20*6-(3-2)
696 119*6-(20-2)
4059 696*6-(119-2)
23660 4059*6-(696-2)
137903 23660*6-(4059-2)
803760 137903*6-(23660-2)

というわけで、プログラムに反映してみた。

ついでなので、仕様もintの範囲で該当する数字全てにしてみた。

public void nまでの整数を二つの組に分けて合計した結果が同じだった数字リスト()
{
Console.WriteLine(3);
int 前回の値 = 3;
int 前々回の値 = 0;
while ((long)前回の値 * (long)6 <= int.MaxValue)
{
int 今回の値 = 前回の値 * 6 - (前々回の値 - 2);
Console.WriteLine(今回の値);
前々回の値 = 前回の値;
前回の値 = 今回の値;
}
}

前のコードだとぜんぜん終わらなかったのに、一瞬で終わるようになった。

当たり前か・・・。

Share
カテゴリー: C#

パズル:nまでの整数を二つの組に分けて合計した結果が同じだった2番目と3番目を出力する

問題:1からnまでの整数を二つの組に分けて合計した結果が同じだった2番目と3番目を出力する。

public void nまでの整数を二つの組に分けて合計した結果が同じだった2番目と3番目()
{
//Enumerable.Select().Sum()は使わない方向で
Func<int, int, int> xからyまでの計 = (int x, int y) => ((x + y) * ((y - x + 1) / 2)) + (((y + x) / 2) * ((y - x + 1) % 2));
Func<int, bool> nまでの数字を二つの組に分けて合計した結果が同じ = (int n) => Enumerable.Range(n / 2, n - (n / 2))
.Where(分ける数字 => xからyまでの計(1, 分ける数字) ==
xからyまでの計(分ける数字 + 1, n))
.Select(x => x).Count() > 0;
int[] 該当するnのリスト = Enumerable.Range(2, int.MaxValue - 2).Where(n => nまでの数字を二つの組に分けて合計した結果が同じ(n))
.Select(n => n)
.Take(3).ToArray();
Console.WriteLine("no2:{0},no3:{1}", 該当するnのリスト[1], 該当するnのリスト[2]);
}
Share

FireFox3が固まりすぎる

ちょっと、ブログを巡回していたら、特定のブログで毎回応答が無くなる。他のブラウザなら大丈夫なので、諦めるんだけど、少しもったいない。

他にも、突然固まることが多い。

まぁ、出たばかりだから仕方ないのかな。

Share
カテゴリー: Tool

犯罪予告由来の犯罪なんて微々たるもの

犯罪予告由来の犯罪なんて微々たるもの。

そもそも、予告してから罪を犯すなんて、お人よしもいいところで、

「なんてネット上は平和なんだ。」

と思う。

ほとんどの犯罪は、予告なんてしないだろうし。

予告の大半は狂言であることが多い。

当たり前だけど、予告が無い犯罪のほうが防ぐのが難しい事は誰でも分かっているわけである。

その状況で、どうして「予告犯罪」と「ネットの危険性」を同じ文脈で語ろうとする記事があるのか疑問に思う。

Share