なにかコードが書きたくなったのだけどネタがない。
cvsの変更履歴を検索するちょっとしたツールのデータベースのファイルがとても大きくなったので少し工夫することにした。(RubyKaigi09で話したやつ)
cvsのリビジョン番号とファイル名の組を文書IDのように見立てた辞書があるのでこれをなんとかする。今回はリビジョン番号を一意な整数に変換する辞書をいじる。
整数のtrie
cvsのリビジョン番号は偶数個の整数を「.」で区切ったものなのでIntegerのArrayと考えるとtrieで作れそう‥。
で、Hashのデフォルト値のprocを使って書いた。なんか変だ。
「0123456789.」のtrie
候補は「0123456789.」 の11文字しかないのだから11の枝を持つ木なんじゃね?
と思って書こうとしたけど、今度は書く前に気付いた。
11進数
「.」を「a」に置き換えたら、11進数なんじゃね? そしたらいつでも計算できるから辞書なんて要らないや。
'1.9.70.312'.gsub(/\./, 'a').to_i(11)
20進数
本当にそうか? 「..」は存在しない。「.」の前はいつも数字であるのだからなんとかならないか?
ということで「0.」を「a」に、「1.」を「b」に「9.」を「j」に置き換えて20進数にしてみた。
module CVSRev module_function def to_i(rev) rev.gsub(/(\d)\./) {|a| ($1.to_i + 10).to_s(20)}.to_i(20) end def to_rev(i) i.to_s(20).gsub(/[abcdefghij]/) {|a| (a.to_i(20) - 10).to_s + '.'} end end rev = '1.9.70.312' p it = CVSRev.to_i(rev) p CVSRev.to_rev(it)
というところまでやって飽きた。