13082006 music
メタモのチケットきた。
BLACK STROBE MARK FARINA が気になる。
13082006 music
11082006 perl
昨日に引き続き3章を読み進めていたら、フィボナッチ数をキャッシュで高速化する例が。
Higher-Order Perl: Transforming Programs with Programsコードはこんな感じで、割と普通な。
my %cache; sub fib{ my $n = shift; unless (exists $cache{$n}){ if($n < 2){ $cache{$n} = 1; }else{ $cache{$n} = fib($n-1) + fib($n-2); } } return $cache{$n}; }
さて、昨日のタプルを使ったコードとどっちが速いのか比べてみた。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | #!/usr/bin/perl use strict; use warnings; use Benchmark qw(cmpthese); sub fibStep { my $n = shift; return [$n->[1], $n->[0] + $n->[1]]; } sub fibPair { my ($n, $fs, $fp) = @_; return [0,1] if ($n == 0); return $fs->($fp->($n-1,$fs,$fp)) } sub fastFib { my $n = shift; my $fs = \&fibStep; my $fp = \&fibPair; my $fib_num = $fp->($n,$fs,$fp); return $fib_num->[0]; } my %cache; sub fib{ my $n = shift; unless (exists $cache{$n}){ if($n < 2){ $cache{$n} = 1; }else{ $cache{$n} = fib($n-1) + fib($n-2); } } return $cache{$n}; } my $number = 50; my $count = 10000000; my $fibcache = \&fib; my $fibfast = \&fib; cmpthese($count, { 'Cache' => $fibcache->($number), 'Fast' => $fibfast->($number) }); |
とりあえず1000万回まわしてみたけどそれでもwarningがでるので、この際無視。
./fib.pl (warning: too few iterations for a reliable count) (warning: too few iterations for a reliable count) Rate Fast Cache Fast 38461538/s -- -27% Cache 52631579/s 37% --
キャッシュしたほうが速いというのがイマイチ理解できん。何でじゃろか?
普通のhaskellプログラミングを読み終えて、なんか次に読むものないかなと探していたら、webarchiveに面白そうなページがあることを知ったので、ダウンロードして読んでます。
3回目の講義資料に、タプルを使って高速にフィボナッチ数を計算する話があったので、なんでそうなるのかを理解するために手で書き下してみた。
普通に書くとこんな感じ(fib)。
fact :: Int -> Int fact n | n == 0 = 1 | n > 0 = fact (n-1) * n
書き下すと、計算量があっという間に増えていくことがわかる。
fib 5 => fib 3 + fib 4 => (fib 1 + fib 2) + (fib 2 + fib 3) => (fib1 + (fib 0 + fib 1)) + ((fib 0 + fib 1) + (fib 1 + fib 2)) => (fib1 + (fib 0 + fib 1)) + ((fib 0 + fib 1) + (fib 1 + (fib 0 + fib 1)))
タプルを使った例(fastfib)
フィボナッチ数列を効率良く計算する方法を考えよう.前に見たとおり,フィボナッチ数列の各項は,その前の二つの項の和である.逆に言えば,二つの連続した項の値が与えられれば,次の項を計算するのは簡単なのだ.
fibStep :: (Int, Int) -> (Int, Int) fibStep (u, v) = (v, u+v) fibPair :: Int -> (Int, Int) fibPair n | n == 0 = (0, 1) | otherwise = fibStep (fibPair (n-1)) fastFib :: Int -> Int fastFib = fst . fibPair
コードを眺めただけではなんで速くなるのか実感がわかなかったので、書き下してみる。
fastFib 5 => fst (fibPair 5) => fst (fibStep (fibPair 4)) => fst (fibStep fibStep (fibPair 3)) => fst (fibStep fibStep fibStep (fibPair 2)) => fst (fibStep fibStep fibStep fibStep (fibPair 1)) => fst (fibStep fibStep fibStep fibStep fibStep (fibPair 0)) => fst (fibStep fibStep fibStep fibStep fibStep (0, 1)) => fst (fibStep fibStep fibStep fibStep (1, 1)) => fst (fibStep fibStep fibStep (1, 2)) => fst (fibStep fibStep (2, 3)) => fst (fibStep (3, 5)) => fst (5, 7) => 5
をを、タプルにすることで、計算量が減ってます、自分で展開していくとなるほどとよくわかる。
さて、最近Higher-order Perlを読んでいる僕としては、これをperlで書いてみたくなるわけである。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | #!/usr/bin/perl use strict; use warnings; sub fibStep { my $n = shift; return [$n->[1], $n->[0] + $n->[1]]; } sub fibPair { my ($n, $fs, $fp) = @_; return [0,1] if ($n == 0); return $fs->($fp->($n-1,$fs,$fp)) } sub fastFib { my $n = shift; my $fs = \&fibStep; my $fp = \&fibPair; my $fib_num = $fp->($n,$fs,$fp); return $fib_num->[0]; } my $number = shift; print fastFib($number) |
サブルーチンのリファレンスを引数にとらないといけないのがhaskellと異なるとこかな。あとは書いてて思ったのは関数の型を書くとプログラムの流れが理解しやすいナァと。
実行すると一瞬で計算が終わる(速い!)
実際に処理の流れを追うために-dオプションを付けて実行してsを連打すると、main::fibPairがどんどん実行されて$nが0になったところで今度はmain::fibStepが次々実行されていく様がわかる。
Higher-order Perlの5章にもフィボナッチ数列のことが書いてあるのだが、まだそこまで読み進めていない。(今3章突入したところ)
Higher-Order Perl: Transforming Programs with Programshaskellを勉強しながら、Higher-order Perlを読むと、色々新たな発見があって楽しい。
10082006 perl
実家に帰ったら、婆さんが数独にはまってた。ボケ防止にいいらしい。ちょうどいいので、flashの数独をgoogleで適当に探してきてお気に入りに登録しておいてやったら喜ばれたヨ。まぁ、使うかどうかわからんけど。
ちょうど、Highr Order Perl読み始めたところだし、家に戻ってきて、数独ソルバでも書いてみるかと思ってたら、タイミングよくUno, dos, tres, quatro!にエントリが。
Higher-Order Perl: Transforming Programs with Programsバックトラック法ってのを使えばいいのねと自分で書いてみたのはマス目を一つ一つ移動してくコードだったんだけど、再帰深すぎるヨっていうエラーを吐いて終了。なんかダメダメだなぁ。他の人のを読んでみるとまだ埋まってないマス目を再帰で埋めていくべきだったことに気付いた。ちょっとこれに引っ張られたかなと反省。
まだ埋まってないマス目の配列と、過程として数字を置いたマス目の配列の二つを用意して、バックトラック法で解くというわけですな。
とか、わかった上で、三行数独ソルバを読むと、説明もついてるしよくわかった、素敵。
家のマシンで三行数独ソルバを実行してみるとこんな感じ。
$ time perl sudoku.pl < sample 825169734 463857921 917234658 684712593 759386142 231495867 548621379 376948215 192573486 #本当はココまで一行で出力 real 0m1.439s user 0m1.436s sys 0m0.004s
プログラム・プロムナードにhaskellの数独ソルバが載ってたのでそれも実行してみた。ちゃんと理解しないといけないと思いつつ、今回はコピペ。ghciで計算させた。
*Main> sudoku sample [8 2 5 1 6 9 7 3 4 4 6 3 8 5 7 9 2 1 9 1 7 2 3 4 6 5 8 6 8 4 7 1 2 5 9 3 7 5 9 3 8 6 1 4 2 2 3 1 4 9 5 8 6 7 5 4 8 6 2 1 3 7 9 3 7 6 9 4 8 2 1 5 1 9 2 5 7 3 4 8 6 ] (0.28 secs, 26584692 bytes)
haskellもperlクイズみたいなのを誰かやってくれたら嬉しいナァ。とか。
09082006 Linux
yum-fastestmirrorは、ミラーリストから速いリポジトリを自動的に選択してくれる。Fedora Extrasにパッケージが用意されているので、yumコマンドでインストールできる。
入れてみたが、そもそも家の回線が遅いのであまり実感できないのかも。または、いつも使っている理研のミラーが速いからプラグイン入れても速く感じないのかな。
08082006 Linux
新しいマシンにFedoracore入れたらXが表示されない、、、のに、システムがX再起動をかけまくって無限ループに陥ってどうしようもないので、[Ctrl-Alt-F2]でコンソールにして作業してたら。
なんすかそれ?と
最近のLinuxはグラフィカルなログイン画面がデフォルトなので、真っ黒画面にlogin:だけがでるのが普通だって知らないのね。(昔はx11startとか打って、fvwm95とか使ってたのに)
ちなみに、[Ctrl-Alt-F7]でコンソールから X に復 帰
07082006 pdic
ここのところ、立て続けに自分の考えを英語で表現できないもどかしさを感じて凹むという事態が続いたので、このままではいかんと思い、どうにかしようと決心した。
今までは、gooの英和を使っていたのだけど、ひけない単語が結構あったのと、レスポンスが若干気になるので、英辞郎使えないかと色々調べた。
ブックマークレットは便利だが、いちいちブックマークレットを実行させるためにカーソルを移動するのがちょっと手間かな。右クリックでメニューバーに表示されんかなと思って探したら発見。

これで結構快適に辞書を扱える。ただ、Biomedical,SBDDな単語とかはさすがにヒット率が低いので、単語とか例文とか自分で追加、修正したいなぁと。となると、辞書データを買って自分好みに育て上げるほうがエエので、辞書データも購入してみた。
pdicは使い始めて2,3日だが凄く快適で、もっと早くに使っておけばとか思った。常駐させておけば、コピー(Ctrl-c)した途端に辞書を探して、ヒットすればポップアップして表示するので使いやすい。Meadowだと、ハイライトするだけでポップアップ表示するのでもっと楽。
viewerで探してみつからない単語は編集画面になるので、そのままgoogleなんかで調べて登録すれば辞書データも充実するし、、、
当面はこれを使っていこうかと。
06082006 静岡
05082006 静岡
毎度でつけ麺はじめたそうなので、遅まきながら出陣。子供連れなので、早めの空いてる時間にでもと平日の昼の部の始まりにあわせて。
ちょっと、早く着きすぎた。
そんなときは信号渡ってすぐの、三島大社で涼みながら待つことに。
うーん他にも2,3人うろうろしておる。もしや?!と思ったらその通り、開店待ちのおじさんたちでした。
開店即入店だったので、混まずに入れた。というわけで、ベビーカーもあまり邪魔にならずに、僕とU隊長の間に置かせてもらえた。毎度は子連れにヤサシゲなので素敵です。しかも前回は3ヶ月以上前に行ったのに覚えられてたのにはちょっとびっくり。
潮と醤油のつけ麺を。僕は潮。毎度の細い麺でつけ麺はどうだろうか?と思ってたが、やはりそこは麺職人、配合とか変えてつけ麺用の麺を用意してあるとのこと。
で、つけ麺だが、若干麺が太い、でもちもちしてて旨い。麺の旨さが引き立つ潮で正解だった。
麺が長いせいもあるんだと思うんだが、ちょっと麺がほぐれにくくて苦労したかなってくらい。水切りの加減かな。少しスープ割りもしてもらって余ったつけ汁を美味しくいただいた。