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

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

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

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

Q&A

解決済

2回答

280閲覧

出目が0~3のサイコロ(その2)

kintarock777

総合スコア34

Ruby

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

0グッド

0クリップ

投稿2017/09/15 22:26

出目が0~3のサイコロを振って、それぞれの目が揃うまで降り続けその回数をカウントするコードを作りました。
それを1000回繰り返してその平均値を割り出すコードを付け加えました。
少数点以下第1位まで求めたいのですが、実行すると小数点以下第3位まで表示されてしまいます。どうしたらよいでしょうか?

sum = 0 1000.times do n = 4 num = Array.new(n) count = 0 until num.all? deme = Random.rand(n) num[deme] = true count += 1 end sum += count end p sum/1000.round(1) #ここにround(1)を付け加えましたがうまく計算してくれません

実際実行した結果

ruby 2.3.3p222 (2016-11-21 revision 56859) [x64-mingw32] C:\Users\owner>cd c:\ruby23-x64\ruby c:\Ruby23-x64\ruby>ruby test1.rb 8.379 #小数点以下第3位まで出てしまいました c:\Ruby23-x64\ruby>

よろしくお願いいたします。

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

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

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

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

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

guest

回答2

0

y.rb

ruby

1N = 4 # サイコロの目の種類 2PLAY_COUNT = 1000 3 4# すべての目がでるまでサイコロを振った回数を返す 5def play 6 nums = [] 7 nums << Random.rand(N) while nums.uniq.size != N 8 nums.size 9end 10 11sum = 0 12PLAY_COUNT.times { sum += play } 13puts(format('%.1f', sum.to_f / PLAY_COUNT))

前の質問への回答
https://teratail.com/questions/92645
に1000回繰り返してその平均値を割り出すコードをつけてみました。

表示する小数点以下の桁数は format を使って制御しています。
sum / PALY_COUNT では、整数/整数 なので計算結果が整数になってしまいます。

sum.to_f とすることで、 FLOAT/整数 となるようにしています。こうすると計算結果も FLOAT になります。

実行例
イメージ説明

投稿2017/09/15 23:17

katoy

総合スコア22324

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

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

kintarock777

2017/09/17 04:16 編集

回答ありがとうございます。 katoyさんのコードだと、より簡潔になりますね。 def を使ったコードが、よりプログラムっぽくなっていてカッコイイです。 untilを使った前出のコードでも、defを使ったコーディングを試してみたのですがうまくいきません。おそらく変数が2つ以上あるためplayに値が代入できないと思うのですが、変数を1つに絞ったコードが作れません。 ただいま、試行錯誤中です。
kintarock777

2017/09/17 04:09 編集

N = 4 count = 0 nums = Array.new(N) until nums.all? nums[Random.rand(N)] = true count += 1 end p count ここまでシェイプアップできましたが(笑) untilした回数自体をカウントするメソッドとか、あるのでしょうか?
katoy

2017/09/17 05:50

play メソッドを until で書いてみました。(play2, play3 の2通リで) def play2 count = 0 nums = Array.new(N) until nums.all? nums[Random.rand(N)] = true count += 1 end count end def play3 nums = Array.new(N, 0) until nums.all? { |x| x > 0 } nums[Random.rand(N)] += 1 end nums.sum end play3 は、nums[x] には xの目が出た回数を格納するようにしています。 すべての目の出た回数を合計した値を返すようにすることで、 count 変数を使わずに済ませています。
kintarock777

2017/09/17 09:28 編集

回答ありがとうございます。 早速試してみました。play2は試したところ、うまく機能しました。 変数が2個あっても大丈夫だったということは、最後の処理の値(count)がplay2の値として代入されるのでしょうか?とにかく正常に実行できました。 play3は、試してみたところ、”nums.sum”のところがうまく計算できませんでした def play3 nums = Array.new(N, 0) until nums.all? { |x| x > 0 } nums[Random.rand(N)] += 1 end nums.sum  #<=ここの部分が機能しない end 結局 for文を追加して、 def play3 nums = Array.new(N, 0) until nums.all?{ |x|x > 0 } nums[Random.rand(N)] += 1 end sum = 0 for i in 0..3 sum += nums[i] end end こんな感じになってしまい、また変数が増えてしまいました。 結論として、katoyさんに書いていただいた最初のコード "while nums.uniq.size ~ "のヤツが一番シンプルできれいなコードの ように感じました。 とにかく新しい書き方が出てくると、ワクワクします。 意味を考えるのに必死ですが(笑)
katoy

2017/09/17 13:38

配列の合計を求めることについては次を参照していろいろ試してみてください。 (ruby の version がふるいと sum のメソッドは動作しません。)
kintarock777

2017/09/17 20:38

いつも回答ありがとうございます。大変心強いです。 またこれからもいろいろ教えてください。
guest

0

ベストアンサー

Rubyでは、メソッド実行のほうが演算子より優先されるので、sum/(1000.round(1))と解釈されてしまいます。

p (sum/1000.0).round(1)とするか、printfで書式指定をかけてprintf '%.1f', sum/1000.0の夜にしましょう(1000.0としているのは、整数÷整数では結果が整数になってしまうので、浮動小数点数演算に持ち込むためです)。

投稿2017/09/15 22:36

maisumakun

総合スコア145183

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問