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

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

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

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

8回答

1006閲覧

乱数を飛ばす、例えば(0,1,2,4,5)のように3を飛ばして乱数を生成する方法

退会済みユーザー

退会済みユーザー

総合スコア0

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

1クリップ

投稿2022/02/18 17:49

乱数で例えば0〜5の数字を作り、if文でその数字によって処理を分岐させているのですが、たとえばif文の中の処理を
10回読んだらその処理を呼びたくありません。つまり乱数の3のif文が10回呼ばれたら、0,1,2,4,5というような乱数を
生成したいです。
現在、Swiftで作っているのですがC/C++でも構わないので乱数の飛ばし方、もしくはいい方法などがあれば教えていただきたいです。

C

1 2for(int i = 0; i < 50; i++) { 3 srand((unsigned int)time(NULL)); 4 int n = rand() % 6; 5 6 if(n == 0) { 7 処理1 // 10回呼ばれたらn == 0を呼びたくない 8 } 9 else if(n == 1) { 10 処理2 // 10回呼ばれたらn == 1を呼びたくない 11 } 12 else if(n == 2) { 13 処理3 // 10回呼ばれたらn == 2を呼びたくない 14 } 15 else if ... すべてランダムに10回ずつ読んで終了 16} 17

よろしくおねがいします。

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2022/02/20 09:59

みなさんのご回答、どれも良かったので迷いましたが、 BAの方の回答は、コードがなくても直感的にわかりやすく、すっきりまとまってる感じだったので BAにさせていただきました。
guest

回答8

0

もとから10個づつ作っておいて取り出す方が意図が伝わりやすくないですか?

swift

1let seq = Array(repeating: 0...5, count: 10) 2 .flatMap { $0 } 3 .shuffled() 4 5for n in seq { 6 switch n { 7 case 0: 処理1() 8 ... 9 ... 10 case 5: 処理5() 11 default: () 12 } 13}

投稿2022/02/19 07:15

MasakiHori

総合スコア3384

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

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

yudedako67

2022/02/20 04:01

実際の用途にはあってるかもしれませんが、この方法だと質問のコードとはコードが実行される確率が変わります。 例えば最初が0であった場合に次も0である確率は、質問のコードだと1/6ですが、このコードでは9/59です。
guest

0

C

1#include <stdio.h> // printf, putchar 2#include <stdlib.h> // srand, rand 3#include <string.h> // memset 4#include <time.h> // time 5 6int main(void) 7{ 8 char a[6 * 10]; 9 for (int i = 0; i < 6; i++) memset(a + i*10, i, 10); 10 srand(time(0)); 11 int i = 60; 12 while (i > 0) { // 50回実行したければ (i > 10) 13 int j = rand() % i, n = a[j]; 14 a[j] = a[--i]; 15 printf(" %d", n); // 処理(n+1)を実行 16 } 17 putchar('\n'); 18}

投稿2022/02/19 06:28

kazuma-s

総合スコア8224

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

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

0

各値の呼び出し回数を記録しておき、上限に達した値を取り除いていく方法もあります。

C++

1#include <iostream> 2#include <vector> 3#include <numeric> 4#include <random> 5 6int main() 7{ 8 const int VAL_CNT = 6; 9 const int LOP_CNT = 50; 10 const int MAX_CNT = 10; 11 12 std::vector<int> counts(VAL_CNT); // 呼び出し回数を保持 13 std::vector<int> vals(VAL_CNT); 14 std::iota( vals.begin(), vals.end(), 0);// 乱数で得たい値 0, 1,... 15 16 std::random_device rnd; 17 for( int i = 0; i < LOP_CNT; i++){ 18 19 // 乱数で位置によって値を得る 20 int pos = rnd() % vals.size(); 21 int n = vals[pos]; 22 23 // nによる処理 24 std::cout << n << std::endl; 25 26 // 呼び出し上限回数を満たした値を取り除く 27 counts[n]++; 28 if( counts[n] >= MAX_CNT){ 29 std::cout << "remove " << n << std::endl; 30 vals.erase(std::remove(vals.begin(), vals.end(), n), vals.end()); 31 32 // 初期条件(VAL_CNT * MAX_CNT < LOP_CNT)により弾切れで続行できなくなる場合あり 33 if( vals.size() == 0){ 34 break; 35 } 36 } 37 } 38 39 // 確認 40 std::cout << "counts" << std::endl; 41 for( int i = 0; i < counts.size(); i++){ 42 std::cout << i << ":" << counts[i] << std::endl; 43 } 44 return 0; 45}

投稿2022/02/19 03:24

can110

総合スコア38266

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

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

0

ベストアンサー

①出目とカウントのpairをvectorで保持
std::vector<std::pair<int,int>> v(6)

②vectorをシャッフル
std::shuffle( v.begin(),v.end(),engine ) → engine:乱数生成器

③v.size()以下の乱数nを生成
v[n].first → 出目
v[n].second++ → カウントを増やす

④カウントが10になったらvectorから削除
std::iter_swap( v.begin()+n, v.end()-1 )→n番目の要素を最後の要素と交換
v.pop_back()→最後の要素を削除

③④を繰り返す

投稿2022/02/19 02:55

編集2022/02/19 03:02
Serbonis

総合スコア581

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

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

0

こんなやりかたもアリっちゃアリかと

C++

1#include <iostream> 2#include <vector> 3#include <numeric> 4#include <random> 5 6int main() { 7 std::vector<int> dice; 8 9 std::vector<int> v(6); 10 std::iota(v.begin(), v.end(), 0); // v = [ 0 1 ... 5 ] 11 for ( int i = 0; i < 10; ++i ) { // dice = 10個のv 12 dice.insert(dice.end(), v.begin(), v.end()); 13 } 14 std::random_device seed_gen; 15 std::mt19937 engine(seed_gen()); 16 std::shuffle(dice.begin(), dice.end(), engine); // diceの要素をかき混ぜる 17 18 for ( int value : dice ) { 19 std::cout << value << ' '; 20 } 21}

投稿2022/02/18 22:54

episteme

総合スコア16614

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

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

0

こんな感じでしょうか。

swift

1// 出た目の回数をカウントするための配列 2var count = Array(repeating: 0, count: 6) 3 4for i in 0..<50 { 5 var n: Int 6 repeat { 7 n = Int.random(in: 0..<6) 8 } while count[n] >= 10 // すでに 10 回以上出たものはやり直し 9 10 // 出た目の回数を増やす 11 count[n] += 1 12 13 // n を使った処理 14}

なお、Swift では srand は不要ですが、C でもループで毎回 srand するのは無意味です。


追記: 別解として、こんなのもありかな?

swift

1var count = Array(repeating: 0, count: 6) 2 3for i in 0..<50 { 4 // 0 〜 5 のうち、まだ 10 回出てないものの配列を作り、その中からランダムに選ぶ 5 let n = (0..<6).filter { count[$0] < 10 }.randomElement()! 6 7 count[n] += 1 8 9 // n を使った処理 10}

投稿2022/02/18 20:05

編集2022/02/18 20:36
hoshi-takanori

総合スコア7895

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

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

thkana

2022/02/18 23:28

Cのsrandをループで毎回やったら「不要」とか「無意味」というレベルでなく多分期待しない(ダメな)結果を得ることになると思います。
guest

0

特定の数値を出したくないなら、乱数を出すのをループにしておいて、特定の数値でないならループを抜けるようにしとけばよろしい
#その数値ならループする

投稿2022/02/19 00:05

y_waiwai

総合スコア87774

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

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

0

「処理」のほうに、自分が呼ばれた回数をカウントして規定回以上だったらなにもせずに戻るという仕込みをする手もありますね。

投稿2022/02/18 23:25

thkana

総合スコア7639

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問