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

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

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

bash(Bourne-again-Shell)は sh(Bourne Shell)のインプリメンテーションに様々な機能が追加されたシェルです。LinuxやMac OS XではBashはデフォルトで導入されています。

Ruby

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

Q&A

解決済

4回答

1689閲覧

macのbashでのプログラム実行について

Naggy

総合スコア32

bash

bash(Bourne-again-Shell)は sh(Bourne Shell)のインプリメンテーションに様々な機能が追加されたシェルです。LinuxやMac OS XではBashはデフォルトで導入されています。

Ruby

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

0グッド

0クリップ

投稿2016/10/10 14:40

編集2016/10/11 15:40

###質問内容

現在、Rubyプログラミングの勉強がてらオイラープロジェクトの問題を解くことに注力しています。
しかしながら、計算量が多いプログラムに対して、私のbashは途中で計算を止めてしまうようです。
例えば、
https://projecteuler.net/problem=12
の問題に対して以下に記す「実行したプログラム」のようなプログラムを実行したのですが、bashで経過を見ていると途中で計算を止めてしまいます。
実行後、毎度カレントディレクトリには.filename.rb.swpというファイルが容量12288で保存されています。
これが関係あるのでしょうか??
作成しているプログラム自体は雑なものなのですが、変数をいじって計算量を減らせば最後まで計算してくれるので、macかbash自体になんらかの設定が必要なのではないかと考えています。

ご助力いただければ幸いです。

###実行したプログラム
test.rb

def factorization(num) tmp = num factors = [] i = 2 num = num.to_i loop do if (num % i) == 0 then num = num / i factors.push(i) break if num == 1 else i = i + 1 end end array = factors.uniq array << tmp array2 = array array.each{|i| array.each{|j| if array.max % (i * j) == 0 then array2 << (i * j) end } } return array2.sort.uniq end def triangular_number(num) i = 0 number = 0 loop do dif = 1 + i number = dif + number i += 1 break if i >= num end return number end n = 50 i = 2 loop do array = factorization(triangular_number(i)).uniq if array.size == n then p i p triangular_number(i) p array break end i += 1 end

で上記のプログラムをbashで実行しました。

ruby test.rb

###使用している環境

GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin15)
Copyright (C) 2007 Free Software Foundation, Inc.

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

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

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

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

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

mit0223

2016/10/10 14:45

シェルのコーディング部分を ``` (バッククォート3つ)で囲んでいただけますでしょうか。
ikedas

2016/10/11 12:05

使用している環境を書くのでしたらRubyの情報を書いてください。bashはこの際関係ないと思います。
Naggy

2016/10/11 15:41

お返事遅れて申し訳有りません。 ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-darwin15]
guest

回答4

0

bashの設定などでなく、自分のコードが非効率であることが原因であるとわかりました!
膨大な計算量になると実行完了までに時間がかなりかかることを実感できてよかったです。
一応色々改良したら10秒ほどで計算できるようにはなりましたので、記載したいと思います。(おそらくまだまだ改良点はあると思います。もしご指摘があればご教授お願いします。)
ありがとうございました!

def divisors_number(num,primelist) unless Integer === num then p "function:factorization requires only integer" exit end if num == 1 then end factors = [] i = 0 primes = primelist.flatten loop do if (num % primes[i]) == 0 then num = num / primes[i] factors.push(primes[i]) break if num == 1 else i = i + 1 end end factors.sort! i=0 indexs = [1] loop do if factors[1] == nil then break elsif factors[0] == factors[1] then factors.shift indexs[i] += 1 else factors.shift i += 1 indexs[i] = 1 end end indexs.collect!{|n| n + 1} return indexs.inject(:*) end def nth_triangular_number(num) i = 0 number = 0 loop do dif = 1 + i number = dif + number i += 1 break if i >= num end return number end #n is number of divisors. #i is triangular number and must be more than 2 def calculate() #this number in braces would be not appropriate, so please pay attention. primelist = prime_list(2000) n = 500 i = 2 answer = 0 loop do if divisors_number(nth_triangular_number(i),primelist) > n then answer = nth_triangular_number(i) break end i += 1 end p answer end calculate

投稿2016/10/12 05:56

Naggy

総合スコア32

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

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

0

.filename.rb.swpはvi(vim)の作業用テンポラリファイルでしょう。
filename.rbを開いたままのvi(vim)がいるのではないでしょうか。
ps -efなどでご確認ください。

投稿2016/10/12 01:15

imutakaoru

総合スコア356

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

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

0

ベストアンサー

の問題に対して以下に記す「実行したプログラム」のようなプログラムを実行したのですが、bashで経過を見ていると途中で計算を止めてしまいます。

factorization()の後半ですが、

ruby

1# ... 2 3array = factors.uniq 4array << tmp 5array2 = array 6array.each{|i| 7 array.each{|j| 8 if array.max % (i * j) == 0 then 9 array2 << (i * j) 10 end 11 } 12} 13

約数をすべて求める、という意図だろうと想像しますが、これでできるのかな。

Rubyでは変数はオブジェクトへの単なる参照ですから、array2 = arrayとすればarray2arrayは同じ配列を指します。array2にpushするとarrayも要素が増えて見えます。つまり、eachで反復している間にも反復するものが増えていくという……。

これだと意図した通りに動かないだけでなく、止まらなくなると思います。私の環境ではiを63にして試したところ、一晩放置しても終わりませんでした。

あとちなみに、array.maxtmpと同じになるはずなのでいちいち計算し直さなくていいですね。また、eachで反復している中で同じものをeachで反復していますが、これで約数が全部求まるんでしょうか。そもそも、同じ結果になるような乗算を何度も繰り返しているので、とても効率が悪いと思います。

コードをいろいろ変えてみるのも大事ですが、まずは「コードのここで何をしたいのか」を整理してみてください。コードが簡潔になり、高速にもなると思います。

実行後、毎度カレントディレクトリには.filename.rb.swpというファイルが容量12288で保存されています。
これが関係あるのでしょうか??

viでファイルを編集したときにできるスワップファイルでしょう。関係ないです。


コードを見ていると、因数を見つけるときに素数だけ試せばいいんではないかとか (ちなみに素数を計算することは要求されてないので数表から持ってきてもいいだろとか)、そもそも約数の数がわかればいいので実際に約数を全部求める必要はないんではないかとか、iのときの結果にはi-1のときの結果の一部を使えるねとか、いろいろ思うところはありますが、ぐっとこらえて書きません (←書いてる)。

あとで、自分の書いたコードを追記したくなったら、してしまうかもしれません。

投稿2016/10/12 01:11

ikedas

総合スコア4315

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

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

Naggy

2016/10/12 05:52

ぐっとこらえて書ききれないことがすごく助かりました! プログラムの書き方や作法がちんぷんかんぷんなので、後々使えるリユースできるプログラムを書くよりも、目的を効率良く達成できるプログラムを作る必要性だったり、雑な書き方が計算速度に影響を与えていてしっかりスマートに書く必要性が学べました! いかんせん、動かない理由がbashの設定なのか、プログラムが非効率だからなのかという疑問が解消できてよかったです! ありがとうございました!
guest

0

rubyは不慣れですが、Linux上(i5)で御提示のプログラムを実行しました、nが30超えるとかなりの実行時間が掛かり、n=35では戻ってきませんでした。(10分程待ちましたが)
おそらく環境では無くてプログラムの負荷に原因が有るのかと思います。
またarray2 = arrayの部分は array2 = [] にすると少し早くなりました。割り切れる数を見つける部分(array.each)で時間が掛かっている様です。
filename.rb.swpが作成される事は実行中も含め有りませんでした。

投稿2016/10/11 17:19

A.Ichi

総合スコア4070

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問