### Author Topic: Random number help  (Read 278 times)

#### rickus

• Full Member
• Posts: 107
##### Random number help
« on: January 07, 2017, 04:11:18 pm »
This may have a simple solution but, alas, it's been a puzzler and it eludes me.

I'm generating a random list of 5 whole numbers, say, between 1 and 100. When the numbers are generated, I do not want any of the numbers to be within -5 or +5 of any other number. For example, if the number 45 is generated there should not be any other number generated between 39 and 51, as though I am creating a numeric buffer around each randomly-generated number. Maybe the solution is so simple that I can't get it! Thanks!

#### SkyCharger001

• Hero Member
• Posts: 2292
##### Re: Random number help
« Reply #1 on: January 07, 2017, 07:02:29 pm »
A. a simple solution:
split the range into separate blocks and pick something from between the 1/4th and the 3/4th of each

B. a bit more involved solution (effectively throws away candidates that have become ineligible) :
Code: [Select]
`DIM t(99) AS INTEGERDIM r(5) AS INTEGERCONST mindev = 12FOR p = 0 TO 99    t(p) = p + 1NEXT pz = 100FOR x = 0 TO 4    a = INT(RND * z)    r(x) = t(a)    q = 0    FOR g = a + mindev TO a - mindev STEP -1        IF g >= 0 AND g < z THEN            n = ABS(t(g) - r(x)) 'does it count as less            IF n <= mindev THEN 'than mindev deviation?                q = q + 1                FOR p = g TO z - 2                    SWAP t(p), t(p + 1)                NEXT p            END IF        END IF    NEXT g    PRINT r(x)    z = z - qNEXT x`discovered and fixed a minor oversight in what to throw away
« Last Edit: January 07, 2017, 07:24:58 pm by SkyCharger001 »

#### STxAxTIC

• Newbie
• Posts: 17
• Let's just be enemies.
##### Re: Random number help
« Reply #2 on: January 07, 2017, 08:26:28 pm »
You can make things easier by picking a random number between 0 and 20 and then multiplying by 5. That'll prolly get you what you need, just check (like sky said) that you don't get the same result twice.

(Play with the numbers to taste but consider the idea conveyed.)

#### Pete

• Hero Member
• Posts: 7167
• Cuz I sez so varmint!
##### Re: Random number help
« Reply #3 on: January 08, 2017, 12:52:24 am »
You can make things easier by picking a random number between 0 and 20 and then multiplying by 5. That'll prolly get you what you need, just check (like sky said) that you don't get the same result twice.

(Play with the numbers to taste but consider the idea conveyed.)

Argh. Never send a theoretical physicist to do a real physicist's job.

Code: [Select]
`RANDOMIZE TIMERDIM x%(100)DO    x% = INT(RND * 100) + 1 ' Number range 1 to 100    IF x%(x%) = 0 THEN        FOR i% = -5 TO 5            IF x% + i% >= 0 AND x% + i% <= 100 THEN x%(x% + i%) = -1        NEXT        PRINT x%;        FOR i% = 1 TO 100            IF x%(i%) = 0 THEN EXIT FOR        NEXT        IF i% > 100 THEN EXIT DO    END IFLOOP`
Give a man a program, and he does one thing for a day. Teach a man to program, and he does one thing for a lifetime.

#### waltersmind

• QB64 Partner Site Owner
• Hero Member
• Posts: 565
• TheJoyfulProgrammer.com
##### Re: Random number help
« Reply #4 on: January 08, 2017, 03:07:02 am »
rickus,

Here is a demo that I personally belive gives you exactly what you are wanting, plus some.

With the following demo, you define at the top the minimum number wanted, the maximum number wanted, how many numbers you want found (by sizing the RndNumbers array to how ever many you want), and the size of the margin you want. Please note, the margin definition is for one side (where you two sides to make your buffer - see the code for details).

Then the rest of the code takes care of everything.

If you set the min to max distance to close to each other, the demo we adjust the number of numbers it will provide you at the end. For example, if you set the min value to 1 and the max value to 5, then run it, the demo will only return one number.

This demo does use a little brute force, but I believe it is cut down to a bare minimum.

With no further ado, here is the code:

Code: [Select]
`CONST MinNumber = 1CONST MaxNumber = 100CONST Margin = 5 '  DEFINED AS ONE-SIDEDDIM RndNumbers(5) AS LONGDIM Index AS INTEGERDIM InSideANumMargin AS _BYTEDIM NotInRangeCount AS LONGIndex = LBOUND(RndNumbers)SCREEN _NEWIMAGE(600, 800, 32)T% = TIMERRANDOMIZE T%PRINT "T%: "; T%'  GET INTEGER NUMBERSDO    RndNumbers(Index) = RND * (ABS(MaxNumber) - ABS(MinNumber)) + 1    InSideANumMargin = 0    '  IT'S NOT THE FIRST SO LET'S LOOP FROM THE FIRST ARRAY INDEX TO THE ONE BEFORE THE CURRENT INDEX    '  TO MAKE SURE THE CURRENT ARRAY VALUE ISN'T WITHIN THE MARGINS OF THE OTHERS    FOR i = LBOUND(RndNumbers) TO Index - 1        IF RndNumbers(Index) >= (RndNumbers(i) - Margin) AND RndNumbers(Index) <= (RndNumbers(i) + Margin) THEN            InSideANumMargin = 1        END IF    NEXT    IF InSideANumMargin = 0 THEN        Index = Index + 1    END IF    '  MAKE SURE THIS ISN'T THE FIRST ARRAY INDEX OR THE LAST. IF SO, SKIP IT.    IF (Index - 1) >= LBOUND(RndNumbers) AND Index <= UBOUND(RndNumbers) THEN        '  DEFINE THE CurrentIndex TO THE MINIMUM NUMBER        CurrentIndex = MinNumber        DO            '  RESET SOME VALUES            MatchesAvailable = 0            NotInRangeCount = 0            '  SEARCH THROUGH ALL ARRAY VALUES TO SEE IF CurrentIndex IS WITHIN THEIR MARGINS            FOR I2 = LBOUND(rndnumbers) TO Index - 1                '  CHECK TO SEE IF CurrentIndex IS WITHIN THE MARGINS OF THE CURRENT ARRAY VALUE                IF CurrentIndex < (RndNumbers(I2) - Margin) OR CurrentIndex > (RndNumbers(I2) + Margin) THEN                    '  INCREMENT NOT-IN-RANGE-COUNT IF CurrentIndex IS OUTSIDE OF CURRENT ARRAY VALUE'S MARGINS                    NotInRangeCount = NotInRangeCount + 1                END IF            NEXT            '  CHECK TO SEE IF CurrentIndex IS NOT IN RANGE OF ANY OF THE VALUES IN THE ARRAY.            '  FOR THIS TO BE TRUE, THE NotInRangeCount MUST EQUAL THE NUMBER ARRAY VALUES DEFINED.            '  IF CurrentIndex IS FOUND TO BE INSIDE ANY OF THE DEFINED ARRAY VALUE MARGINS, THEN            '  THE CURRENT INDEX IS NOT USABLE.            IF NotInRangeCount = (Index - LBOUND(rndnumbers)) THEN                '  WE HAVE A MATACH TO AN OPEN INDEX SLOT                MatchesAvailable = 1                '  LEAVE THIS LOOP                EXIT DO            END IF            '  IF WE MADE IT HERE, THEN WE NEED INCREMENT THE CurrentIndex            CurrentIndex = CurrentIndex + 1            '  IF THE CurrentIndex IS LESS THAN THE MAXNUMBER, CONTINUE THE LOOP UNTIL THE END        LOOP WHILE CurrentIndex <= MaxNumber        '  WE NEED TO CHECK TO SEE IF WE HAVE SCANNED THE ENTIRE SPECTRUM        IF MatchesAvailable = 0 THEN            '  AT THIS POINT, THERE ARE NO MORE POSSIBLE MATCHES, SO THERE IS NO NEED TO CONTINUE ON.            Index = Index - 1            EXIT DO        END IF    END IFLOOP WHILE Index <= UBOUND(rndnumbers)PRINTIF Index > UBOUND(rndnumbers) THEN Index = UBOUND(rndnumbers)'  DISPLAY ALL THE NUMBERS WE WERE ABLE TO FIND WITHIN GIVEN RANGE WITH GIVEN MARGINSIF Index = UBOUND(rndnumbers) THEN    PRINT "ALL "; (UBOUND(rndnumbers) + 1); " ARRAY INDEX'S HAVE BEEN DEFINED!"ELSE    PRINT "ONLY "; (Index + 1); " OUT OF "; (UBOUND(rndnumbers) + 1); " ARRAY INDEX'S WERE DEFINED!"END IFPRINTFOR i = LBOUND(rndnumbers) TO Index    PRINT "RndNumbers("; i; "): "; RndNumbers(i)NEXT_DISPLAY`

Let me know close this is to what you are wanting.

Happy Coding!

Walter Whitman
The Joyful Programmer
www.TheJoyfulProgrammer.com
www.TheJoyfulProgrammer.com/qb64/forum/

#### rickus

• Full Member
• Posts: 107
##### Re: Random number help
« Reply #5 on: January 08, 2017, 01:09:26 pm »
Thanks, coders, for the different examples that achieve the solution. I'll need to dissect each one and see how they work. -rickus

#### TempodiBasic

• Sr. Member
• Posts: 389
##### Re: Random number help
« Reply #6 on: January 11, 2017, 05:21:58 pm »
Hi Rickus

1. if we must generate at random 5 integer with a positive value  between 1 and 100 and no common value in the range n-5 and n+5 we use 11 numbers, so in 100 numbers it is possible to generate 100/11   numbers with that feature, but to preserve range around each number  we must generate a number from 6 to 94,

2.  it seems that math calculation 's result is  strange  in fact if 45 is the first number then 45-5 = 40 and not 39, 45+5 = 50 and not 51!

So
flowchart:
randomize timer
choose number
add to list of number used

See again
FOR eachProblem% = 1 TO Max%
IF NOT solution%(EachProblem%) THEN
goto Solved
ELSE
PRINT "Solution in coming"
END IF
NEXT
Solved:
PRINT "Smile!"

#### SMcNeill

• Moderator
• Hero Member
• Posts: 5796
##### Re: Random number help
« Reply #7 on: January 11, 2017, 08:38:26 pm »
For this, I'd just set an array of answers and then shuffle it.

Dim Result(20)
For I = 1 TO 20
Result(I) = 5 * I
NEXT

FOR J = 1 to 5 'only need 5 numbers, no need to swap the rest
SWAP Result(J), Result(INT(RND * 20) + 1)
NEXT

FOR I = 1 TO 5
PRINT Result(I)
NEXT

********************

You've got such a small dataset here, I think simply assigning the possible values to an array and then shuffling it once would be the most efficient method to be certain you got unique results suitable to your needs.
http://bit.ly/TextImage -- Library of QB64 code to manipulate text and images, as a BM library.

http://bit.ly/Color32 -- A set of color CONST for use in 32 bit mode, as a BI library.

#### Pete

• Hero Member
• Posts: 7167
• Cuz I sez so varmint!
##### Re: Random number help
« Reply #8 on: January 11, 2017, 08:54:32 pm »
Well you're wrong, but it's nice to see you back. Hope the X-mas trees sold like hotcakes this year!

To clarify, you and Bill only have solutions that work in multiples of 5. Your code works fine for that but numbers other than multiples of 5 can have a lower and upper bounds of 5 between them. Run my example to see what I mean. Of course maybe I misunderstood what the OP wanted. One of us did.

Clippy's furry friend: http://www.network54.com/Forum/183705/message/1483222907

Pete
Give a man a program, and he does one thing for a day. Teach a man to program, and he does one thing for a lifetime.

#### rickus

• Full Member
• Posts: 107
##### Re: Random number help
« Reply #9 on: January 11, 2017, 08:59:42 pm »
No, Pete, you were right on the money about what I was trying to create. Steve's solution looks like what STxAxTIC (above) had proposed. I find it fascinating that, in coding, there are so many ways to achieve a desired result. Thanks again, all.

#### SMcNeill

• Moderator
• Hero Member
• Posts: 5796
##### Re: Random number help
« Reply #10 on: January 11, 2017, 09:05:09 pm »
Aye, I read the problem wrong.  I still think simply creating a list (array) and making use of it is the simplest solution.

Code: [Select]
`DEFLNG A-ZDIM SHARED Results(1 TO 5)RANDOMIZE TIMERFOR c = 1 TO 20    GenerateNumbers    FOR i = 1 TO 5: PRINT Results(i),: NEXT 'Remember to read our result from left to right for each 5 numbers in our answer set    PRINTNEXTSUB GenerateNumbers    DIM L(1 TO 100): LC = 100 'initialize list of possible numbers, set original list count to 100    TC = 0 'temporary counter to be updated as we check the list for valid possible answers    FOR i = 1 TO 100: L(i) = i: NEXT 'create the initial list    FOR i = 1 TO 5 'do a loop 5 times to get the 5 values we want        Results(i) = L(INT(RND * LC) + 1) 'Get the result from our list        TC = 0 'Reset the temp list counter        FOR j = 1 TO LC 'Check all the values in our current list            IF L(j) <= Results(i) - 5 OR L(j) >= Results(i) + 5 THEN 'if the values in our list are still valid                TC = TC + 1                L(TC) = L(j) 'keep them in the new list            ELSE                'Else we don't add the invalid answers back to the update list of possible answers            END IF        NEXT        LC = TC 'our list of possible answers is now narrowed down from what it was before it ONLY the values that are still valid for our purposes    NEXTEND SUB`
For the above, we start with a list of 100 possible values (1 to 100).
Then we get a random number from that list.
A quick check of the list and we remove all values that no longer fit our criteria.
And we get the next answer.
Repeat and Rinse a few more times...

Easiest way I can think to do as was originally suggested.
http://bit.ly/TextImage -- Library of QB64 code to manipulate text and images, as a BM library.

http://bit.ly/Color32 -- A set of color CONST for use in 32 bit mode, as a BI library.

#### waltersmind

• QB64 Partner Site Owner
• Hero Member
• Posts: 565
• TheJoyfulProgrammer.com
##### Re: Random number help
« Reply #11 on: January 12, 2017, 10:10:42 am »
Has anyone looked at the code I provided? It does exactly what he wants plus some. If rickus decided to change the upper value to a lower number, say 10, my code provides the total number of choices it finds, which could be between 1 to 2 depending on the what the RND function returns. My demo also checks to see if there are any other possible values available through brute force, but only looks for the first available number if there is one.

You can adjust the marginal space wanted, the upper and lower bounds to search for, and it stores the numbers in array. To change the amount of numbers to return, all you need to do is change the array size. The code is heavily commented as well, so you can understand what I am doing

Please have a look at my demo and see if it is what you wanted. Oh, it has been heavily tested as well.

Steve, welcome back! I missed you being around.

Happy Coding!

Walter Whitman
The Joyful Programmer
www.TheJoyfulProgrammer.com
www.TheJoyfulProgrammer.com/qb64/forum/

#### SkyCharger001

• Hero Member
• Posts: 2292
##### Re: Random number help
« Reply #12 on: January 12, 2017, 10:15:09 am »
SMcNeill: That's basically the same as my B. suggestion, but I believe that mine is a bit more efficient.
For example: Your version seems to check the entire array list for the new count, mine merely subtracts the positions that have become ineligible from the count of the previous iteration. (can save a few cycles)

#### Pete

• Hero Member
• Posts: 7167
• Cuz I sez so varmint!
##### Re: Random number help
« Reply #13 on: January 12, 2017, 10:17:00 am »
My code's better than your code
My code's better than yours
My code's better 'cause I say it's better 'cause
My codes better than yours

Pete

Give a man a program, and he does one thing for a day. Teach a man to program, and he does one thing for a lifetime.

#### waltersmind

• QB64 Partner Site Owner
• Hero Member
• Posts: 565
• TheJoyfulProgrammer.com
##### Re: Random number help
« Reply #14 on: January 12, 2017, 12:31:54 pm »
I am by no means stating that my version is better than anyone else's, but I would like to get a little feedback on it. At this point, no one has commented on my project.

I spent several hours on it coming up with the algorithm, coding it, and thoroughly testing it.

Happy Coding!

Walter Whitman
The Joyful Programmer
www.TheJoyfulProgrammer.com
www.TheJoyfulProgrammer.com/qb64/forum/