ソフトウェア開発したい日記

「面白い!」と思った頭の体操や、数学の問題を載せていきます
その他ロードバイクででかけた先の写真や、ソフト開発のメモ等

【問題10】嘘つき猫 正直猫

2010年03月30日 22時41分42秒 | 頭の体操
【問題10】
1歳から4歳まで、年齢の異なる4匹の猫A,B,C,Dがいます。
猫たちは、年上の猫に対しては嘘の、年下の猫に対しては真実の発言をします。

猫A「猫Bは3歳だよ」
猫C「猫Aは1歳ではないよ」

さて、猫A~Dの年齢は?


 解答はこちら 

【解答】
猫A・・・2歳
猫B・・・4歳
猫C・・・3歳
猫D・・・1歳

猫Cの発言が嘘のとき、猫Aは1歳となりますが、年下の猫に対して嘘はつかないので
猫Cの発言は真実となります。また、猫Cは猫Aより年上となります。

猫Aの発言が真実だとすると、猫Aは4歳、猫Bは3歳となりますが、
猫Aが最年長となってしまい、「猫Cは猫Aより年上」と矛盾します。

すなわち猫Aの発言は嘘で、猫Bは3歳ではなく、猫Aより年上となります。
猫Bが2歳だとすると、猫Aが1歳となり矛盾するため、猫Bは4歳となり
猫Cが3歳、猫Aが2歳、余った1歳が猫Dとなります。



クラスに誕生日の同じ人がいる確率

2010年03月29日 12時38分46秒 | 数学
クラスに誕生日の同じ人がいる確率

直感的でないことで有名ですが、具体的な数値とともに
どれだけ直感とずれているかを考察。

たとえば45人クラスの場合、45人全員の誕生日が異なる確率を求め、
1から引けば良い。(余事象)

45人全員の誕生日が異なる確率は、365P45 / 365^45なので、
45人クラスで誕生日の同じ人がいる確率は、

1 - 365P45 / 365^45 = 0.94097590 = 94.1%

となります。誕生日が同じというのはなかなか起きないことのように見えて、
45人いれば9割以上起こるという、そんな感じのお話。
最近では、小説「数学的にありえない」の中で、この話を利用した賭けが登場していました。Newtonでも最近ので書いてあったような気がします。

ちなみに、
10人クラスの場合 0.11694818 = 11.7%
20人クラスの場合 0.41143838 = 41.1%
30人クラスの場合 0.70631624 = 70.6%
40人クラスの場合 0.89123181 = 89.1%
45人クラスの場合 0.94097590 = 94.1%
50人クラスの場合 0.97037358 = 97.0%
60人クラスの場合 0.99412266 = 99.4%
70人クラスの場合 0.99915958 = 99.9%
となります。

途中までは下に凸の関数、途中からは上に凸の関数となってます。
変曲点となる人数は忘れましたが、グラフから察するに20人くらいのような気がします。

【問題9】メトロノームの音の間隔

2010年03月28日 21時45分08秒 | 頭の体操
【問題9】
あるメトロノームがカチ、カチ・・と6回鳴るのに6秒かかった。
では、このメトロノームが12回鳴るのにかかる時間は何秒?


 解答はこちら 

【解答】
さすがに慌てて12秒、と答える人はほとんど居ないかな?

6回鳴るとき、音と音の間隔の数は5。
1つの間隔に要する時間は、6÷5=1.2秒

12回鳴るとき、音と音の間隔は11なので
12回鳴るのにかかる時間は、1.2×11=13.2秒

なんとなく雰囲気というか、引っ掛け方が
エレベータの問題と似てるような気がしないでもないような

Javaでアニメーションgifの書き出し

2010年03月27日 21時10分55秒 | ソフト開発日記
シミュレータの映像をgifアニメで書き出したい。
というわけで、gifアニメの作成方法のメモ。

IDEは相変わらずNetBeansで。

まずは適当な場所で変数等宣言。

public static BufferedImage buffer;
Iterator it = ImageIO.getImageWritersByFormatName("gif");
ImageWriter iw = it.hasNext() ? (ImageWriter) it.next() : null;
File outfile = new File("書き出すファイルのパス.gif");

録画ボタンを押したときのアクションに、次のようなソースを入れる。

try {
 ImageOutputStream ios = ImageIO.createImageOutputStream(outfile);
 iw.setOutput(ios);
 iw.prepareWriteSequence(null);
} catch (IOException ex) {ex.printStackTrace(); }
page = 0;
rec = true;

Threadクラスを継承し、run()メソッドをオーバーライドしたクラスの
whileループの中の、repaint()メソッドの後に次のようなソースを挿入。

if (rec) {
 try {
  Thread.sleep(10);
  iw.writeToSequence(new IIOImage(buffer, null, null), null);
  page++;
  if (page > MAX_PAGE || stop) {
   iw.endWriteSequence();
   rec = false;
  }

 } catch (IOException ex) { ex.printStackTrace();}
}

これで、シーケンスの数がMAX_PAGEになるか、boolean型のstopがtrueに
なるまでiwに書き続け、iw.endWriteSequence()で終わりの1枚を書き出してgifアニメの完成。

それから、描画先はすべてBufferedImageのbufferにする必要があり
オーバーライドするpaintComponentメソッドは次のように書く。


public void paintComponent(Graphics gBuf){
 super.paintComponent(gBuf);
 if(Mechanics.buffer == null){
  Mechanics.buffer = new BufferedImage(this.getWidth(), this.getHeight(), BufferedImage.TYPE_INT_RGB);
 }
 Graphics g = buffer.createGraphics();

/* ここからBufferedImageに描画していく */
 g.drawRect・・・

/* 最後にBufferedImageに描画されたものを表示 */
 gBuf.drawImage(buffer, 0, 0, this);
}


こんな感じかなぁ。一応できたけれど、上のほうで書いた
Thread.sleep(10);くらい処理待ちさせないと、repaint()による描画が完了する前にシーケンスに書き込むっぽくて
チカチカしたgifアニメになってしまう。
FPS調整はしているけども、シーケンス書き込む処理が重いせいっぽい。
自分のパソコンがちょっと古いってのもあるだろうけど・・

とりあえず一応gifアニメ生成できたってことでよしとして
今後はより最適な書き出し方や、gifアニメのシーケンスの切り替え速さや
アニメーションの繰り返し回数なんかを設定していきたいなぁ