単方向リストのデータがおかしくなって、ループしているときに、これを判定するにはどうすればよいか。
ループしていれば、先頭からたどっていけば、同じアドレスが出てくるので、ハッシュにでも覚えていけばできる。しかし、情報を2つしか持たなくても以下のようにできる。

bool IsLoop(List p)
{
  List q = p;
  while (p != null && q != (p = p.next) && p != null)
  {
    p = p.next;
    q = q.next;
  }
  return p != null;
}

(@ITの会議室では、ちょっと間違えた。)
pはqの2倍の速さで進むので、ループしていると追いつく。


神社なんかで願い事をするとき、「世界平和」を願っている。(本当の話である) しかし、世界平和とは抽象的すぎる。よく考えると、人によって世界平和の意味は違うような気がする。抽象的な願い事をしても意味がないような気がするし、「XXXの紛争がなくなりますように」とかの方がいいのかもしれない。
全知ならば全能であるはずである。しかし、全能とは実現できないものかもしれない。全知とは、そもそも自己矛盾なのかもしれない。


ソフトウェア開発をシンプルにする考え方のコツに、日付をチェックする機能を作れというのがある。
http://www.atmarkit.co.jp/fdotnet/nagile/nagile02/nagile02_03.html
私だったら、次のように書く。

/// <summary></summary>
public sealed class Date
{
	private int		year;
	private int		month;
	private int		day;
	/// <summary></summary>
	public Date() : this(0, 0, 0) {}
	/// <summary></summary>
	public Date(int y, int m, int d)
	{
		year = y;
		month = m;
		day = d;
	}
	/// <summary></summary>
	public bool IsValid()
	{
		try
		{
			DateTime dt = new DateTime(year, month, day);
		}
		catch (ArgumentException)
		{
			return false;
		}
		return true;
	}
}


要点は、

  1. publicなものには、空でもコメントを書く。(中身はリリースまでになるべく埋める)
  2. アクセス修飾子は、必ず書く。
  3. デフォルトコンストラクタは書く。
  4. このくらいの規模だと、sealedで封印する。
  5. チェックは、コンストラクタでなく別のメソッドを設ける。 結果をキャッシュしない限りプロパティにはしない。
  6. チェックは、楽をできるなら楽をする。(速度が気になるなら自前でチェックするだろうが)
  7. DateTimeはstructである。classとstructの境界は、私の場合、48ビットぐらいだ。

よほどのことがない限りメンバにshortを使わないが、メンバがshortならこのクラスをstructにするだろう。
記事の内容は、トップダウン開発の勧めだが、ある程度、開発の規模が大きくなればボトムアップでもやる方が効率がいいだろう。