« Rubyのlambdaでクロージャを書いてみた | Home | 後悔と失意の週末 »

March 26, 2012

変数を宣言せずに1から100までの和を求める方法

twitterで、

@nullmineral
「1から100までの整数の和を表示するプログラムを作れ」という問題を鼻で笑う諸君、「但し変数は新たに宣言しないこと」 という条件を付けても鼻で笑っていられるかな?

というtweetがあったので、あぁ再帰を使えば簡単。Rubyで書くとこんな感じかな。

def sum(n, r)
    if(n > 100)
        return r;
    else
        sum(n+1, n+r);
    end
end

p sum(1, 0)

だが、もっと強者がいた。

p (1 + 100) * 100 / 2

等差数列の和の公式....ボロ負けでした...orz


追記:
twitterでいろいろツッコミをいただいたので、追記。

@littlestarling:
(1..100).inject(0){|i, sum| sum += i} だと宣言してることになるのかな。まあ公式ちゃんと使う方が正しいっすね。

ほう。こんなものもあるのか。ということで調べてみると、Rubyの1.9系には、Enumerateにreduceというメソッドがあり、injectの別名のようだ。これを使うとわずか1行で書ける。

(1..100).reduce(:+)

すばらしい。LISPでこのような問題を解く場合、「Lisp脳」の謎に迫る - Schemeプログラマの発想に記されているように、「データからデータへの変換」を考える。すなわち、1から100までのリストを作って、それをいじって結果を出すという考え方だ。例えばSchemeで書くとしたらこんな感じになる。

(use srfi-1)
(fold  + 0 (iota 100 1))

injectやreduceを使ったやり方は、まさにこの考え方だ。ちなみにreduceに渡している":+"というのは、+演算子のSymbolで、これはSchemeでいうと'+'という関数をFOLDに渡すことに相当する。

最後に、もう一つ。

@hiromiso:
sum(1:100)

GNU Rか... またもや敗北...orz

No TrackBacks

TrackBack URL: http://www.argv.org/~chome/blog/mt-tb.cgi/245

About this Entry

This page contains a single entry by chomy published on March 26, 2012 11:39 PM.

Rubyのlambdaでクロージャを書いてみた was the previous entry in this blog.

後悔と失意の週末 is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.