プログラマメモ2 - programmer no memo2

目次

[pku] 1008 Maya Calendar 2008/03/30



問題文が長がそうだったので後回しにしていたのをチャレンジ。
マヤのカレンダー
なんかちょっとオカルトっぽい、説があるようで、何か近寄りがたいなマヤカレンダー。



解き方は、えーと、Haabで与えられた値から日にちをもとめて、日にちから、Tzolkinを求めるという方法。

package p1008;

import java.util.Scanner;
import java.util.regex.MatchResult;

public class Main {

public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
System.out.println(n);
for (int i = 0; i < n; i++) {
scanner.findInLine("(\\d+)\\. ([a-z]+) (\\d+)");
MatchResult result = scanner.match();
int pos = 1;
int d = Haab(Integer.parseInt(result.group(pos++)), result
.group(pos++), Integer.parseInt(result.group(pos++)));
System.out.println(Tzolkin(d));
}
}

static int Haab(int d, String m, int y) {
y = y * 365;
int mm = monthOfHaab(m);
return d + (20 * mm) + y;
}

static String Tzolkin(int d) {
int m = d % 20;
int nd = (d % 13) + 1;
int y = (d / 20) / 13;

return String.format("%d %s %d", nd, Tzolkin[m], y);
}

static int monthOfHaab(String s) {
for (int i = 0; i < Haab.length; i++) {
if (Haab[i].equals(s))
return i;
}
throw new RuntimeException("not found Haab month...");
}

static int Tzolkin(String s) {
for (int i = 0; i < Tzolkin.length; i++) {
if (Tzolkin[i].equals(s))
return i + 1;
}
throw new RuntimeException("not found Tzolkin month...");
}

static final String[] Haab = { "pop", "no", "zip", "zotz", "tzec", "xul",
"yoxkin", "mol", "chen", "yax", "zac", "ceh", "mac", "kankin",
"muan", "pax", "koyab", "cumhu", "uayet" };

static final String[] Tzolkin = { "imix", "ik", "akbal", "kan", "chicchan",
"cimi", "manik", "lamat", "muluk", "ok", "chuen", "eb", "ben",
"ix", "mem", "cib", "caban", "eznab", "canac", "ahau" };
}

3値論理 - 論理積 論理和 2008/03/29

3値論理 です。Groovyを使って、論理積 論理和を出力してみました。

論理積
t ^ t = t
t ^ f = f
t ^ u = u
f ^ t = f
f ^ f = f
f ^ u = f
u ^ t = u
u ^ f = f
u ^ u = u
論理和
t ∨ t = t
t ∨ f = t
t ∨ u = t
f ∨ t = t
f ∨ f = f
f ∨ u = u
u ∨ t = t
u ∨ f = u
u ∨ u = u


やはりクロージャーが使えるのはいいですね。
NullPointer例外を発生させるという小手先な方法をとっています。


class PrintThreeValued {
static void main(args) {

def printLogicalProduct = { p, q ->
try {
if(p==null || q==null) throw new NullPointerException()
printf("%s ^ %s = %s%n", p?"t":"f", q?"t":"f", (p && q)?"t":"f");
} catch (e) {
printf("%s ^ %s = %s%n", p == null ? "u" : p?"t":"f",
q == null ? "u" : q?"t":"f", ((p!=null&&!p) || (q!=null&&!q))?"f":"u");
}
}

def printLogicalDisconjunction = { p, q ->
try {
if(p==null || q==null) throw new NullPointerException()
printf("%s ∨ %s = %s%n", p?"t":"f", q?"t":"f", (p || q)?"t":"f");
} catch (e) {
printf("%s ∨ %s = %s%n", p == null ? "u" : p?"t":"f",
q == null ? "u" : q?"t":"f", ((p!=null&&p) || (q!=null&&q))?"t":"u");
}
}

def bs = [true, false, null];

def process = {c ->
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
c(bs[i], bs[j]);
}
}

}
println "論理積";
process(printLogicalProduct)
println "論理和";
process(printLogicalDisconjunction)

}
}

CASE式はSQL-92で標準にとりこまれている。 2008/03/29

CASE式はSQL-92で標準にとりこまれている。
というわけでCASE式を使わない、使えない理由はなんらない。

参照整合性とは 2008/03/29

AがBを参照するのに、Bが存在していないといけないこと。

3値論理を絡めて考えてみた システム間での誕生日の取り扱い。 2008/03/29
2008/03/31

はじめに


実際あるかどうかわからないけど、ちょっと考えてみました。

誕生日って、年月日のことをさしていると思います。
で、誕生時刻っていうのもありそうです。

birth_day
birth_time
とかなんとかなるのでしょうか。

で、これをリレーショナルデータベースで取り扱うというふうに考えてみます。

まあ、一般に、誕生日というのは大抵の人が知っています。
が、しかし、誕生した時刻っていうのは知らない人がいるのではないかと思います。会話の中では、あまりでてこないような気がします(僕だけかもしれませんが...)

誕生時刻を知らない場合には、birth_timeは不明でunknownです。そこで、NULLを入れちゃいたいわけです。

ちなみに、インドの占星術とかで、占うと誕生時刻が必要です。

システム間でおこりそうな問題



あるシステムAでは、ユーザの誕生日しか扱っていませんでした。
あるシステムBでは、ユーザの誕生時刻も必要としていました。

システムAからユーザ情報をシステムBに移行します。
※このときに欠けた情報を収集しなおすことができないという条件とします。

すると、何が起こるでしょうか。

あるシステムAでは、誕生時刻を扱っていないので、あるシステムBに移行する際に、「正しくない」もしくは「明らかではない」情報が入りこむことになります。

システムBは、RDBを使って、SQLを使用してデータベースの操作を行っています。
birth_timeには、NOT NULL制約になっていたとしたら、移行の際に、「正しくない」情報が入ることになります。
たとえば00:00もしくは、23:59で値を入れるとかです。
birth_timeにNULLを入れることができるのであればNULLを入れて《不明(unknown)》ということにできそうです。

さらに...



さらに、あるシステムCにユーザ情報を移動させないといけなくなりました。
あるシステムCは、インド占星術にともなった占いをサポートしています。ユーザの誕生時刻が必要です。

システムCにデータを移行するもととなるシステムBでは、bitrh_timeに「正しくない」情報が入っている可能性があります。「正しくない」情報が、存在する可能性がある理由は、あるシステムAからデータを移行させたことが原因です。

こういうことってありそうな気がするんですがどうでしょうか。

と、いろいろ思考実験していくと、データベースが「あいまい」になる可能性はあるのだなぁと。

3値論理 論理積 2008/03/29

3値論理(three-valued-logic, 3VL)は、
第三の論理値を持つ論理システムのことだそうです。SQLで使われているそうです。



uはunknownの意味です。

論理積 p ^ qを出力してみました。
命題pと命題qが真の時に、真となって、あとはどちらかかfalseだとfalse

t ^ t = t
t ^ f = f
t ^ u = u
f ^ t = f
f ^ f = f
f ^ u = f
u ^ t = u
u ^ f = f
u ^ u = u


論理積を出力するコードです。
NullPointer例外を使ったロジックでなっています。

public class TestBoolean {

public static void main(String[] args) {
b();
}

static void b() {
Boolean[] bs = { true, false, null };
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
printLogicalProduct(bs[i], bs[j]);
}
}

}

static void printLogicalProduct(Boolean p, Boolean q) {
try {
System.out.printf("%s ^ %s = %s%n", p?"t":"f", q?"t":"f", (p && q)?"t":"f");
} catch (NullPointerException e) {
System.out.printf("%s ^ %s = %s%n", p == null ? "u" : p?"t":"f",
q == null ? "u" : q?"t":"f", ((p!=null&&!p) || (q!=null&&!q))?"f":"u");
}
}

// nullpointer ocurred!!
static void a() {
Boolean b = null;
if (b) {
System.out.println("true");
} else {
System.out.println("false");
}
}
}

流れるようなインターフェイスの練習 2008/03/28

「流れるようなインターフェイス」の練習


getter,setterは変更せず、setterには手を加えず、まず、フィールド変数名と同じ名前のsetメソッドを用意して、そのメソッドが自分自身(this)をかえすというイメージかなと。


import java.util.ArrayList;
import java.util.List;

public class TestDoc {

public static void main(String[] args) {

Doc.Author author = new Doc.Author().name("ugo.nakawaka");
Doc.Content content = new Doc.Content().text("test");

Doc doc = new Doc().author(author)
.content(content);

DocDoc docDoc = new DocDoc();
docDoc.add(doc).add(doc);

}

static class DocDoc {
List<Doc> list = new ArrayList<Doc>();
public DocDoc(){}

public DocDoc add(Doc doc){
list.add(doc);
return this;
}

}

static class Doc {

Content content;
Author author;

public static class Author {
String name;
public Author(){}
public Author name(String name){
this.name = name;
return this;
}
}
public static class Content {
String text;
public Content(){}
public Content text(String text){
this.text = text;
return this;
}
}
public Author getAuthor() {
return author;
}
public Content getContent() {
return content;
}
public Doc author(Author author) {
this.author = author;
return this;
}
public Doc content(Content content) {
this.content = content;
return this;
}
}
}


計測せずに、「絶対」という言葉を使うのは危険だなと。

メタファとアナロジー 2008/03/27

僕が会話のなかでメタファーとかなんとかいうときは、メタファーというのがかっこいいとかなんとか思ってるからだろけども、たぶんに、正確ではない、というか不正確かも。
なんかアナロジーといったほうがいいような文脈で使ってるかも。

雑記 おぶじぇくとしこう 2008/03/27

ナイーブな自分


オブジェクト指向について、僕が、昔、感じて考えてことは、これって世界を写し取れるかも、という、まあ壮大なことだったわけです。
それで、プログラム書けるってすごいなぁとか思いつつ、いつか、思いのままにオブジェクトを作って、世界をいじるんだとか思ってたかも知れません。しかし、いまは、そんなナイーブなことは考えていません。

結局は、オブジェクトを作る人の主観なわけです。


結局は、クラスを作る人の主観なわけですと、言い切ってしまうのも、どうかと思うのですが、そんなにはずれてないと思います。現実をスケッチして、がんばって表現しようとしてもですよ、それはやはり現実、現象のある一面を捉えているものでしかないわけであって、それは《あなたの世界》をこえて存在しているわけではないと思うのです。
その人の受けた学校教育や、それまでの経験、読んだ本、経験してきたプロジェクトとか、世界観がもろに反映していると思うのです。

なぜ、こんなことを書く方いいますと


がんばってオブジェクト脳をつくらなければいけない必要もないわけで、自分が相手にしているシステムの、問題領域(ドメイン)にまあせいぜい注意して、がんばっていこうかなという意思表示なわけなのでした。

じゃんけんプログラムを条件分岐なしで。 2008/03/26

アルゴリズム・サイエンス:入口からの超入門 (アルゴリズム・サイエンスシリーズ―超入門編)
浅野 哲夫
4320121678

立ち読みしていて、「第8章 分岐命令の威力 - 分岐の除去」という項目を読んでなるほどと思ったしだい。

じゃんけんプログラムで条件分岐をなくしてみます。
簡単なじゃんけんプログラムを作成してみます。
結果を導くを方法に、if文を使った条件分岐版と、条件分岐を使わないで結果を求める方法で作成してみました。
ユーザが入力した値と、コンピュータがランダムでだした値で比較するというものです。

条件分岐(if)をネストするのがつねづねいやだいやだと思ってるいる人なので、
「条件分岐をなくす」が、僕的に目からうろこ状態だったのでした。

ユーザの状態3通り、コンピュータの状態3通りなので、9通りの結果が導きだせます。


import java.util.Random;
import java.util.Scanner;

public class Janken {

public static void main(String[] args) {

System.out.println("永遠にじゃんけんします。");
String[] t = { "グー", "チョキ", "パー" };
System.out.println("入力してください。入力してEnter 0:グー 1:チョキ 2:パー");
Scanner scanner = new Scanner(System.in);
while (true) {
int u = scanner.nextInt();
int r = r();
System.out.printf("あなた:%s コンピュータ:%s%n", t[u], t[r]);
System.out.println("条件分岐版:" + a(u, r));
System.out.println("条件分岐なし版:" + b(u, r));
}
}

/**
* 条件分岐して結果をとりだします。
* @param u
* @param r
* @return
*/
static String a(int u, int r) {

if (u == r)
return "あいこ";

if ((u == 0 && r == 1) || (u == 1 && r == 2) || (u == 2 && r == 0))
return "あなたの勝ち";

return "you lose!!";
}

/**
* 条件分岐をせずに結果をとりだします。
* @param u
* @param r
* @return
*/
static String b(int u, int r) {
String[][] t = { { "あいこ", "あなたの勝ち", "you lose!!" },
{ "you lose!!", "あいこ", "あなたの勝ち" },
{ "あなたの勝ち", "you lose!!", "あいこ" } };
return t[u][r];
}

static int r() {
return new Random().nextInt(3);
}
}

生産者と消費者とsynchronized 2008/03/25

Javaです。
生産者と消費者の実験のためのコード。

スタックに生産者がつんでいくのを消費者がpopして減らしていくというイメージ。
お互い壱秒休んで作業して休んで作業の繰り返しです。

import java.util.Stack;

public class TestT4 {
public static void main(String[] args) {

final Stack<Integer> stack = new Stack<Integer>();

Runnable consumer = new Runnable() {
public void run() {
while (true) {
sleep(1000);
synchronized (stack) {
if (!stack.isEmpty())
stack.pop();
}

}
}
};

Runnable producer = new Runnable() {
int cnt = 0;

public void run() {
while (true) {
sleep(1000);
synchronized (stack) {
stack.push(cnt++);
}

}
}
};

Runnable observer = new Runnable() {
public void run() {
while (true) {
sleep(1000);
System.out.println("" + stack);
}
}
};

new Thread(producer).start();
new Thread(producer).start();
new Thread(consumer).start();
new Thread(consumer).start();
new Thread(consumer).start();
new Thread(observer).start();
}

static void sleep(long l) {
try {
Thread.sleep(l);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}


まずいコードです。
消費者の数が増える例外をだす可能性が増えます。
でる例外は、java.util.EmptyStackExceptionです。
stackが空ではなかったらpopするとしているのですが、空ではないと判断した直後で別の消費者がpopしてしまう可能性があります。
import java.util.Stack;

public class TestT4 {
public static void main(String[] args) {

final Stack<Integer> stack = new Stack<Integer>();

Runnable consumer = new Runnable() {
public void run() {
while (true) {
sleep(1000);
if (!stack.isEmpty())
stack.pop();
}
}
};

Runnable producer = new Runnable() {
int cnt = 0;
public void run() {
while (true) {
sleep(1000);
stack.push(cnt++);
}
}
};

Runnable observer = new Runnable() {
public void run() {
while (true) {
sleep(1000);
System.out.println("" + stack);
}
}
};

new Thread(producer).start();
new Thread(producer).start();
new Thread(consumer).start();
new Thread(consumer).start();
new Thread(consumer).start();
new Thread(observer).start();
}

static void sleep(long l) {
try {
Thread.sleep(l);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

ポアソン分布の理解のための手習い。その3 2008/03/25

ますます自信がないですが...
ポアソン分布です。
PoissonGeneratorを使っているからポアソン分布です...

えーと、壱時間に平均100回おきる事象があり、それが毎分ごとどれぐらいでおきるかというのをシュミレートしてみるというのが趣旨です。

まず100を60でわって平均を求めてそれをPoissonGeneratorに渡すというふうにしてみました。
それで、毎分ごとにおきる事象の回数を求めるという感じです。

結果です。なんとなく現実でもおこりそうな感じがでてるような気がしますが、どうでしょう?

mean:1.666667
1分 起きた回数の総数:1 起きた回数:1
2分 起きた回数の総数:1 起きた回数:0
3分 起きた回数の総数:4 起きた回数:3
4分 起きた回数の総数:6 起きた回数:2
5分 起きた回数の総数:6 起きた回数:0
6分 起きた回数の総数:8 起きた回数:2
7分 起きた回数の総数:10 起きた回数:2
8分 起きた回数の総数:10 起きた回数:0
9分 起きた回数の総数:11 起きた回数:1
10分 起きた回数の総数:13 起きた回数:2
11分 起きた回数の総数:13 起きた回数:0
12分 起きた回数の総数:17 起きた回数:4
13分 起きた回数の総数:22 起きた回数:5
14分 起きた回数の総数:24 起きた回数:2
15分 起きた回数の総数:24 起きた回数:0
16分 起きた回数の総数:24 起きた回数:0
17分 起きた回数の総数:27 起きた回数:3
18分 起きた回数の総数:28 起きた回数:1
19分 起きた回数の総数:28 起きた回数:0
20分 起きた回数の総数:28 起きた回数:0
21分 起きた回数の総数:31 起きた回数:3
22分 起きた回数の総数:33 起きた回数:2
23分 起きた回数の総数:35 起きた回数:2
24分 起きた回数の総数:35 起きた回数:0
25分 起きた回数の総数:36 起きた回数:1
26分 起きた回数の総数:38 起きた回数:2
27分 起きた回数の総数:41 起きた回数:3
28分 起きた回数の総数:43 起きた回数:2
29分 起きた回数の総数:44 起きた回数:1
30分 起きた回数の総数:45 起きた回数:1
31分 起きた回数の総数:46 起きた回数:1
32分 起きた回数の総数:47 起きた回数:1
33分 起きた回数の総数:48 起きた回数:1
34分 起きた回数の総数:50 起きた回数:2
35分 起きた回数の総数:52 起きた回数:2
36分 起きた回数の総数:55 起きた回数:3
37分 起きた回数の総数:56 起きた回数:1
38分 起きた回数の総数:59 起きた回数:3
39分 起きた回数の総数:61 起きた回数:2
40分 起きた回数の総数:62 起きた回数:1
41分 起きた回数の総数:64 起きた回数:2
42分 起きた回数の総数:65 起きた回数:1
43分 起きた回数の総数:66 起きた回数:1
44分 起きた回数の総数:67 起きた回数:1
45分 起きた回数の総数:67 起きた回数:0
46分 起きた回数の総数:68 起きた回数:1
47分 起きた回数の総数:69 起きた回数:1
48分 起きた回数の総数:69 起きた回数:0
49分 起きた回数の総数:73 起きた回数:4
50分 起きた回数の総数:73 起きた回数:0
51分 起きた回数の総数:77 起きた回数:4
52分 起きた回数の総数:81 起きた回数:4
53分 起きた回数の総数:83 起きた回数:2
54分 起きた回数の総数:90 起きた回数:7
55分 起きた回数の総数:93 起きた回数:3
56分 起きた回数の総数:97 起きた回数:4
57分 起きた回数の総数:98 起きた回数:1
58分 起きた回数の総数:98 起きた回数:0
59分 起きた回数の総数:100 起きた回数:2
60分 起きた回数の総数:102 起きた回数:2


import java.util.Random;

import org.uncommons.maths.random.PoissonGenerator;

public class TestT2 {
public static void main(String[] args) {

int occured = 0;
//壱時間に平均100回おきる事象
double mean = 100d/60d;
System.out.printf("mean:%f%n", mean);
//分ごとにその事象がおきることをシュミレートしてみる
for(int i=1;i<=60;i++){
int r = r(mean);
occured += r;
System.out.printf("%d分 起きた回数の総数:%d 起きた回数:%d%n",i, occured, r);
}

}

static int r(double mean) {
Random random = new Random();
PoissonGenerator generator = new PoissonGenerator(mean, random);
return generator.nextValue();
}
}

ポアソン分布の理解のための手習い。その2 2008/03/25

ポアソン分布です。Javaです。
使ってみたライブラリは、



ポアソン分布の平均および分散は、λ に等しい。ポアソン分布 - Wikipedia


λが10とした場合、
100回生成して、生成するごとに平均をとっていきます。
なんとなく平均におさまっていきますね。
多分、そういうことだと思う。

10万回行った場合は、
count:100000 r: 6 a:998012 mean:9.980

10にますます近づく。

count: 1 r: 5 a:5 mean:5.000
count: 2 r: 6 a:11 mean:5.500
count: 3 r:17 a:28 mean:9.333
count: 4 r:11 a:39 mean:9.750
count: 5 r: 7 a:46 mean:9.200
count: 6 r: 8 a:54 mean:9.000
count: 7 r: 9 a:63 mean:9.000
count: 8 r:11 a:74 mean:9.250
count: 9 r: 6 a:80 mean:8.889
count:10 r:13 a:93 mean:9.300
count:11 r:10 a:103 mean:9.364
count:12 r:11 a:114 mean:9.500
count:13 r: 7 a:121 mean:9.308
count:14 r:13 a:134 mean:9.571
count:15 r:10 a:144 mean:9.600
count:16 r:13 a:157 mean:9.813
count:17 r: 5 a:162 mean:9.529
count:18 r:11 a:173 mean:9.611
count:19 r: 8 a:181 mean:9.526
count:20 r: 7 a:188 mean:9.400
count:21 r: 7 a:195 mean:9.286
count:22 r: 9 a:204 mean:9.273
count:23 r:11 a:215 mean:9.348
count:24 r: 6 a:221 mean:9.208
count:25 r: 6 a:227 mean:9.080
count:26 r:11 a:238 mean:9.154
count:27 r:10 a:248 mean:9.185
count:28 r:15 a:263 mean:9.393
count:29 r: 8 a:271 mean:9.345
count:30 r:11 a:282 mean:9.400
count:31 r:14 a:296 mean:9.548
count:32 r:11 a:307 mean:9.594
count:33 r:15 a:322 mean:9.758
count:34 r: 9 a:331 mean:9.735
count:35 r:10 a:341 mean:9.743
count:36 r:11 a:352 mean:9.778
count:37 r: 8 a:360 mean:9.730
count:38 r:10 a:370 mean:9.737
count:39 r: 4 a:374 mean:9.590
count:40 r:13 a:387 mean:9.675
count:41 r: 7 a:394 mean:9.610
count:42 r:11 a:405 mean:9.643
count:43 r:14 a:419 mean:9.744
count:44 r:10 a:429 mean:9.750
count:45 r:11 a:440 mean:9.778
count:46 r:11 a:451 mean:9.804
count:47 r:11 a:462 mean:9.830
count:48 r:12 a:474 mean:9.875
count:49 r: 8 a:482 mean:9.837
count:50 r:11 a:493 mean:9.860
count:51 r:14 a:507 mean:9.941
count:52 r:10 a:517 mean:9.942
count:53 r:10 a:527 mean:9.943
count:54 r: 2 a:529 mean:9.796
count:55 r: 5 a:534 mean:9.709
count:56 r:10 a:544 mean:9.714
count:57 r: 7 a:551 mean:9.667
count:58 r: 7 a:558 mean:9.621
count:59 r: 7 a:565 mean:9.576
count:60 r:11 a:576 mean:9.600
count:61 r:11 a:587 mean:9.623
count:62 r:12 a:599 mean:9.661
count:63 r: 9 a:608 mean:9.651
count:64 r:13 a:621 mean:9.703
count:65 r: 7 a:628 mean:9.662
count:66 r: 5 a:633 mean:9.591
count:67 r:11 a:644 mean:9.612
count:68 r:11 a:655 mean:9.632
count:69 r:17 a:672 mean:9.739
count:70 r: 7 a:679 mean:9.700
count:71 r:12 a:691 mean:9.732
count:72 r: 7 a:698 mean:9.694
count:73 r:17 a:715 mean:9.795
count:74 r: 8 a:723 mean:9.770
count:75 r: 7 a:730 mean:9.733
count:76 r:13 a:743 mean:9.776
count:77 r:11 a:754 mean:9.792
count:78 r: 8 a:762 mean:9.769
count:79 r:14 a:776 mean:9.823
count:80 r:12 a:788 mean:9.850
count:81 r: 6 a:794 mean:9.802
count:82 r: 7 a:801 mean:9.768
count:83 r: 7 a:808 mean:9.735
count:84 r: 7 a:815 mean:9.702
count:85 r:16 a:831 mean:9.776
count:86 r: 5 a:836 mean:9.721
count:87 r: 9 a:845 mean:9.713
count:88 r:10 a:855 mean:9.716
count:89 r:10 a:865 mean:9.719
count:90 r:10 a:875 mean:9.722
count:91 r:11 a:886 mean:9.736
count:92 r: 8 a:894 mean:9.717
count:93 r:15 a:909 mean:9.774
count:94 r: 9 a:918 mean:9.766
count:95 r: 9 a:927 mean:9.758
count:96 r: 6 a:933 mean:9.719
count:97 r: 9 a:942 mean:9.711
count:98 r:19 a:961 mean:9.806
count:99 r:15 a:976 mean:9.859
count:100 r:13 a:989 mean:9.890



import java.util.Random;

import org.uncommons.maths.random.PoissonGenerator;

public class TestT {

public static void main(String[] args) {

double a = 0d;
for(int i=1;i<=100;i++){
int r = r(10);
a += r;
System.out.printf("count:%2d r:%2d a:%.0f mean:%.3f%n", i, r, a, (a/i));
}
}

static int r(double mean){
Random random = new Random();
PoissonGenerator generator = new PoissonGenerator(mean, random);
return generator.nextValue();
}
}


ポアソン分布の理解のための手習い。 2008/03/25
2008/03/25

待ち行列の説明をみてて、「ポアソン分布」というのがでてきたので、ちょっと勉強。

使ったライブラリは、


ポアソン分布で値を生成して生成した回数で割ってみる。
結果は
mean:1000
ポアソン分布でだした値の平均:998.928

もちろん繰りかえせば値もちょっとかわる。
平均をとることに意味があるかは、わからないけど...



このライブラリ使うとポアソン分布の値が手軽にとれるよってことで。

package t;

import java.util.Random;

import org.uncommons.maths.random.PoissonGenerator;

public class TestRandomOccur {

public static void main(String[] args) {
int mean = 1000;
System.out.println("mean:" + mean);
//print_random(mean);
print_poisson(mean);
}

static void print_poisson(int mean) {
double m = 0d;
int cnt = mean;
for (int i = 0; i < cnt; i++) {
double g = r(mean);
// System.out.println(g);
m += g;
}
System.out.println("ポアソン分布でだした値の平均:" + (m / cnt));
}

// static void print_random(int mean) {
// double m = 0d;
// int cnt = mean;
// for (int i = 0; i < cnt; i++) {
// double g = r2(mean);
// System.out.println(g);
// m += g;
// }
// System.out.println("ランダムでだした値の平均:" + (m / cnt));
// }

static int r(int mean) {
Random random = new Random();
PoissonGenerator poissonGenerator = new PoissonGenerator(mean, random);
return poissonGenerator.nextValue();
}

static int r2(int mean) {
Random random = new Random();
return random.nextInt(mean);
}
}

待ち行列のための練習 その1 2008/03/24

よくわかってないけど。

Rのプログラム

mm1.mu=function(lam,mu){ #lam 平均到着率 mu 平均サービス率
ro=lam/mu; p0=1-ro
W=1/(mu - lam);L=W*lam; Wq=W * lam/mu; Lq=Wq*lam
a=c(ro, W, L, Wq, Lq);
names(a) = c("稼働率", "平均待ち時間", "平均系の長さ", "平均列待ち時間", "平均待ち行列の長さ");
a; }



プログラムは、
Rで学ぶ経営工学の手法
長畑 秀和 大橋 和正
4320018559

を参考にしています。




参考

指数的な増え方 2008/03/24

利子が7%ついた場合の5年後


1.07かけてそれを5回くりかえして合計するか、1.075してそれをかけてもとめることができる。



public class TestA {

public static void main(String[] args) {
System.out.println(a(5));
System.out.println(b(5));
}

static double d = 1.07;
static final double base = 10.77;
static double a(int c){
double b = base;
for(int i=0;i<c;i++){
b *= d;
}
return b;
}

static double b(int c){
return base * Math.pow(d, c);
}
}

E.F.Coddとは誰か。 2008/03/23

リレーションモデルを提案した人。



ちなみに、SQLとリレーショナルモデルは違う。

ビッグなオー 2008/03/22

正直、計算量なんてまともに考えたことがなかったです...Orz....

まず、O記法なるものを使用して表現します。
ビッグオーとかオー記法といったりするようです。



で、調べはじめると、きりがなさそうなので、大雑把な理解ぐらいでいいのかなと...
コードを書くうえで、なんとなくイメージできるレベルで。

順番は、
O(log n)<O(n)<O(n log n)<O(nk)<O(kn)<O(n!)


あと、O(nk)以下のものを、多項式時間でとけるもの。O(kn)以上でとけるものらしくて、指数関数時間は、実用的ではないらしい。

自分なりにまとめてみたかったけど、よくわからないので、こつこつこつこつ考えていこう。


参考

「計算量のオーダ」の説明については、Short Coding ~職人達の技法~がよかったです。

外字への道 その4 2008/03/19


前回のコードが問題ありありだっあので、いろいろ修正。
1.文字列の処理が根本的にだめだった。
2.Java Web Start上でjavassistを使えるためのコードに修正。

javassistのバージョンは、CtMethodのメソッドのtoClassでProtectionDomainを引数にとれることができるものを使用しています。

どういうことをしているかといいますと、net.sf.jasperreports.engine.export.TextRendererクラスがロードされるまえに、TextRendererのrenderParagraphメソッドの振る舞いを変更するようにしてJasperReportsで外字を表示できるようにします。

このコードはJasperReportsだったら何でもよいというコードではなくて、JRGraphics2DExporterを使う場合で、さらにWindowsならば有効というコードです。
表示する文字が外字領域のものであれば、その文字を表示するための情報にフォントがEUDCを設定しています。


public class TestJasperUtils {

{

try {

javassist.ClassPool pool = javassist.ClassPool.getDefault();
javassist.CtClass myCtClass;
pool.appendClassPath(new javassist.LoaderClassPath(
TestJasperUtils.class.getClassLoader()));

myCtClass = pool
.get("net.sf.jasperreports.engine.export.TextRenderer");
javassist.CtMethod ctMethod = myCtClass
.getDeclaredMethod("renderParagraph");

StringBuffer buffer = new StringBuffer();
buffer.append(" {");
buffer.append(" java.text.AttributedCharacterIterator paragraph = null;");
buffer.append(" ");
buffer.append(" if ($3 == null)");
buffer.append(" {");
buffer.append(" paragraph = ");
buffer.append(" new java.text.AttributedString(");
buffer.append(" \" \",");
buffer.append(" new java.text.AttributedString(");
buffer.append(" $1, ");
buffer.append(" $2, ");
buffer.append(" $2 + 1");
buffer.append(" ).getIterator().getAttributes()");
buffer.append(" ).getIterator();");
buffer.append(" }");
buffer.append(" else");
buffer.append(" {");
buffer.append(" paragraph = ");
buffer.append(" new java.text.AttributedString(");
buffer.append(" $1, ");
buffer.append(" $2, ");
buffer.append(" $2 + $3.length()");
buffer.append(" ).getIterator();");
buffer.append(" }");
buffer.append("");
buffer.append(" java.awt.font.LineBreakMeasurer lineMeasurer = new java.awt.font.LineBreakMeasurer(paragraph, net.sf.jasperreports.engine.export.TextRenderer.LINE_BREAK_FONT_RENDER_CONTEXT);");
buffer.append(" ");
buffer.append(" while (lineMeasurer.getPosition() < paragraph.getEndIndex() && !isMaxHeightReached)");
buffer.append(" {");
buffer.append(" ");
buffer.append(" int startIndex = lineMeasurer.getPosition();");
buffer.append(" ");
buffer.append("");
buffer.append(" java.awt.font.TextLayout layout = lineMeasurer.nextLayout(formatWidth);");
buffer.append("");
buffer.append(" if (isMinimizePrinterJobSize)");
buffer.append(" {");
buffer.append(" ");
buffer.append(" java.text.AttributedString tmpText = ");
buffer.append(" new java.text.AttributedString(");
buffer.append(" paragraph, ");
buffer.append(" startIndex, ");
buffer.append(" startIndex + layout.getCharacterCount()");
buffer.append(" );");
buffer.append(" java.text.AttributedCharacterIterator iter = tmpText.getIterator();");
buffer.append(" for(char c = iter.first(); c != java.text.CharacterIterator.DONE; c = iter.next()) {");
buffer.append(" java.util.Map map = new java.util.LinkedHashMap();");
buffer.append(" ");
buffer.append(" if(0xe000 <= c && c <= 0xf8ff){");
buffer.append(" int pos = iter.getIndex();");
buffer.append(" map.put(java.awt.font.TextAttribute.FAMILY, \"EUDC\");");
buffer.append(" tmpText.addAttributes(map, pos, pos+1);");
buffer.append(" continue;");
buffer.append(" } ");
buffer.append(" }");
buffer.append(" ");
buffer.append(" layout = new java.awt.font.TextLayout(tmpText.getIterator(), grx.getFontRenderContext());");
buffer.append(" ");
buffer.append(" }");
buffer.append("");
buffer.append(" float lineHeight = lineSpacingFactor * ");
buffer.append(" maxFontSizeFinder.findMaxFontSize(");
buffer.append(" new java.text.AttributedString(");
buffer.append(" paragraph, ");
buffer.append(" startIndex, ");
buffer.append(" startIndex + layout.getCharacterCount()");
buffer.append(" ).getIterator(),");
buffer.append(" fontSize");
buffer.append(" );");
buffer.append("");
buffer.append(" if (drawPosY + lineHeight <= textHeight)");
buffer.append(" {");
buffer.append(" drawPosY += lineHeight;");
buffer.append(" ");
buffer.append(" switch (horizontalAlignment)");
buffer.append(" {");
buffer.append(" case 4 :");
buffer.append(" {");
buffer.append(" if (layout.isLeftToRight())");
buffer.append(" {");
buffer.append(" drawPosX = 0;");
buffer.append(" }");
buffer.append(" else");
buffer.append(" {");
buffer.append(" drawPosX = formatWidth - layout.getAdvance();");
buffer.append(" }");
buffer.append(" if (lineMeasurer.getPosition() < paragraph.getEndIndex())");
buffer.append(" {");
buffer.append(" layout = layout.getJustifiedLayout(formatWidth);");
buffer.append(" }");
buffer.append("");
buffer.append(" break;");
buffer.append(" }");
buffer.append(" case 3 :");
buffer.append(" {");
buffer.append(" drawPosX = formatWidth - layout.getAdvance();");
buffer.append(" break;");
buffer.append(" }");
buffer.append(" case 2 :");
buffer.append(" {");
buffer.append(" drawPosX = (formatWidth - layout.getAdvance()) / 2;");
buffer.append(" break;");
buffer.append(" }");
buffer.append(" case 1 :;");
buffer.append(" default :");
buffer.append(" {");
buffer.append(" drawPosX = 0;");
buffer.append(" }");
buffer.append(" }");
buffer.append("");
buffer.append(" draw(layout);");
buffer.append(" }");
buffer.append(" else");
buffer.append(" {");
buffer.append(" isMaxHeightReached = true;");
buffer.append(" }");
buffer.append(" }");
buffer.append(" }");


ctMethod.setBody(new String(buffer));

myCtClass.toClass(TestJasperUtils.class.getClassLoader(),
TestJasperUtils.class.getProtectionDomain());

} catch (Exception e) {
e.printStackTrace();
} catch (Error e) {
e.printStackTrace();
} catch (Throwable e) {
e.printStackTrace();
}
}

}

独立事象が同時に起こる確率は... 2008/03/17

独立事象が同時に起こる確率は、それぞれの確率の積に等しい.


それで、独立事象とは、起きる事象同士が、えーと、影響を与えないようなことを指していまして、たとえば二回サイコロをふりますと、最初の一回目の結果が、二回目に影響を与えないし、二回目のサイコロの目が一回目のサイコロの目に影響を与えないって感じしょうか(あたりまえか....)。

[pku] 3518 prime gap 2008/03/15



頭をそんなにひねらないで解ける問題ということで。

与えられた値の直近上の素数と直近下の素数との差を求めるわけですね。

package p3518;

import java.math.BigInteger;
import java.util.Scanner;

public class Main {

public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
int t = scanner.nextInt();
if (t == 0)
break;

int d = 0;
int u = 0;
int max = 1299709;
for (int i = t; 1 < i; i--) {
if (isPrime(i)) {
d = i;
break;
}
}
for (int i = t; t <= max; i++) {
if (isPrime(i)) {
u = i;
break;
}
}
System.out.println(u - d);
}
}

static boolean isPrime(long n) {
return BigInteger.valueOf(n).isProbablePrime(10);
}
}

GridBagUtil(s)にからめて日々の反省を綴る。 2008/03/15

たまにふとプログラム書いて動かすお仕事なら、毎日、会社がある場所に移動しないでも、働けるよなぁとたまに思います。

同僚から、GridBagUtil(s)を作ってGridBagでレイアウト組むのがらくになったという話を聞いて、なるほど、と思ったのは、いままで、EclipseならVE(visual editor)がないとGUIアプリつくるの面倒だなぁ、と感じていたのが、実は、複雑なレイアウトでなければ、たしかに、レイアウトのためのユーティルつくって使えばいいじゃんということに気がついたからなのでした。

検索かける場合は、GridBagUtilにsをつけないほうが多くでます。

簡単な方法で、楽したほうがいい部分は、《楽》をするという感覚が、最近自分からすっぽりぬけていました。
反省、反省。

それで、今回のように人からふとしたこを聞いて、実際にいろいろ人がひしめくあう職場に移動して、仕事するメリットを感じるわけでして、あっ、でも結構ノイズがおおくて、いらいらすることもたしかなのですが。

はなしかわって、あと、ふと感じるのは、要領のいい人は、なんでもコピペして、動かしちゃうんですよね。
僕も、コピペプログラマなので、負けずとコピペしちゃうんですけどね。ほほほ。
インターネットがない場所では働けない体になってしまったなと。

ウェブ進化論にあった、高速道路みたいなもんで、インターネットのおかげで、学習するのはらくになりましたね。
おいどんなんて学習せずに脊髄反射的にコピペしてしまうので、それが怖いんですけどね。



ちなみに、ユーティリティクラスのお尻につけるのは、utilかutilsかはてまたutilityか、apacheのcommonsをよく使う人なら自然とutilsなんでしょうかねー。

参考

外延的記法、内包的記法 2008/03/15

A = {a1,a2,...,an}
って感じで書くのが外延的記法
列挙的定義ともいいます。

で、それに対して、
条件P(x)を満たしているx全体の集合Xを
X = {x|P(x)}
って感じに書く方法を内包的記法っていいます。

参考

java処理の応答をよくするための手習い。 2008/03/15
2008/03/15

全体にかかる時間は、各タスクにかかる時間の総量


全体にかかる時間は、各タスクにかかる時間の総量になります。
例えば、A,B,Cと三つのタスクにわけると考えて、実行の順序に意味がある場合、つまり、タスク間に実行順序の依存がある場合は、トータルでかかる時間は、A + B + Cとなります。

Aタスクには、3秒
Bタスクには、2秒
Cタスクには、1秒
かかるとすると、計6秒かかります。



例えば、Aがあるデータベースにたいするクエリー、BはAの結果を受けて行うファイル処理、最後にCは全体の結果をまとめる、というようなロジック構成は実際にありそうです。

この場合は、各タスクの実行処理を改善しないと、応答時間はよくなりません。

簡単なコードになおすと下記のような感じになるかと思います。



public class TestTh {

public static void main(String[] args) throws InterruptedException {

long start = System.currentTimeMillis();
TestTh th = new TestTh();
System.out.println(th.longTask());
long end = System.currentTimeMillis();
System.out.println("" + ((end - start) / 1000f) + " sec.");
}

public String longTask() throws InterruptedException {

taskA();
taskB();
taskC();

return "success";
}

public void taskA() throws InterruptedException {
Thread.sleep(3000);
System.out.println("*** taskA success...");
//if(true) throw new RuntimeException("Oh!!");
}

public void taskB() throws InterruptedException {
Thread.sleep(2000);
System.out.println("*** taskB success...");
}

public void taskC() throws InterruptedException {
Thread.sleep(1000);
System.out.println("*** taskC success...");
}
}



次にタスク間に順序依存がない場合


次にタスク間に順序依存がない場合、たとえば、Aタスク、Bタスクは実行順序を逆にしても結果が同じなるような場合は、A,Bを同時に実行してもよいわけです。



この場合だと同時に実行できるA,Bタスクで時間がかかるほうがコストとなります。

Aタスクには、3秒
Bタスクには、2秒
Cタスクには、1秒
だとするとA>Bなので、
3+1で4秒がトータルとなります。

実行順序に依存関係がない場合は、スレッドを使って並行処理するとたいてい応答がよくなります(たぶん)。

jdk1.4で動作させるために、concurrentのライブラリを使ってます。


import edu.emory.mathcs.backport.java.util.concurrent.Callable;
import edu.emory.mathcs.backport.java.util.concurrent.ExecutionException;
import edu.emory.mathcs.backport.java.util.concurrent.FutureTask;
import edu.emory.mathcs.backport.java.util.concurrent.SynchronousQueue;
import edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor;
import edu.emory.mathcs.backport.java.util.concurrent.TimeUnit;


public String longTask() throws InterruptedException {

ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 2, 100000,
TimeUnit.SECONDS, new SynchronousQueue());
Callable callableA = new Callable() {

public Object call() throws Exception {
taskA();
return Boolean.TRUE;
}
};
Callable callableB = new Callable() {

public Object call() throws Exception {
taskB();
return Boolean.TRUE;
}
};

List list = new ArrayList();
list.add(callableA);
list.add(callableB);
try {
List resuList = executor.invokeAll(list);

// タスクAとタスクBが終了したのちに以下、実行。
Iterator iterator = resuList.iterator();
while (iterator.hasNext()) {
FutureTask t = (FutureTask) iterator.next();
try {
System.out.println(t.get());
} catch (ExecutionException e) {
// e.printStackTrace();
}
}
} finally {
executor.shutdown();
}

taskC();

return "success";
}


まとめ


図でまとめるとこんな感じかな。


タスクの実行結果に順番がない場合(依存がない場合)は、スレッドを使って、応答をよくすることができます。
あっ、なんでもかんでもスレッドにのせていいわけではないですし、もちろんスレッドを生成するコストより順番に実行した結果時間がかかる場合にのみ有効です。

java5から導入されたconcurrent系のライブラリを念頭に入れて、1.4環境ならbackportのライブラリを使うのもありかなと思います。

[java] Robotつかってペースト 2008/03/14

Javaです。

Robot使ってマウスを移動させて、プレスして、それから値をペーストです。

Windowsの外字入力をするのが面倒だったので、文字列を生成してクリップボードにコピーしてペーストしています。

kepressを続けておこなえば、同時押しのようになるのでctrl + vができるというわけなのですね。

えーと、注意しないといけないのは、マウスでpressしたら、release.
キーを入力したリリースするのを忘れないように。

GUIの開発でテストを自動化しようと思ったら、ショットカットキーをいろいろ用意しておいたほうがよさげですね。

import java.awt.AWTException;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;

public class TestRobot_2 {

public static void main(String[] args) throws AWTException {
a();
}

/*
* 値を生成して、テキストフィールドがあるアプリケーションのマウスを移動させて、クリックして値をペーストしてみる。
*
*/
static void a() throws AWTException {
Robot robot = new Robot();
// 特定の文字列を生成
char base = 0xe520;// unicode
StringBuilder builder = new StringBuilder();
for (char i = base; i < 0xe5e0; i++) {
builder.append(i);
}

// クリップボードに値をコピー
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
StringSelection selection = new StringSelection(new String(builder));
clipboard.setContents(selection, null);

// ここの位置に入力するためのフィールドがあると考えてマウスを移動...
robot.mouseMove(-600, 400);

// 入力フィールドにマウスをプレス
robot.mousePress(InputEvent.BUTTON1_MASK);
robot.mouseRelease(InputEvent.BUTTON1_MASK);

robot.delay(300);

// ペースト
p(robot);
}

// ペーストします(ctrl + v)
static void p(Robot robot) {
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_V);
robot.keyRelease(KeyEvent.VK_CONTROL);
robot.keyRelease(KeyEvent.VK_V);
}
}

正規表現 orしてグループ 2008/03/14

正規表現です。javaです。
orして、グループにしています。

String t = "p.atext.p p.text.p ";
t = t.replaceAll("(text|atext)", "x.q.$1");
System.out.println(t);


結果は、
p.x.q.atext.p p.x.q.text.p

ProtectionDomainって何? 2008/03/11

ProtectionDomainって何ぞね?

えーと、コードの権限をあらわしているみたい。

ProtectionDomain クラスは、ドメインの属性をカプセル化し、与えられた Principal のセットの代わりに実行される場合に、そのインスタンスに対してアクセス権のセットが与えられるクラスのセットを含みます。
javadoc5


ProtectionDomainの情報は Classクラスの getProtectionDomain()メソッドでアクセスできる。

実際に使ってみたけど、javaでのセキュリティとか権限についての知識ないのでなんとも....


参考
Summer2000 5:security

はまってみないとわからないEDT(Event Dispatch Thread)の恐怖。 2008/03/11

はまってみないとわからないEDT(Event Dispatch Thread)の恐怖。
恐怖とはいいすぎだけど...

UIコンポーネントを触るときはEDTのうえで行うこと
口をすっぱくして何度も繰り返す。
UIコンポーネントを触るときはEDTのうえで行うこと

時間がかかる処理は、別スレッドでおこなって、結果をUIコンポーネントに返すときにEDTのうえで行うようにする。

図にしてみたけど、なんかちがうかなぁー


参考

署名済みのJarを使ったJava Web Start上でJavassistを使うとき 2008/03/11
2008/03/11

普通にEclipse上で開発していて、Javassistでバイトコードをさわって、toClassして問題なかったのにそれをJavaWebStart化するとエラーになりました。

javassist.CannotCompileException: by java.lang.SecurityException: class "クラス名"'s signer information does not match signer information of other classes in the same package


で、うーんと悩んだわけです。

すると、下記のようなものをみつけました。


webstartで、使えるようなので、調べた結果。

toClassするときに、クラスローダーと、ProtectionDomainを渡せばいいようです。

myCtClass.toClass(クラス.class.getClassLoader(), クラス.class.getProtectionDomain());


あと、webstartだと、すぐにクラスがみつかりません。
poolにクラスへのパスを渡してあげます。そのときに、LoaderClassPathを使うとうまくいきました。

pool.appendClassPath(new javassist.LoaderClassPath(クラス.class.getClassLoader()));


ちなみに、webstart上でのリソースをみつける方法に注意!!

Java Web Start でアプリケーションリソースを見つけるには、アプリケーションをロードしたクラスローダを使用します。たとえば、アプリケーションのメインスレッド内で次のメソッドを呼び出します。

this.getClass().getClassLoader();

次のメソッドも使用できます。

Thread.getCurrent().getContextClassLoader();
Java Web Start - よくある質問 (FAQ)


参考

antでjavacで、target="1.4" source="1.4" 2008/03/10

antでjavacするときにターゲットなるjavaのバージョンの指定は、
target="1.4" source="1.4"
でいいっぽいです。

ちなみに48.0は1.4で49.0が5.0っぽい。
49.0って4がついてるから1.4かとカン違いしていたよ。
Orz...

あとクラスのバージョンを書き換えて、実行させている人がいた


そんなことできるんだ!!余裕があるときためしてみよう...

参考

誕生日の一致:ランダムに%d人を集めた%d部屋では、%d部屋で誕生日の一致がありました。%n その2 2008/03/08

誕生日一致の確率

ランダムにX人を集めた部屋で、どれだけの確率で誕生日の一致がおこるのか?


23人以上いる部屋から50%をこえる確率で同じ誕生日の人がいることになる。
57人以上いる部屋から99%の確率で同じ誕生日がいることになるよう。
153人以上から100%になる、コンピュータの計算の精度によるから、えーと、厳密の厳密でいうと100%にはならないと思うのだけど、まあ、問題ない精度だと思うので。

計算してなんだけど、ほんとにあったているのかしら...不安。

すると、たとえばある会社のフロアの中で100人いれば、おなじ誕生日の人はほぼ確実にいることになるのかな。
えーと、もちろん自分と同じではなくて、少なくとも同じ誕生日をもつ一組ってこと。


public class YourBirthDay2 {

/**
* @param args
*/
public static void main(String[] args) {
for(int i=1;i<=365;i++){
double d = calculationOfProbability(i);
System.out.printf("%d人いる部屋で誕生日が一致する確率は、%f %d%%n", i, d, (int)(d * 100));
}
}

/**
* <p>
* 部屋にいる人の数から誕生日が一致する確率を求めます。<br>
* 一年を365日として考えます。
* </p>
*
* @param n 部屋にいる人の数
* @return
*/
static double calculationOfProbability(int n){
double d = 365d;
double p = 1.0;
n = n - 1;
for(int i= 1;i<=n;i++){
p *= (d-i)/d;
}
//System.out.println(p);
return 1d - p;
}
}



1人いる部屋で誕生日が一致する確率は、0.000000 0%
2人いる部屋で誕生日が一致する確率は、0.002740 0%
3人いる部屋で誕生日が一致する確率は、0.008204 0%
4人いる部屋で誕生日が一致する確率は、0.016356 1%
5人いる部屋で誕生日が一致する確率は、0.027136 2%
6人いる部屋で誕生日が一致する確率は、0.040462 4%
7人いる部屋で誕生日が一致する確率は、0.056236 5%
8人いる部屋で誕生日が一致する確率は、0.074335 7%
9人いる部屋で誕生日が一致する確率は、0.094624 9%
10人いる部屋で誕生日が一致する確率は、0.116948 11%
11人いる部屋で誕生日が一致する確率は、0.141141 14%
12人いる部屋で誕生日が一致する確率は、0.167025 16%
13人いる部屋で誕生日が一致する確率は、0.194410 19%
14人いる部屋で誕生日が一致する確率は、0.223103 22%
15人いる部屋で誕生日が一致する確率は、0.252901 25%
16人いる部屋で誕生日が一致する確率は、0.283604 28%
17人いる部屋で誕生日が一致する確率は、0.315008 31%
18人いる部屋で誕生日が一致する確率は、0.346911 34%
19人いる部屋で誕生日が一致する確率は、0.379119 37%
20人いる部屋で誕生日が一致する確率は、0.411438 41%
21人いる部屋で誕生日が一致する確率は、0.443688 44%
22人いる部屋で誕生日が一致する確率は、0.475695 47%
23人いる部屋で誕生日が一致する確率は、0.507297 50%
24人いる部屋で誕生日が一致する確率は、0.538344 53%
25人いる部屋で誕生日が一致する確率は、0.568700 56%
26人いる部屋で誕生日が一致する確率は、0.598241 59%
27人いる部屋で誕生日が一致する確率は、0.626859 62%
28人いる部屋で誕生日が一致する確率は、0.654461 65%
29人いる部屋で誕生日が一致する確率は、0.680969 68%
30人いる部屋で誕生日が一致する確率は、0.706316 70%
31人いる部屋で誕生日が一致する確率は、0.730455 73%
32人いる部屋で誕生日が一致する確率は、0.753348 75%
33人いる部屋で誕生日が一致する確率は、0.774972 77%
34人いる部屋で誕生日が一致する確率は、0.795317 79%
35人いる部屋で誕生日が一致する確率は、0.814383 81%
36人いる部屋で誕生日が一致する確率は、0.832182 83%
37人いる部屋で誕生日が一致する確率は、0.848734 84%
38人いる部屋で誕生日が一致する確率は、0.864068 86%
39人いる部屋で誕生日が一致する確率は、0.878220 87%
40人いる部屋で誕生日が一致する確率は、0.891232 89%
41人いる部屋で誕生日が一致する確率は、0.903152 90%
42人いる部屋で誕生日が一致する確率は、0.914030 91%
43人いる部屋で誕生日が一致する確率は、0.923923 92%
44人いる部屋で誕生日が一致する確率は、0.932885 93%
45人いる部屋で誕生日が一致する確率は、0.940976 94%
46人いる部屋で誕生日が一致する確率は、0.948253 94%
47人いる部屋で誕生日が一致する確率は、0.954774 95%
48人いる部屋で誕生日が一致する確率は、0.960598 96%
49人いる部屋で誕生日が一致する確率は、0.965780 96%
50人いる部屋で誕生日が一致する確率は、0.970374 97%
51人いる部屋で誕生日が一致する確率は、0.974432 97%
52人いる部屋で誕生日が一致する確率は、0.978005 97%
53人いる部屋で誕生日が一致する確率は、0.981138 98%
54人いる部屋で誕生日が一致する確率は、0.983877 98%
55人いる部屋で誕生日が一致する確率は、0.986262 98%
56人いる部屋で誕生日が一致する確率は、0.988332 98%
57人いる部屋で誕生日が一致する確率は、0.990122 99%
58人いる部屋で誕生日が一致する確率は、0.991665 99%
59人いる部屋で誕生日が一致する確率は、0.992989 99%
60人いる部屋で誕生日が一致する確率は、0.994123 99%
61人いる部屋で誕生日が一致する確率は、0.995089 99%
62人いる部屋で誕生日が一致する確率は、0.995910 99%
63人いる部屋で誕生日が一致する確率は、0.996604 99%
64人いる部屋で誕生日が一致する確率は、0.997190 99%
65人いる部屋で誕生日が一致する確率は、0.997683 99%
66人いる部屋で誕生日が一致する確率は、0.998096 99%
67人いる部屋で誕生日が一致する確率は、0.998440 99%
68人いる部屋で誕生日が一致する確率は、0.998726 99%
69人いる部屋で誕生日が一致する確率は、0.998964 99%
70人いる部屋で誕生日が一致する確率は、0.999160 99%
71人いる部屋で誕生日が一致する確率は、0.999321 99%
72人いる部屋で誕生日が一致する確率は、0.999453 99%
73人いる部屋で誕生日が一致する確率は、0.999561 99%
74人いる部屋で誕生日が一致する確率は、0.999649 99%
75人いる部屋で誕生日が一致する確率は、0.999720 99%
76人いる部屋で誕生日が一致する確率は、0.999777 99%
77人いる部屋で誕生日が一致する確率は、0.999824 99%
78人いる部屋で誕生日が一致する確率は、0.999861 99%
79人いる部屋で誕生日が一致する確率は、0.999891 99%
80人いる部屋で誕生日が一致する確率は、0.999914 99%
81人いる部屋で誕生日が一致する確率は、0.999933 99%
82人いる部屋で誕生日が一致する確率は、0.999948 99%
83人いる部屋で誕生日が一致する確率は、0.999960 99%
84人いる部屋で誕生日が一致する確率は、0.999969 99%
85人いる部屋で誕生日が一致する確率は、0.999976 99%
86人いる部屋で誕生日が一致する確率は、0.999982 99%
87人いる部屋で誕生日が一致する確率は、0.999986 99%
88人いる部屋で誕生日が一致する確率は、0.999989 99%
89人いる部屋で誕生日が一致する確率は、0.999992 99%
90人いる部屋で誕生日が一致する確率は、0.999994 99%
91人いる部屋で誕生日が一致する確率は、0.999995 99%
92人いる部屋で誕生日が一致する確率は、0.999997 99%
93人いる部屋で誕生日が一致する確率は、0.999997 99%
94人いる部屋で誕生日が一致する確率は、0.999998 99%
95人いる部屋で誕生日が一致する確率は、0.999999 99%
96人いる部屋で誕生日が一致する確率は、0.999999 99%
97人いる部屋で誕生日が一致する確率は、0.999999 99%
98人いる部屋で誕生日が一致する確率は、0.999999 99%
99人いる部屋で誕生日が一致する確率は、1.000000 99%
100人いる部屋で誕生日が一致する確率は、1.000000 99%
101人いる部屋で誕生日が一致する確率は、1.000000 99%
102人いる部屋で誕生日が一致する確率は、1.000000 99%
103人いる部屋で誕生日が一致する確率は、1.000000 99%
104人いる部屋で誕生日が一致する確率は、1.000000 99%
105人いる部屋で誕生日が一致する確率は、1.000000 99%
106人いる部屋で誕生日が一致する確率は、1.000000 99%
107人いる部屋で誕生日が一致する確率は、1.000000 99%
108人いる部屋で誕生日が一致する確率は、1.000000 99%
109人いる部屋で誕生日が一致する確率は、1.000000 99%
110人いる部屋で誕生日が一致する確率は、1.000000 99%
111人いる部屋で誕生日が一致する確率は、1.000000 99%
112人いる部屋で誕生日が一致する確率は、1.000000 99%
113人いる部屋で誕生日が一致する確率は、1.000000 99%
114人いる部屋で誕生日が一致する確率は、1.000000 99%
115人いる部屋で誕生日が一致する確率は、1.000000 99%
116人いる部屋で誕生日が一致する確率は、1.000000 99%
117人いる部屋で誕生日が一致する確率は、1.000000 99%
118人いる部屋で誕生日が一致する確率は、1.000000 99%
119人いる部屋で誕生日が一致する確率は、1.000000 99%
120人いる部屋で誕生日が一致する確率は、1.000000 99%
121人いる部屋で誕生日が一致する確率は、1.000000 99%
122人いる部屋で誕生日が一致する確率は、1.000000 99%
123人いる部屋で誕生日が一致する確率は、1.000000 99%
124人いる部屋で誕生日が一致する確率は、1.000000 99%
125人いる部屋で誕生日が一致する確率は、1.000000 99%
126人いる部屋で誕生日が一致する確率は、1.000000 99%
127人いる部屋で誕生日が一致する確率は、1.000000 99%
128人いる部屋で誕生日が一致する確率は、1.000000 99%
129人いる部屋で誕生日が一致する確率は、1.000000 99%
130人いる部屋で誕生日が一致する確率は、1.000000 99%
131人いる部屋で誕生日が一致する確率は、1.000000 99%
132人いる部屋で誕生日が一致する確率は、1.000000 99%
133人いる部屋で誕生日が一致する確率は、1.000000 99%
134人いる部屋で誕生日が一致する確率は、1.000000 99%
135人いる部屋で誕生日が一致する確率は、1.000000 99%
136人いる部屋で誕生日が一致する確率は、1.000000 99%
137人いる部屋で誕生日が一致する確率は、1.000000 99%
138人いる部屋で誕生日が一致する確率は、1.000000 99%
139人いる部屋で誕生日が一致する確率は、1.000000 99%
140人いる部屋で誕生日が一致する確率は、1.000000 99%
141人いる部屋で誕生日が一致する確率は、1.000000 99%
142人いる部屋で誕生日が一致する確率は、1.000000 99%
143人いる部屋で誕生日が一致する確率は、1.000000 99%
144人いる部屋で誕生日が一致する確率は、1.000000 99%
145人いる部屋で誕生日が一致する確率は、1.000000 99%
146人いる部屋で誕生日が一致する確率は、1.000000 99%
147人いる部屋で誕生日が一致する確率は、1.000000 99%
148人いる部屋で誕生日が一致する確率は、1.000000 99%
149人いる部屋で誕生日が一致する確率は、1.000000 99%
150人いる部屋で誕生日が一致する確率は、1.000000 99%
151人いる部屋で誕生日が一致する確率は、1.000000 99%
152人いる部屋で誕生日が一致する確率は、1.000000 99%
153人いる部屋で誕生日が一致する確率は、1.000000 100%
以下,100%

誕生日の一致:ランダムに%d人を集めた%d部屋では、%d部屋で誕生日の一致がありました。%n 2008/03/08

誕生日の一致の謎

ランダムにX人を集めた部屋で、どれだけの確率で誕生日の一致がおこるのか?


一年をとりあえず365日と考えて、みました。

まず、コンピュータ上で再現。
乱数を使っているので実行しているので、下記の結果はかならずしも再現しませんが、おおむねこんな感じ。

参考にした本によると、23人以上では同じ誕生日の人がいる確率は50%をこえているそうです。

誕生日の一致:ランダムに2人を集めた10部屋では、0部屋で誕生日の一致がありました。
誕生日の一致:ランダムに3人を集めた10部屋では、0部屋で誕生日の一致がありました。
誕生日の一致:ランダムに4人を集めた10部屋では、0部屋で誕生日の一致がありました。
誕生日の一致:ランダムに5人を集めた10部屋では、0部屋で誕生日の一致がありました。
誕生日の一致:ランダムに6人を集めた10部屋では、1部屋で誕生日の一致がありました。
誕生日の一致:ランダムに7人を集めた10部屋では、0部屋で誕生日の一致がありました。
誕生日の一致:ランダムに8人を集めた10部屋では、1部屋で誕生日の一致がありました。
誕生日の一致:ランダムに9人を集めた10部屋では、1部屋で誕生日の一致がありました。
誕生日の一致:ランダムに10人を集めた10部屋では、0部屋で誕生日の一致がありました。
誕生日の一致:ランダムに11人を集めた10部屋では、1部屋で誕生日の一致がありました。
誕生日の一致:ランダムに12人を集めた10部屋では、3部屋で誕生日の一致がありました。
誕生日の一致:ランダムに13人を集めた10部屋では、1部屋で誕生日の一致がありました。
誕生日の一致:ランダムに14人を集めた10部屋では、3部屋で誕生日の一致がありました。
誕生日の一致:ランダムに15人を集めた10部屋では、1部屋で誕生日の一致がありました。
誕生日の一致:ランダムに16人を集めた10部屋では、1部屋で誕生日の一致がありました。
誕生日の一致:ランダムに17人を集めた10部屋では、5部屋で誕生日の一致がありました。
誕生日の一致:ランダムに18人を集めた10部屋では、6部屋で誕生日の一致がありました。
誕生日の一致:ランダムに19人を集めた10部屋では、3部屋で誕生日の一致がありました。
誕生日の一致:ランダムに20人を集めた10部屋では、2部屋で誕生日の一致がありました。
誕生日の一致:ランダムに21人を集めた10部屋では、5部屋で誕生日の一致がありました。
誕生日の一致:ランダムに22人を集めた10部屋では、6部屋で誕生日の一致がありました。
誕生日の一致:ランダムに23人を集めた10部屋では、3部屋で誕生日の一致がありました。
誕生日の一致:ランダムに24人を集めた10部屋では、5部屋で誕生日の一致がありました。
誕生日の一致:ランダムに25人を集めた10部屋では、6部屋で誕生日の一致がありました。
誕生日の一致:ランダムに26人を集めた10部屋では、4部屋で誕生日の一致がありました。
誕生日の一致:ランダムに27人を集めた10部屋では、6部屋で誕生日の一致がありました。
誕生日の一致:ランダムに28人を集めた10部屋では、7部屋で誕生日の一致がありました。
誕生日の一致:ランダムに29人を集めた10部屋では、9部屋で誕生日の一致がありました。
誕生日の一致:ランダムに30人を集めた10部屋では、8部屋で誕生日の一致がありました。
誕生日の一致:ランダムに31人を集めた10部屋では、6部屋で誕生日の一致がありました。
誕生日の一致:ランダムに32人を集めた10部屋では、7部屋で誕生日の一致がありました。
誕生日の一致:ランダムに33人を集めた10部屋では、8部屋で誕生日の一致がありました。
誕生日の一致:ランダムに34人を集めた10部屋では、8部屋で誕生日の一致がありました。
誕生日の一致:ランダムに35人を集めた10部屋では、8部屋で誕生日の一致がありました。
誕生日の一致:ランダムに36人を集めた10部屋では、7部屋で誕生日の一致がありました。
誕生日の一致:ランダムに37人を集めた10部屋では、8部屋で誕生日の一致がありました。
誕生日の一致:ランダムに38人を集めた10部屋では、8部屋で誕生日の一致がありました。
誕生日の一致:ランダムに39人を集めた10部屋では、10部屋で誕生日の一致がありました。
誕生日の一致:ランダムに40人を集めた10部屋では、9部屋で誕生日の一致がありました。
誕生日の一致:ランダムに41人を集めた10部屋では、10部屋で誕生日の一致がありました。
誕生日の一致:ランダムに42人を集めた10部屋では、10部屋で誕生日の一致がありました。
誕生日の一致:ランダムに43人を集めた10部屋では、10部屋で誕生日の一致がありました。
誕生日の一致:ランダムに44人を集めた10部屋では、10部屋で誕生日の一致がありました。
誕生日の一致:ランダムに45人を集めた10部屋では、10部屋で誕生日の一致がありました。
誕生日の一致:ランダムに46人を集めた10部屋では、9部屋で誕生日の一致がありました。
誕生日の一致:ランダムに47人を集めた10部屋では、10部屋で誕生日の一致がありました。
誕生日の一致:ランダムに48人を集めた10部屋では、9部屋で誕生日の一致がありました。
誕生日の一致:ランダムに49人を集めた10部屋では、10部屋で誕生日の一致がありました。
誕生日の一致:ランダムに50人を集めた10部屋では、9部屋で誕生日の一致がありました。


import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Random;

public class YourBirthDay {

public static void main(String[] args) {
int n = 2;
int COUNT = 10;
for(int i=n;i<51;i++){
test(i, COUNT);
}
}

static void test(int n, int COUNT) {
int countOfCoincidence = 0;
// System.out.println(room);
for (int i = 0; i < COUNT; i++) {
Room room = new Room(n);
sort(room.persons);
// System.out.println(room);
if (whatACoincidence(room.persons))
countOfCoincidence++;
}
System.out.printf("ランダムに%d人を集めた%d部屋では、%d部屋で誕生日の一致がありました。%n", n,
COUNT, countOfCoincidence);
System.out.printf("確率:%f%n", calculationOfProbability(n));

}

/**
* <p>
* 部屋にいる人の数から誕生日が一致する確率を求めます。<br>
* 一年を365日として考えます。
* </p>
*
* @param n 部屋にいる人の数
* @return
*/
static double calculationOfProbability(int n){
double d = 365d;
double p = 1.0;
n = n - 1;
for(int i= 1;i<=n;i++){
p *= (d-i)/d;
}
//System.out.println(p);
return 1d - p;
}

static void sort(List<Person> list) {
Collections.sort(list, new Comparator<Person>() {
public int compare(Person o1, Person o2) {
return new Integer(o1.birthDay).compareTo(new Integer(
o2.birthDay));
}
});
}

static boolean whatACoincidence(List<Person> list) {
for (int i = 1; i < list.size(); i++) {
if (list.get(i - 1).birthDay == list.get(i).birthDay) {
return true;
}
}
return false;
}

static class Person {
int birthDay;
String name;

public Person(String name) {
this.name = name;
this.birthDay = random();
}

public String toString() {
return String.format("name:[%s] birthday:[%s]", name, birthDay);
}

}

static class Room {
List<Person> persons = new ArrayList<Person>();

public Room(int n) {
for (int i = 0; i < n; i++) {
persons.add(new Person("" + i));
}
}

public String toString() {
StringBuilder builder = new StringBuilder();
builder.append(persons);
return new String(builder);
}
}

static int random() {
return new Random().nextInt(365);
}
}

アーランのパターン照合って? 2008/03/06

ほとんどの言語では=は、代入なんだけど、Erlangでは、パターン照合をあらわすそうです。
で、どういうことかというと、最初に=使うと変数に値を束縛して、二度目の=はパターン照合ってことらしい。

シェルで試した結果。

Eshell V5.6 (abort with ^G)
1> X = 100 + 77.
177
2> X = 7.
** exception error: no match of right hand side value 7
3> X = 177.
177
4> 177 = X.
177
5>


177 = Xという書き方もありのようで、これはパターン照合しているってことなんですよね。

えーと、あと式の終わりは.(ピリオド)であらわします。

[java] Errorについて 2008/03/05

javaです。Errorについてです。

java.lang.Errorってあまり経験することがなかったので、メモします。
といいつつ、以前にもメモしてます。



参考にしている書籍は、プログラミング言語Java第4版です。

えーと、Javaでは、例外型はスローされるオブジェクトとして設計されるので、Throwableクラスを継承して作成されます。
例外には、チェックされる例外(checked exception)と、チェックされない例外(unchecked exception)があるそうです。

チェックされる例外は、メソッドがスローすると宣言した例外以外をスローしないことをコンパイルがチェックします。チェックされない例外は、コンパイルがチェックしません。

チェックされる例外は、java.lang.Exceptionを継承して作成されます。
チェックされない例外は、java.lang.RuntimeExceptionか、java.lang.Erroを継承して作成されます。

例外の階層


むっ、ErrorはThrowableを継承してます。すると何でも例外をcatchしたければ、Throwableでcatchできる(それがよいか悪いかは別にして...)

一般的にはプログラムロジックの誤りを反映して、実行時に適切に回復できない状態を、チェックされない例外は表します。プログラミング言語Java第4版 p.244


えーと、するとチェックされる例外は、どう対処するか明確に記述しないといけないわけですが、問題はチェックされない例外にたいする態度ですね。

まずい例外処理の書き方はException(Throwable)で何でもかんでも受けて例外のもみ消しですかね。
しかし、何がおこるかわからないことにも対応しないといけないし!!

参考
Java 入門 | 例外の種類

プログラミング言語Java 第4版 (The Java Series)
ケン・アーノルド ジェームズ ゴスリン デビッド ホームズ
4894717166

フィボナッチ数列に現れる偶数の値の合計をもとめる。その2 2008/03/05


うう
計算するのも課題ですよね...

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

public class F {

public static void main(String[] args) {

int i = 0;
int sum = 0;
while (true) {
int n = fibo(i).intValue();
if (!(n <= 4000000))
break;
if ((n % 2) != 0) {
sum += n;
}
i++;
}
System.out.println(sum);
}

public static BigDecimal fibo(int x) {

class Fibo {

Map m = new HashMap();

public BigDecimal fibo(int x) {

BigDecimal r = null;

if ((r = (BigDecimal) m.get(x)) != null)

return r;

switch (x) {

case 0:

case 1:

r = new BigDecimal(1);

break;

case 2:

r = new BigDecimal(2);

break;

default:

r = fibo(x - 1).add(fibo(x - 2));

}

m.put(x, r);

return r;

}

}
;

Fibo f = new Fibo();

return f.fibo(x);

}
}



関連
プログラマメモ2: [java]フィボナッチ数列

フィボナッチ数列に現れる偶数の値の合計をもとめる。 2008/03/05


フィボナッチ数列に現れる偶数の値の合計をもとめる。
400万以下の値で行う。

フィボナッチ数列を計算で求めるのをすぐにできなかったので、テーブルを利用。


int n = 4000000;
long[] l = {0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,
1597,2584,4181,6765,10946,17711,28657,46368,75025,
121393,196418,317811,514229,832040,1346269,
2178309,3524578,5702887,9227465,14930352,24157817,
39088169};
long sum = 0;
for(int i=2;i<l.length;i++){
if(l[i] <= n && l[i] % 2 == 0) sum += l[i];
}
System.out.println(sum);

タプルって何ぞや? 2008/03/04



タプルはtuple。

数学や計算機科学などいくつかの分野で、通常順序づけられた対象の並びを表すために用いられる


順序づけられた並びってことらしい。
タプルをもっているプログラミング言語がある。
Pythonとか、Erlangとか、いろいろある。
Pythonが検索エンジンでひっかる率が高そう。
タプルはJavaにはないね。

タプルは、配列とかリストとも違うってことらしい。

リストは長さが可変、タプルは変更できないっぽい。

タプルを本とか、ノートにたとえて、リストをファイル(リフィルできる)ものにたとえることもあるらしい。

このタプルを考えるにあたって、ひとつの言語だけでなく、いろいろな言語をさわったほうがよさげっぽい。

リレーショナルデータベースとか考えるにあたってタプルは重要っぽい。

参考
タプルと直積

Erlangをインストール 2008/03/04

windowsはインストーラでインストールしました。
macはmac portsを使いました。

自分のマシンにインストールしていた、mac portsのバージョンが古かったので、
1.6をインストールしなおしました。



それから
sudo port install erlang

しました。

erlangの起動は、erlコマンドで行います。

現在のインストールされたerlangのバージョンをチェック
$ erl -version
Erlang (ASYNC_THREADS) (BEAM) emulator version 5.6


info erlang
erlang R12B-0, lang/erlang (Variants: universal, smp, ssl, i386)

タグから類似度をはかる - アイデアレベル 2008/03/03

詳しくみていないのですが、記事の類似度で結ぶサービスがリリースされていました。



どういうふうな仕組みになのかというのは開発者のブログにありました。
記事の類似度を測る方法として、ベクトル空間モデル(TF*IDF)を用いています。こえむの編集後記 » ブログを記事で結ぶブログパーツ『シムエントリ』をリリース


ところで、ベクトル空間モデルから、昔、ちょっとだけ触ったことがあるコンセプトベースのことを思い出しました。

コンセプトベースには概念検索なるものがあったなぁ。

以前、プログラマメモ2: Blogger 関連ありそうな記事のリンクをつける。を試していたとき、タグの付け方から、類似度をもう少し正確に割り出すことができないかなぁと思っていました。

で、記事全体から単語を抽出するのは大変そうなので、単純にタグ(Bloggerならラベル)から、記事の類似度をはかってクラスタリングするのはありなのではないかというふうに考えたわけです。

タグ(ラベル)は記事を書いた作者が、意図をこめてつけるので、その時点である程度記事のグループ化ができているわけでし。

ですが、タグってあんまり細かく分類してつけてないですよね。固有名詞をさほど使っていない。記事が増えると大雑把なくくりで記事が埋没してしまう。タグでそもそも分類しようと考えないほうがいいのかも。

参考


記事から自動でタグの候補をみつけてくれるサービスもありますね。


タグ(ラベル)から記事の類似度をはかるのはありだと思うんですが、どうなんでしょうかね。

順序を変えて実行しても結果が一緒ということであれば 2008/03/02

ふと考えたこと。

こんな手順でコードを書いている。

まず処理をまとめる
a処理
b処理
c処理
※a,b,cとつけているだけでとくに意味はない。

で、このときに可能な限り順番に依存しないようにする。
どういうことかというと、
b処理を実行するためにはかならずa処理をしなければいけないということをなくすようにする。

あとは、効率のよくなるような処理のブロックの組み合わせになるようにする

自分のJavaのコーディングでの傾向は、すぐにユーティリティクラスを用意します。で、ユーティリティクラスはユーティリティメソッド(static)の集まり。
ユーティリティメソッドの組み合わせで、処理を行うようにしてます。

処理の組み合わせを決定するのにif文で場合分けをコードにどんどん埋め込まないように注意します。
呼び出しもとで分けるように努力します。

例えば(あくまでも例えですよ!!)
a();
b();
if(判定){
c();
} else {
d();
}

とはしないようにします。

if(判定){
パターン1
}else{
パターン2
}

パターン1
a();
b();
c();
パターン2
a();
b();
d();

って感じでするのが好きです。




ちなみに、フラグに1とか0の値を使うのは好きではないです。
flagA = 0;
flagB = 1;
でひとつの状態をあらわすような作りには決してしたくないです。
アドホックな感じがします。
このパターンを容認してしまうと、都合でどんどんflagXxxを追加してしまいます。
開発者が自分のその時の都合でフラグを追加するような仕組みはやめないとのちのち不幸になります。
フラグを追加するだけで、かけ算の状態を考慮しないといけなくなります。

flagA(0|1) x flagB(0|1|2) x flagC(0|1)
って感じで。
さらに嫌な感じになる可能性は、このフラグをみる順序が絡む場合です。
順序を考慮に入れることで、組み合わせの数が減るように感じますが、順序がコードを汚す原因になることもあります。

フラグを急遽入れて、その場をしのぐという方法は、あとからコードに手を入れないといけいときによく起きる感じがします。

こういったことが長く続くと、コードを捨ててバージョンをあげようという話になるのかもしれません。


stateごとに名前をつけて状態は管理したいです。