# n!(nの階乗)を求めるプログラムを1行で書いてみる。
_published: 2007/09/18_ 
「[数検(数学検定)の完全対策 1~3級](http://d.hatena.ne.jp/asin/4534022964/helloworld0f-22)」の準1級2次の問題です。
> 0以上の整数nの値を入力させ、n !を計算するプログラムをつくりなさい。
というわけで、Rubyで書いてみました。まずは、普通に。
```ruby
n = gets.to_i
k = 1
n.times do |i|
k *= i.next
end
puts k
```
Ruby初心者なので、書き方がスマートでないかもしれません。 `times` にたどり着くのすら、時間がかかってしまいました。でも、アルゴリズムは正しいですよね。(数値以外を入力されたときのエラー処理は考えなくてもいいようです。)
で、これを1行で書けるのではないかと思い、チャレンジしてみました。ちょっと、考えてみてください。
```ruby
k = 1
gets.to_i.times { |i| k *= i.next }
puts k
```
ここまでは、楽勝ですよね。次は、表示のところを工夫して。
```ruby
k = 1
puts k if gets.to_i.times { |i| k *= i.next }
```
Rubyの `if` は `nil` と `false` 以外はすべて真になるのでしたね。そして、 `times` メソッドは `self` (ここでは `gets.to_i` の値)を返します。ですから、必ず `k` が表示されることになります。
ここまではOK。問題は、 `k = 1` の部分です。ここでハマりました。 `times` に渡したブロックのスコープ外で `k` を `1` で初期化しなければなりません。C言語系なら `;` (セミコロン)で区切れば、どんな処理でも1行で書けます。でも、それでは面白くありません。
そんな時、「Ruby Cookbook」を読んでいたのですが(日本語版だと内容がカットされているので英語版)、「block」の部分を読んでいて思いつきました。ブロックを使えば、いけるのでは?
```ruby
lambda { |k| puts k if gets.to_i.times { |i| k *= i.next }}.call(1)
```
`lambda` で匿名メソッド(Rubyでもこう呼ぶんですか?)を定義して、いきなりcallします。 k を引数にして、 `1` を入れればOKです。無事に動きました。「n!(nの階乗)を求めるプログラムを1行で書いてみる」プロジェクト、達成!
なにしろ、Ruby初心者なので、もっとスマートな書き方がありそうな気がします。どうでしょうか?