Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

N88BASICで乱数を出したいのですが・・ ・。

433 views
Skip to first unread message

tamao

unread,
Jul 4, 2000, 3:00:00 AM7/4/00
to
ミニロトの5つの数字を選ぶプログラムを作ったのですが、
毎回同じ結果しか出ません。どこに問題があるのでしょう?

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です。ロムベーシックです。

タマオ tam...@peach.ocn.ne.jp

TANAKA Jiro

unread,
Jul 4, 2000, 3:00:00 AM7/4/00
to
"tamao" <tam...@peach.ocn.ne.jp> writes:
:10 FOR A=1 TO 5

:20 PRINT INT(RND(1)*31)+1
:30 NEXT A

「乱数」は、本当の乱数でなく、疑似乱数で、
しかも、リセット後に生成される値は、毎回同じになります。

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>

tamao

unread,
Jul 5, 2000, 3:00:00 AM7/5/00
to
R.田中二郎さん、フォローありがとうございます。

"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文とかを使って、同じ数字が出ないようにする方法を教えていただけますでしょう
か。
なんか頼りすぎで、申し訳ありませんが、宜しくお願いします。

タマオ tam...@peach.ocn.ne.jp


ka...@sra-tohoku.co.jp

unread,
Jul 5, 2000, 3:00:00 AM7/5/00
to
かべ@SRA東北

>> > 「乱数」は、本当の乱数でなく、疑似乱数で、
>> > しかも、リセット後に生成される値は、毎回同じになります。
>> これは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
「自分はレーサーだっていうのかい? たいしたことないじゃないか。」
------------------------------------------------------------------------------

ku...@gssm.otsuka.tsukuba.ac.jp

unread,
Jul 5, 2000, 3:00:00 AM7/5/00
to
久野です。

tam...@peach.ocn.ne.jpさん:
> とりあえず、時計を利用する方法で、毎回違う数字が出るようになり
> ました。・・・が。一度に出てくる5つの数字の中に、ダブって出て
> くることがあります。

簡単に考えて、4番目までOKだったとして、5番目の数字がこれまでの
4つと同じでない確率はたったの0.6ですからダブるのは当然です。

> 機械が、決まった乱数テーブルから拾ってくる以上、避けられないの
> でしょうか?

サイコロを振ったってなんだって同じことです。

> IF文とかを使って、同じ数字が出ないようにする方法を教えていただ
> けますでしょうか。

定石は「配列に0~9までの数字を入れておき、乱数を使ってこの中の
2箇所をランダムに交換することを十分繰り返し、最後に先頭から5個と
る」ことです。交換だけしてれば同じ数字が2つ現われることは絶対な
いでしょ?

最初に考えた人は偉いと思ってる 久野

Shinji KONO

unread,
Jul 5, 2000, 3:00:00 AM7/5/00
to
河野 真治@琉球大情報工学です。

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
河野真治 @ 琉球大学工学部情報工学科

ku...@gssm.otsuka.tsukuba.ac.jp

unread,
Jul 5, 2000, 3:00:00 AM7/5/00
to
久野です。

ko...@ie.u-ryukyu.ac.jpさん:
> なんかこの「十分」ってところがあまり効率が良くないような...

もう1つ配列を用意してここに10個乱数を詰めて、元の0~9の整数
の配列とペアにして乱数側をキーとして整列するのならまあ十分ですよ
ね。

それをさぼって「適当にシャッフルする」でどれくらい済むもんかな
あと思いまして。

実は整列するよりシャッフルする方がよいとか? 久野

Toyohisa Kameyama

unread,
Jul 6, 2000, 3:00:00 AM7/6/00
to
亀山です.

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

Kanji Nakagawa

unread,
Jul 6, 2000, 3:00:00 AM7/6/00
to
In article <16208.9...@rananim.ie.u-ryukyu.ac.jp>
<ko...@ie.u-ryukyu.ac.jp> wrote:
> なんかこの「十分」ってところがあまり効率が良くないような...

そうですね。それに、どれぐらい混ぜれば十分なんでしょう???

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 ソフトウェアの不正コピーは自滅行為

ku...@gssm.otsuka.tsukuba.ac.jp

unread,
Jul 6, 2000, 3:00:00 AM7/6/00
to
久野です。

ka...@anet.ne.jpさん:


> 配列は一つで足りますよ。
> 全要素から乱数で一つ選び、それを一つめの要素と交換。
> 二つめ以降の要素から乱数で一つ選び、それを二つめと交換。
> 三つめ以降の要素から乱数で一つ選び、それを三つめと交換。
> 四つめ以降の要素から乱数で一つ選び、それを四つめと交換。
> ‥‥(中略)‥‥

なるほど、言われてみればそうですね。

誰が考えたんでしょう? 久野

NRG

unread,
Jul 9, 2000, 3:00:00 AM7/9/00
to
> ミニロトの5つの数字を選ぶプログラムを作ったのですが、
> 毎回同じ結果しか出ません。どこに問題があるのでしょう?
> マシンはPC-9801RAです。ロムベーシックです。

5 RANDOMIZE INP(&H71)

これでシステムタイマーを呼び出してみては?
PC98のみでしか使用できませんが確実な方法です。

----
NRG
mailto:nr...@flashmail.com



Kunihito Takayashiki

unread,
Jul 9, 2000, 3:00:00 AM7/9/00
to
> 5 RANDOMIZE INP(&H71)
> これでシステムタイマーを呼び出してみては?
> PC98のみでしか使用できませんが確実な方法です。

N88-BASICならRADOMIZE TIMEで良いのでは?

高屋敷 一仁 Kunihito Takayashiki
ニュースグループの新設などについては以下のWeb pageを参照してください
http://www2s.biglobe.ne.jp/~kyashiki/fj/


NRG

unread,
Jul 12, 2000, 3:00:00 AM7/12/00
to
> N88-BASICならRADOMIZE TIMEで良いのでは?
TIMEじゃなくてTIME$ではありませんか?
もしTIME$なら文字列を返す関数です。

その場合は
RANDOMIZE VAL(MID$(TIME$,2))
または
RANDOMIZE VAL(RIGHT$(TIME$,2))
となるでしょう。

この場合は秒単位の初期化になるので
1/60の確率で同じパターンになります。
(システムを再起動しない限り)

INP(&H71)
ではWindowsのGetTickCount APIと
同じような感じの動作をします。
これにより確実な乱数の初期化が期待できます。

----
NRG
mailto:nr...@flashmail.com

Kunihito Takayashiki

unread,
Jul 14, 2000, 3:00:00 AM7/14/00
to
> > N88-BASICならRADOMIZE TIMEで良いのでは?
> TIMEじゃなくてTIME$ではありませんか?

timeで数値が返ってきますよ。もしかして、F-BASICだったかな?

> もしTIME$なら文字列を返す関数です。

そうですね。

> その場合は
> RANDOMIZE VAL(MID$(TIME$,2))

それだと、2文字目以降がVALの中で評価されません?

NRG

unread,
Jul 24, 2000, 3:00:00 AM7/24/00
to
> timeで数値が返ってきますよ。もしかして、F-BASICだったかな?

少なくとも私が使っていたN88-BASIC(DISK/DOS)では
多分無かったと思います。
(現在手元に無いもので確認できません)


> > RANDOMIZE VAL(MID$(TIME$,2))
> それだと、2文字目以降がVALの中で評価されません?

ご指摘のように私の間違えです。

----
NRG
mailto:nr...@flashmail.com
0 new messages