2007年10月アーカイブ

レポートを送るときは、早稲田メールから
レポートの控えはとって置くこと

などと言われるが、そんなことをしていたら5MBの容量なんてあっという間に使い切ってしまう


そこで、GoogleのGmailを使い、
・早稲田メールにきたメールは全てGmailに転送されるようにし、
・Gmailから早稲田メールのアドレスとしてメールを送信すればよい


やり方は、
(1) Gmailのアカウントを持っていなければ取得する
 無料で使えるので、ここからGmailのアカウントを取得する
 今回の使い方では、早稲田メールのアドレスとして送信するので、このときのアカウント名(~~~@gamil.comの~~~の部分)はなんでもいい

(2) Gmailにログインし、早稲田メールとして送れるように設定
 Gmailにログインしたら、右上の設定をクリックし、アカウントの設定から他のメールアドレスを追加をクリック
 ポップアップされたウィンドウのメール アドレスのフォームに、自分の早稲田メールのアドレス(~~~@~~~.waseda.jp)を入力し、次のステップ ≫を押し、確認メールの送信を押す

(3) 早稲田メールから承認する
 確認メールの送信を押すと、早稲田メールの方に、認証のメールが送信される。
 これは、Gmailから他のアドレスとして送信するので、本人なのかなりすましなのかを見分ける為に行うもの
 で、送られてきたメールにあるURLをクリックするか、メールに書かれている確認コードを入力するかすれば、認証は完了
 これで、Gmailからメールを送るときに、Gmailのアドレスか、早稲田メールのアドレスかを選ぶことができる。

(4) 早稲田メールからの転送設定
 Waseda-net portalから早稲田メールにログインし、左のメニューからメールフィルタをクリックし、新規作成

 フィルタ名:転送(※何でもいい)
 フィルタの条件:受信する全メッセージに適用
 フィルタの動作:次のアドレスに転送をチェック
           テキストエリアに(1)で取得したGmailのアドレス(~~~@gmail.com)を入力
           設定してない人は、携帯にも転送されるように、携帯のメアドも入力

 以上の設定をしたら設定をクリックし転送設定を完了させる



以上で早稲田メールに来たメールは全てGmail(と携帯)に転送され、Gmailからそのアドレスとして送ることができるようになった。



オプションとして、
(5) Gmailのラベル設定
 いわゆる、早稲田メールとして扱うメールは、それ専用のフォルダに自動振り分けされるように設定する。
 Gmailはきたメールをフォルダに分けて管理するのではなく、ラベルをつけて管理するようになっている。これだと1つのメールに複数のラベルが付けることも可能になった
 Gmailにログインし、右上の設定をクリックし、フィルタタブから新しいフィルタの作成をクリック
 宛先の欄に、早稲田メールのアドレスを入力し次のステップ ≫
 ラベルを適用をチェックし、隣のセレクトボックスから新しいラベルを選び、ラベル名を付ける
 フィルタを作成を押せば、早稲田メールから転送されてきたメールには全てこのラベルか付けられる



何か質問とかあれば気軽にコメントを


※この設定は自己責任において行ってください



P.S.
日刊スポーツ.comの速報によると、早慶戦は8回の表を終わって(?) 早稲田 7 - 0 慶應
これで、早稲田の三季連続優勝かな
そろそろ校歌を覚えなきゃw
Value Domainでドメインをとって、サーバーはXREAって感じでやってたんだが、同じサーバーを共有している誰かがアホなことをしたのか、hotmailのフィルタに引っかかってしまい、hotmailにメールが送れなかった

あと、信頼性とか容量とか考えても、googleなら文句なし!

今、Gmailの容量4GBあるしね


それと、今度汎用jpドメインをとることになってて、Gmailで独自ドメインとして設定しようじゃないか的なノリになったので、やり方をまとめておく



(1) まず、ドメインをとる
 Value Domainとかで取ってください


(2) Google Appsに申し込む
 有料版と無料版があるけど、無料版で十分だと思う
 申し込む時に、(1)でとったドメインを入れる

(3) 管理用IDを作る
 ~~~@(2)で入れたドメインが管理用IDとしてこれから使っていく

(4) Gmailを有効にする
 管理用IDでGoogle Appにログインし、Gmailを有効にする。
 「メールの配信設定」でセレクトボックスがEnomになっており、Enomにログインして設定しろって書いてあるが、Value Domainにログインして設定を行う。

(5) Value DomainでDNSの設定を行う
 Value Domainにログインできたら、DNSレコード/URL転送の設定から設定画面に入る。
 (4)の画面の指示通り、以下の設定を入れる

ホスト名 ターゲット タイプ MX設定
@ aspmx.l.google.com. MX 10
@ alt1.aspmx.l.google.com. MX 20
@ alt2.aspmx.l.google.com. MX 30
@ aspmx2.googlemail.com. MX 40
@ aspmx3.googlemail.com. MX 50
@ aspmx4.googlemail.com. MX 60
@ aspmx5.googlemail.com. MX 70
@ v=spf1 include:aspmx.googlemail.com ~all TXT 10

最後の行のTXTレコードの設定は載っていないが、所有ドメインの偽装メールを防ぐ~SPFレコードの設定によると、他人が自分のドメインでなりすましをしないように、自分のサーバー以外でそのドメインを使えないようにする設定らしい


(6) 設定を完了する
 (4)の画面の一番下に指定された手順を完了しましたというボタンがあるので押す

これで一応使える状態になる



参考サイト
風見鶏の目
Gmail for your domainをVALUE DOMAINで使う
所有ドメインの偽装メールを防ぐ~SPFレコードの設定
eNom管理の独自ドメインでSPFレコード設定
OCamlで再帰関数や、他の関数を呼び出す関数などをデバッグする時に、
traceを使えば、何回くらい再帰が起こってるのかとか、引数が正しく渡されてるかを確認できる

関数hogeについてtraceしたければ

# #trace hoge;;

と打ち、関数を実行すればよい
また、traceを辞めたい時は

# #untrace hoge;;

と打てばよい。

長めの関数を書く時や、試行錯誤しながらコーディングする時は意外に便利だ
友人と「日暮里」を「ひぐらざと」って読んでたとか、「マルイ(OIOI)」を「オイオイ」って読んでたなんて話で盛り上がってたら、ブログにまとめてくれました。
うえちょこ@ぼろぐの情報を正しく読むによると、IT media Biz.IDの難読サービスを読んでみるにもまとまってるみたい。

東京に来てすぐの頃は、ドトールとかなんて読むのか分からなかったし、EXCELSIOR(エクセルシオール)を見るとついエクスクルーシブオアー(EXCLUSIVE OR)って言いそうになるw(マテ

地名なんかはその土地の人じゃなければ間違えるのは仕方ないけど、IT用語に方言とかないからきちんと知っておきたい。
10年前とかヤフーのコトをヤッホーって言ってる人とかいたし、winnyの作者が逮捕される前とか、「ウィニー」なのか「ウィンニー」なのかよくわかんなかった。

さらに、未だにAltキーのことをアルトって言ってしまう・・・

以下に、↑の2つの記事をまとめたもの+αを表にしてみた。(結構独断と偏見で分けているので、不快に感じた方はコメントください。修正します)


正しい主流ではない?違う
Yahoo!ヤフーヤッホー
del.icio.usデリシャスデルシオウス
flickrフリッカー
Skypeスカイプスカイペ、スキープ
Twitterトゥイッター
Senduitセンド ユー イット
Scribd恐らく「すくりぶど」もしくは「すくらいぶど」
Alexaアレクサ
Plaxoプラクソ
Xeonジーオン
XOOPSズープス
VGAブイジーエー
SCSIスカジー
ATAエーティーエー、アタ
IEEEアイトリプルイーアイイーイーイー
Wnnウンヌ
ATOKエイトックアトック
Entourageアントラージュ
POPポッピピーオーピー
IMAPアイマップイマップ
SMTPエスエムティーピー
PINGピン、ピング
PNGピング、ピーエヌジー
TIFティフ
.orgドット オルグ
SaaSサース
Biz.IDビズアイディ
.rarラーアールエーアール
.aviエーブイアイアヴィ
.wavウェーブ、ウェブワヴ
XREAエクスリアエックスレア
pleiadesプレアデスパラダイス
enumエナムイナムエニューム
falseフォルスファルス
charキャラクターチャー、キャラ
varcharバーカー?バーキャラ、バーチャー
PEARペアーピアー
mojaviモハビモジャビ
PERLパールペール
Delphiデルファイデルフィー
Adobeアドビアドベ、アドーブ
Macromediaマクロメディアマイクロメディア
Pythonパイソンフィトン
DreamWeaverドリームウィーバードリームウェーバー
DirectXダイレクトエックスディレクトエックス
Altキーオルトキーアルトキー
BINDバインドビンド
GeForceジーフォースゲフォース
Ajaxエイジャックスアジャックス
LaTexラテフ、ラテックラテックス
WiFiワイファイウィフィ
脆弱性ぜいじゃくせいきじゃくせい
javacジャヴァシージャヴァック
usageユーセッジうさげ
WindowsVistaウィンドウズ ビスタウィンドウズ エム イー ツー
平成19年度 秋 ソフトウェア開発技術者を受けてきました

自己採点の結果は、
午前:54/80  ・・・ 67.25%
午後Ⅰ:86/100 ・・・ 86%
午後Ⅱ:75/100 ・・・ 75%
でした。

午前の解答はIPAに載っている公式のもので、午後の解答と配点は、
ここのものを使いました。


受かってたら、平成20年春にデータベース、平成20年秋にネットワークでも受けようかと



データベース編(途中で力尽きた)
○正規化
・非正規形
 繰り返し項目がある表
・第一正規形
 繰り返しを除いた表
・第ニ正規形
 主キーによって項目が決まる表
・第三正規形
 主キー以外の項目によっては決まらない表

○主キー
・主キー
 この項目によってデータを特定できる
・外部キー
 他の表の主キーを参照する
・複合キー
 2つ以上の項目が合わさって初めてキーとなる項目
・候補キー
 表の中に主キーとなりうる項目がたくさんある
・代替キー
 候補キーの中から1つが主キーとなり、残ったものが代替キー

○SQL
・CREATE TABLE
CREATE TABLE 表名 (
 項目名 型,
 項目名 型,
 オプション
)
PRIMARY KEY (列名):主キー
FOREIGN KEY (列名0)
REFERENCES 表名1 (列名1):列名0を外部キーとし、表名1の列名1を参照する
UNIQUE (列名):重複した値をとらない
列名 NOT NULL:NULLをとらない
CHECK (条件):条件にあった列とする

・CREATE VIEW

・INSERT
INSERT INTO 表名 (項目名, 項目名)
  VALUE(値, 値)

・UPDATE
UPDATE 表名
SET 項目名 = 挿入する値
WHERE 項目名 = 挿入前の値

・DELETE
DELETE FROM 表名
WHERE 項目
デフォルトで定義されている、Listの中のmap, fold_right, fold_leftという関数を使ってみる


まず、List.mapとは、以下のような関数であり、リストの要素1つ1つに対して引数の関数を実行し、その結果をリストで返してくれるものである。

# let rec map f = function
[] -> []
| h::t -> (f h) :: map f t;;
val map : ('a -> 'b) -> 'a list -> 'b list = <fun> 


このmapを使って、
[1;2;3] と["a";"b"] を受け取ると両者の「直積」、つまり[(1,"a");(1,"b");(2,"a"); (2,"b");(3,"a");(3,"b")] を返すような関数productを書くと

let rec product a b = 
  match a with
    [] -> []
  | h::t -> (List.map (fun x->(h,x)) b) @ product t b
;;


のようになる。これは、リストaの要素を順番に、リストbのすべての要素とのtuple(組)を作っていけばよい。
また、前回[OCaml]#6 今までの改良&powerset(べき集合)のpowersetをmapを用いて書き直すと、

let rec powerset a =
  match a with
    [] -> [[]]
  | h::t -> (List.map (fun x -> h::x) (powerset t))@(powerset t)
;;

のように簡単に書ける。だが、powerset tの部分で同じ計算を2度やるなど非効率なので、この結果を変数に保持しておいて、次のように改良できる。

let rec powerset a =
  match a with
    [] -> [[]]
  | h::t -> let p = powerset t in (List.map (fun x -> h::x) p)@p
;;




次に、fold_rightを使ってみる。
fold_rightの定義は以下のようになっている。

# let rec fold_right f a unit =
match a with
[] -> unit
| h::t -> f h (fold_right f t unit);;

fold_rightfold_leftは、畳込み関数と呼ばれ、unitとリストの最後の項との演算、その結果と最後から2番目との演算、その結果と最後から3番目との演算、その結果と・・・というように、引数を2つとり、1つ返す関数を右から順に行っていく。例えば、リストの和を計算したければ、

let sum a =
  List.fold_right (+) 0 a
;;

のように簡単に定義できる。
ここで、(+)は(fun x y -> x+y) のことである。
他にも、リストの最大値を求める関数listMaxや

let listMax a = 
  List.fold_right max a min_int
;;

unitにbを指定することで、リストとリストの連結を行う関数appendや、

let append a b =
  List.fold_right (fun x y -> x::y) a b

リストの長さを求める関数length

let length a =
  List.fold_right (fun x y -> 1 + y) a 0
;;

が簡単に定義できる。
また、先ほどのmap

let map f a =
  List.fold_right (fun x y -> (f x) :: y) a []
;;

のように定義できる。これは、1つ1つの要素に対し、fを実行し、今までの結果と繋げていけばよい

同様にfold_leftという関数も存在し、これはfold_rightとは逆にリストの左の要素から順に演算を行うものである。左から順に行ってくれることで、リストを逆順にするreverseが次のように実装できる。

let reverse a =
  List.fold_left (fun x y -> y::x) [] a
;;

このリストの反転は、fold_leftだからこそ出来ることで、積み上げられたプリントの一番上を取って、別のところに重ねていくのと同じである。
最後に、二つのリストa,bに対しその内積(a[0]*b[0] + a[1]*b[1] + a[2]*b[2] + a[3]*b[3] + a[4]*b[4] +・・・+ a[length-1]*b[length-1])を計算する関数inner_productを考える。
これはまず、関数combineによって、2つのリストの第n項同士をtupleにし、それをfold_rightを用いて掛けて足していくだけである。 funを定義する時に、(x,y) z つまり、掛け算をすべき組と今までの和を引数にとることに気がつけば簡単である。

let rec combine a1 a2 = 
  match (a1,a2) with
    ([],_) -> []
  | (_,[]) -> []
  | (h1::t1, h2::t2) -> (h1,h2) :: combine t1 t2
;;

let inner_product a b =
  List.fold_right (fun (x,y) z -> x*y + z) (combine a b) 0
;;

以上、まだ提出してない人はお早めに(笑)
○スケジューリングアルゴリズム
実行可能状態にあるプロセスの内、どのプロセスを実行するか
・到着順方式
 先に起動したプロセスを先に実行する方法
 先に到着したプロセスがCPUを長く利用するプロセスの場合、システムの応答性が低くなる
・処理時間方式
 プロセスが必要とする処理時間の短い順に実行する
・ラウンドロビン方式
 処理を一定時間行い、時間切れになったら実行可能状態に戻して列の最後に
・優先度順方式
 プロセスに優先度をつけ、優先度の高いプロセスから順に実行する
 優先度が低いプロセスがなかなか実行されない
・多重待ち行列方式
 ラウンドロビン方式に優先度順方式を取り入れたもの
 最初は高い優先順位と短いCPU時間を割り当て、その後は優先度を低くしてCPU時間を長くしていく

○排他制御
・デッドロック
 複数のプロセスがお互いにロック解除を待ち、先に進まない状態
・セフォマ
 排他制御を実行するための変数
 0ならロック状態、1ならロック取得可能
・P操作
 セフォマが0より大きければ1減らしてロック取得。0なら待機
・V操作
 セフォマを1増やし、ロック解除

○データ構造
・リスト
・LIFO(スタック)
 逆ポーランド記法で使う
・FIFO

○木
・2分木
 親の持つ子要素が2つ以下で左右の子を区別する木
・2分探索木
 各接点が持つデータについて、『左部分木の値<親<右部分木の値』が成り立つ』木
 親が削除された場合、左部分木の最大値か右部分木の最小値を親にする
・ヒープ
 各接点について、『親≦子』または『親≧子』の関係が成り立っている2分木
 左右の子の大小は問わない
・AVL木
 各接点について左部分木と右部分木の高さの差が±1までに収まる2分探索木
 挿入や削除の後に最適化を行う必要あり
・B木
 子の最大数がm、最少数がm/2となるタ分木
 データは葉に格納

○探索
・線形探索法
 前から順にデータをデータを調べていく。データ右端に番兵と呼ばれる目的のデータを入れて終了判定
 O(n)
・2分探索法
 ソート済みのデータに対し、真ん中の値を調べ、調べる範囲を半分にしていく
 O(log n)
・ハッシュ表
 データをハッシュ関数(データを配列の長さで割った余り)で求めた場所に格納する
 値によって衝突が起こる。衝突時の処理として、オープンアドレス法とチェイン法がある
・オープンアドレス法
 衝突が発生した時、別の関数でサイド計算し、そのアドレスに格納する
・チェイン法
 衝突が発生した時、その場所にリストを作り、リストに格納する
・ハッシュ法
 O(1)で追加、削除、嘆息を行えるが、衝突が多いとこの限りではない

○ソート
・選択整列法
 先頭から順に最小値を探し、先頭を交換
 比較回数O(n^2)
・交換法(バブルソート)
 隣り合わせになっているデータの大小を正していく
 比較回数O(n^2)
・挿入整列法
 整列部分にデータを挿入する方法。前から順位整列していって、次のデータをその中に挿入する
 比較回数O(n^2)
・シェルソート
 挿入整列法を改良したもの
 データをいくつかの部分列に分割し、分割したデータに対し挿入整列法を行う
・ヒープソート
 ヒープ木を作成し、根の値を最大値としれ取り出す、残りを再構築し、これを繰り返す
 計算量は、O(n log n)
・クイックソート
 基準となる値を決め、それより大きいか小さいかで分割し、この分割を最後まで繰り返す分割統治法
 計算量はO(n log n)
 最も高速なソートだが、データが整列済みだとオワッテル
・マージソート
 データを最後まで分割し、併合しながらソートしていく分割統治法
 大量のメモリが必要
 計算量は(n log n)
・安定な整列法
 同じ値が含まれている場合、ソート前とソート後でその順序が保たれているものを安定という
 安定:バブルソート、納入整列法、シェルソート、マージソート
 不安定:ヒープソート、クイックソート

○文字列探索
・力任せ法
 前から順に比較し、違ったら比較する位置を1つずらす
・KMP法
 前から順に比較し、違ったら、そこから比較しなおす
・BM法
 見つけたい文字列の右から比較する。違ったら見つけたい文字列分ずらして比較

【CPU】
○ALU
CPUの演算子装置

○レジスタ
・命令レジスタ
 取り出した命令を記憶
・プログラムカウンタ
 次の命令のアドレスを記憶
・ベースレジスタ
 プログラムの先頭アドレスを記憶
・指標レジスタ(インデックスレジスタ)
 修飾アドレスのときに使う
・汎用レジスタ
 なんにでも使える

○アドレス指定方式
・即値方式
・直接アドレス指定方式
・間接アドレス指定方式
 アドレス先にアドレスがある
・指標(インデックス)アドレス指定方式
 アドレス部+インデックスレジスタ
・ベースアドレス指定指定
 アドレス部+ベースレジスタ
・相対アドレス指定方式
 アドレス部+プログラムカウンタ

○クロック周波数
・CPI(Cycles Per Instruction)
 1命令を実行するのに必要なクロック数
・MIPS(Million Instruction Per Second)
 1秒間に何百万回命令が実行されるか
・FLOPS(FLoating-point on Operations Per Second)
 1秒間に実行できる浮動少数演算の回数

○CPUの設計
・CISC(Complex Instruction Set Computer)
 可変長な複雑な命令を理解できるが高速化できない
・RISC(Reduced Instruction Set Computer)
 固定長な命令しか理解できないが、高速化できる

○処理速度の高速化
・パイプライン方式
 1つの命令の実行を、(1)命令取り出し、(2)命令解読、(3)オペランド読み出し、(4)実行などの段階に分け、ずらしながら実行する。
 分岐があると効果が薄くなる
・スーパーパイプライン方式
 パイプライン方式の命令ステージをより細かく分割したもの
・スーパースカラ方式
 パイプラインを複数持つ

○マルチプロセッサ
・SISD(Single Instruction Single Data)
 1命令で1つのデータを処理する
・SIMD(Single Instruction Multiple Data)
 1命令で複数のデータを処理する
・MISD(Multiple Instruction Single Data)
 複数命令で1データを処理する
・MIMD(Multiple Instruction Multiple Data)
 複数命令で複数データを処理する


【メモリ】
○メモリ配置
・単一区間方式
 メモリを1つの区画とし、1つだけロード
・多重区画方式
 メモリを一定区画に分割、1区画以上のものはロードできない
・可変区画方式
 区画の大きさを変更できるが、断片化(フラグメンテーション))が起こる

○メモリ不足の解消
・オーバーレイ
 プログラムを分割し、必要な部分だけロード
・スワッピング
 優先度の低いプログラムを補助記憶装置に退避
・仮想記憶
 メモリの内容を補助記憶装置に退避
 実メモリには仮想メモリのアドレスを入れる。

○仮想記憶
・ページング方式
 固定長のページに分割
・セグメント方式
 可変長のセグメントに分割

○仮想記憶のページ置き換え方式
・LRU(Least Recentlu Used)
 最後に参照されてからの時間が長いものkら追い出す
・FIFO(First In First Out)
 最初に記憶したものから追い出す
・LFU(Least Frequently Used)
 参照頻度が最も少ないものから追い出す

○RAM
・RAM(Random Access Memory)
 電源を切ると消える、揮発性メモリ
・SRAM(Static RAM)
 高速だが高価で、キャッシュメモリに使われている
・DRAM(Dynamic RAM)
 低速だが安価で、メインメモリとして使われている

○ROM
・ROM(Read Only Memory)
 電源を切っても消えない不揮発性メモリ
・マスクROM
 読み出し専用メモリ。BIOSとか家電で
・PROM(Programmable ROM)
 書き込み可能なメモリ
・EPROM(Erasable Programmable ROM)
 紫外線でデータを消去できるメモリ
・EEPROM(Electrical Erasable Programmable ROM)
 電気的にデータを消去できるメモリ。フラッシュメモリはこれ

○メモリの高速化
・ライトスルー方式
 書き込みの際にキャッシュメモリとメインメモリの両方に書き込む。
 読み込み時のみ高速化
・ライトバック方式
 キャッシュメモリにだけ書き込み、キャッシュメモリを追い出す必要が生じた時点でメインメモリに書き込む。
 読み書きで高速化され、ライトスルー方式より高速
・メモリインターリーブ
 キャッシュメモリを複数の区画に分割し、連続したアドレスに同時にアクセスできるようになる

○キャッシュメモリの割付け方法
・ダイレクトマッピング
 メインメモリのブロックをキャッシュメモリの決められてブロックに割付け
 メインメモリのアドレスをキャッシュメモリのブロック数で割ったあまりの位置に割付け。アドレス変換は楽だけど、非効率的
・フルアソシアティブ
 メインメモリのブロックをキャッシュメモリのどの場所にも割付けられる。効率的だがアドレス変換が複雑
・セットアソシアティブ
 ダイレクトマッピングとフルアソシアティブの間
 決められたセット内において、どこに割付けても良い
 フツーはこれ


【割り込み】
○内部割込み
エラーなどにより、実行中のプログラムにより行われる
・プログラムによる割り込み
 オーバーフロー、ゼロによる除算などの実行時エラー
・スーパーバイザコール(システムコール)割り込み 
 プログラムからOSに入出力処理を依頼したときに発生
・ページフォールト割り込み
 メモリに存在しないページにアクセスした時に発生

○外部外部割込み
・入出力割込み
 周辺機器との入出力動作が終了した時に発生
・タイマ割り込み
 タイマから受ける一定間隔の割り込み。スレッドの交代とか
・機械チェック割り込み
 ハードウェアの異常などによって発生

【周辺機器】
○補助記憶装置
・HDDのアクセス時間
 シーク(位置決め)時間+サーチ(回転待ち)時間+データ転送時間
 =平均位置決め時間+半回転するのにかかる時間+読みたいデータ量を読む時間
・磁気テープ(DAT)によるバックアップ
 データをレコードに分割し、レコードをブロック化因子に基づいてブロック化
 ブロック間にはIBGというスペースを入れて書き込む

○周辺機器とのデータ転送
・DMA(ダイレクトメモリアクセス)
 CPUを介さずに周辺機器とメモリで直接データをやりとりする。
 周辺機器の転送速度の遅さをCPUに影響させないので処理が速くなる
・チャネル
 周辺機器のデータ転送専用のプロセッサのこと。DMAの発展

○周辺機器との接続
・PCI
 拡張バスインターフェース
・AGP
 ビデオカード専用インターフェース
・IDE
 HDDを接続する規格。光学式ドライブを含めATA/ATAPIとして標準化
・SCSI
 補助記憶装置やプリンタを接続する規格
・USB
 電源を入れたまま抜き差しができ、127台まで接続できる
・セントロニクス
 プリンタ接続する規格
・RS-232C
 モデム用
・IEEE1394
 最大63台まで接続できる高速転送インターフェース
 電源を入れたまま抜き差しできる(ホットプラグ)
・IrDA
 赤外線通信の規格。通信距離は1m
・Bluetooth
 2.5GHzの電波で通信。通信距離は10m
さっき書いた、 [OCaml]#5 和集合 積集合 差集合 対称差集合のunion、intersectionについて、このプログラムはO(n)であるcontainをn回再帰しているのでO(n^2)の手間がかかる。
ここで、引数として与えるリストがソート済みならば、O(n)でもっと早く実行できる。


引数のリストは昇順にソートされているので、2つのリストの先頭の要素つまり最小値を取り出し、値が違えば小さい方と同じ値はもう1つのリストには含まれていないことがわかる。intersectionも同様にして求めると、

let rec union l1 l2 =
  match (l1,l2) with
    (_,[]) -> l1
  | ([],_) -> l2
  | (h1::t1,h2::t2) -> if(h1=h2) then h1::(union t1 t2)
                  else if(h1<h2) then h1::(union t1 l2)
                  else h2::(union l1 t2)
;;

let rec intersection l1 l2 =
  match (l1,l2) with
    ((_,[]) | ([],_)) -> [] (* 片方のリストが空なら空リストを返す *)
  | (h1::t1,h2::t2) -> if(h1<h2) then intersection t1 l2
                  else if(h1>h2) then intersection l1 t2
                  else h1::(intersection t1 t2)
;;


最後に、あるリストを与えた時にそのリストのべき集合を返すpowersetを考える。
例えば、powerset [1;2;3;]と実行すると、[[]; [1]; [2]; [3]; [1; 2]; [1; 3]; [2; 3]; [1; 2; 3]]を返すという具合である。

これは再帰的に考えると、n個の要素からなる集合のべき集合は、n-1個の要素からなる集合のべき集合を求め、それとそれの各要素にn個目を加えたものの和集合である。 この、べき集合の各要素(要素といってもリストだが)にn個目を加える作業は別メソッドで定義した。powerset2は、リストのリストと、追加する要素を受け取り、リストのリストから先頭のリストを取り出し、要素を加えたものと加えないものを計算し、残りは再帰的に求める。

let rec powerset2 element listInList =
  match listInList with
    [] -> []
  | h::t -> h :: (element::h) :: (powerset2 element t)
;;

let rec powerset list = 
  match list with 
    [] -> [[]]
  | h::[] -> [[];[h]]
  | h::t -> powerset2 h (powerset t)
;;


ちなみに、実行すると、
# powerset [1;2;3];;
- : int list list = [[]; [1]; [2]; [1; 2]; [3]; [1; 3]; [2; 3]; [1; 2; 3]]
# powerset ["egg"; "sausage"; "spam"];;
- : string list list =
[[]; ["egg"]; ["sausage"]; ["egg"; "sausage"]; ["spam"]; ["egg"; "spam"];
 ["sausage"; "spam"]; ["egg"; "sausage"; "spam"]]

となって、確かにべき集合を求めることが出来た
数学の集合、つまり重複を許さないリストについて考えてみる。リストの結合演算子"@"では、結合するリストに同じ要素があれば、結合後のリストにはそれが2個でてくる。これを、要素が重複しない、和集合(A∪B)を返してくれるメソッドunionを定義したい。
重複しないようにするには、先頭から順に結合するリストにも同じものが入っているかを調べればよい。同じものが入っているかどうかは、[OCaml]#4 リストとmatch文のcontainを使えばよく

# let rec contain list n =
  match list with
    [] -> false
  | h::t -> if h=n then true
            else contain t n
  ;;

# let rec union a b = 
  match a with
    [] -> b
    | h::t -> if(contain b h) then union t b
                else h::union t b
  ;;

となり、同様に、積集合(A∩B)intersection、差集合(A-B)defference、対称差(A∪B-A∩B)symmetric differenceを定義する。

# let rec intersection a b = 
  match a with
    [] -> []
    | h::t -> if(contain b h) then h :: intersection t b
                else intersection t b
  ;;
# let rec defference a b = 
  match a with
    [] -> []
    | h::t -> if(contain b h) then defference t b
                else h::defference t b
  ;;
# let rec symmetric_defference a b = 
    defference a b @ defference b a
  ;;

となる。
OCamlでは、配列ではなくリストが使われる。
リストの宣言&初期化の仕方は、
# let array = [1; 2; 3; 4];;
val array : int list = [1; 2; 3; 4]
# let charArray = ['a'; 'b'; 'c'];;
val charArray : char list = ['a'; 'b'; 'c']
のようにやる。

また、リストの要素は同じ型でないといけないので、char型とint型、float型とint型を混ぜて使おうとするとエラーになる。
 # let array = [1; 2; 'a'];;
This expression has type char but is here used with type int
# let array = [1.0; 2];;
This expression has type int but is here used with type float

リストとリストの結合は、演算子"@"を使う。
# let a = [1;2;3];;
val a : int list = [1; 2; 3]
# let b = [2;4;5];;
val b : int list = [2; 4; 5]
# let c = a @ b;;
val c : int list = [1; 2; 3; 2; 4; 5]
これはあくまでリストの結合なので、前のリストに続いて後ろをくっつけただけである。

同じように、ある要素をリストの先頭に挿入する場合は、"::"を用いて
# let d = 0::a;;
val d : int list = [0; 1; 2; 3]
のようにする。


ある要素がリストに含まれているかを調べるには、containメソッドを次のように定義すればよい。
# let rec contain list n =
  match list with
    [] -> false
  | h::t -> if h=n then true
            else contain t n
  ;;
val contain : 'a list -> 'a -> bool = <fun>

これは、まず、match文で仮引数のlistについて比較し、
listの要素が無ければnが含まれているわけないのでfalseを返し、
そうでない時、listを最初の要素h(head)と残りのリスト(tail)に分割し、hがnと等しかったらtrueを返し、そうでない時、残りの部分tとnを比較する。

"|"と"||"は"または"の意味で、前者は、比較最中にtrueが決まると残りの部分は検討せずにtrueを返し、後者は最後まで計算をする。"&"と"&&"も同様である。
実行結果は、先ほどのリストa( = [1; 2;3])を使うと、
# contain a 1;;
- : bool = true
# contain a 4;;
- : bool = false
となる。


次回は、集合(map)の実装について考える
百式さんで同じIPを使っている他のサイトの一覧を出してくれる『myIPneighbors』というのが紹介されていた。

myIPneighborsは同じIP、つまり同じサーバー内にどんなサイトがあるのか調べてくれるサイトである。
これを使うと、共有レンタルサーバーなど、自分以外にどんなサイトがあるのか、いくつくらいサイトがあるのかなどを調べることが出来る。
最近、サーバーが重いと思ったら、同じサーバーを使っている誰かが重い処理をしているのかもしれない。
逆に、他の人にはそんなに重そうなページが無いのであれば、重くている犯人はあなたかも知れない
@IT - 携帯機器向け「Mobile Firefox」開発へや Mozilla Corporationのエンジニアリング責任者であるマイク・シュローファー氏のブログに書かれているように、FireFoxのモバイル版が開発されるらしい。

Mozillaは既に、Minimoという名前で実験的に携帯用ブラウザを作っているが、今回のは"FireFox"が名前につくのでカナリ高いクオリティーが期待できる。
IT戦記 [javascript] 一行で IE の JavaScript を高速化する方法に載っているように、JScriptの最初に

/*@cc_on _d=document;eval('var document=_d')@*/

を入れるだけで、IEでの動作が高速化される。
これは、documentを使うより、var doc = document;としてdocを使う方がいちいちシステム内部の処理を呼ばなくて済む分速くなるかららしい。
なので、_d = documentとし、JScript中のdocumentを_dに置換してしまえばこの恩恵を受けることができる。

ここで、狂ったように速いと言われたGWT1.4のメールアプリのソースを見てみると、確かにdoc = documentとか書かれてあった。このソースはGWT1.4をダウンロードすれば、サンプルソースとしてついてくる。

実際に確かめてみたのだが、IEでは本当に5倍くらい速くなったのだが、FireFoxでは効果が見られなった
長い処理を書く時や書いた処理を保存したい時など、やはりエディタでソースを書き、それを読み込むようにしたい。

外部ファイル、sorce.txtを読み込む場合は、
# #use "sorce.txt";;
とすればよい。

また、ソースないにコメントを書きたい場合は、
(* コメント*)
のように、(*と*)でくくる。

CやJAVAでいう、/* ~~~ */と同じように使う。
10月10日、今日は何の日でしょう。

10月10日
  ↓



そう、今日は『萌』の日である。



これを知人に言ってみると、他にも面白い合体文字が

H × ERO →  HERO(英雄)



一番笑ったのが、


小五 × ロリ → 悟り

である。

『悟り』という字を作った人は神だww
[OCaml]#1 OCamlで関数や変数を定義するでは関数をlet 変数(関数)名 引数1 引数2・・・のように定義したが、再帰関数を定義する場合にはrecというオプションが必要となる。

例を挙げて説明すると、
n xの2引数をとり、xのn乗を計算する再帰関数powerは、
# let rec power n x =
  if(n=0) then 1
  else if(n mod 2 = 0) then power (n/2) (x*x)
  else x * power (n/2) (x*x)
;;
val power : int -> int -> int = <fun>
のようにletと関数名の間にrecを入れる。そして、単にxをn回掛けるとO(n)の手間になってしまうので、再帰をうまく使いO(logn)で出来るようにした。
これは、例えば、x^10はx^10 = (x^5)^2 = (x*(x^2)^2)^2 とすると、掛け算の処理は4回で済む。
このようにx^2を(x^(n/2))^2とする時に、nが偶数か奇数かで分類している。


もうひとつ例を挙げると、フィボナッチ数列の第n項を求める関数を考える。
# let rec fib n =
  if n<=2 then 1
  else fib (n-1) + fib (n-2)
  ;;
val fib : int -> int = <fun>
とやってしまうと、fib (n-1) + fib (n-2)を求める過程で同じ計算を何度もしてしまうことになり効率が悪い。 これをO(n)で計算するためには、第n項から第1項に向かって順に求めていくのはなく、
実際にあなたがフィボナッチ数列を求めるように、第1項から第n項に向かって計算していけばよい。
つまり、
# let rec fib2 a b n cnt =
 if(n=cnt) then b
   else fib2 b (a+b) n (cnt+1)
;;
val fib2 : int -> int -> int -> int -> int = <fun>
# let fib n =
    fib2 1 1 n 2
;;
val fib : int -> int = <fun>
とすればよい。fib2でのcntはbが第何項かを保持している
ここで、recオプションを用いた再帰関数や、そのうち書くつもりだがandを用いて関数を同時に宣言する以外では、関数内で用いる関数は、その関数の定義時には既に定義されていなければならない。なので、補助関数fib2はfib内で使われているので、fib以前に定義しなければならない。
OCaml入門の第一歩として、変数や関数の定義をしてみる。
まずOCamlは、CやJAVAのようにソースコードを何行も書いてそれを一気にコンパイルすると言った形を取らず、 命令を書いたらそれが一行一行実行される。(正確には;;と打つたびに実行される)

なので、関数名や変数名が重複すると、2回目以降で定義した時に上書きされてしまう。だが、これはデバッグなんかを簡単に出来るので慣れてしまえば逆に便利だ

まずは変数の定義と四則演算
# let a = 7;;
val a : int = 7
# let b = 5;;
val b : int = 5
# a + b;;
- : int = 12
# a - b;;
- : int = 2
# a * b;;
- : int = 35
# a / b;;
- : int = 1
# a mod b;;
- : int = 2

浮動小数点を扱いたい時は
# let c = 2.5;;
val c : float = 2.5
# let d = 0.2;;
val d : float = 0.2
# c +. d;;
- : float = 2.7
# c -. d;;
- : float = 2.3
# c *. d;;
- : float = 0.5
# c /. d;;
- : float = 12.5
のように演算子にも.をつける必要がある。もし、それを書き忘れたら
# c + d;;
This expression has type float but is here used with type int
と即座にエラーが出て、コンパイルエラーで何行目が・・・のようにならずに違えた瞬間に教えてくれる。
また、円周率の計算は次の式でできる。
# let pi = 4.0 *. atan(1.0);;
val pi : float = 3.14159265358979312



関数の定義も同じletを使って行える。
# let f a b x =
  a*x + b
;;
val f : int -> int -> int -> int = <fun>
# f 3 4 5;;
- : int = 19
と書くと、3つの整数を引数にとって、a*x +bを返す関数が定義できる。
また、
# let f2 = f 2 3;;
val f2 : int -> int = <fun>
# f2 2;;
- : int = 7
のように、関数を使って関数を定義することも出来る。f2は、ひとつの整数を引数にとり、2*x+3を返す関数である。
関数型言語であるOCaml(Objective Caml)を使ってみる。OCamlは、実行速度がJavaなどよりはるかに速く、Cにかなり近いスピードが出る。そして、使用言語が自由なICFP(International Conference on Functional Programming,国際関数型プログラミング学会)のプログラミングコンテストの上位者の多くがOCamlを使っているらしい。

今回は、その動作環境のインストールについて
マシンはWindowsPCを想定している。
WindowsでOCamlをインストールする場合、CygwinとMinGWの2種類の方法があるが、今回はCygwinで入れることにする。

①まず、http://www.cygwin.com/からCygwinをインストールするためのsetupファイルをダウンロードする。Cygwin自体はインストールされているが、OCamlは入ってないという人もこちらから

②ダウンロードできたらsetup.exeを実行し、『次へ』→『次へ』→Default Text File TypeをDOS / textにして『次へ』→『次へ』
→『次へ』ダウンロードサーバーの一覧が出るが下のほうのftp://~~~.jpを選び『次へ』→DevelからOcamlを選んでinstallに、後は『次へ』を選んでいくとインストールできる。

インストールが完了したら、Cygwinを起動し、OCamlと打てばOCamlが実行できる。終了する時は、#quit;;
注意しないといけないのが、画面にはすでに#が出ているが、それとは別に#quit;;を打つ必要があること

だが、このままでは、OCaml実行中にキーボードの→や←を押すと、表示はされないがそのキーコードが入力されてしまい、実行時にエラーとなる。

これはかなり不便なので、leditというソフトを入れる。

ここからledit-1.11.tar.gzをダウンロード

④解凍ツールを持っている場合は解凍し、なければCygwinのtar xzvf ledit-1.11.tar.gzコマンドで解凍する

⑤解凍したら、Cgwinで出来たフォルダの中に移動し、makeコマンドを実行

⑥その後、make installコマンドを実行

これでleditがインストールされる。起動は、Cgwinでledit OCamlと打てば実行でき、今度は→とか←とかを打ってもへんなことにはならない

iKnow

あわせて読みたいブログパーツ
Firefox meter