Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Random Numbers
#1
can anybody tell me how to do the following please


I have got 24 numbers that i want to pick out a random, but once a number has been picked out then it can not be pick out again, also the numbers will be printed out 12 on each side of the screen

i.e.

1-----2
24---10
Reply
#2
heres something i knocked up when you were asking about the football schedular (its for freebasic, but if your on QB, it shouldn't be too different)

the important thing for you to note, is the array TeamChosen, this stores if a number has already been selected.

Code:
Function GetRandInt(lb, ub) As Integer
  return Int((ub - lb + 1) * rnd + lb)
End Function

Randomize Timer

Dim NumTeams As Integer
Dim TeamNames(64) As String
Dim TeamChosen(64) As Integer

Print "Please enter the number of teams."
Print ">";
Input NumTeams

For i = 1 To 6
  If 2^i = NumTeams Then
    Depth = i
    Exit For
  End If
Next i

If Depth = 0 Then
  Print "Number of teams should one of 2, 4, 8, 16, 32, 64"
  Sleep
  End
End If

For i = 1 To NumTeams
  Print
  Print "Please enter team " & i & " name"
  Print ">";
  Input TeamNames(i - 1)
  If TeamNames(i - 1) = "" Then TeamNames(i - 1) = chr(64 + i)
Next i

Cls
Print "-------"
Print "Stages: " & Depth
Print
Print "  ---------"
Print "  Stage 1"
For i = 1 To NumTeams \ 2
  Do
    TeamA = GetRandInt(1, NumTeams)
    If TeamChosen(TeamA) = 0 Then
      TeamChosen(TeamA) = 1
      Exit Do
    End If
  Loop
  Do
    TeamB = GetRandInt(1, NumTeams)
    If TeamChosen(TeamB) = 0 Then
      TeamChosen(TeamB) = 1
      Exit Do
    End If
  Loop
  Print "    ----"
  Print "    Game " & i & ":"
  Print "      " & TeamNames(TeamA - 1) & "   vs   " & TeamNames(TeamB - 1)  
  Print
Next i

For i = 2 To Depth
  Print "  -----"
  Print "  Stage " & i
  inc = 1
  For ii = 1 To NumTeams \ (i * 2)
    If i = Depth Then
      Print "    Final"    
    ElseIf i = Depth - 1 Then
      Print "    Semi " & ii & ":"    
    Else
      Print "    Game " & ii & ":"
    End If
    Print "      " & "Winner of Stage " & i - 1 & ", Game " & inc & "   vs   " & "Winner of Stage " & i - 1 & ", Game " & inc + 1
    Print
    inc = inc + 2
  Next ii
Next i

Sleep
End



Heres just a simple prog that does what you want. The do..loop forces it to keep trying till it gets an unused number

Code:
Function GetRandInt(lb, ub) As Integer
  return Int((ub - lb + 1) * rnd + lb)
End Function

Randomize Timer

Dim TeamChosen(64) As Integer

For i = 1 To 24
  Do
    TeamA = GetRandInt(1, 24)
    If TeamChosen(TeamA) = 0 Then
      TeamChosen(TeamA) = 1
      Exit Do
    End If
  Loop
  Print TeamA
Next i

Sleep
End
EVEN MEN OF STEEL RUST.
[Image: chav.gif]
Reply
#3
Quote:can anybody tell me how to do the following please

I have got 24 numbers that i want to pick out a random, but once a number has been picked out then it can not be pick out again, also the numbers will be printed out 12 on each side of the screen
i.e.
1-----2
24---10

Here's some code fucused on your exact problem. (I tested it too.)
Code:
defint a-z
RANDOMIZE TIMER
const lower = 1             'Want random numbers starting with 1
const upper = 24            '... and ending with 24.
dim rands (lower to upper)  'Array to hold unique random numbers.
dim dup   (lower to upper)  'Array to track duplicates.
uniquecnt = 0               'Count of unique random numbers so far.

do while uniquecnt < upper  'loop until have 24 unique random nums.
   r = INT(RND * (Upper - lower + 1)) + lower  'get a random number
   if dup(r) = 0 then       'If not a duplicate.
      dup(r) = 1            'Flag number as used.
      uniquecnt=uniquecnt+1 'Count as unique
      rands(uniquecnt) = r   'Save this unique random number
   end if
loop
rem ... Print out rands array from 1 to 24 as required.
*****
Reply
#4
On a related note, the best random numbers are stock quotes..
Peace cannot be obtained without war. Why? If there is already peace, it is unnecessary for war. If there is no peace, there is already war."

Visit www.neobasic.net to see rubbish in all its finest.
Reply
#5
Quote:On a related note, the best random numbers are stock quotes..

Interesting thought.
*****
Reply
#6
Regarding random selection from a given list.

I have been bothered by the "repeat until a random number has not been selected yet" beat-to-fit forcing methods I see. Finally, I have come up with a more direct approach. I based it on:

1. Create a string list in any order.
2. Create a string array of random numbers of any practical size. It doesn't matter if any are repeated.
3. Add the items from the string list to the end of the random number strings in the string array.
4. Sort the string array.
5. Separate the last part of the string array, to produce the desired, randomized, original list.

Here is a "first approach" program to do this, for the string list with the numbers from 1 to 99:

Code:
'Rand-RAE.bas, by RAEsquivel, 10-14-2006, randamizes a series of numbers or
'characters
'At present, it is set up to randomize the numbers 1 to 99


CLS
RANDOMIZE TIMER

n = 99
m = LEN(STR$(n))

'a will hold a 3-digit random number, a hyphen, and a 2-digit number,
'with a leading and trailing space, a total of 8 characters
DIM a(n) AS STRING * 8

'b will hold a randomized 2-digit number
DIM b(n) AS STRING * 3

'assign a random  number to the series 1,2,3,...n
FOR i = 1 TO n
  a(i) = STR$(INT(RND(1) * 1000))
  a(i) = MID$(a(i), 2, 3) + "-" + STR$(i)
  '''PRINT a(i)
NEXT i


'sort the strings according to the ramdom numbers generated
again:
FOR i = 1 TO n - 1
  k = 0
  IF a(i) > a(i + 1) THEN
    k = 1
    SWAP a(i), a(i + 1)
  END IF
  IF k = 1 THEN
    GOTO again:
  END IF
NEXT i


'print each randomized number, preceded with its number of occurance
FOR i = 1 TO n
  b(i) = MID$(a(i), 5, 3)
  PRINT USING "##"; i;
  PRINT "="; b(i), '''; ", ";
NEXT i
Ralph, using QuickBASIC 4.5 and Windows XP Home Edition and Service Pack 2, with HP LaserJet 4L printer.
Reply
#7
Here's a slightly different approach. Ralph sparked my interest when he said the forced random method bothered him.


This code was written for FB, but I'm hoping that it will run under QB too. I used the -lang QB switch. Wink

Code:
Randomize Timer
Defint A-Z
Const False = 0, True = Not False


Dim Text(1 To 20) As String

For i = Lbound(Text) To Ubound(Text)
    If i<10 Then
        Text(i) = "Slot #0" + Ltrim$(Str$(i))
    Else
        Text(i) = "Slot #" + Ltrim$(Str$(i))
    End If
Next


Dim Slot(Lbound(Text) To Ubound(Text) ) As Integer

For i = Lbound(Slot) To Ubound(Slot)
    Slot(i) = True
Next


For Cnt = Lbound(Text) To Ubound(Text)
    
    i = Lbound(Text) + Int(Rnd * (Ubound(Text) - Lbound(Text)))
    
    Do
        GotSlot = False
        If Slot(i) Then
            Slot(i) =  False
            Print Text(i)
            GotSlot = True
        Else
            i = i + 1
            If i>Ubound(Text) Then i = Lbound(Text)
        End If
    Loop Until GotSlot
    
Next

Sleep
Reply
#8
Dr_:

Hats off to your lightning-fast program execution. Mine takes a while to run, probably due to my crude, bubble-sort algorithm.

I was able to understand all your code, except the DO-LOOP. There, I got confused :oops:
Ralph, using QuickBASIC 4.5 and Windows XP Home Edition and Service Pack 2, with HP LaserJet 4L printer.
Reply
#9
Well, first it picks an integer within bounds at random. Then, it falls into that do...loop.

If Slot(i) = True, then this number hasn't been chosen yet, so it sets Slot(i) to False, sets the GotSlot flag to True and prints out the contents od Text(i).

Otherwise, it increments i, instead of choosing another random number. Just add an out-of-bounds check to i, and it will loop through until it actually finds the first instance of Slot() that isn't False.
Reply
#10
Very ingenius, Dr_D, but a little too convulated for me. I can sort of follow it, but my simplistic mind could never have come up with that DO-LOOP.
Ralph, using QuickBASIC 4.5 and Windows XP Home Edition and Service Pack 2, with HP LaserJet 4L printer.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)