The QBasic Forum      Other Subforums, Links and Downloads
 Return to Index  

Improved version of Random Select & Discard algorithm

March 23 2008 at 4:23 PM
Solitaire  (Login Solitaire1)
 - 
from IP address 24.90.213.75


Response to Select & discard algorithm for unique random numbers

Instead of printing each selected number as it comes up and discarding it, this version saves the number to the end of the array, which is not used in the next repeat as the range is decremented. When the range gets down to zero, the random selected numbers are now in the array in the reverse order they were selected. This order can then be printed out all at once in another FOR loop. I also improved the user interface.


===================================================================
'Set of unique random numbers in a range without duplicates
'Simulate pulling number out of a hat; remove selected number from mix
'This version saves selected numbers to end of array in random order
'Saved numbers keep moving down as range is diminished with each repeat
DIM range AS INTEGER, ran AS INTEGER, x AS INTEGER, selnum AS INTEGER
DIM index AS INTEGER, rng AS STRING, ans AS STRING
DIM man AS STRING, many AS INTEGER
RANDOMIZE TIMER
DO
    CLS
    PRINT "Press any key to repeat, Tab for a new range; Esc to quit..."
    PRINT : INPUT ; "Enter a range up to 22:  ", rng$
    ran = CINT(VAL(rng$))
    IF ran > 20 THEN ran = 22 : LOCATE , 26 : PRINT "22     ";
    IF ran <= 0 THEN ran = 12 : LOCATE , 26 : PRINT "12     ";
    PRINT : INPUT ; "How many selections? ", man$;
    many = CINT(VAL(man$))
    IF many <= 0 OR many > ran THEN many = ran : LOCATE , 22 : PRINT ran; "  ";
    REDIM arry(ran) AS INTEGER
    DO
        range = ran
        FOR x = 1 TO range      'assign sequential values to array
            arry(x) = x
        NEXT x
        DO
            index = INT(RND * range + 1)    'select random index
            selnum = arry(index)            'selected number
            'move array down to overwrite arry(index)
            FOR x = index TO range - 1
                arry(x) = arry(x + 1)
            NEXT x
            arry(range) = selnum    'save selected number to end of array
            range = range - 1       'decrease array range after selection
        LOOP UNTIL range = 0        'no more numbers in hat
        PRINT : PRINT
        FOR x = 1 TO many            'print list of random numbers
            PRINT arry(x);
        NEXT x
        ans$ = INPUT$(1)
    LOOP UNTIL ans$ = CHR$(27) OR ans$ = CHR$(9)
LOOP UNTIL ans$ = CHR$(27)
SYSTEM

====================================================================
Note: This version saves the selected numbers in reverse order of selection, as it adds that number to the end of the current range, which diminishes with each repeat. In order to save selection in same order, you must add number to end of the full array and move the entire array down with each repetition. This would be less efficient than the above version, which requires fewer repetitions as the array diminishes.

To alter the program to use the full array, simply replace these two lines:

FOR x = index TO range - 1

to: FOR x = index TO ran - 1


and

arry(range) = selnum

to: arry(ran) = selnum

However, it really makes no difference in which order the selections are presented, since they are still random and unique.


    
This message has been edited by Solitaire1 from IP address 24.90.213.75 on Mar 26, 2008 7:43 AM
This message has been edited by Solitaire1 from IP address 24.90.213.75 on Mar 24, 2008 7:24 PM
This message has been edited by Solitaire1 from IP address 24.90.213.75 on Mar 24, 2008 7:23 PM
This message has been edited by Solitaire1 from IP address 24.90.213.75 on Mar 24, 2008 7:17 PM
This message has been edited by Solitaire1 from IP address 24.90.213.75 on Mar 24, 2008 6:54 PM
This message has been edited by Solitaire1 from IP address 24.90.213.75 on Mar 23, 2008 4:50 PM
This message has been edited by Solitaire1 from IP address 24.90.213.75 on Mar 23, 2008 4:28 PM


 
 Respond to this message   
Responses