脳ざらし紀行


2004-12-24

_ [Ruby] ちかん

こんな感じで。

def perm(arry)
  return [arry] if arry.size <= 1
  ret = []
  beg = arry[0]
  rest = perm(arry[1..-1])
  rest.each{|a|
    ret << [beg] + a
    a.size.times{|i|
      ret << a[0..i] + [beg] + a[i+1..-1]
    }
  }
  return ret
end

p perm( [:a, :b, :c] )

もっと長い配列をちかんしたい場合。

class Permutation
  def initialize(ary)
    if ary.size <= 1
      @buf = [ary]
    else
      @buf = []
      @beg = ary[0]
      @rest = Permutation.new(ary[1..-1])
      fill_buf()
    end
  end

  def fill_buf
    return @buf if @buf.size > 0
    if @rest and a = @rest.perm
      @buf << [@beg] + a
      a.size.times{|i|
        @buf << a[0..i] + [@beg] + a[i+1..-1]
      }
      return @buf
    else
      return nil
    end
  end
  
  def perm
    ret = @buf.pop
    if ret
      return ret
    else
      if fill_buf()
        return @buf.pop
      else
        return nil
      end
    end
  end
end

perm = Permutation.new((1..100).to_a)
6.times{
  p perm.perm
}

_ [Ruby] 逆転の発想

ふと思いついて Zlib のメモリーリークを直してみようと思った。けど、どうやったらいいか良く分からなかった。ruby の例外は C 言語の longjump で実装されている。C++ と違って C 言語にはスタックを巻き戻す時にデストラクタを実行するような仕組みがないので、人が管理しないといけない。どこら辺で例外が起きたことを検知してメモリを解放するコードを書いたらいいかはコードの全体を把握していないといけない。でもまあ、ext/zlib/zlib.c の全体なんて知るわけないし。

なんで C 言語には GC がないんだろう。

とか思っていたら解決法を思いついた。C 言語で頑張らずに Ruby のコードで書けば良いのだ。

require 'zlib'
module Zlib
  class Inflate
    def self.inflate(string)
      zstream = self.new
      buf = zstream.inflate(string)
      zstream.finish
      zstream.close
      buf
    end
  end
end

こう書いておけばメモリリークは起きない。

_ [本] 放浪の天才数学者エルデシュ

本の画像ポール・ホフマン著『放浪の天才数学者エルデシュ』、読了。

お名前:
E-mail:
コメント:
本日のリンク元

最近のコメント

2003|01|02|03|04|05|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|04|05|
2011|04|
2012|03|07|
2013|01|02|07|
トップ «前の日記(2004-12-23) 最新 次の日記(2004-12-26)» 編集