パスカルの三角形

| | コメント(6)

たまにはプログラム関係のことでも書きましょうかな。

言語の特徴を見るための例題ってのはいろいろありますが、
パスカルの三角形はなかなかいい基準ではないかと思います。
Rubyでパスカルの三角形を書いてみると、こんな感じ。

6行。本体は2行です。


def comb n, p
  (p==0 or p==n) ? 1 : (p-1..n-1).inject(0){|s,i| s + comb(i, p-1)}
end
 
def pascal m
  (0..m-1).each{|n| (0..n).each{|p| print "#{comb(n, p)} "}; puts;}
end

まぁ、やや強引なところがあるのでばらしますと


def comb n, p
  if p == 0 or p == n then
    1
  else
    (p - 1 .. n - 1).inject(0) do |s, i|
      s + comb(i, p - 1)
    end
  end
end

def pascal m
  (0 .. m - 1).each do |n|
    (0 .. n).each do |p|
      print "#{comb(n, p)} "
    end
    puts
  end
end

いやぁ、なんて気持ちいいんだろうか。
見事に書き易く、読み易いです。

関数起動と実行結果。


pascal 16
1 
1 1 
1 2 1 
1 3 3 1 
1 4 6 4 1 
1 5 10 10 5 1 
1 6 15 20 15 6 1 
1 7 21 35 35 21 7 1 
1 8 28 56 70 56 28 8 1 
1 9 36 84 126 126 84 36 9 1 
1 10 45 120 210 252 210 120 45 10 1 
1 11 55 165 330 462 462 330 165 55 11 1 
1 12 66 220 495 792 924 792 495 220 66 12 1 
1 13 78 286 715 1287 1716 1716 1287 715 286 78 13 1 
1 14 91 364 1001 2002 3003 3432 3003 2002 1001 364 91 14 1 
1 15 105 455 1365 3003 5005 6435 6435 5005 3003 1365 455 105 15 1

combがコンビネーションnCpを求める関数で、
pascalがm段のパスカルの三角形を出力する関数です。
数値範囲リテラルと畳み込みのinjectが効いてます。
ということはHaskellとかでも同程度の簡潔さで書けるかと思いますが、
Rubyの方が文法的に敷居が低いんですね。(C/UNIX呪い効果)
each(map)/select(filter)/inject(fold)/sortとかを.で繋いでくとたまりません。
Rubyは標準ライブラリもかなりUNIX感覚で使えるように設計されていて、
IOとかはコマンドそのまんまだったりします。
IO.foreachとかFind.findとか最高ですね。
Tempfile.openも良い。

楽しくて簡潔。
簡単なのに奥が深い。
凝ろうと思えばけっこういける。
ソースのここが気に食わないと思ったら、
ちょっと頭を捻ると綺麗に解決できる。
でもあまり考えないでもとりあえず動くものはすぐにできる。

私が世の中で一番使い易いと思う言語はRubyです。 (美しいとは思いません)
Cという言語とUNIXというOSの呪いがどうしても消えそうもないこの業界だからこそ使い易い。
CとUNIXを前提にしたらRubyは最終進化形態なのではないかとすら思います。
ただ言うまでもなくCはベストではないしUNIXはベストではありません。
前提を取り払ったらRubyもベストではありません。
でもほとんどの人は同じ前提の上に立っているので、
ほとんどの人にとってRubyは最も使い易い言語である可能性が高いです。
CとUNIXに不満を感じない人にとっては尚更。

というわけで個人的にはC/UNIXの呪いが消えるまではRubyを越えるのは非常に難しいと考えます。
Rubyより人気のある言語が出たらいよいよ次世代コンピューティングと言えるかなと。
いい線いってるのはちらほらと存在するのだけど、普及しないと意味ないです。
で普及しない理由は必ずあります。
開発者周辺のやる気がないとかしょぼい理由も含めて。

もうC/UNIXは飽きました。
進歩してるようで進歩してないですよ基本部分は。
JavaもC#もCと大差ないです。
WindowsもMacもいつまでたってもUNIXのまんま。
いい加減新しいことやろうぜ。
あれがベストなんて本気で思ってるわけじゃあるまい。
変えるのめんどいから放置してるだけだろ。
Googleもあるものでなんとかするってスタンスっぽいし。
まだ当分流れは変わりそうもないですね。
ま、せめてRubyで仕事やらしてくれや。

コメント(6)

wiz :

ん~、ruby微妙な感じかな~。感想としては。

オブジェクト指向がしっかりしてるって話なんでperlよりよさげ
なんだけど、私的には文法はCの拡張がいいかなと。

配列オブジェクトなんかは言語レベルでサポートしていながらも
実装はちゃんと外で出来るように持っていければいいかなみたいな。

rubyってfor(;;)みたいな使い方は出来ないのかしら?
さすがにforeach型のみはなぁ・・・
まあ、オブジェクト指向ではforeachが一般的で、異質なforは
foreachで代用可能だから無くてもいいてのはそうなんだけどな~

ま~とりあえず、そのうちrubyはじめるかもな~
この系統の言語ははじめてかな~。pythonが似てると言えば
似てるかな~

forはあるけどこれは一般的なforeachですね。
Cスタイルのforはありません。
次のコードは0から5までの数字を表示します。

for i in 0..5
  p i
end

Rubyの場合はfor文使うよりもeachメソッドを使うのが主流です。

(0..5).each do |i|
  p i
end

あと、細かい制御が必要ならwhileが使えます。

i = 0
while i > 5
  p i
  i += 1
end


>なんだけど、私的には文法はCの拡張がいいかなと。

個人的には十分Cライクだと思いますが。
どの辺が気に食わないですか?
やっぱりendですかね。
私も最初はend嫌いだったんだけど、
慣れるとけっこう読み易いですよ。
まぁ主観ですけどね。

anm :

Javaはもうおなか一杯かな。
言語としての限界も見えちゃったし。

Rubyのいいところは書きやすさもそうですが、
読み易さかなあと思います。驚き最小の法則が効いてます。

最近、うちの研究室やら学会やらでHaskellがブームなのですが、
あれは書く分には楽しいのですが、読むのがつらいです(長いと特に顕著)。

まあ、読みにくさと言えば定評のあるLispですが(ぉ
僕としてはカッコとコッカに美を見いだしてるので普通の感覚には戻れません(苦笑

ただ僕はCは結構好きです。
長いこと使ってますが、Javaみたいに嫌いにならないんだよね。
きれいなCのコードって本当に見てて溜息が出てしまう。

RubyがUNIX系のハッカーに好まれるのは
Ruby自体もさることながらCで拡張できる機構にあるのでは、とか思ったり。

とりあえずは、LispとRuby中心でやっていきたいですね。今後は。

> きれいなCのコードって本当に見てて溜息が出てしまう。

そのコードはCだから綺麗なんでしょうか。
そういうのは見たことないんで良かったら教えてください。

典型的なハッカータイプの人間って非常に保守的だと思います。
Rubyはそういう保守的な人達に受け入れられるように作られてますね。

wiz :

遅くなってしまいましたがとりあえずまだ新しいエントリは
内容なので間に合ったことにして書いておきます~

とりあえず、endもそうなんだけど、やっぱ始まりの{も欲しいなと。
あとは、whileに括弧が無いよ~とかそんな感じかな。なんと書くか、

if a > 5 && b 5) && (b < 7))

が良い感じ。もろに好みの問題ですがね~。というか括弧は
好きにつけていいんだとかそういう話な気がする・・・

まあとりあえず、そのうちruby始めるかもって話なので、始めれば
中規模のものはrubyで書くかもといった感じです。
perlはオブジェクト指向がアレなんででかいのは書き辛い上に、
スレッドとかその辺りもいい加減で微妙に使い辛い。
ちょっとした処理の時はかなり良い感じなんだけど・・・

はあ・・・rubyの宿題できないよ・・・・・・・・ :

るびい むずすぎる><

このブログ記事について

このページは、yuchが2005年5月24日 01:01に書いたブログ記事です。

ひとつ前のブログ記事は「7つの習慣」です。

次のブログ記事は「皐月」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

Powered by Movable Type 4.01