@m_seki の

I like ruby tooから引っ越し

cvsのリビジョン番号

なにかコードが書きたくなったのだけどネタがない。
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)

というところまでやって飽きた。