BBC BASIC
« Lottery numbers & non repeating values tool »

Welcome Guest. Please Login or Register.
Sep 24th, 2017, 01:28am


Cross-platform BBC BASIC (Win32, Linux x86, Android, Mac OS-X, Raspberry Pi)

« Previous Topic | Next Topic »
Pages: 1  Notify Send Topic Print
 thread  Author  Topic: Lottery numbers & non repeating values tool  (Read 527 times)
michaelgallup
Guest
smiley Lottery numbers & non repeating values tool
« Thread started on: Mar 28th, 2016, 08:42am »

This is the Canadian LOTTO MAX.. there are 7 numbers out of 49 that you must pick.

This program should be up to everyones standards.
1) no use of GOTO or GOSUB
2) no ancient coding ways.
3) it was built from the ground up
4) it has key detection so you can roll for more numbers
5) it has a tool that prevents repeating values ( this took a lot of testing)

( I hope you like the tool that checks for repeating values. It may be useful for other things)

Please let me know if there is any improvements I should make with my coding.


Thankyou.
Code:
      DIM x%(7)
      CLS:PROC_newnumbers
      REPEAT
        key$=""
        key$ =INKEY$(1)
        IF LEN(key$) = 1 THEN
          IF key$="r" OR key$="R" THEN PROC_newnumbers
        ENDIF
      UNTIL key$="q" OR key$="Q"
      PRINT "done"
      END
      DEF PROC_newnumbers
      CLS
      PRINT "Here is 7 numbers for Lotto Max"
      REPEAT
        FOR t=1 TO 7
          x%(t)=RND(49)
        NEXT t
        PROC_comparray(7)
      UNTIL cond$="cleared"
      FOR t=1 TO 7
        PRINT x%(t)
      NEXT t
      PRINT "Press R or r for more numbers or Press Q or q to quit"
      ENDPROC
      DEF PROC_comparray(n)
      cond$="cleared"
      nex=1
      FOR cou=1 TO n
        FOR co=nex TO n
          IF cou<>co THEN IF x%(cou)=x%(co) THEN cond$="duplicate"
        NEXT co
        nex=nex+1
      NEXT cou
      ENDPROC
 

« Last Edit: Mar 29th, 2016, 06:11am by michaelgallup » User IP Logged

Richard Russell
Administrator
ImageImageImageImageImage


member is offline

Avatar




Homepage PM


Posts: 587
smiley Re: Lottery numbers & non repeating values tool
« Reply #1 on: Mar 29th, 2016, 10:18am »

on Mar 28th, 2016, 08:42am, michael gallup wrote:
Please let me know if there is any improvements I should make with my coding.

Since you asked I'm afraid that there are several things that could be improved.

The most fundamental problem is that you have failed to adhere to the concept of information hiding which is so important in modern computing (and crucial for a general-purpose routine that might go into a library). Here are some examples in PROC_comparray():
  1. The array itself is global, forcing the user to give it a specific name x%(). And what if he wants to check two or more different arrays?!

  2. The result is passed back in a global cond$. This is bad practice (reminiscent of an old-fashioned GOSUB). Since the routine returns a single Boolean result (either the array has duplicates or it doesn't) a function would be a better choice than a procedure here.

  3. The temporary variables used within the routine (nex, cou and co) are globals and could therefore corrupt a variable of the same name used elsewhere in the program!
Another, unrelated, problem is that your routine assumes that the array indices start from 1, but what if the user wants to check duplicates in an array that starts at index 0?

I wonder if you ran the Cross Reference utility on your program, since this would have drawn attention to some of these issues (but you mustn't rely on it to do so).

As an example of how it could be improved, here is a re-written version:

Code:
      DEF FN_checkduplicates(x%(), i%, n%)
      LOCAL C%,I%,J%
      IF n% <= i% THEN = FALSE
      FOR I% = i% TO n%-1
        FOR J% = i%+1 TO n%
          IF x%(I%) = x%(J%) THEN C% = TRUE
        NEXT
      NEXT
      = C% 

Take note of these salient points:
  • A function is used rather than a procedure.

  • The function returns a Boolean result FALSE or TRUE.

  • The array to be checked is passed as a parameter.

  • Both the starting and ending indices are passed as parameters.

  • The variables used within the function are declared as LOCAL.

  • Static integer variables are used where possible for speed and to reduce memory use.
If you are greatly concerned about performance, the function could bail out early as soon as a duplicate is found:

Code:
      DEF FN_checkduplicates(x%(), i%, n%)
      LOCAL C%,I%,J%
      IF n% <= i% THEN = FALSE
      FOR I% = i% TO n%-1
        FOR J% = i%+1 TO n%
          IF x%(I%) = x%(J%) THEN C% = TRUE : EXIT FOR I%
        NEXT
      NEXT
      = C% 

Even faster would be to do this, but some people don't like to see multiple exit points from a function:

Code:
      DEF FN_checkduplicates(x%(), i%, n%)
      LOCAL I%,J%
      IF n% <= i% THEN = FALSE
      FOR I% = i% TO n%-1
        FOR J% = i%+1 TO n%
          IF x%(I%) = x%(J%) THEN = TRUE
        NEXT
      NEXT
      = FALSE 

Richard.

« Last Edit: Mar 29th, 2016, 10:30am by Richard Russell » User IP Logged

michaelgallup
Guest
smiley Re: Lottery numbers & non repeating values tool
« Reply #2 on: Mar 29th, 2016, 11:06am »

Thanks.. I will study function use and implement them into my future programs.
User IP Logged

PatrickM
New Member
Image


member is offline

Avatar




PM


Posts: 12
smiley Re: Lottery numbers & non repeating values tool
« Reply #3 on: Apr 10th, 2017, 3:38pm »

Quote:
Even faster would be to do this, but some people don't like to see multiple exit points from a function:

Code:
      DEF FN_checkduplicates(x%(), i%, n%)
      LOCAL I%,J%
      IF n% <= i% THEN = FALSE
      FOR I% = i% TO n%-1
        FOR J% = i%+1 TO n%
          IF x%(I%) = x%(J%) THEN = TRUE
        NEXT
      NEXT
      = FALSE 
 



This surprised me, I didn't know you could do that - I thought it would result in a 'Too many FORs' error, but now that I've tested it I see that would only be a problem on the BBC Micro and (I assume) other older versions of BBC Basic.
User IP Logged

Richard Russell
Administrator
ImageImageImageImageImage


member is offline

Avatar




Homepage PM


Posts: 587
smiley Re: Lottery numbers & non repeating values tool
« Reply #4 on: Apr 10th, 2017, 4:10pm »

on Apr 10th, 2017, 3:38pm, PatrickM wrote:
I didn't know you could do that - I thought it would result in a 'Too many FORs' error...

Possibly, but if so I think that behaviour is unique to the 6502 versions of BBC BASIC. As far as I know every other version, including later ones from the Acorn stable (e.g. ARM BASIC V), all of mine (including the 8-bit Z80 version) and Brandy allow you to abort from inside a FOR...NEXT - or any other variety of loop - like that.

Nevertheless EXIT FOR etc. (available in BB4W and BBCSDL) is generally preferable. Its omission from earlier versions of BBC BASIC is one of the few significant limitations of the language, in my opinion. It's understandable that it wasn't in the 8-bit versions but with hindsight it should have been added at the same time as WHILE...ENDWHILE and multi-line IF...ENDIF.

Richard.
User IP Logged

MarsFS
New Member
Image


member is offline

Avatar




PM

Gender: Male
Posts: 9
smiley Re: Lottery numbers & non repeating values tool
« Reply #5 on: Sep 1st, 2017, 04:39am »

Here's another example of how it might be done using less loops and reduced redundant comparisons. The check for dupes FN gets called before assigning a new number to the array and printing is included in the main loop. Variables have been added to allow a different amount of numbers and number range.

Another nice addition would be to sort the numbers before printing.
Code:
      REM Lotto number generator

      max%=49
      nums%=7

      DIM x%(nums%-1)

      REPEAT
        PROC_newnumbers
        key$ =GET$
      UNTIL key$="q" OR key$="Q"
      PRINT "Done"
      END

      DEF PROC_newnumbers
      LOCAL t,n

      CLS
      PRINT "Here is ";STR$(nums%);" numbers for Lotto Max:": PRINT

      FOR t=0 TO nums%-1
        REPEAT
          n=RND(max%)
        UNTIL FNnodupes(n,t-1)
        x%(t)=n
        PRINT STR$(n);"  ";
      NEXT t

      PRINT: PRINT
      PRINT "Press any key for more numbers, Press 'Q' to quit"
      ENDPROC

      DEF FNnodupes(n,c)
      LOCAL t

      IF c>-1 THEN
        FOR t=0 TO c
          IF n=x%(t) =FALSE
        NEXT
      ENDIF
      =TRUE
 
User IP Logged

Leo
New Member
Image


member is offline

Avatar




PM


Posts: 10
smiley Re: Lottery numbers & non repeating values tool
« Reply #6 on: Sep 1st, 2017, 5:19pm »

Here's a very simple version which does multiple lines and outputs numbers in order (without sorting).
Code:
      REM Simple Lottery. Multiple lines, output ordered.
      NMAX%=49
      LMAX%=7

      DIM N&(NMAX%)
      @%=&02

      INPUT "How many lines", J%
      FOR I%=1 TO J%
        PROC_Line
      NEXT

      END

      REM Create and print a lottery line
      DEF PROC_Line
      LOCAL c%, i%, x%
      N&()=0

      REPEAT
        x% = RND(NMAX%)
        IF N&(x%) = 0 THEN
          N&(x%) = x%
          c% += 1
        ENDIF
      UNTIL c% = LMAX%

      FOR i%=1 TO 49
        IF N&(i%) THEN PRINT " " i%,;
      NEXT
      PRINT
      ENDPROC
 
« Last Edit: Sep 1st, 2017, 7:08pm by Leo » User IP Logged

Richard Russell
Administrator
ImageImageImageImageImage


member is offline

Avatar




Homepage PM


Posts: 587
smiley Re: Lottery numbers & non repeating values tool
« Reply #7 on: Sep 1st, 2017, 8:35pm »

on Sep 1st, 2017, 5:19pm, Leo wrote:
Here's a very simple version which does multiple lines and outputs numbers in order (without sorting).

Personally I dislike and distrust all solutions that rely on repeatedly choosing a 'random' number until it's not one of a previously chosen set (or repeatedly choosing a set of numbers until some condition is met).

I dislike it because the execution time is not predictable. Suppose one was using that technique to draw 52 cards from a pack; the last card drawn is already known (it's the only one left) but a 'repeat RND(52) until not already chosen' loop might have to repeat dozens or hundreds of times before that unique number is selected. Theoretically it could take an indefinitely long time.

I distrust it because it is not obvious 'by inspection' that the method is statistically sound. It probably is, but as I'm not a mathematician I can't be confident that it really is resulting in an unbiased selection (to the degree that the pseudo-random number generator allows, at least).

So I would always prefer a method that has a predictable execution time and guaranteed statistics, such as a well understood and documented shuffling algorithm (e.g. the Fisher-Yates or Knuth shuffle).

Richard.
« Last Edit: Sep 1st, 2017, 8:44pm by Richard Russell » User IP Logged

MarsFS
New Member
Image


member is offline

Avatar




PM

Gender: Male
Posts: 9
smiley Re: Lottery numbers & non repeating values tool
« Reply #8 on: Sep 1st, 2017, 10:20pm »

Here's another version using a knuth shuffle with multiple lines and sorted and formatted output:
Code:
      REM Lotto number generator

      max%=49
      nums%=7

      DIM allNumbers(max%)
      DIM sorted(max%)

      REM Creat a fresh set of numbers
      FOR T%=1 TO max%
        allNumbers(T%)=T%
      NEXT

      REPEAT
        PROC_newnumbers
        key$ =GET$
      UNTIL key$="q" OR key$="Q"
      PRINT "Done"
      END

      DEF PROC_newnumbers
      LOCAL T%,N%,C%,J%,A$

      CLS
      PRINT "Lotto Number Picker"
      PRINT "-------------------"

      INPUT "How many lines (1-18): ", J%
      IF J%<2 OR J%>18 THEN
        J%=1
        A$="is 1 line"
      ELSE
        A$="are "+STR$(J%)+" lines"
      ENDIF

      CLS
      PRINT "Here ";A$;" of ";STR$(nums%);" numbers for Lotto Max:": PRINT

      FOR C%=1 TO J%
        REM randomly shuffle the numbers
        FOR T% = max% TO 2 STEP -1
          SWAP allNumbers(T%),allNumbers(RND(T%))
          sorted(T%)=0
        NEXT
        sorted(1)=0

        REM choose a random set and sort
        N%=RND(max%-nums%+1)
        FOR T%=N% TO N%+nums%-1
          sorted(allNumbers(T%))=allNumbers(T%)
        NEXT

        REM print sorted list
        PRINT "Line ";RIGHT$("0"+STR$(C%),2);":   ";
        FOR T%=1 TO max%
          IF sorted(T%) PRINT RIGHT$(" "+STR$(sorted(T%)),2);"  ";
        NEXT

        PRINT
      NEXT
      PRINT:PRINT "Press any key for more numbers, Press 'Q' to quit"
      ENDPROC

 

User IP Logged

Richard Russell
Administrator
ImageImageImageImageImage


member is offline

Avatar




Homepage PM


Posts: 587
smiley Re: Lottery numbers & non repeating values tool
« Reply #9 on: Sep 2nd, 2017, 11:15am »

on Sep 1st, 2017, 10:20pm, MarsFS wrote:
Here's another version using a knuth shuffle with multiple lines and sorted and formatted output

Nice, and works without modification on both BB4W and BBCSDL!

For my own interest I ran some tests on how many calls to RND(52) might be necessary before a specific unique number is returned. The answer seemed to be that needing to call it more than 900 times is not that unlikely (the highest I saw was 996)! Obviously typically it will be fewer, but it illustrates the uncertainty in execution time that can arise from using that technique.

Richard.
User IP Logged

Leo
New Member
Image


member is offline

Avatar




PM


Posts: 10
smiley Re: Lottery numbers & non repeating values tool
« Reply #10 on: Sep 2nd, 2017, 4:00pm »

Although I can't disagree with the logic behind "run time is unpredictable" - the lottery case here is a complete frippery. It's just a "throwaway" toy.
Of course I wouldn't use the technique I did for anything approaching any seriousness but I stand by my choice for the lottery case because..

a) It's a complete frippery.
b) The program is very short.
c) We're only selecting ANY 7 numbers from 49 so there's no chance of this taking forever.
d) The quality of the random numbers is irrelevant because any 7 will have an equal chance of winning.

I also ran some trials (a lot).
The maximum number of lookup clashes in any single line was 6 - sounds a lot.
However, in creating 10000 lottery lines a repeat lookup was necessary in 6.7% of cases - no problem.

Henceforward I will use the dates of my children's birthdays to derive (winning) lottery lines. grin
User IP Logged

Richard Russell
Administrator
ImageImageImageImageImage


member is offline

Avatar




Homepage PM


Posts: 587
smiley Re: Lottery numbers & non repeating values tool
« Reply #11 on: Sep 2nd, 2017, 4:43pm »

on Sep 2nd, 2017, 4:00pm, Leo wrote:
I stand by my choice for the lottery case because...

That's fine, with those qualifications. The trouble is that people may adapt the code for other applications without appreciating its limitations (for example they may come upon it years later as the result of a search).

My experience is that there is widespread misunderstanding about pseudo-random numbers and statistics, and although it's unlikely that anybody would use BBC BASIC for an online casino program, or something like that, it's not impossible.

Several years ago I wrote this article at the Wiki to draw attention to some of the pitfalls. It includes simple lottery draw and card shuffling programs. It's out of date to the extent that BBC BASIC no longer uses the value of TIME as a seed.

Richard.
« Last Edit: Sep 2nd, 2017, 4:52pm by Richard Russell » User IP Logged

Leo
New Member
Image


member is offline

Avatar




PM


Posts: 10
smiley Re: Lottery numbers & non repeating values tool
« Reply #12 on: Sep 2nd, 2017, 9:00pm »

Thanks for that link Richard - very good article.
Although I'm gradually working my way through the info in the wiki, I admit I haven't read that one before. Everybody who uses BB4W should go and rummage through the wiki - there's so much excellent information in there.

I use CryptGenrandom a lot for 'professional' use. I think I posted something here that used it a short time ago - but I don't remember what right now. (My memory ain't what it used to be).

Thanks again for the info.
User IP Logged

Pages: 1  Notify Send Topic Print
« Previous Topic | Next Topic »

Donate $6.99 for 50,000 Ad-Free Pageviews!


This forum powered for FREE by Conforums ©
Sign up for your own Free Message Board today!
Terms of Service | Privacy Policy | Conforums Support | Parental Controls