鳩山政権 友愛精神の定義

http://sankei.jp.msn.com/politics/policy/091112/plc0911122212018-n1.htm
至ってまともな話。

政治ネタは怖くて手を出したくないのですが、ずっとよくわからなかった『友愛(精神)』の定義を見つけることができたようなのでメモ。なお、政治的意図は無い旨、念のため明記。

私はまず私の抱く政治理念の大元について申し述べたいと思います。その第一は、民主政治のあり方についてであります。およそ民主主義の基調は個人の自由の達成と人格の尊厳とを主張する自由主義にありますが、それは同時に他人の自由と人格の尊厳とを認めることを前提としておることでありまして、私はこれを友愛精神と呼んでおります。要するに、互譲、寛容の精神こそ民主政治を正しく運用させる基本であると思うのであります。

(第22国会。1955年4月25日)鳩山一郎首相の国会演説より

友愛精神は鳩山一郎氏から承継されたようだ。

引用元: http://www.amazon.co.jp/%E6%AD%A6%E5%99%A8%E3%81%A8%E3%81%97%E3%81%A6%E3%81%AE%E3%80%8C%E8%A8%80%E8%91%89%E6%94%BF%E6%B2%BB%E3%80%8D%E2%80%95%E4%B8%8D%E5%88%A9%E7%9B%8A%E5%88%86%E9%85%8D%E6%99%82%E4%BB%A3%E3%81%AE%E6%94%BF%E6%B2%BB%E6%89%8B%E6%B3%95-%E8%AC%9B%E8%AB%87%E7%A4%BE%E9%81%B8%E6%9B%B8%E3%83%A1%E3%83%81%E3%82%A8-%E9%AB%98%E7%80%AC-%E6%B7%B3%E4%B8%80/dp/4062583437 p.34。

検索したら全文掲載されていた。

瑕疵担保責任

この仕事の大変な事情 | 日経 xTECH(クロステック)

 さて,ようやく検収を終えて請求書を出し,売上が立ったとしてもまだ油断はできない。もう一つ「瑕疵(かし)担保責任期間」というのがあるのだ。納品後に問題があったことが発覚した場合,無償で修正することを約束する,いわば保証期間みたいなもので,半年から1年程度に設定されることが多いようだ。仕事を終えて,お金も受け取った後,何カ月かしてすっかりほとぼりが冷めたころに「バグが出たんですけど」と連絡があれば,無償で対処しなくてはならない。

もし瑕疵担保責任期間を契約において約定しなかった場合、民法の契約各論が適用されることになるハズ(契約内容による)。民法の契約の定めによれば、売主は買主が善意の場合、「知ったときから1年」の間損害賠償を請求可能。もし、隠れた瑕疵が大きく、目的が不達となる場合は、契約自体を解除できるようになってしまう。
瑕疵担保責任は無過失責任。たとえ、どんなにがんばっていてもバグがあれば損害賠償を請求可能になる。ソフトウェア開発においては、結構重要な法律の話だろう。

担保物権

担保物権の種類

担保物権の通有性

担保物権が通常有する性質(略して、通有性)

  • 付従性
  • 随伴性
    • 担保物権が売却などによって移転した場合、担保物権もそれに従って移転するという性質。
  • 不可分性
  • 上代位性
    • 担保物権の目的物がなんらかの事情によって金銭等のほかのものに代わった場合、担保物権者はこれらのものに対しても権利を行使できるという性質。

担保物権の効力

  • 優先弁済的効力
  • 留置的効力
  • 収益的効力
    • 賃料を債務の弁済にあてる効力。不動産質のみ。

まとめ

留置権 質権 抵当権 先取特権
付従性
随伴性
不可分性
上代位性 ×
優先弁済的効力 ×
留置的効力 × ×
収益的効力 × × ×

IndexOfを使って書き直してみました。

先日の記事:2009-10-12 - (ジラールのF)#関連。
筆者さんからのコメントに触発されてIndexOfを用いて書き直してみました。StringBuilderを使うのがポイントですね。そこそこ速いです。

    private static string get1DimCantorDust(int time)
    {
	if (time == 0) return "X";
	string c = get1DimCantorDust(time-1);
	return c + new String('.', c.Length) + c;
    }
    private static int numOverlap(string p, string patC)
    {
	int num = 0;
	for (int start = patC.IndexOf(p, 0); start != -1; start = patC.IndexOf(p,++start)) ++num;
	return num;
    }
    private static bool isBlank(string[] pat)
    {
        foreach (string p in pat) if (p.IndexOf('X') != -1) return false;
        return true;
    }
    public int occurrencesNumber(string[] pattern, int time)
    {
	StringBuilder projX = new StringBuilder(new String('.', pattern.Length));
	StringBuilder projY = new StringBuilder(new String('.', pattern[0].Length));
        for (int x = 0; x < pattern.Length; ++x)
            for (int y = 0; y < pattern[0].Length; ++y)
                if (pattern[x][y] == 'X') projX[x] = projY[y] = 'X';
        for (int x = 0; x < pattern.Length; ++x)
            for (int y = 0; y < pattern[0].Length; ++y)
                if ((pattern[x][y] == '.') && (projX[x] == 'X') && (projY[y] == 'X')) return 0;

        string patCantor = get1DimCantorDust(time);
        int mX = numOverlap(projX.ToString(), patCantor);
        int mY = numOverlap(projY.ToString(), patCantor);
        return !isBlank(pattern) ? mX * mY :
		mY * (patCantor.Length - pattern.Length + 1) +
		mX * (patCantor.Length - pattern[0].Length + 1) - mX * mY;
    }

「1000のアルゴリズムを持つ男」vs.「やわらか頭脳」の第二問目の解答を試みる

「1000のアルゴリズムを持つ男」vs.「やわらか頭脳」 (1/3) - ITmedia エンタープライズ
前回に引き続き第二問目、2次元カントール集合に関する問題。
回答が与えられているので、答えを新たに考えるわけではありませんが、内容が難しいので、答えを参照しつつ、自分に分かりやすいように書き直しました。特に記事の回答がマズイ等なことを主張しているわけではないですよ、と一応注意。

自分の改変部分について

  1. getstring関数は文字列型を返しますが、結局C[k+x] == 'X'と、ブール値判定を行ったものを用いているので、最初からブール型の1次元カントール集合(2次元カントール集合の射影集合(projection set))を返すようにした。
  2. オーバラップの判定部分を分離してisOverlap関数とした。

あと、個人的には全て'.'で構成されているパターンの計算が難しかったですね。

Code

    private static bool[] get1DimCantorDust(int time)
    {
        if (time == 0) return (new bool[] { true });
        bool[] prev = get1DimCantorDust(time - 1);
        bool[] res = new bool[3 * prev.Length];
        prev.CopyTo(res, 0);
        prev.CopyTo(res, 2 * prev.Length);
        return res;
    }
    private static bool isOverlap(bool[] pat, bool[] patC, int init)
    {
        for (int it = 0; it < pat.Length; ++it) if (pat[it] != patC[init + it]) return false;
        return true;
    }

    private static bool isWhitePattern(string[] pat)
    {
        foreach (string p in pat) if (p.IndexOf('X') != -1) return false;
        return true;
    }
    public int occurrencesNumber(string[] pattern, int time)
    {
        bool[] projX = new bool[pattern.Length];
        bool[] projY = new bool[pattern[0].Length];
        for (int x = 0; x < pattern.Length; ++x)
            for (int y = 0; y < pattern[0].Length; ++y)
                if (pattern[x][y] == 'X') projX[x] = projY[y] = true;
        for (int x = 0; x < pattern.Length; ++x)
            for (int y = 0; y < pattern[0].Length; ++y)
                if ((pattern[x][y] == '.') && projX[x] && projY[y]) return 0;
        bool[] patCantor = get1DimCantorDust(time);

        int mX = 0;
        int mY = 0;
        for (int initX = 0; initX + projX.Length <= patCantor.Length; ++initX)
            if (isOverlap(projX, patCantor, initX)) ++mX;
        for (int initY = 0; initY + projY.Length <= patCantor.Length; ++initY)
            if (isOverlap(projY, patCantor, initY)) ++mY;
        return isWhitePattern(pattern) ?
            mY * (patCantor.Length - pattern.Length + 1) +
            mX * (patCantor.Length - pattern[0].Length + 1) - mX * mY : mX * mY;
    }

結果

Test Case #0...PASSED
Test Case #1...PASSED
Test Case #2...PASSED
Test Case #3...PASSED
Test Case #4...PASSED
Test Case #5...PASSED
Test Case #6...PASSED
Test Case #7...PASSED
Test Case #8...PASSED
Test Case #9...PASSED

「1000のアルゴリズムを持つ男」vs.「やわらか頭脳」の第一問目の解答を試みる

「1000のアルゴリズムを持つ男」vs.「やわらか頭脳」 (1/3) - ITmedia エンタープライズ
こちらの記事の問題が面白そうだったので第一問目だけ解いてみることにしました。あっているかどうかは知りませんのでご注意を。
該当の問題は以下、

人間が1人、モンスターがM匹、ウサギがB匹います。ここから、モンスターか人間がいなくなるまで無作為に2匹(もしくは1人と1匹)を選び出し、以下の行動を繰り返します。
モンスターとモンスターが選ばれると、両方のモンスターが死にます
モンスターとモンスター以外が選ばれると、モンスター以外が殺されてしまいます
ウサギとウサギが選ばれると、何も起こりません
ウサギと人間が選ばれると、人間の生存確率が最も高くなるように、ウサギを殺す、またはそのままにする、のどちらかの選択をします
モンスターの数Mとウサギの数Bが与えられたときに、最後に人間が生き残る確率を答えなさい。ただし、M、Bともに1000以下の整数とする。

難しそうですが、問題文からはすぐに以下のことがわかります。

  • モンスターを消すには、モンスター×モンスターのペアを作る方法しかありません。そのため、もしモンスターの数が奇数でペアが作れなければ、残念なことに人間は生き残ることができません。すなわち、Mが奇数であれば生存確率は常に0%になります。
  • モンスターの数が0のとき、問題文より、ウサギ×人間のペアを作ると人間が生き残ることとなります。すなわち、M=0であればBの数に関係なく人間は必ず生き残ることになります。
    • このことから、(全てのモンスターが消え、かつ、全てのウサギと人間が生き残る確率)==(人間が生き残る確率)という等式がなりたつはずです。
  • ウサギ×ウサギのペアは無視してOK。

以上のことを踏まえ、C#で記述してみると、

amespace TopCoderSolver
{
    class Program
    {
        static void Main(string[] args)
        {
            for (int i = 1; i != 10; ++i)
            {
                System.Console.WriteLine("|{0}|{1}|", i, lifeProbability(i, 0));
            }
        }
        public static double lifeProbability(double M, double B)
        {
            return M == 0 ? 1.0 : M == 1 ? 0 : B == 0 ? (M / (M + 1)) * ((M-1)/M) * lifeProbability(M - 2, 0):
                   (M/(M + B + 1)) * ((M-1)/(M + B)) * lifeProbability( M - 2, B ) + (M/(M + B + 1)) * (B/ (M + B)) * lifeProbability( M, B-1);
        }
    }
}

と、なります。ムリヤリ2行です。正解しているかは、どんなもんでしょう、ちょっとわかりませんね。
B=0で固定し、Mを1〜9まで動かしたときの結果は以下です。

M 生存確率
1 0%
2 0.333333333333333%
3 0%
4 0.2%
5 0%
6 0.142857142857143%
7 0%
8 0.111111111111111%
9 0%
[追記]

いきなり間違いを見つけたので、コードを修正。
[追記]
コードをもう一度修正しました。

[追記]

理論面をうまく説明されているところを見つけました。
天狗人生 : やわらか頭脳か?


ただ、筆者さんからのコメントによれば再帰はつかわないということなので、考え中。

[追記]

Topcoder

the question doesn't ask to compute how fast you win..(1/M+1)
but you could win where number of bunnies is not zero and where bunny meets monster, bunny meets bunny or bunny meets you(could get killed or not) before all monsters die

question is biased to computing the probability of winning in least number of meetings

ウサギは関係ないみたい。問題は納得ができていないところ。

生存確率の定義を勘違いしているのが原因かな。

[追記]

問題文をもう一度読んでみる。

モンスターの数Mとウサギの数Bが与えられたときに、最後に人間が生き残る確率を答えなさい。ただし、M、Bともに1000以下の整数とする。

『ただ一人、人間が生き残る』という条件ではなかった。ウサギが全部生き残ってかつ人間が生き残ってもOKだ。ウサギ関係ない。生存確率はモンスターの数にだけ依存する。
こうかな?

        public static double lifeProbability(double M, double B)
        {
            return M == 0 ? 1.0 : (M + 1) % 2 == 0 ? 0 : 1.0 / (M + 1);
        }

答えは同じ。

[追記]

ブックマークのコメント経由のこれが最短か。

        public static double lifeProbability(int M, int B)
        {
            return (M+1)%2 / (double)(M + 1);
        }

Scripting.Dictionaryをもう少しだけ使いやすく。

VBAにおけるディクショナリ

VBAには標準の配列データ型以外に、Dictionaryというデータ型を用いることが出来ます。
Dictionary型のデータを使う為には、大別して2つの方法が存在します。

1.宣言 Dim dict As New Dictionary を用いる方法。

これは一見お手軽な方法ですが、事前にVBエディタの[ツール(T)]->[参照設定(R)]から[Microsoft Scripting Runtime]のチェック欄にチェックを入れておく必要があります。

この設定後であれば、

Dim dict As New Dictionary

と宣言することでディクショナリ型が使えるようになります。
しかしながら、上記設定をしておかなければ、上記宣言はエラーとなってしまいますので、例えば配布する必要があるEXCELシートで使用する場合、余計な手間、コストがかかることとなります。

2.CreateObject関数を用いる方法。

CreateObject関数はWindowsにおいて基盤部品であるCOMオブジェクトを呼び出す関数です。
この関数を用いることで、1.のような事前の設定無しにディクショナリ型を用いることができます。
宣言例:

Dim dict As Dictionary
Set dict = CreateObject("Scripting.Dictionary")

この方法であれば、たとえ配布するEXCELシートであってもエラー無しに使用することができます。
ただ、2行目のステートメントは呪文めいてて覚えにくいですね。

ファクトリ関数を用いた改善。

1.の方法は簡潔ですが汎用性がありません。一方2.の方法は汎用性がありますが、呪文めいていて、慣れない人には難しいものがあるかと思います。
ファクトリ関数を用いることでこの問題を多少改善することができます。
Factoriesという名前をつけた標準モジュールにおいて以下のようなディクショナリを返すファクトリ関数を記述するとします。

Public Function Dict() As Dictionary
    Set Dict = CreateObject("Scripting.Dictionary")
End Function

この簡単なファクトリ関数を用いることで、

Dim dict As Dictionary
Set dict = Dict

という比較的直感的にディクショナリ型のデータを使用することができるようになります。

番外編:Collectionを用いる方法

VBA標準のCollection型を用いる方法もあります。
Collection型のデータは一般的に動的配列として使用するものだと認知されていると思われますが、実はディクショナリとしても使用することが出来ます。

一般的なCollection型データの使用方法。

Dim collect As New Collection 'Dictionaryと異なり事前の設定は不要
collect.Add 1
collect.Add hello
MsgBox collect.Item(1) '1を表示
MsgBox collect.Item(2) '"hello"を表示

と、このように一般的な動的配列の用途しかなさそうなCollectionデータ型ですが以下のように使うこともできます。

Dim colDict As New Collection
colDict.Add Item:="world",Key:="hello"
colDict.Add "hoge", "fuga"  'Dictionary型とは逆で第一引数に要素、第二引数がキーです。
MsgBox colDict.Item("hello") '"world"を表示
MsgBox colDict.Item("fuga") '"hoge"を表示

身も蓋も無い話をしてしまえば、Dictionary型は使用せずにすべてCollection型で統一してしまうのが、もっとも利便性が高いのかもしれません。
参考:
http://members3.jcom.home.ne.jp/daruma_kyo/info/redim_or_collection.html#df
2009-08-08