ペンシルパズルsolver開発はプログラミングのよいトレーニングになり

最近はまってました。楽しかった。もう飽きたけどorz
作ったのは数独、お絵かきロジック、スリザーリング、カックロです。ソースの公開予定はないです(^^;
この手のパズルは基本的に総当たりで試してあっている入力を返します。ただし本当に総当たりだととんでもない組み合わせになるので動的計画法や枝刈りで総数を減らします。この総数をどうやって減らすかが高速化のカギになっていると思います。ちなみに後から知ったのですがこの方法、「バックトラッキング」という名前が付いていました。そーなのかー。

実際、これらのプログラムは既にいっぱい作られているのでほしければ持ってくれば良いだけですが実際に自力で作ることはアルゴリズムプログラミングのいいトレーニングになると思います。また如何に効率化を考えればより一層、論理的思考のトレーニングになります。もちろん、その言語そのものの実装力のトレーニングにもなります。今回でも少し技術力UPした・・・と思いたいです(^^;

11月も12月も2016年も終了し、1月も終了しそうです

忙しすぎて書けませんでした。まあいつものことですが。
最近にしては珍しく、開発で忙しかったのでそこそこネタはたまっています。ですがまとめる時間がありません。もう少し余裕が出始めたらちょくちょくネタだしします。

最近の変化としてはswiftの勉強を始めました。そのうちiPhoneアプリを作ろうと考えております。Mac Book Proを購入しようか考えていたところ、不具合のニュースを見て早速頓挫しましたが。

Macがなくてもswiftの勉強はできます。IBMがなかなかいいものを用意してくれました。
https://swiftlang.ng.bluemix.net
ここで適当なプログラムを書いて練習しております。
一通り文法が使えるようになったら本格的に始めようと思います。
しかし、肝心の作るアプリのアイデアがない・・・。まあとりあえず既存アプリでもなんでもよいから粗製乱造して経験を溜めるところからスタートですね。

今年中にそこそこ実用的なアプリがUPできるといいなー。

浮動小数比較の落とし穴

業務でリファクタリングを実施していた。演算結果が変わらないように毎回比較して違っていればエラーを吐くようにして、改良を進めていた。

if( std::abs( result - test ) > std::numeric_limits< double >::epsilon() ){
	std::cout << "error : " << result << " , " << test << std::endl;
}

浮動小数点は演算が一致する保証がないので、その差が非常に小さい値であるかどうかで評価する、まあ数値計算での基本ですね。
何の変哲もない上記のコード、実は大きな落とし穴があった。私はこれにはまってかなりの工数を無駄にしてしまった。

double型には普通の数値以外にいくつか特別な表現がある。例えば0割をした場合に∞になったりする。その特別表現の一つにNaNがある。NaNとは、Not a Numberという意味で、つまりは「数値ではない」という意味です。数学的には0/0等の不定形の演算を施すと出てくるおうです。
今回、改良中に何を間違ったのか結果がNaNを返すようになっていた。NaNの演算規則はよくわからないが、とりあえず数値比較演算は相手が何であれすべてfalseを返すっぽいです。なので上記のコードはresultとtestが異なるにも関わらずifをすり抜けてしまいます。エラーが出ないから演算結果が一致していると思って進めていて結果、全部やり直しになってしまいました。orz
とうわけで、上記コードをNaNにも対応できるように少し修正してみました。

if( !( std::abs( result - test ) <= std::numeric_limits< double >::epsilon() ) ){
	std::cout << "error : " << result << " , " << test << std::endl;
}

数学的には全く同じですが、NaNの場合は不等号が必ずfalseになるので、不等号の向きを逆にすることによりNaNの場合もifに入ることになります。

次回から気をつけます。

9月も10月も終了しました

さて、この2カ月で私はどれだけ成長できたか?何の進歩もしていない気がして残念。
仕事が微妙に忙しくて帰る時間が酷いことになっており、特に面白そうな進捗はありません。残念。
11月もまだまだ微妙に忙しそうです。お手伝い仕事、引き受けるんじゃなかった。失敗。

8月も終了しました

8月第一週に夏休みがあった。ただし会社から付与されているのは1日だけ。残り4日は有給休暇を強制消化させられた。労基法的にどうなんだろうと思うのだがまあ仕方がない。
今年の夏休みはきつかった。いや、人の親になった時点で自分の休みなどなくなるものだからそれは仕方がないが今年は格別だった。
うちには現在、6歳の娘と1歳の息子がいる。普段、上の子は幼稚園の預かり保育で下の子が認可保育園に通っている。上の子は預かり保育を嫌がっているので私の夏休み中は行かなかった。下の子はそもそも制度として預かれなかった。市の方針なのかその保育園の方針なのかわからないが、親が休みの日は預かれないそうだ。そして妻は産休明けということで今年の夏休みはなし。ただし6カ月経った10月以降に休みを取ることが可能だそうだ。なかなか厳しい会社である。そういうわけで夏休み中は2人の子供を私が一人で見ることになった。昨年は妻が産休中で常に下の子を見てくれていたので上の子だけを見ていればよかった。それ以前も上の子だけ見ていればよかったしそもそも保育園で預かってもらえたので適度に休むことができた。というわけで二人同時に見るのは今年が初めてである。
ただでさえ子供を2人見るのは大変な上に困ったことに2人は年が離れている。一緒に遊ぶこともできなければどこかに連れていくにもかなり制限がかかる。例えば昨年は上の子をプールに連れていったのだが、下の子はまだプールに入れないから二人同時に見ることができない。下の子が騒ぐので映画館も無理。遊園地も上の子が一人で乗れる乗り物が少ないので難しい。というわけで下の子を見ながら上の子を退屈させないで色々な場所に連れていくのは骨が折れました。
実家に帰るにも下の子はまだ卒乳していないので泊まれない。日帰りで行くには少々遠いので今年は帰りませんでした。

さて、ただでさえ見るのに忙しいのに私の体にだんだん異変が起き始めていた。最初は胃に違和感があったのだがだんだん痛さがひどくなってきた。かなり痛くなってきて流石にこれはおかしいと思い病院に行ってきた。ちなみに病院に行くのにも一苦労。子供を連れていくわけにもいかないし預ける場所もないので、妻に少し早く帰ってきてもらって病院の受付終了ぎりぎりに行きました。そして診断結果は・・・結論からいうとよくわからかった。腹部の検査を行ったがすべて正常、しょうがないから一応整腸剤が処方されました。このときは私も医師も根本的に勘違いしていました。その後、痛みはさらに強くなっていき、さらに広範囲になってきた。さらにある日、風呂に入るために服を脱いでいたら後ろにいた娘がすさまじい顔で見ていた。どうしたのか尋ねたら何か出来ているという。鏡で頑張って見てみたら見事な発疹ができていました。そして次の日に病院に行って診断結果は「帯状疱疹」でした。そう、最初は痛みが局所的だったので場所的にも胃の病気だと思ったのだが実は皮膚の病気でした。検査しても何も出ないはずでした。無事診断も出来て投薬治療が始まったわけでしたが2週間くらいは強い痛みに悩まされました。そんな痛みの中、二人の子供を見るのはかなりきつかったです。

来年以降は下の子も卒乳して行ける範囲も広がるだろうし、上の子も小学生なので友達の家に行ったりもう少し一人で行動もできるようになるだろう。そして妻も休みがとれるはずなので四六時中私が見る必要もなくなるだろう。ましてや帯状疱疹にまたなることは・・・。

おそらく今年は人生で最大な苦難の夏休みであっただろう。ていうかあってくれ。

テンプレート引数に自身を継承したクラスのみ受け付ける方法

昨日のトピックの例のように、継承して自身を基底クラスのテンプレートに渡すというタイプのライブラリはしばしば見かけます。

//あるライブラリにおいて・・・
template< class T >
class Library;

//継承してから自分自身をテンプレート引数に渡す
class MyClass:public Library< MyClass >

こういったライブラリの場合、テンプレートに異なるクラスを渡されたら困ります。なのでその場合にわかりやすいエラーが返ってくることが望ましいです。
C++11からtype_traitsというライブラリが入りました。最初、これを見たとき一体何に使うのか全く分からなかったのですが(いや今でもよくわかってないですが)今回のような場合にとりあえず使えます。
リファレンスを調べたらありました、継承関係にあるかどうかを調べるライブラリが。
http://www.cplusplus.com/reference/type_traits/is_base_of/
こいつを使えばわかりやすいエラーを返せるような実装ができそうです。

template< class T >
class Library
{
	static_assert( std::is_base_of< Library, T >::value, "template T must be base of this" );
};

これで適切なコンパイルエラーを返すことができるようになりました・・・。と思ったのですが正しく使っても出るようです。

error C2139: 'MyClass' : 定義されていないクラスは、コンパイラの組み込み型の特徴である '__is_base_of' への引数として使用できません

VisualStudioでの例ですがおそらく他のコンパイラでも同様かと思います。
要するに自作のクラスMyClassは少なくともこの時点(is_base_of)では不完全でありますよと。確かに継承の最中なので不完全でしょうね。というわけで他の実装方法が必要なのですが・・・。あまり綺麗ではないかもしれないがコンストラクタに入れるという策をとりました。

template< class T >
class Library{
public:
	Library(){
		static_assert( std::is_base_of< Library, T >::value, "template T must be base of this" );
	}
};

これでコンストラクタを呼ばれる場所まで評価されないので継承先のクラスも完成した後なので問題がない。
ただしこれ別の問題があって、コンストラクタが呼ばれるような実装でないと評価されない、つまり、継承先のクラスを実際に使うような実施になっていなければテンプレート引数が間違っていてもエラーを返しません。
自作のクラスで使う分には問題ないでしょうが、さらにライブラリを作る場合は問題になる場合があるかもしれませんね。