こんにちは、ゲストさん

Choklogトップ - ランダムブログ - ログイン - ヘルプ

フェルマーテスト(ruby版)

「nを素数、aをnより小さい正の任意の整数とすると、aのn乗はnを法としてaと合同である」


上記はフェルマーテストについてのSICPの記述を転記したものです。gaucheでフェルマーテストを書く前に、rubyでフェルマーテストを実装して、「ああ、なるほど」と理解を深めました。そのときのコードを貼り付けておきます。何かの参考になれば幸いです。


#!/usr/bin/ruby
def FermatTest (n, a)
    if( a == (exp(a, n) % n) ) then
        puts n.to_s + " is prime.\n"
    end
end

def exp (a, n)
    return 1 if n == 0
  
    t = a
    (n - 1).times { |i|
        a = a * t
    }
    a
end

1000.times {|i|
    FermatTest(i, rand(i - 1) + 1) if i > 2
}



「3 ~ 1000」の範囲の整数に対してフェルマーテストを行うことができます。

rubyでオブジェクトのディープコピー

rubyのObject.cloneやObject.dupではオブジェクトのディープコピーを作成できない。オンラインマニュアルには次のようにある。


clone や dup は「浅い(shallow)」コピーであることに注意してください。オブジェクト自身を複製するだけで、オブジェクトの指している先(たとえば配列の要素など)までは複製しません。



これに対して、Marshalを使い、擬似的なディープコピーを実現できる。


def deep_copy(obj)
  Marshal.load(Marshal.dump(obj))
end

a = deep_copy(b)



シリアライズしてデシリアライズして返す、という力業。『The Ruby Way』のP.225で紹介されていた。


amazon
『The Ruby Way―Ruby道への招待』

gemでバージョン指定してパッケージをインストールする

scrubytを使いたくて、次のようにしてみた。

$ sudo gem install scrubyt
ERROR:  Error installing scrubyt:
        scrubyt requires RubyInline (= 3.6.3)


自分の環境ではRubyInlineが最新バージョン(3.6.6)だったため、動作しなかった。何ということでしょう。

バージョン指定は、次のようにgemの引数にできる(ref: 「scRubytをちょこっと触ったけど挫折 (polog)」)

$ sudo gem install RubyInline --version '= 3.6.3'
Successfully installed RubyInline-3.6.3
1 gem installed
Installing ri documentation for RubyInline-3.6.3...
Installing RDoc documentation for RubyInline-3.6.3...


この状態で、再びscrubytをインストールしてみる。

$ sudo gem install scrubyt
Successfully installed scrubyt-0.3.4
1 gem installed


「Successfully installed」が出ました。嬉しい。