« 2007年11月 | メイン | 2008年3月 »

2007年12月27日

Ruby入門とか読むくらいならコレを読め

いまさら気がついたことに激しく後悔しています。もっとずっと早く読めばよかった...。

Rubyソースコード完全解説: 第1章 Ruby言語ミニマム
http://i.loveruby.net/ja/rhg/book/minimum.html

このページでは冒頭でこんなことが書いてあります。

Ruby言語について、当面第一部を理解するのに必要な知識だけ簡単に解説しておく。プログラミング上のテクニックであるとか注意すべきところなんてものは全く指摘しないので、この章を読んだからと言ってRubyプログラムが書けるようになるわけではない。既にRuby言語の経験がある読者はこの章は飛ばして問題ないだろう。

とばして読んではいけません、もしあなたがRubyを手足のように使いこなせるのではなければ。とわたしは感じました。それはわたしのレベルが低すぎるのでしょうか。

この第1章、「ミニマム」というだけあって短いです。しかし、ユーザから見えるRubyの仕組みが簡潔にまとまっています。メカニズムの原則がわかります。メカニズムの原則がわかることが、そのメカニズムでかたちづくられたものを使いこなすのに、どれだけ重要かはいうまでもないでしょう。

プログラミングそのものはわかっていて、でもRubyはどう使えばいいんだろう? と思っているひとは、誰でもRHG第1章は読むべきです。と思います。

すくなくともわたしはもっと前によむべきだった、と思いました。クラス定義と定数定義、includeとnew、などが示唆的でした。はい。

2007年12月 8日

Lightroom SDK: プラグインの構成

プラグインの配置場所

プラグイン名.lrplugin or プラグイン名.lrdevpluginのフォルダを、/Library/Application Support/Adobe/Lightroom/Modulesに入れる。

Windowsならexeがあるのとおなじところ、またはC:\Documents and Users\username\Application Data\Adobe\Lightroom\Modules(Windows XP) or C:\Users\username\AppData\Roaming\Adobe\Lightroom\Modulesc (Vista)

プラグインの構成ファイル

Info.lua
プラグインの情報。バージョンとか、動作を定義したスクリプトとか、そういった情報を入れたテーブルをreturnするコードを書いておく。
動作定義ファイル.lua
最低限、Info.luaから参照されるスクリプトファイルが必要。

Info.luaの例

return {
	LrSdkVersion = 1.3,
	LrSdkMinimumVersion = 1.3

	LrToolkitIdentifier = 'jp.skoji.my_export_plugin',
	
	LrExportServiceProvider = {
		title = "skoji uploader",
		file = 'uploader.lua',
	},
}

続く...

Lightroom SDK: Luaとの差異

ちょっとだけLua自体を勉強してわずかにパワーアップしたところで、またLightroom SDKのGuideに戻ります。

namespace

どうもnamespaceって概念はLua自体にはないみたい。Lightroomでは、いくつかの関数を定義したテーブルを「Namespace」と呼んでいるそうな。Lua5.1にはmoduleという概念があるけれども、それとは関係ない。

built in functionであるimport()は、Lightroom SDKで定義しているnamespaceにアクセスする手段。

プラグイン側であたらしいnamespaceは作れない(というのは、正確にどういう意味なのかまだ理解できてない)

class, object

クラスもオブジェクトも、Luaの言語仕様にはなくて、Lightroom SDKの用語。実態はテーブル。 namespace同様、classもプラグインで新しくつくることはできない。ってこれも、どうやって「できなく」しているのかが理解できてません。

Lua組み込み機能

Lua5.1の機能がすべて使えるわけじゃない。collectgarbage(), getmetatable(), module()なんてあたりは使えない。

2007年12月 1日

アルゴリズム

http://blog.livedoor.jp/dankogai/archives/50957658.htmlをよんで。

メルセンヌ・ツイスタ以外は理解してたはずなのにけっこう忘れてる。ということで思い出すために実装してみます。Rubyで。

ユークリッドの互除法

実装自体はとても簡単。aとbの最大公約数を求めるgcd(a,b)は次のようにかけます。

def gcd(a, b)
  b, a = [a,b].sort
  until b == 0
     a, b = b, a%b
  end
  a
end

それより、「なぜこれで最大公約数が求まるのか」は、それほど直感的じゃありません。

整数A, B、ただしA > Bがある。

GCD(x, y)は、xとyの最大公約数とする。

A/Bの商がQ、剰余がRとする。Q,Rは整数。

このとき、

A = B * Q + R ... (1) 

したがって

R = B*Q - A ... (2)

C= GCD(A,B)とすると、(2)の右辺はB*Q - AはCで割り切れる。
したがって、(2)の左辺RもCで割り切れる。よって、CはRの約数。つまり、

C = GCD(A,B) <= GCD(B,R) ... (3)

ここでGCD(B,R) = C'とする。
(1)の右辺はC'で割り切れる。したがって左辺AもC'で割り切れる。
つまり、C'は、A,Bの公約数。
したがって、

C' =GCD(B,R) <= GCD(A,B) ... (4)

(3),(4)から、GCD(A,B) = GCD(B,R)。

ここでひといき。ここまでで、「AとBの剰余がRであるとき、GCD(A,B)=GCD(B,R)である」といえます。AがBで割り切れるまでこの操作を続ければ、そのうちGCD(A,B) = GCD(B,0)になります。GCD(B,0)は明らかにBです。

こりゃ証明の形になってないですね。この繰り返しを証明の形で記述するにはどうするんだっけ。思い出せないや。

エラトステネスの篩

なんか不格好な実装

def primes(n)
  searchlist = (2..n).map
  primelist = [ 1 ]
  while searchlist.last > primelist.last **2
    p =  searchlist[0]
    primelist << p
    searchlist = searchlist.find_all { | x | x % p > 0 }
  end
  primelist +  searchlist
end

バイナリサーチ

def binarySearch(arr, n)
  if (arr.length < 1)
    return nil
  end

  p = arr.length / 2

  case n <=> arr[p] 
  when -1 then return binarySearch(arr[0,p], n)
  when 0  then return n
  when 1  then  return binarySearch(arr[p+1, arr.length - p],n)
  end
end