質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

ループ

ループとは、プログラミングにおいて、条件に合致している間、複数回繰り返し実行される箇所や、その制御構造を指します

再帰

情報工学における再帰とは、プログラムのあるメソッドの処理上で自身のメソッドが再び呼び出されている処理の事をいいます。

Q&A

解決済

3回答

2850閲覧

2重の再帰はスタック配列を使わないとループに直せませんか?

f_acid

総合スコア56

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

ループ

ループとは、プログラミングにおいて、条件に合致している間、複数回繰り返し実行される箇所や、その制御構造を指します

再帰

情報工学における再帰とは、プログラムのあるメソッドの処理上で自身のメソッドが再び呼び出されている処理の事をいいます。

0グッド

0クリップ

投稿2015/05/10 02:18

再帰関数saikiを再帰しないnot_saikiに直したらメモリ不足で落ちました。
配列を使わなければもっといけるような気がするのですが…
どうにかなりませんか?数学には疎いので…

lang

1#saiki.rb 2def saiki a,b,c 3 if c==1 4 return a*b 5 elsif b==1 6 return a 7 else 8 return saiki a, saiki(a, b-1, c), c-1 9 end 10end 11 12def not_saiki a,b,c 13 stack = [] 14 loop do 15 if c==1 16 b *= a 17 return b if stack.empty? 18 c = stack.pop 19 elsif b==1 20 b = a 21 c = stack.pop 22 else 23 b -= 1 24 stack << c-1 25 end 26 end 27end 28 29puts not_saiki *ARGV.map{|s|s.to_i}

lang

1$ ruby saiki.rb 3 3 9

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

回答ではありませんが、すこし調べてみたことを書きます。

ruby saiki,rb 3 3 1 => 9 = 3 * 3 = 3 ^ 2
ruby saiki,rb 3 3 2 => 27 = 3 * (3 * 3) = 3 ^ 3
ruby saiki,rb 3 3 3 => 7625597484987 = 3 ^ 27 = 3 ^ (3 ^ 3)

確信はできませんが、 saiki(3, 3, 4) が 3 ^ (3 ^ (3 ^ 3)) となるとすると、
これ時点ですでに 通常のコンピュータ言語で扱える数の範囲を超えます。

7625597484987 を google 検索すると グラハム数というものが出てきます。

ruby コードから 再帰性を取り除くだけでは この関数の 一般項は結果の数が大きくなりすぎ 計算できないと思います。
(関数が呼ばれる回数も大変なことになってます。
saikie 関数の先頭に puts "#{a}, #{b}, #{c}" をいれて プログラムを実行すると、とんでもない回数の呼び出しが発生することがわかります。

備考1
ruby saiki.rb 3 3 4 は私の環境では ... 7267 levels のエラーがでました。
おそらく再帰のネストの限界が 7264 なのだとおもわれます。
ruby の再帰の深さ制限は制御が可能です。
$ export RUBY_THREAD_VM_STACK_SIZE=100000000
$ ruby saiki.rb 3 3 4
とすると、... 694457 levels... のエラーになります。

質問;
この関数定義はどこから入手したものですか?
この関数定義には なんらかの背景があるものと思います。
その背景を知りたいです。

投稿2015/05/10 08:12

katoy

総合スコア22324

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jun68ykt

2015/05/10 08:30

こんにちは。自分も、saiki(3,3,3)を紙と鉛筆で追って、3^(3^3)にたどり着きました。グラハム数なんていうのがあるのですね。勉強になりました!
guest

0

どちらをベストアンサーにしようか迷ったのですが、結局自分がしたかったのは、
saiki(3,3,9)を、途中まででいいのでできるだけ計算したかったのです。
数学的手法を使って、なんとかメモリ不足にならないように出来ないか・・・?と思って質問しました。

この再帰関数は適当に計算量が大きくなりかつ計算が終わりそうなものを考えました。

・・・ただ今、様々な試行錯誤の結果、saiki(a,b,c)=a→b→c、なことが判明しました。
ものすごく先を越されてましたしこのsaikiただの劣化版ですね。

投稿2015/05/23 17:53

編集2015/05/23 18:52
f_acid

総合スコア56

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

この再帰関数は,ある値以上で極めて巨大な数になるというアッカーマン関数に似た関数になっています.
通常のコンピュータでは到底扱えないくらいの桁数の数を生成するので,
単に再帰でないものに書きなおせるとは思えません.

この問題で問われていることはなんでしょうか?

投稿2015/05/10 12:01

katzC4ISR

総合スコア66

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問