Qbasicnews.com

Full Version: Can't figure this one out...
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I have tried endlessly to figure out a solution to my dilemma. First consider my code:

Code:
DIM character(1 TO 254)
DIM used(1 TO 254)

FOR x = 1 TO 254
redo:
  RANDOMIZE TIMER
  a = INT(RND * 254)
  IF a = 0 THEN GOTO redo
  IF a = used(a) THEN GOTO redo
  character(x) = a
  used(a) = a
NEXT x

Now my goal with this program is to create random numbers between 1 and 254 that do not repeat. My problem lies within the line of code that reads:

Code:
IF a = used(a) THEN GOTO redo

For some reason unknown to me, the program hangs at this point.

Any ideas?

Thanks for any help.

:???:
Quote:I have tried endlessly to figure out a solution to my dilemma. First consider my code:

Code:
DIM character(1 TO 254)
DIM used(1 TO 254)

FOR x = 1 TO 254
redo:
  RANDOMIZE TIMER
  a = INT(RND * 254)
  IF a = 0 THEN GOTO redo
  IF a = used(a) THEN GOTO redo
  character(x) = a
  used(a) = a
NEXT x

INT(RND * 254) +1 will make 1 the lowerbound nubmer (least possible)

your problem sounds awfully familiar to this other guy's... pv something...

you have to check all of used(a) against the current (a) in order to make sure they don't repeat.

using GOTO isn't clean, and this probably creates an infinite loop in your program.
It's not the goto. You're wrong. Using goto is perfectly clean. Misuse of GOTO, as anything else, is unclean. Smile

The answer is:

You can get the same number twice with the rnd! if you do, you have an infinite loop because used(a) = a!

PS: You only need to say "RANDOMIZE TIMER" once, not for every time you get a random number. Won't help saying it more.
This probably isn't the easiest way to do it, but it does it:

Code:
DIM character(1 TO 254)
DIM used AS STRING * 900

FOR x = 1 TO 254
redo:
  RANDOMIZE TIMER
  a = INT(RND * 254)
  n$ = "." + LTRIM$(RTRIM$(STR$(a))) + "."
  IF INSTR(used, n$) THEN GOTO redo
  used = used + n$
  character(x) = a
NEXT x

An easier (and more obvious) way that I just thought of (and would have thought of earlier if I was reasonably intelligent) you could have used(1 to 254), and then when a number (say 16) was generated:

Code:
if used(16) then goto redo
used(16) = 1
character(x) = 16

Of course, 16 would be replaced by a variable.
Thanks, RST--your code portion worked. I had to take out the DIM statement for 'used'; it wouldn't work this way. So, what I did is I put used$ instead of used and it worked.

Thanks again.
Looking at the code the problem is at
Code:
a = INT(RND * 254)
It's due to RND allway return a single less than 1, so you get a number between 0 and 253, but you discard the 0.
The for loop goes from 1 to 254, but you only get 1 to 253. Your code never fill the array, the loop is infinite.

As Potato say the solution is
Code:
INT(RND * 254) +1

Another approach for you task will be fill the table in the right order
Code:
DIM character(1 TO 254)

FOR x = 1 TO 254
  character(x) = x
NEXT x

Then shuffle the array (another algorithm surely will be better)
Code:
y = 128
WHILE y > 1
  x = 1
  WHILE x + y <= 254
    IF RND <= 0.5 THEN SWAP character(x), character(x + y)
    x = x + 1
  WEND
  y = y \ 2
NEXT t
See this?
IF a = used(a) THEN GOTO redo

Should be
IF a = used(x) THEN GOTO redo
That does seem now to be the most likely replacement for a = used(a)......
Since a is the random number, he's calling random parts of the used array. Pretty funny.