June 04, 2006
木を0,1で表現 14:25
- Permalink
- Comments (382)
- Trackbacks (0)
Scheme
最近プログラミングしてなかった。 授業で出てきた、木を0,1で表現するアルゴリズムってのが面白そうなのでリハビリということで実装してみた。
(use gauche.collection)
(use srfi-1)
; ex. pathls = ((1 2) (2 3))
(define (tree->label pathls)
(let loop ((nodes (make-node-list pathls)))
(cond ((<= (length nodes) 0) (error "why is there no node?"))
((= (length nodes) 1) (get-label (car nodes)))
((= (length nodes) 2) (apply append (sort (map get-label nodes) label>?)))
(else
(let1 non-leaf-nodes (filter (lambda (n) (not (leaf? n))) nodes)
(let iter ((nln non-leaf-nodes)
(promises '()))
(if (null? nln)
(begin
(for-each force promises)
(loop non-leaf-nodes))
(begin
(let1 node (car nln)
(set-label! node (concat-labels node))
(iter (cdr nln) (cons (delete-leaves! node) promises)))))))))))
(define (make-node id)
(list id (list 0 1) '()))
(define (get-label node)
(cadr node))
(define (get-id node)
(car node))
(define (get-branches node)
(caddr node))
(define (get-leaves node)
(filter leaf? (get-branches node)))
(define (set-label! node label)
(set-car! (cdr node) label))
(define (leaf? node)
(>= 1 (length (get-branches node))))
; nodeと隣接する葉を削除するpromiseを返す
; 葉の削除後このnodeが葉になる可能性があり、削除を遅延しておかないと
; ほかのノードのdelete-leaves!でこのnodeが葉と見なされて消されてしまう
(define (delete-leaves! node)
(let1 non-leaf-nodes (filter (lambda (br) (not (memq br (get-leaves node))))
(get-branches node))
(delay (set-car! (cddr node) non-leaf-nodes))))
; nodeにbranch-nodeへの枝を追加する
(define (add-branch! node branch-node)
(set-car! (cddr node) (cons branch-node (get-branches node))))
; pathで指定されたノード間をつなぐ ex. path: (1 2)
(define (connect! path nodes)
(let ((node1 (get-node-by-id (car path) nodes))
(node2 (get-node-by-id (cadr path) nodes)))
(add-branch! node1 node2)
(add-branch! node2 node1)))
(define (label>? label1 label2)
(> (length label1) (length label2)))
(define (make-node-list pathls)
(let1 nodes (map make-node (path-list->node-id-list pathls))
(for-each (cut connect! <> nodes) pathls)
nodes))
(define (get-node-by-id id nodes)
(find (lambda (n) (eq? id (get-id n))) nodes))
(define (path-list->node-id-list pathls)
(delete-duplicates (apply append pathls)))
(define (concat-labels node)
(append '(0)
(apply append (sort (cons (cdr (drop-right (get-label node) 1))
(map get-label (get-leaves node)))
label>?))
'(1)))
長いね。
アルゴリズムの詳しい説明はめんどくさいんでしないけど、 大まかに言うとノードにラベルを振って、 葉をそれが隣接するノードのラベルで表現したらその葉を消していくって感じ。 ノードのラベルが変化していくので代入の手続きを使ったけど、 代入はまだまだ慣れないなあ。混乱する。
個人的には遅延評価がうまいこと使えたのがよかったです。いや、うまいのかどうかはわかんね。 使いたかっただけじゃないかと。
ノードが1, 2, ...で、枝を(1 2)とかと表現。
gosh> (tree->label '((1 3) (2 3) (3 4) (5 6) (6 7) (8 9) (4 10) (7 10) (9 10))) …☆ (0 0 0 0 1 0 1 1 1 0 0 0 1 1 1 0 0 1 1 1) gosh> (tree->label '((1 2) (3 4) (2 5) (4 5) (5 6) (7 8) (8 10) (9 10) (5 10))) (0 0 0 1 1 0 0 1 1 0 1 1 0 0 0 1 1 0 1 1) gosh> (tree->label '((a b) (b c) (c d) (e f) (f d) (d g) (g h) (h i) (h j))) …○ (0 0 0 0 1 0 1 1 1 0 0 0 1 1 1 0 0 1 1 1)
木が0, 1で表現できるなんて面白い。 そう言えば、これは木の同型判定アルゴリズムとかいってたな。☆と○が同じ結果だから 同じ木ですってことでいいんだったかな。
ん、待てよ。わざわざdelay使わなくても
(define (delete-leaves! node)
(let1 non-leaf-nodes (filter (lambda (br) (not (memq br (get-leaves node))))
(get-branches node))
(lambda () (set-car! (cddr node) non-leaf-nodes))))
として、tree->labelのところを
(for-each force promises) ↓ (for-each (lambda (p) (p)) delete-proc)
としても同じじゃないか。ハズカシス(´Д⊂)
やっぱり遅延評価はまだ使いどころがわからないっていうか、まず勉強するのが先か。
ラベルを木に 17:27
- Permalink
- Comments (1897)
- Trackbacks (0)
Scheme
木を0,1のラベルにするやつの逆をやってみた。
(use srfi-1)
(define (label->tree label)
(let loop ((label (cdr (normalize label)))
(stack (list 1))
(num 2)
(pathls '()))
(cond ((null? label) pathls)
((= 1 (car label)) (loop (cdr label) (cdr stack) num pathls))
((= 0 (car label))
(loop (cdr label) (cons num stack) (+ num 1) (cons (list num (car stack))
pathls))))))
; label->treeがすっきりするようにlabelを変形
(define (normalize label)
(let1 sp (split-point label)
(if (= sp (length label)) label
(append (cons 0 (take label sp))
(cdr (drop label sp))))))
(define (split-point label)
(let loop ((num 1) (sum 0) (l label))
(let1 n (if (= 0 (car l)) 1 -1)
(if (= 0 (+ sum n)) num
(loop (+ num 1) (+ sum n) (cdr l))))))
gosh> (tree->label '((1 3) (2 3) (3 4) (5 6) (6 7) (8 9) (4 10) (7 10) (9 10))) (0 0 0 0 1 0 1 1 1 0 0 0 1 1 1 0 0 1 1 1) gosh> (label->tree (list 0 0 0 0 1 0 1 1 1 0 0 0 1 1 1 0 0 1 1 1)) ((10 9) (9 1) (8 7) (7 6) (6 1) (5 3) (4 3) (3 2) (2 1))
ノードの番号は当然一致しないけど、同じ木ができたっぽい。もう一個。
gosh> (tree->label '((1 2) (3 4) (2 5) (4 5) (5 6) (7 8) (8 10) (9 10) (5 10))) (0 0 0 1 1 0 0 1 1 0 1 1 0 0 0 1 1 0 1 1) gosh> (label->tree (list 0 0 0 1 1 0 0 1 1 0 1 1 0 0 0 1 1 0 1 1)) ((10 1) (9 8) (8 1) (7 2) (6 5) (5 2) (4 3) (3 2) (2 1))
同じっぽい。
June 06, 2006
Ubuntuを6.06にしたよ 12:41
- Permalink
- Comments (1958)
- Trackbacks (0)
Linux
ubuntuの6.06が出たので/etc/apt/sources.listを適当にs/breezy/dapper/してupgrade, dist-upgradeとかしつつ、 途中で再起動したらinitが起動せずに
ALERT! /dev/hda1 does not exist. Dropping to a shell.
となってBusyBoxとかいうのが起動した。(((( ;゜Д゜)))ガクガクブルブル
BusyBoxじゃなんもできないのでぐぐったら出てきたやつを 参考に、 以前使ってたハードディスクをつけて、そこに入ってるVine Linuxを起動、 ubuntuのハードディスクをマウントした後chrootでそちらへ。このコマンドすげぇ! 見ためはVine、頭脳はUbuntu。そして何事もなかったかのようにdist-upgrade続行。
なるほど、ここで本来ならKnoppixを使うわけですか。まー今ドライブ死んでるからどうせ使えないんだけど。
Ubuntu-jaのページを見ると ubuntu-desktopとubuntu-desktop-jaを入れとけって感じなのでこれも。
それでも直らないので調べてたら、ちょうど
dpkg-reconfigure linux-image-2.6.15-19-k7 fixed it for me.
てのを見つけた。同じようにしたら解決。簡単に済んでよかった……。なんか最近解決のしかたが適当すぎ。
June 07, 2006
m4a to ogg 18:12
- Permalink
- Comments (2009)
- Trackbacks (0)
Linux
あれ? Ubuntu6.06にしたときに何かあったのか、Rhythmboxでm4aファイルが聴けなくなった。 適当にaptitudeで突っ込んでも解決しない。 VIP STAR以外全部m4aなので、ここはとりあえずoggに変換しとく。
Howto:convert aac/mp4 to wav/mp3/ogg on Linuxという ページを参考に。
#m4a2ogg
infile=$1
wavfile=${infile%.*}.wav
mplayer -ao pcm "$infile" -ao pcm:file="$wavfile"
oggenc "$wavfile"
rm "$wavfile"
MPlayerすごい。MPlayerだとm4a再生できるんだよなぁ。てことはGStreamerとかいうのがいけないのかな。
これで
find . -name "*.m4a" -exec m4a2ogg {} ;
で全部再帰的にかたづくかと思ったけど、いくつか失敗する。ちっ。
ん、m4a再生できてるじゃん! 再起動が必要だったのかしらん。時間の無駄だった……。
June 10, 2006
ターミナルに出力する文字に色とかつけたい 01:07
- Permalink
- Comments (2368)
- Trackbacks (0)
Ruby
ターミナルにバーっと結果を吐き出すプログラムをRubyで作ることが多いんで、 もうちょっと結果が見やすくなるように色とか付けたくなったんで作ってみた。
作ってる途中でこの車輪は先に発明されているんじゃないかと思って調べたらあった(´Д⊂)
でもこれ、両方ともうまくいかないケースがあるんですよ。
underlineが途中で切れちゃう。これでは気持ち悪いんで、作る。
class String
BACKGROUND = {
:on_black => 40,
:on_red => 41,
:on_green => 42,
:on_yellow => 43,
:on_blue => 44,
:on_magenta => 45,
:on_cyan => 46,
:on_white => 47
}
COLOR = {
:black => 30,
:red => 31,
:green => 32,
:yellow => 33,
:blue => 34,
:magenta => 35,
:cyan => 36,
:white => 37
}
DECORATION = {
:bold => 1,
:dark => 2,
:italic => 3,
:underline => 4,
:blink => 5,
:rapid_blink => 6,
:negative => 7,
:concealed => 8,
:strikethrough => 9
}
DECORATION.keys.each{|name| eval <<-EVAL }
def #{name.to_s}
apply_style(DECORATION[:#{name.to_s}])
end
EVAL
COLOR.keys.each{|name| eval <<-EVAL }
def #{name.to_s}
apply_style(COLOR[:#{name.to_s}], COLOR.values)
end
EVAL
BACKGROUND.keys.each{|name| eval <<-EVAL }
def #{name.to_s}
apply_style(BACKGROUND[:#{name.to_s}], BACKGROUND.values)
end
EVAL
private
def apply_style(style, ignored_styles = [])
style_stack = [style]
result = self.dup
result.gsub!(/\e\[(\d+;)*\d+m/) do |match|
if match == "\e[0m"
if style_stack.pop.empty? or $'.empty?
""
else
match + create_parameter(style_stack)
end
else
new_style = get_style(match) - ignored_styles
style_stack << new_style
create_parameter(new_style)
end
end
"\e[#{style}m#{result}\e[0m"
end
def create_parameter(styles)
if styles.empty?
""
else
"\e[#{styles.flatten.compact.uniq.join(";")}m"
end
end
def get_style(param)
param.scan(/\d+/).map{|d| d.to_i }
end
end
underlineが切れたりとか、予想外のことは多分起こんない。
Term::ANSIColorからon_redなどの名前を拝借。 italicとかstrikethroughとかオレが調べたところには載ってなかったな……。つーか、 DECORATIONのメソッドはboldとunderlineとnegativeくらいしかまともに表示されなかった。 非対応ということなのかしらん。
あとyellow黄色じゃないんですが。whiteもon_whiteも灰色だし。 でもね、boldすると黄色くなったりするし、もう見ための色に名前を合わせるのは無駄だと悟った。
June 12, 2006
勝てー日本! 21:40
- Permalink
- Comments (1905)
- Trackbacks (0)
日記
がんばれ日本! うおおおおおおおおおおっ!!!
┌─┐ ┌─┐
│●│ │●│
└─┤ └─┤
_ ∩ _ ∩ ニッポン!
( ゜∀゜)彡 ( ゜∀゜)彡 ニッポン!
┌─┬⊂彡┌─┬⊂彡
|●| |●|
└─┘ └─┘
……。
/~ヽ /~ ヽ
| |i_∧ゝ ノ
ノ ノ;´Д`) / うわぁぁぁぁぁっ!
( ノ ソ
ヽ ヽ 最悪の時間帯に怒涛の失点キタ━━━━━━(゜∀。)━━━━━━ッ!!
\ \
\ \
_ / .\ _
/ミ (⌒Y. / ̄.\ .\ ミヽ
 ̄\ ,_ _,/ \,_ _,ノ ̄
June 13, 2006
クォート付きリストは返しちゃダメ? 03:40
- Permalink
- Comments (1911)
- Trackbacks (0)
Scheme
On Lispより。
関数は安全に書き換えられないものを返してはいけないということだ. だから返り値にクォート付きオブジェクトを含むような関数を書くのは避けるべきだ.
んお。そうなのか。On LispにあるコードをSchemeで試してみる。
(define (exclaim expression) (append expression '(oh my))) (exclaim '(lions and tigers and bears)) ;;=> (lions and tigers and bears oh my) (append! (exclaim '(lions and tigers and bears)) '(goodness)) ;;=> (lions and tigers and bears oh my goodness) (exclaim '(lions and tigers and bears)) ;;=> (lions and tigers and bears oh my goodness)
おお。exclaimの'(oh my)のcddrがappend!によって変更されてしまうみたい。 クォートした'(oh my)ってのの実体は一体なんなんだろう。
(define (exclaim2 expression) (append expression '(oh my))) (exclaim2 '(lions and tigers and bears)) ;;=> (lions and tigers and bears oh my)
別の手続きに'(oh my)を使ってもそちらの'(oh my)は変更されていないようなので、 クオートされたものは手続きごとに環境のような形で持っているんだろうか。 それともそんなまどろっこしいことはなくて、適当にどこかに確保されるだけかな?
まさかこんなことも……。
(define (foo) '(a)) (foo) ;;=> (a) (set-car! (foo) 3) (foo) ;;=> (3) (set-cdr! (foo) 4) (foo) ;;=> (3 . 4)
Cで言うstaticのついたローカル変数のような、オブジェクト指向言語で言うクラス変数のような。 とにかく呼び出しごとに毎回生成されるものではないみたい。考えたこともなかったよ。
(define (exclaim expression) (append expression (list 'oh 'my)))
なら安全。なんとなくそうしてたけど、なるほどねぇ。
June 18, 2006
今日は勝つぞっ! 16:28
- Permalink
- Comments (0)
- Trackbacks (1)
日記
┌─┐ ┌─┐
│●│ │●│
└─┤ └─┤
_ ∩ _ ∩ ニッポン!
( ゜∀゜)彡 ( ゜∀゜)彡 ニッポン!
┌─┬⊂彡┌─┬⊂彡
|●| |●|
└─┘ └─┘
まさかのスコアレスドロー……(つД`)
ヽ(Д´ )ヘ < シュートお前が打てよ!!
___ (┌ ) ≡≡≡≡≡
/ /| M \ ;。:;。
/ / | ( ゜д) ‖
/ / | (┘)┘ ‖
/ / > > ‖
/ / ‖
| ̄ ̄| ∧ ○ ヽ(Д´ )ヘ < いやお前が打てよ!!
| | じゃあ俺が (┌ ) ≡≡
| | \ ;。:
___ ヽ(゜д゜)ヘ
/ /| (┌ )
/ / |○(゜д゜) \
/ / | (┘)┘
/ / >丶>
/ / ヽ
| ̄ ̄| ヽ (∀`) < どうぞどうぞ
| | ヽノ( ノ)
| | ヾ < \
痛いニュースより、 秀逸なAA。 どこまでいいやつなんだ、柳沢……。 そこは敵のゴールだからシュート打っていいんだよ?(´;ω;`)
June 27, 2006
lolとは 03:56
- Permalink
- Comments (59)
- Trackbacks (0)
日記
YouTubeのコメント欄見てるとよく「lol」って書き込みがあるんで、調べてみた。
LOL (also spelled lol) is an abbreviation for "laughing out loud", "laugh out loud", or less commonly "lots of laughter".
なるほど、「糞ワロタ」か。
にしても、YouTubeのコメントは見て気持ちのいいもんじゃないことが多い。 「kill jap」だの「fuck jap」だの……。fuckin' japくらいわかるよ、ばがちんがー!
いやー嫌われてますねー、一部に。
June 28, 2006
戦隊もの 01:48
- Permalink
- Comments (1972)
- Trackbacks (0)
音楽
ひげぽんさんが戦隊ものCDをとりあげていたんだけど、 ちょうど少し前オレもYouTubeで戦隊ものとかメタルヒーローものを漁ってた。
せっかくなんでブックマークから少し出してこよう。 スーパー戦隊魂ライブ。これもやばげ。2004年か……生で見たかったなぁ。
チェンジマンとフラッシュマンのかっこよさは異常。 まー、こういうのは一番熱心に見てたものが一番かっこいいんだろうね。
CDはこれかな(↓アサマシ注意w)。金に余裕ができたら買いそうだ。
コロムビアミュージックエンタテインメント (2005/01/19)
売り上げランキング: 39,506

豪華な顔ぶれJune 30, 2006
スパマーにモテモテ 00:23
- Permalink
- Comments (1862)
- Trackbacks (0)
blog
このブログがトラックバック・スパマーにモテモテなので、 このブログへのリンクのないトラックバックは蹴ることにした。
ついでに蹴ったやつのログをとるようにしたんだけど、それ見ると3日連続で20件/日。 何がしたいんだろう……。
英語に何度目かのやる気を出してみるテスト 01:16
- Permalink
- Comments (1893)
- Trackbacks (0)
日記
やっぱ後々いろんなところに響いてくるのは英語力だろうってんで、 英語の勉強をはじめることにする。
やるのは、数年前に買って本棚に眠っていた ヒーローズinアメリカ。
アルク (1999/05)
売り上げランキング: 203,849
リスニングの本なんだけど、シャドーイングに使う。 と言っても本見ながらなんで、正確にはシャドーイングとは言わないらしい。
きっかけはOn Off and Beyondさんの「すばらしい英語勉強法」 というエントリ。本の使い道ができてよかった。


