• 締切済み

【乱数】任意の範囲、固定個数、重複しない乱数

テニスのダブルス組み合わせ用のスクリプトを考えております。 ネットでいろいろ探して試してみましたが Javascript初心者で、寄せ集めでは限界がありますので質問させてください(;^_^A 【何をしたいのか】 ・テキストボックスで任意の数字(整数)で範囲と行数を指定。 ・結果は数値4個固定とし、4個で1グループ。この4個内は重複がないように。 ・4個1グループを指定の行数分求める。 ・このとき、なるべくならすでに出た数字は後回しにしたい。例えば1~10の範囲としたら、1~10すべて出るまでは一度出た数字は後回しになるように。 ・小さい範囲で大きな行数を指定すれば、必ず同じ組み合わせが出ることは了承。 ・結果は下記のようにしたい。 1,6,8,3 2,4,5,10 9,7,2,3 ・ ・ 3,6,8,1(1行目と同じ組み合わせだが順不同なので可、またはまったく同じのが出ても可) 【現在の状況】 ネットで拾ったサンプルから、何をどのように書き換えたらいいのかわからずです(;^_^A 【サンプルの提示】 ■範囲の乱数■ <HTML> <HEAD> <SCRIPT LANGUAGE="JavaScript"> <!-- function gen_random(num1, num2) { retval=Math.random(); document.write(Math.floor(retval * (num2 - num1)) + eval(num1)); } //--> </SCRIPT> </HEAD> <BODY> <center> <table border=1 cellpadding=4> <form name=myform> <tr><td bgcolor=#ffffe4 align=center> <font color=blue> 乱数の範囲 </td></tr> <tr><td align=center> <input type=text name=d1 size=2 maxlength=2> ~ <input type=text name=d2 size=4 maxlength=4> </td></tr> <tr><td align=center> <input type=button name=btn1 value=乱数発生 onClick=gen_random(myform.d1.value,myform.d2.value)><br> </td></tr> </form> </table> </center> </BODY> </HTML> ---------------------------------------- ■30個を5行ずつ出している <HTML> <HEAD> <SCRIPT LANGUAGE="JavaScript"> var i; for(i=1 ; i <=30 ;i++) { document.write(Math.floor(Math.random()*10) +"<BR>"); if(i%5 == 0) document.write("<HR>"); } </SCRIPT> </HEAD> <BODY> </BODY> </HTML> --------------------------------------------------------- ■重複しない、しかも後回しになる?■ <HTML> <HEAD> <SCRIPT LANGUAGE="JavaScript"> //once_rand: min以上max未満の重複しない乱数を生成するためのオブジェクト function once_rand(min,max){   this.cnt=max-min;   this.arr=[];   //乱数候補を配列に格納   for(var i=0;i<this.cnt;i++){this.arr[i]=min++;} } //乱数を取り出すメソッド once_rand.prototype.next=function(){   if(this.cnt<=0){     //もう乱数候補が残っていない     return undefined;   }   //乱数を取り出す位置を決定   var idx=Math.floor(Math.random()*(this.cnt));   //乱数を取り出す   var rand_val=this.arr[idx];   //重複しないように最後尾の要素で上書き(今のthis.arr[this.cnt-1]は次回以降使われない)   this.arr[idx]=this.arr[this.cnt-1];   //残りの乱数候補が減少   this.cnt--;   return rand_val; } //テスト var rand1 = new once_rand(1,15); //1以上15未満 var str=rand1.next(); while(1){   var rand_val=rand1.next(); //乱数を取り出す   if(rand_val == undefined){break;}   str += ","+rand_val; } alert(str); </SCRIPT> </HEAD>

みんなの回答

noname#84373
noname#84373
回答No.7

<div id="p">あっさりってどうなのよ;_;</div> <script type="text/javascript"> //全角空白は半角空白かタブに変換のこと //@cc_on Array.prototype.shuffle_FY = function () {  var n = this.length;  var r;  var w;    while (n) {   r = Math.random() * n |0;   w = this[--n];   this[n] = this[r];   this[r] = w;  }  return this; } var max = 10; var member = []; var i = 1; var nx = []; var text = []; var g = 10; var o; var c = 0; var t; var lt=[]; for (;i <= max; nx.push(i++)); while (g) {  if (member.length < 4) {   while (o = nx.shift()) member.push(o)   member = member.shuffle_FY();  }  t = member.shift(); nx.push(t); lt.push(t);  c++;  if (c==4) {   c = 0;   text.push(lt.join(', '));   lt = [];   g--;  } } document.getElementById('p').innerHTML = text.join('<hr>'); </script>

noname#84373
noname#84373
回答No.6

ご指摘ありがとうございます。あれから他のページの回答も 参考にさせてもらい、偏りがあることを知りました。 手を抜いちゃだめってことなんですかね^^;

  • Gotthold
  • ベストアンサー率47% (396/832)
回答No.5

> member = member.sort(function () { return Math.random() > 0.5 ? 1 : -1 }); シャッフルするために比較関数に乱数を使うパターンはたまに見るけど、 推移律が満たされない比較関数をsortに渡すってどうなんだろう? 停止性とか大丈夫なのかな。 あとこの方法だと全ての組み合わせが等確率で出現しないと思う。 ランダムソート(笑)とは - 西尾泰和のはてなダイアリー http://d.hatena.ne.jp/nishiohirokazu/20071121/1195641084 ↑は今調べて見つけたページだけどランダムソート(笑)は言い得て妙だと思った。 とりあえずシャッフルアルゴリズムにはFisher-Yatesを薦めとく。

noname#84373
noname#84373
回答No.4

さらに訂正。 <div id="p"></div> <script type="text/javascript"> var max = 10; var member = []; var i = 1; var nx = []; var text = []; var g = 10; var o; var c = 0; var t; var lt=[]; for (;i <= max; nx.push(i++)); while (g) {  if (member.length < 4) {   while (o = nx.shift()) member.push(o)   member = member.sort(function () { return Math.random() > 0.5 ? 1 : -1 });  }  t = member.shift(); nx.push(t); lt.push(t);  c++;  if (c==4) {   c = 0;   text.push(lt.join(', '));   lt = [];   g--;  } } document.getElementById('p').innerHTML = text.join('<hr>');

Tobykun
質問者

お礼

ありがとうございました!! マルチポスト怒られました(;^_^A アセアセ・・・ 今後は気をつけるようにします。 本当にありがとうございました♪

noname#84373
noname#84373
回答No.3

連続でごめん。今日はやっぱりボケてる。 var max = 10; var member = []; var i = 1; var nx = []; var text = []; var g = 10; var o; var c; for (;i <= max;member.push(i++)); while (g--) { member = member.sort(function () { return Math.random() > 0.8 ? 1 : -1 }); while (o = nx.shift()) member.push(o); c = 4; while(c--) nx.push(member.shift()); text.push(nx.join(', ')); } document.getElementById('p').innerHTML = text.join('<hr>'); マルチ突っ込まれるぞ!^^;

noname#84373
noname#84373
回答No.2

さっそくミス発見。 <div id="p"></div> <script type="text/javascript"> var max = 10; var member = []; var i = 0; var nx = []; var text = ''; var g = 10; for (;i < max;) member.push(i++); while (g--) { member = member.sort(function () { return Math.random() > 0.8 ? 1 : -1 }); for (i=0;i<4;i++) member.push(nx.shift()); nx = []; for (i=0;i<4;i++) nx.push(member.shift()); text += nx.join(', ') + '<hr>'; } document.getElementById('p').innerHTML = text; </script>

noname#84373
noname#84373
回答No.1

つっこまれそうだなぁ~! 数値が0.8のところは、本来0.5なんだけど うまく説明できないけど微調整して・・・。 <div id="p"></div> <script type="text/javascript"> var max = 10; var member = []; var i = 0; var nx = []; var text = ''; var g= max; for (;i < max;) member.push(i++); while (g--) { member = member.sort(function () { return Math.random() > 0.8 ? 1 : -1 }); while(nx[0]) member.push(nx.shift()); nx = []; for (i=0;i<4;i++) nx.push(member.shift()); text += nx.join(', ') + '<hr>'; } document.getElementById('p').innerHTML = text;

関連するQ&A

  • 乱数の生成について

    下記のスクリプトではボタンをクリックして乱数を生成しています。 ボタンをクリックする事無く、windowが開くと同時に乱数を生成するにはどのようにすれば良いでしょうか? <HTML> <HEAD> <SCRIPT LANGUAGE="JavaScript"> <!-- function gen_random(num1, num2) { retval=Math.random(); document.myform.ans.value = (Math.floor(retval * (num2 - num1)) + eval(num1)); } //--> </SCRIPT> </HEAD> <BODY> <center> <form name=myform> 乱数の範囲 <input type=hidden name=d1 value=1000> <input type=hidden name=d2 value=9999> <input type=button name=btn1 value=乱数発生 onClick=gen_random(myform.d1.value,myform.d2.value)><br> 乱 数:<input type=text name=ans size=4> </form> </center> </BODY> </HTML>

  • 【乱数発生】 JavascriptからPerlへ移植したい

    テニスのダブルス組み合わせ用のスクリプトを考えております。 ネットでいろいろ Javascriptでは教えていただいたのですが、 携帯からはJS使えないことを後で知り、 Perl-CGIならいけるのでは?と。 Perlについてまったくわからないので 下記の件について、大変僭越ではありますが 移植をお願いしたいのです(;^_^A 【何をしたいのか】 ・テキストボックスで任意の数字(整数)で範囲と行数を指定。 ・結果は数値4個固定とし、4個で1グループ。この4個内は重複がないように。 ・4個1グループを指定の行数分求める。 ・このとき、なるべくならすでに出た数字は後回しにしたい。例えば1~10の範囲としたら、1~10すべて出るまでは一度出た数字は後回しになるように。 ・小さい範囲で大きな行数を指定すれば、必ず同じ組み合わせが出ることは了承。 ・結果は下記のようにしたい。 1,6,8,3 2,4,5,10 9,7,2,3 ・ ・ 3,6,8,1(1行目と同じ組み合わせだが順不同なので可、またはまったく同じのが出ても可) 以下は、Javascriptで稼動するソースになります。 ※後半のFORM部分からPOSTして CGIにて受取、乱数生成したHTMLを表示させるようにしたいのです。 ---------------------------------------------- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=shift_jis"> <meta http-equiv="Content-Language" content="ja"> <meta http-equiv="Content-Script-Type" content="text/javascript"> <meta http-equiv="Content-Style-Type" content="text/css"> <script type="text/javascript"> <!-- function OnceRand(min, max) { if(isNaN(min) || isNaN(max) || parseInt(min) >= parseInt(max)) throw new Error("指定の値に誤りがあります。"); this.min = parseInt(min); this.max = parseInt(max); this.createArray(); } /* 配列を作成します。 */ OnceRand.prototype.createArray = function() { this.original = []; for(var ix = this.min; ix <= this.max; ix++) { this.original.push(ix); } this.arr = this.original.concat(); }; /* 次の値を取り出します。 */ OnceRand.prototype.next = function(length) { var per = []; if(0 >= length) return per; for(var ix = 0; ix < length; ix++) { if(this.arr.length <= 0) this.arr = this.original.concat(); do { var dup = false; var ax = Math.floor(Math.random() * this.arr.length); for(var px = 0; px < per.length; px++) { if(per[px] == this.arr[ax]) dup = true; } } while(dup) per.push(this.arr.splice(ax, 1)[0]); } return per; }; /* 乱数を生成します。 */ function genRandom() { var minBox = document.getElementById("min"); var maxBox = document.getElementById("max"); var lineBox = document.getElementById("line"); var console = document.getElementById("console"); var consoleClone = console.cloneNode(false); var lineMax = parseInt(lineBox.value); var rand1 = new OnceRand(minBox.value, maxBox.value); for(var lx = 0; lx < lineMax; lx++) { var texts = rand1.next(4); var textLine = document.createTextNode(texts.join(" ,")); var breakLine = document.createElement("br"); consoleClone.appendChild(textLine); consoleClone.appendChild(breakLine); } console.parentNode.replaceChild(consoleClone, console); } // --> </script> <title>範囲乱数</title> </head> <!--ここからはページ表示部分--> <body> <div> 範囲:<input type="text" id="min" value="" size=2 maxlength=2> ~<input type="text" id="max" value="" size=2 maxlength=2> <br> 行数:<input type="text" id="line" value="" size=2 maxlength=2> <br> <input type="button" value="乱数発生" onclick="genRandom();"> </div> <div id="console"></div> </body> </html> -------------------------------------------------------

  • aspの表示

    こんにちは。 aspでこのように作成し、予定では、for文が回るたびに□■がどんどん変わっていくはずだったのですが、 これを実行するとメイン関数が終了したあとにHTMLが表示されてしまいます。 何か方法はないのでしょうか? よろしくお願いします。 <% Option Explicit%> <SCRIPT Language="JavaScript"> var cnt=0 var msg="□□□□□□□□□□"; function aaa() { msg=msg.replace(/□/,"■") document.textForm.box.value=msg; cnt +=1 if (cnt >9 ){ msg="□□□□□□□□□□"; cnt =0 } } </SCRIPT> <HTML> <HEAD> <title>タイトル</title> </HEAD> <BODY> <FORM> <TABLE> <TR > <TD> </TD> </TR> </TABLE> </FORM> </BODY> </HTML> <% Call Main '--------------------------------------------------- ’メイン関数 '--------------------------------------------------- Sub Main() For i=0 to 3 Response.write("<" + "SCRIPT Language=JavaScript" + ">" + " aaa(); <" + "/" + "SCRIPT>") Next End Sub %>

  • テーブルとテーブルの間の隙間

    以下の様なHTMLでIE6で表示した場合、●Aと●Bの間に、微妙な隙間が入ってしまいます。 どうやっても隙間が無くなりません。 ●Aの部分には、画像がランダムに表示されるようなスクリプトを記述していますが、 そのスクリプトを削除したら、ちゃんと隙間が無くなるのです(^^;) これって方法はありますか?どうにかランダムに表示させたいので、アドバイス下さい。 ============================ <script language="javascript" src="../js/top.js"></script> </HEAD> <BODY topmargin="0"> <DIV align="center"> <TABLE border="0" cellspacing="0" cellpadding="0"> <TBODY> ●A <TR> <TD width="800"><SCRIPT LANGUAGE="JavaScript">random_img2()</SCRIPT> <noscript><IMG src="../img/1.jpg" alt="" width="800" height="300"></noscript></TD> </TR> ●B <TR> <TD width="800"><A href="../index.html">HOME</A> &gt;&gt; TEST</TD> </TR> </TBODY> </TABLE> ============================ ※実際のHTMLには●Aと●Bという文字は入っておりません。 以下はtop.jsで記述している内容です。 ============================ function random_img1(num1,num2) { if((num1 - num2) > 0) { var big = num1 var small = num2 } else { var big = num2 var small = num1 } var range = big - small + 1 var number = Math.floor(Math.random()*range) + small return(number) } function random_img2() { var img_src = "../img/" + random_img1(1,3) + ".jpg" document.write("<IMG SRC='" + img_src + "'>") } ============================

    • ベストアンサー
    • HTML
  • javascriptで指定するtrを削除した時に、IEとfirefoxで動作が異なる

    はじめて、投稿いたします。 現在、javascriptで指定した行を削除するような動作を作っているのですが、firefoxとIEで動作が異なってしまうため困っています。 ちなみに、firefoxでは、実現してほしい動作をしてくれるのですが、IEではうまく動作してくれません。 tableのtrが3つ以上ある場合は、指定した行が正常に削除します。 しかし、IEだと、trが2つの時には、1番目のtrを削除しようとすると、一緒に2番目のtrの中身が見えなくなってしまいます。 ちなみに、その中の情報が削除されたのかなと思い、alertで表示させるとどうやら削除はされておらず、表示しなくなってしまうようです。 どうすれば、firefoxとIEで、同じような動作をするようにできるのでしょうか? よろしくお願いします。 以下に、ソースを貼っておきます。 <html> <head> <script type="text/javascript"> <!-- function delete_tr(html_this) { var TR = html_this.parentNode.parentNode; TR.parentNode.deleteRow(TR.sectionRowIndex); var table = document.getElementById('test_table'); var tr_num; var td_num; for (tr_num = 0; tr_num < table.rows.length; tr_num++) { for (td_num = 0; td_num < table.rows[tr_num].cells.length; td_num++) { alert(table.rows[tr_num].cells[td_num].innerHTML); } } } --> </script> </head> <body> <h1>Hello World !!</h1> <table border="1" id="test_table"> <tr> <td> <input type="button" value="delete" onClick="delete_tr(this)" /> </td> <td style="display: none;">------ bbbb ------</td> <td>------ cccc ------</td> </tr> <tr> <td> <input type="button" value="delete" onClick="delete_tr(this)" /> </td> <td style="display: none;">------ BBBB ------</td> <td>------ CCCC ------</td> </tr> <tr align="center"> <td colspan="3"> <input type="button" value="add"> </td> </tr> </table> </body> </html>

  • 乱数の取得

    キー操作をした時に複数の乱数を習得させようと思っています。 【キ─操作関数】  int num[3] = {11, 22, 33}; ←初期化のため数字は適当です。  srand((unsigned int)time(NULL))  for(int i=0; i<=3; i++)  {   num[i] = rand % 10;  } 上記のプログラムを書いています。 num[0]、num[1]、num[2]にそれぞれ0~9の乱数が入ると思うのですが、 num[0]にしか乱数が入りません。 num[1]、num[2]には同じ数字(恐らくtimeで取得した数字?)が入っています。 何かお気づきの点がありましたらアドバイスお願い致します。

  • 乱数について

    C言語で0~1の乱数を作成する部分を書いているのですが num[i] = rand()/(RAND_MAX+0.1); と書いてループさせています。 numはdouble型で定義しているのですがこれで実行すると桁数が下6桁まで表示されてしまいます。 欲しいデータは0.1、0.2・・・1.0までの0.1刻みのデータなのですが桁数を制限するにはどうすればいいのでしょうか?

  • 乱数について

    乱数の分布を見るために以下のようなプログラムを書きました。 #include <stdio.h> #include <stdlib.h> #include <math.h> int main() { int i,imax, S[RAND_MAX], r; double x,y; FILE *output1; output1=fopen("random2.data","w"); imax=100000; for(i=0;i<=imax;i++){ r = rand(); S[r] += 1; } for(i=0;i<=RAND_MAX;i++){ fprintf(output1,"%d %d \n",i,S[i]); } return 0; } するとコンパイルできて実行もできるのですが、なぜか乱数が30000を 超えるくらいのところでおかしな値になりました。 原因がわからないのでどなたか教えてください。

  • 重複しない乱数を作り配列に入れる(AS3.0)

    Flash Pro CS5 AS3.0 で記述しています。 1~10の整数をランダムかつ重複せずに配列に格納したいと考えています。 そこで,ネット上で参考になるソースを見つけ, 以下のように書き直しました。 var int_a = new Array(); var int_b = new Array(); function RandomInt():void{ //ここだけ変更すればよい var maxN:Number = 10;//乱数の最大値 //0~maxNの数字を全部配列に入れる for (var i:int=0; i< maxN; i++) { int_a[i] = i+1; } var j:Number = 0; var a_length:Number = int_a.length; //要は配列をシャッフルする while (a_length) { var int_r:Number = Math.floor(Math.random()*(maxN+1-j)); //乱発生した整数を配列int_bに順番に入れ、int_aから削除する int_b[j] = int_a.splice(int_r, 1); j++; //配列int_a内の数字が一つずつ減っていく a_length = int_a.length; } //ここで配列int_bがシャッフルされた trace(int_b); } RandomInt(); としました。 しかし出力結果がなぜか 8,2,4,9,,7,6,5,10,3,1のように抜けている部分があり, 次のフレームで for(var j:int=1; j <= 10; j++){   trace(int_b[j]); } として確認してもやはり 2 4 9 7 6 5 10 3 1 となってしまします。 どの部分がおかしいのか教えていただきたいです。 また,乱数発生の部分で Math.floor(Math.random()*(maxN+1-j)); という風に記述してあったのですが,ここは間違いではないのでしょうか? jを引いていくと発生する乱数の範囲が徐々に狭くなっていってしまうと思ったのですが; それとも元のソースコードを使って ttp://www.renowan.com/blog/?p=143 0~9までの乱数を発生させてそれぞれに1を足す方が簡単でしょうか? よろしくお願いします。

    • ベストアンサー
    • Flash
  • セルの背景画像ランダムチェンジがうまくいきません!

    過去の質問などを参考にセルの背景画像のランダムチェンジのソースを作りましたがうまく表示されません!何かアドバイスがあれば是非お願いします。 <head> <script language="javascript"> var BGimg=new Array(); BGimg[0]="image/01.gif"; BGimg[1]="image/02.gif"; var img_pcs=BGimg.length;//画像の数 var rdm_num=Math.floor(Math.random()*img_pcs);//乱数 function chg_BGimg(){ document.getElementById("changeIMG").style.backgroundImage="url('"+BGimg[rdm_num]+"')"; } </script> </head> <body onload="chg_BGimg();"> <table bgcolor="#333333"> <tr> <td id="changeIMG" style="background-image:url('image/first.gif');">このセルの背景が変わります</td> <td>blank</td> <tr> </table> </body> (実際のテーブルは列11×行9です。) 以上がソースです。どうも初期設定のfirst.gifが一瞬だけ表示されて、あとはテーブルの背景色になり、何も画像が表示されてず、「×」マーク(画像が見つからなかった場合にでるアイコン)もないのです。 このソースの改良点または、全く違う方法でも結構です、何かアドバイスがあれば是非お願いします。よろしくお願いします!

専門家に質問してみよう