10 FOR A=1 TO 5
20 PRINT INT(RND(1)*31)+1
30 NEXT A
これを実行すると、
1
19
30
31
13
と表示され、その後くりかえしても、同じ結果です。
10数年前に少しかじったBASICを、うろ覚えで打ちました。
どなたか直していただけますか。
マシンはPC-9801RAです。ロムベーシックです。
「乱数」は、本当の乱数でなく、疑似乱数で、
しかも、リセット後に生成される値は、毎回同じになります。
5 RANDOMIZE ' 初期値を指定
5 A$=TIME$ : WHILE A$=TIME$ : A=RND : WEND ' 時計を利用
5 WHILE INKEY$="" : A=RND : WEND ' キー入力待ち
の、どれかを追加すれば?
#できれば、毎回、キー入力したほうが良いでしょう R.田中二郎
--
<a href="http://www.nerimadors.or.jp/~jiro/">
[ ji...@nerimadors.or.jp ] [ JR3JXE/1 ] </a>
"TANAKA Jiro" <ji...@nerimadors.or.jp> wrote in message
news:87d7kva...@ace.nerimadors.or.jp...
> "tamao" <tam...@peach.ocn.ne.jp> writes:
> :10 FOR A=1 TO 5
> :20 PRINT INT(RND(1)*31)+1
> :30 NEXT A
>
> 「乱数」は、本当の乱数でなく、疑似乱数で、
> しかも、リセット後に生成される値は、毎回同じになります。
これは98のN88BASIC特有のものでしょうか?
全てのBASICがそうなんですか?
> 5 RANDOMIZE ' 初期値を指定
> 5 A$=TIME$ : WHILE A$=TIME$ : A=RND : WEND ' 時計を利用
> 5 WHILE INKEY$="" : A=RND : WEND ' キー入力待ち
> の、どれかを追加すれば?
>
とりあえず、時計を利用する方法で、毎回違う数字が出るようになりました。
・・・が。一度に出てくる5つの数字の中に、ダブって出てくることがあります。
機械が、決まった乱数テーブルから拾ってくる以上、避けられないのでしょうか?
IF文とかを使って、同じ数字が出ないようにする方法を教えていただけますでしょう
か。
なんか頼りすぎで、申し訳ありませんが、宜しくお願いします。
>> > 「乱数」は、本当の乱数でなく、疑似乱数で、
>> > しかも、リセット後に生成される値は、毎回同じになります。
>> これは98のN88BASIC特有のものでしょうか?
>> 全てのBASICがそうなんですか?
BASICってもいろいろな方言がありますが、
JIS X 3003-1982 (電子計算機プログラム言語 基本BASIC),
JIS X 3003-1993 (電子計算機プログラム言語 Full BASIC)では、いずれも
(JISX3003-1993 5.4.4(4))
randomize文を実行していない時、関数RNDの引用は、プログラムの
実行のたびごとに同じ疑似乱数列を生成する。
つーわけで、JIS BASIC(==ANSI BASIC)準拠の処理系では毎回同じです。
リセット毎ではなく、実行毎に同じです。
同じですとゆーか同じにしないといけない。
N*-BASIC (=~ Microsoft BASIC)はANSI BASICとは系統が違いますが…
同じNEC系でもN6*-BASICはRANDOMIZEの類がなく、毎回違う出力
になったと思います(電源投入直後は同じだったかな?)
------------------------------------------------------------------------------
かべ@sra-tohoku.co.jp VEGA Systems MCMXCI
「自分はレーサーだっていうのかい? たいしたことないじゃないか。」
------------------------------------------------------------------------------
tam...@peach.ocn.ne.jpさん:
> とりあえず、時計を利用する方法で、毎回違う数字が出るようになり
> ました。・・・が。一度に出てくる5つの数字の中に、ダブって出て
> くることがあります。
簡単に考えて、4番目までOKだったとして、5番目の数字がこれまでの
4つと同じでない確率はたったの0.6ですからダブるのは当然です。
> 機械が、決まった乱数テーブルから拾ってくる以上、避けられないの
> でしょうか?
サイコロを振ったってなんだって同じことです。
> IF文とかを使って、同じ数字が出ないようにする方法を教えていただ
> けますでしょうか。
定石は「配列に0~9までの数字を入れておき、乱数を使ってこの中の
2箇所をランダムに交換することを十分繰り返し、最後に先頭から5個と
る」ことです。交換だけしてれば同じ数字が2つ現われることは絶対な
いでしょ?
最初に考えた人は偉いと思ってる 久野
In article <8jvdg6$20...@utogw.gssm.otsuka.tsukuba.ac.jp> ,
ku...@gssm.otsuka.tsukuba.ac.jp writes
> 定石は「配列に0~9までの数字を入れておき、乱数を使ってこの中の
>2箇所をランダムに交換することを十分繰り返し、最後に先頭から5個と
>る」ことです。交換だけしてれば同じ数字が2つ現われることは絶対な
>いでしょ?
> 最初に考えた人は偉いと思ってる 久野
なんかこの「十分」ってところがあまり効率が良くないような...
Perl だと、
srand;
@new = ();
@old = 1 .. 10000; # just a demo
for( @old ){
my $r = rand @new+1;
push(@new,$new[$r]);
$new[$r] = $_;
}
とか書くみたいですね。Basic to Perl translator ぐらいあっても
よさそうだが..
---
Shinji KONO @ Information Engineering, University of the Ryukyus
河野真治 @ 琉球大学工学部情報工学科
ko...@ie.u-ryukyu.ac.jpさん:
> なんかこの「十分」ってところがあまり効率が良くないような...
もう1つ配列を用意してここに10個乱数を詰めて、元の0~9の整数
の配列とペアにして乱数側をキーとして整列するのならまあ十分ですよ
ね。
それをさぼって「適当にシャッフルする」でどれくらい済むもんかな
あと思いまして。
実は整列するよりシャッフルする方がよいとか? 久野
In article <8jvdg6$20...@utogw.gssm.otsuka.tsukuba.ac.jp> ku...@gssm.otsuka.tsukuba.ac.jp (kuno) writes:
>> > IF文とかを使って、同じ数字が出ないようにする方法を教えていただ
>> > けますでしょうか。
>>
>> 定石は「配列に0~9までの数字を入れておき、乱数を使ってこの中の
>> 2箇所をランダムに交換することを十分繰り返し、最後に先頭から5個と
>> る」ことです。交換だけしてれば同じ数字が2つ現われることは絶対な
>> いでしょ?
生成したいのは
1 から 31 までの異る 5 つの数字
のような...
(配列に入れるのを 31 までにすれば良いだけですが...)
ちなみに, こういう方法もあります.
1. 配列に 1 から N (この場合は 31?) までの数字を入れておく.
2. 1 から N までの乱数 X を生成し, 配列の X 番目を答とする.
(配列が 0 から始まる場合は 0 から N - 1)
3. 配列の X 番目の要素と N 番目の要素を交換する.
(N 番目の要素を X 番目に代入するだけでも良いですが...)
4. N を 1 減らす.
5. 必要なだけ (この場合は 5 回) 2 から 4 を繰り返す.
Kameyama Toyohisa
そうですね。それに、どれぐらい混ぜれば十分なんでしょう???
In article <8k0g24$28...@utogw.gssm.otsuka.tsukuba.ac.jp>,
<ku...@gssm.otsuka.tsukuba.ac.jp> wrote:
> もう1つ配列を用意してここに10個乱数を詰めて、元の0~9の整数
>の配列とペアにして乱数側をキーとして整列するのならまあ十分ですよ
>ね。
配列は一つで足りますよ。
全要素から乱数で一つ選び、それを一つめの要素と交換。
二つめ以降の要素から乱数で一つ選び、それを二つめと交換。
三つめ以降の要素から乱数で一つ選び、それを三つめと交換。
四つめ以降の要素から乱数で一つ選び、それを四つめと交換。
‥‥(中略)‥‥
最後の四要素から乱数で一つ選び、それを後ろから四つめと交換。
最後の三要素から乱数で一つ選び、それを後ろから三つめと交換。
最後の二要素から乱数で一つ選び、それを後ろから二つめと交換。
これで完全にシャッフルできます。
本質的には河野さんのPerl版と同じようなものです。
1010 M=31
1020 DIM A(M)
1030 FOR I=1 TO M
1040 A(I)=I
1050 NEXT
1060 FOR I=1 TO M-1
1070 R=INT(RND(1)*M)+1
1080 T=A(R):A(R)=A(I):A(I)=T
1090 NEXT
ただ、元記事の問題は「1から31までの数字の中から5個の数字
を選ぶ」ことですから、最初の5回でじゅうぶんです。
110 RANDOMIZE
120 DIM A(31)
130 FOR I=1 TO 31
140 A(I)=I
150 NEXT
160 FOR I=1 TO 5
170 R=INT(RND(1)*31)+1
180 PRINT A(R)
190 A(R)=A(I)
200 NEXT
手許に BASIC の処理系がなく、上のサンプルは試していません。
以下のように Visual Basic Scripting Edition (VBScript)
に書き直して Windows Scripting Host (WSH) で試してみました。
DIM A(31)
Do
RANDOMIZE
s=""
FOR I=1 TO 31
A(I)=I
NEXT
FOR I=1 TO 5
R=INT(RND(1)*31)+1
s=s+" "+CStr(A(R))
A(R)=A(I)
NEXT
Loop While MsgBox(s, 5) = 4
--
中川 寛治 Kanji Nakagawa ソフトウェアの不正コピーは自滅行為
> 配列は一つで足りますよ。
> 全要素から乱数で一つ選び、それを一つめの要素と交換。
> 二つめ以降の要素から乱数で一つ選び、それを二つめと交換。
> 三つめ以降の要素から乱数で一つ選び、それを三つめと交換。
> 四つめ以降の要素から乱数で一つ選び、それを四つめと交換。
> ‥‥(中略)‥‥
なるほど、言われてみればそうですね。
誰が考えたんでしょう? 久野
N88-BASICならRADOMIZE TIMEで良いのでは?
高屋敷 一仁 Kunihito Takayashiki
ニュースグループの新設などについては以下のWeb pageを参照してください
http://www2s.biglobe.ne.jp/~kyashiki/fj/
timeで数値が返ってきますよ。もしかして、F-BASICだったかな?
> もしTIME$なら文字列を返す関数です。
そうですね。
> その場合は
> RANDOMIZE VAL(MID$(TIME$,2))
それだと、2文字目以降がVALの中で評価されません?