teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

5

先にmenu1をシャッフルしてmenu2が取り出し順で同じ値にならなくなるまでシャッフルを繰り返す方法を追記

2015/08/23 13:19

投稿

KiKiKi_KiKi
KiKiKi_KiKi

スコア596

answer CHANGED
@@ -8,7 +8,7 @@
8
8
  `ジュースA と ジュースB` の様に取り出されてしまいます。
9
9
 
10
10
  各処理をわかり易く書こうと思ったら、
11
- すごく冗長なコードになってしまったので、もう少しリファクタリング出来ると思います。
11
+ すごく冗長なコードになってしまったので、かなりリファクタリング出来ると思います。
12
12
  ```javascript
13
13
  var menu1 = ["ジュースA","チョコA","アメA"];
14
14
  var menu2 = ["ジュースB","チョコB","アメB"];
@@ -176,4 +176,65 @@
176
176
  console.log(m1 + 'と' + m2);
177
177
  }
178
178
  }();
179
- ```
179
+ ```
180
+
181
+ ---
182
+
183
+ **追記**
184
+ 下記の手順で取り出す方法を追記します。
185
+ 0. menu1をシャッフルするして順番を入れ替える
186
+ 0. menu2をシャッフルする
187
+ 0. インデックス順に各配列の要素を取り出してチェック。1回でも値が同じ場合があると2をやり直し
188
+ 0. インデックス順に各配列の要素を取り出す
189
+
190
+ ```javascript
191
+ var menu1 = ["ジュース","チョコ","アメ"];
192
+ var menu2 = ["ジュース","チョコ","アメ"];
193
+ var sameFlg = true;
194
+
195
+ // fisher-yates アルゴリズム
196
+ // katoyさんの書かれている配列をシャッフルする方法
197
+ var shuffle = function(arg) {
198
+ var i, j, l, tmp;
199
+ for(l=arg.length, i=l-1; i>0; i-=1) {
200
+ j = Math.floor(Math.random() * (i+1));
201
+ tmp = arg[i];
202
+ arg[i] = arg[j];
203
+ arg[j] = tmp;
204
+ }
205
+ return arg;
206
+ };
207
+
208
+ // menu1をシャッフル
209
+ menu1 = shuffle(menu1);
210
+
211
+ while(sameFlg) {
212
+ // menu2をシャッフル
213
+ menu2 = shuffle(menu2);
214
+ // 順番に取り出して同じ値が出てくる時はmenu2のシャッフルをやり直す
215
+ sameFlg = false;
216
+ for(var i = 0, l = menu1.length; i<l; i+=1) {
217
+ if(menu1[i] === menu2[i]) {
218
+ sameFlg = true;
219
+ break;
220
+ }
221
+ }
222
+ }
223
+
224
+ console.log('▼ menu1, menu2 それぞれの取り出し順 ▼');
225
+ console.log(menu1, menu2);
226
+ for(var i = 0, l = menu1.length; i<l; i+=1) {
227
+ console.log(menu1[i] + " と " + menu2[i]);
228
+ }
229
+ ```
230
+
231
+ ---
232
+
233
+ いずれにせよ
234
+ A. menu1の`ジュース`とmenu2の`ジュース`を区別する
235
+   = それぞれの袋の中から1つづつ取り出しす かつ 取り出されたモノ(の種類)が被らないようにする
236
+ B. `ジュース`というも区別できないモノのが2つ有るとする
237
+   = 大きな袋に全部入れてランダムに2つ取り出して、取り出されたモノが被らないようにする
238
+
239
+ のどちらかによってコードは変わってくると思います。
240
+ 私が書いたのはいずれも、A. の考え方の場合です。

4

変数名がわかりにくい箇所を修正

2015/08/23 13:19

投稿

KiKiKi_KiKi
KiKiKi_KiKi

スコア596

answer CHANGED
@@ -118,17 +118,17 @@
118
118
  // 配列の並び順のパターンを作成
119
119
  var generatePatterns = function(arg) {
120
120
  var patterns = [];
121
- var sortArg = function(arg, tmp, post, n) {
121
+ var sortArg = function(allPtns, ptnArg, post, n) {
122
122
  if(n > 0) {
123
123
  var next, rest;
124
124
  for(var i=0, l=post.length; i<l; i+=1) {
125
125
  rest = post.slice(0);
126
126
  next = rest.splice(i, 1);
127
- sortArg(arg, tmp.concat(next), rest, n-1);
127
+ sortArg(allPtns, ptnArg.concat(next), rest, n-1);
128
128
  }
129
129
  } else {
130
- console.log(tmp);
130
+ console.log(ptnArg);
131
- arg[ arg.length ] = tmp;
131
+ allPtns[ allPtns.length ] = ptnArg;
132
132
  }
133
133
  };
134
134
  sortArg(patterns, [], arg, arg.length);

3

ちょっとイケてない記述を修正

2015/08/23 07:42

投稿

KiKiKi_KiKi
KiKiKi_KiKi

スコア596

answer CHANGED
@@ -116,25 +116,30 @@
116
116
  };
117
117
 
118
118
  // 配列の並び順のパターンを作成
119
+ var generatePatterns = function(arg) {
120
+ var patterns = [];
119
- var generatePatterns = function(arg, tmp, post, n) {
121
+ var sortArg = function(arg, tmp, post, n) {
120
- if(n > 0) {
122
+ if(n > 0) {
121
- var next, rest;
123
+ var next, rest;
122
- for(var i=0, l=post.length; i<l; i+=1) {
124
+ for(var i=0, l=post.length; i<l; i+=1) {
123
- rest = post.slice(0);
125
+ rest = post.slice(0);
124
- next = rest.splice(i, 1);
126
+ next = rest.splice(i, 1);
125
- generatePatterns(arg, tmp.concat(next), rest, n-1);
127
+ sortArg(arg, tmp.concat(next), rest, n-1);
128
+ }
129
+ } else {
130
+ console.log(tmp);
131
+ arg[ arg.length ] = tmp;
126
132
  }
127
- } else {
128
- console.log(tmp);
129
- arg[ arg.length ] = tmp;
130
- }
133
+ };
134
+ sortArg(patterns, [], arg, arg.length);
135
+ return patterns;
131
- }
136
+ };
132
137
 
133
138
  !function() {
134
139
  var i = 0,
135
140
  l = 0,
136
- allPatternsA = [],
141
+ allPatternsA,
137
- allPatternsB = [],
142
+ allPatternsB,
138
143
  randA,
139
144
  randB,
140
145
  ptnA,
@@ -143,9 +148,9 @@
143
148
 
144
149
  adjustLength(menuA, menuB);
145
150
  console.log('▼ menuAの取り出し方の全パターン ▼');
146
- generatePatterns(allPatternsA, [], menuA, menuA.length);
151
+ allPatternsA = generatePatterns(menuA);
147
152
  console.log('▼ menuBの取り出し方の全パターン ▼');
148
- generatePatterns(allPatternsB, [], menuB, menuB.length);
153
+ allPatternsB = generatePatterns(menuB);
149
154
 
150
155
  randA = Math.floor( Math.random() * allPatternsA.length );
151
156
  ptnA = allPatternsA[randA];

2

変数名の間違いを修正

2015/08/23 07:37

投稿

KiKiKi_KiKi
KiKiKi_KiKi

スコア596

answer CHANGED
@@ -98,8 +98,8 @@
98
98
  0. ループで各配列の並び順に出力
99
99
 
100
100
  ```javascript
101
- var menu1 = ["ジュース","チョコ","アメ"];
101
+ var menuA = ["ジュース","チョコ","アメ"];
102
- var menu2 = ["チョコ","ジュース","アメ","バナナ"];
102
+ var menuB = ["チョコ","ジュース","アメ","バナナ"];
103
103
 
104
104
  // 配列の長さを同じにする
105
105
  var adjustLength = function(arg1, arg2) {

1

配列の値でチェックするパターンを追加

2015/08/23 07:13

投稿

KiKiKi_KiKi
KiKiKi_KiKi

スコア596

answer CHANGED
@@ -95,4 +95,80 @@
95
95
  0. menu1、menu2のそれぞれの並び順のパターンを作成
96
96
  0. ランダムに並び順のパターンを取得
97
97
  0. 同じ取り出し順に同じ値があったら2をやり直し
98
- 0. ループで各配列の並び順に出力
98
+ 0. ループで各配列の並び順に出力
99
+
100
+ ```javascript
101
+ var menu1 = ["ジュース","チョコ","アメ"];
102
+ var menu2 = ["チョコ","ジュース","アメ","バナナ"];
103
+
104
+ // 配列の長さを同じにする
105
+ var adjustLength = function(arg1, arg2) {
106
+ var l1 = arg1.length,
107
+ l2 = arg2.length,
108
+ gap = Math.abs(l1 - l2),
109
+ adjustArg;
110
+ if(gap) {
111
+ adjustArg = (l1 > l2)? arg2:arg1;
112
+ for(var i=0; i<gap; i+=1) {
113
+ adjustArg[ adjustArg.length ] = "なし!";
114
+ }
115
+ }
116
+ };
117
+
118
+ // 配列の並び順のパターンを作成
119
+ var generatePatterns = function(arg, tmp, post, n) {
120
+ if(n > 0) {
121
+ var next, rest;
122
+ for(var i=0, l=post.length; i<l; i+=1) {
123
+ rest = post.slice(0);
124
+ next = rest.splice(i, 1);
125
+ generatePatterns(arg, tmp.concat(next), rest, n-1);
126
+ }
127
+ } else {
128
+ console.log(tmp);
129
+ arg[ arg.length ] = tmp;
130
+ }
131
+ }
132
+
133
+ !function() {
134
+ var i = 0,
135
+ l = 0,
136
+ allPatternsA = [],
137
+ allPatternsB = [],
138
+ randA,
139
+ randB,
140
+ ptnA,
141
+ ptnB,
142
+ isSame = true;
143
+
144
+ adjustLength(menuA, menuB);
145
+ console.log('▼ menuAの取り出し方の全パターン ▼');
146
+ generatePatterns(allPatternsA, [], menuA, menuA.length);
147
+ console.log('▼ menuBの取り出し方の全パターン ▼');
148
+ generatePatterns(allPatternsB, [], menuB, menuB.length);
149
+
150
+ randA = Math.floor( Math.random() * allPatternsA.length );
151
+ ptnA = allPatternsA[randA];
152
+ while(isSame) {
153
+ randB = Math.floor( Math.random() * allPatternsB.length );
154
+ ptnB = allPatternsB[randB];
155
+ isSame = false;
156
+ for(i=0, l=ptnA.length; i<l; i+=1) {
157
+ // 取り出し順の値が被らないかチェック
158
+ if(ptnA[i] === ptnB[i]) {
159
+ isSame = true;
160
+ break;
161
+ }
162
+ }
163
+ }
164
+ console.log('▼ menuA, menuB それぞれの取り出し順 ▼');
165
+ console.log(ptnA, ptnB);
166
+
167
+ console.log('▼ 決まった取り出し順に基いて順番に取り出す ▼');
168
+ for(i=0, l=ptnA.length; i<l; i+=1) {
169
+ var m1 = ptnA[i],
170
+ m2 = ptnB[i];
171
+ console.log(m1 + 'と' + m2);
172
+ }
173
+ }();
174
+ ```