Author Topic: [challenge] A25 : Lottery draw numbers within range  (Read 1386 times)

0 Members and 1 Guest are viewing this topic.

JohnK

  • Administrator
  • Seagull
  • Posts: 10140
[challenge] A25 : Lottery draw numbers within range
« on: February 14, 2022, 08:34:07 AM »
Using only AutoLisp, draw 7 numbers within range ([floor] [ceiling])

Example:
(lotto 2 50)
> (23 7 6 49 14 3 33)
TheSwamp.org (serving the CAD community since 2003)

Donate to TheSwamp.org

dexus

  • Newt
  • Posts: 75
Re: [challenge] A25 : Lottery draw numbers within range
« Reply #1 on: February 14, 2022, 08:55:56 AM »
So, do these numbers have to be random, or can I do something like this :-P
Code - Auto/Visual Lisp: [Select]
  1. (defun lotto (mini maxi / ret)
  2.   (repeat 7
  3.     (setq ret (cons mini ret)
  4.           mini (1+ mini))
  5.   )
  6.   (reverse ret)
  7. )

Code: [Select]
(lotto 2 50)
> (2 3 4 5 6 7 8)

JohnK

  • Administrator
  • Seagull
  • Posts: 10140
Re: [challenge] A25 : Lottery draw numbers within range
« Reply #2 on: February 14, 2022, 09:00:32 AM »
Is that what you call a "first-come-first-win" lottery?! HAHA

Yes, random.
TheSwamp.org (serving the CAD community since 2003)

Donate to TheSwamp.org

kirby

  • Newt
  • Posts: 110
Re: [challenge] A25 : Lottery draw numbers within range
« Reply #3 on: February 14, 2022, 09:06:56 AM »
Cheating by using two library routines...

Code - Auto/Visual Lisp: [Select]
  1. (defun Lotto-kirby (low high / OutList Num )
  2. ; [challenge] A25 : Lottery draw numbers within range
  3. ; Using only AutoLisp, draw 7 numbers within range ([floor] [ceiling])
  4. ; Input:
  5. ;       low - (integer) lower bound for selection
  6. ;       high - (integer) upper bound for selection
  7. ; Returns:
  8. ;       unsoeted list of 7 numbers (assume these should be unique)
  9. ; Uses custom functions:
  10. ;       randombetween
  11. ; Example:
  12. ;       (lotto 2 50) -> (23 7 6 49 14 3 33)
  13.  
  14. (setq OutList nil)
  15.  
  16. (setq Count 7)  ; this should be an input
  17.  
  18. (setq k 1)
  19.         (setq RanNum (randombetween low high 0))        ; get random number using custom function
  20.  
  21.         (if (not (member RanNum OutList))
  22.                 (setq OutList (cons RanNum OutList))    ; build list with no duplicate values
  23.         )
  24.  
  25.         (if (eq (length OutList) Count)
  26.                 (setq k nil)            ; Stop
  27.         )      
  28. ) ; close while
  29. OutList
  30. )
  31.  
  32.  
  33.  
  34. (defun RandomBetween (MinVal MaxVal RetCode / dummy RVal)
  35. ; Random number with bounds
  36. ; KJM - November 1989
  37. ; Input:
  38. ;       a - minimum value (integer or real)
  39. ;       b - maximum value (integer or real)
  40. ;       RetCode - 0 to return integer, nil or anything else return real
  41. ; Returns:
  42. ;       random number between specified bounds (integer or real as specified by RetCode)
  43. ; Uses custom functions:
  44. ;       random1
  45.  
  46. (if (< MaxVal MinVal)
  47.         (setq dummy MaxVal MaxVal MinVal MinVal dummy)
  48. )      
  49.  
  50. (setq RVal (* (abs (- MaxVal MinVal)) (random1)))
  51.  
  52. (if (eq RetCode 0)
  53.         (setq RVal (+ MinVal (fix RVal)))       ; integer
  54.         (setq RVal (+ MinVal RVal))             ; real
  55. )      
  56. RVal
  57. )
  58.  
  59. (defun Random1 ()
  60. ; Generate random real number between 0.0 and 1.0
  61. ; from 101 LISP Routines (1986)
  62.  
  63.     (if (= ran nil)
  64.       (setq ran (/ pi 0.097))
  65.     )
  66.     (setq ran (* ran 9.5))
  67.     (if (>= ran 1)
  68.       (setq ran (/ ran 10))
  69.     )
  70.     (setq ran (- (* ran 100) (fix (* ran 100))))
  71.     ran
  72. )
  73.  

JohnK

  • Administrator
  • Seagull
  • Posts: 10140
Re: [challenge] A25 : Lottery draw numbers within range
« Reply #4 on: February 14, 2022, 09:18:42 AM »
Now that I think about it. I imagine there will only be a few different random number routines posted for all the different submissions. So we can get creative on the random number generator; generate from the date, generate from a string, generate from a point click, etc., etc..
TheSwamp.org (serving the CAD community since 2003)

Donate to TheSwamp.org

dexus

  • Newt
  • Posts: 75
Re: [challenge] A25 : Lottery draw numbers within range
« Reply #5 on: February 14, 2022, 09:22:17 AM »
Is that what you call a "first-come-first-win" lottery?! HAHA

Yes, random.
It always makes me think of this gem: https://xkcd.com/221/

Here is a version using a random number generator I found on cadforum.cz:
Code - Auto/Visual Lisp: [Select]
  1. (defun lotto (mini maxi / rnd ret diff)
  2.   ; https://www.cadforum.cz/en/qaID.asp?tip=1366
  3.   (defun rnd (/ modulus multiplier increment random)
  4.     (if (not seed)
  5.       (setq seed (getvar "DATE"))
  6.     )
  7.     (setq modulus    65536
  8.           multiplier 25173
  9.           increment  13849
  10.           seed  (rem (+ (* multiplier seed) increment) modulus)
  11.           random     (/ seed modulus)
  12.     )
  13.   )
  14.  
  15.   (setq diff (- maxi mini))
  16.   (repeat 7
  17.     (setq ret (cons (+ mini (fix (* diff (rnd)))) ret))
  18.   )
  19.   (reverse ret)
  20. )

Stefan

  • Bull Frog
  • Posts: 303
Re: [challenge] A25 : Lottery draw numbers within range
« Reply #6 on: February 14, 2022, 10:05:33 AM »
I guess duplicates are not allowed.
Code - Auto/Visual Lisp: [Select]
  1. ;System.Random methods
  2. ;"NextDouble" method - random number from 0 to 1
  3. ;"Next" method - random int from 0 to 2147483647
  4. ;(vlax-invoke rn 'next)
  5. (defun lotto-stef (a b n / l i r rn)
  6.   (setq rn (vlax-get-or-create-object "System.Random"))
  7.   (setq l (range-stef a b))
  8.   (repeat (min n (length l))
  9.     (setq i (nth (rem (vlax-invoke rn 'next) (length l)) l)
  10.           r (cons i r)
  11.           l (remove i l);(vl-remove i l)
  12.     )
  13.   )
  14.   r
  15. )
  16.  
  17. (defun remove (i l)
  18.   (if l
  19.     (if
  20.       (= (car l) i)
  21.       (remove i (cdr l))
  22.       (cons (car l) (remove i (cdr l)))
  23.     )
  24.   )
  25. )
  26.  
  27. (defun range-stef (a b / n i l)
  28.   (setq n (- b a)
  29.         i (/ n (abs n))
  30.         l (list b)
  31.   )
  32.   (while (/= a b)
  33.     (setq b (- b i)
  34.           l (cons b l)
  35.     )
  36.   )
  37. )

Code: [Select]
_$ (lotto-stef 2 59 7)
(43 4 14 8 36 32 11)
_$ (lotto-stef 1 49 6)
(13 40 24 4 33 1)
_$ (lotto-stef 1 5 5)
(3 5 4 1 2)
_$

JohnK

  • Administrator
  • Seagull
  • Posts: 10140
Re: [challenge] A25 : Lottery draw numbers within range
« Reply #7 on: February 14, 2022, 10:15:25 AM »
I'm reworking my random number generator. Be back later.
TheSwamp.org (serving the CAD community since 2003)

Donate to TheSwamp.org

JohnK

  • Administrator
  • Seagull
  • Posts: 10140
Re: [challenge] A25 : Lottery draw numbers within range
« Reply #8 on: February 14, 2022, 10:17:13 AM »
Is that what you call a "first-come-first-win" lottery?! HAHA

Yes, random.
It always makes me think of this gem: https://xkcd.com/221/
...
HAHA!
TheSwamp.org (serving the CAD community since 2003)

Donate to TheSwamp.org

JohnK

  • Administrator
  • Seagull
  • Posts: 10140
Re: [challenge] A25 : Lottery draw numbers within range
« Reply #9 on: February 14, 2022, 10:48:39 AM »
So my random number generator is almost working. currently it returns 0 every time. ...so close.
TheSwamp.org (serving the CAD community since 2003)

Donate to TheSwamp.org

JohnK

  • Administrator
  • Seagull
  • Posts: 10140
Re: [challenge] A25 : Lottery draw numbers within range
« Reply #10 on: February 14, 2022, 11:54:13 AM »
my journal:
Making progress! My RNG is now generating either 11.0182 or 0.1473. 
...
At this point I am just typing random numbers on the keyboard to divide and multiply in my formula.
...
I feel like I'm not as close as I thought I was.
...
Should I "(getvar 'DATE)" again or divide by "2549963478631.0241576" here?
...
TheSwamp.org (serving the CAD community since 2003)

Donate to TheSwamp.org

doaiena

  • Mosquito
  • Posts: 3
Re: [challenge] A25 : Lottery draw numbers within range
« Reply #11 on: February 14, 2022, 05:55:10 PM »
I currently dont have enough time to experiment, but i think its possible to generate a very strong random number through the use of WMI. Current cpu speed, ram usage, disk activity, page file size, random process' memory usage... etc. A combination of all those things would add some unique randomness. The problem is that the number generation would be very slow.

kirby

  • Newt
  • Posts: 110
Re: [challenge] A25 : Lottery draw numbers within range
« Reply #12 on: February 15, 2022, 12:08:50 PM »
Random number generators are a bit of a rabbit hole...or possibly the next challenge

Middle Square method
Code - HTML5: [Select]
  1. https://en.wikipedia.org/wiki/Middle-square_method

Linear Congruent Generator method, including a table of parameters used by different sources.  This seems to be the most common method.
Code - HTML5: [Select]
  1. https://en.wikipedia.org/wiki/Linear_congruential_generator

Rosetta Code examples, with BSD and Microsoft methodologies
Code - HTML5: [Select]
  1. http://www.rosettacode.org/wiki/Linear_congruential_generator

Lee Mac has example LCG method on his site using parameters from 'Numerical Recipes' text.

Example code and test based on Rosetta Code examples.  Two versions, one returning integer between 0 and 2^16 and another returning real between 0.0 and 1.0.
Stats show coefficient of skew = 0.0 for trial on sample of 100 trials.  Close enough for cowboys, but certainly not rigorlously tested!

Code - Auto/Visual Lisp: [Select]
  1. (defun C:TestRandomLCG ( / Count MyList MyVal MyStats)
  2. ; Test function for 'RandomLCG'
  3.  
  4. (setq Count 100)
  5. (setq MyList nil)
  6.  
  7. ; Make a bunch of random numbers
  8. (repeat Count
  9.         ;(setq MyVal (RandomLCG1))              ; Test function 'RandomLCG1' (integer 0 to 2^16)
  10.         (setq MyVal (RandomLCG2))               ; Test function 'RandonLCG2' (real 0.0 to 1.0)
  11.         (prompt "\n  Value = ")(princ MyVal)(princ)
  12.        
  13.         (setq MyList (cons MyVal MyList))
  14. ) ; close repeat
  15.  
  16. ; Get statistics
  17. (setq MyStats (Internal_GetStats MyList nil))
  18.  
  19. ; Report
  20. (prompt "\nStatistics:")
  21. (prompt "  Count = ")(princ (nth 0 MyStats))
  22. (prompt "  Min = ")(princ (nth 1 MyStats))
  23. (prompt "  Max = ")(princ (nth 2 MyStats))
  24. (prompt "  Average = ")(princ (nth 3 MyStats))
  25. (prompt "  St Dev = ")(princ (nth 4 MyStats))
  26. (prompt "  Skew = ")(princ (nth 5 MyStats))
  27. )
  28.  
  29.  
  30. (defun RandomLCG1 ( /
  31.                 MyTime m a c temp1 temp2 temp3 OutVal
  32.                 )
  33. ; Generate random number (integer) using Linear Congruent Generator (LGS) with Microsoft Visual C/C++ parameters
  34. ; Initial seed value = 0
  35. ; Sources:
  36. ;       https://en.wikipedia.org/wiki/Linear_congruential_generator
  37. ;       http://www.rosettacode.org/wiki/Linear_congruential_generator
  38. ; Input:
  39. ;       nothing!
  40. ; Returns:
  41. ;       Random integer 0 and 2^16
  42. ; Uses global variables
  43. ;       #seed
  44.  
  45. (if (not #seed)
  46.         (setq #seed 0)          ; Initialize seed
  47. )
  48.  
  49. (setq m (expt 2.0 31.0))        ; modulus 2^31
  50. (setq a 214013.0)               ; multiplier
  51. (setq c 2531011.0)              ; increment aka constant
  52.  
  53. (setq temp1 (+ (* a #seed) c))
  54. (setq temp2 (/ temp1 m))
  55. (setq temp3 (fix temp2))
  56.  
  57. ; Make new seed for next time (global)
  58. (setq #seed (- temp1 (* m temp3)))
  59.  
  60. ; Convert to integer between 0 and 2^16
  61. (setq OutVal (fix (/ #seed (expt 2.0 16.0))))
  62. OutVal
  63. )
  64.  
  65.  
  66.  
  67.  
  68. (defun RandomLCG2 ( /
  69.                 MyTime temp m a c temp1 temp2 temp3 OutVal
  70.                 )
  71. ; Generate random real number between 0.0 and 1.0 using Linear Congruent Generator (LGS)
  72. ; based on Microsoft Visual C/C++ parameters but tweaked to return real between 0.0 and 1.0
  73. ; Initial seed based on seconds value from variable "CDATE"
  74. ; Sources:
  75. ;       https://en.wikipedia.org/wiki/Linear_congruential_generator
  76. ;       http://www.rosettacode.org/wiki/Linear_congruential_generator
  77. ; Input:
  78. ;       nothing!
  79. ; Returns:
  80. ;       Random number between 0.0 and 1.0
  81. ; Uses global variables
  82. ;       #seed
  83.  
  84. (if (not #seed)
  85.   (progn
  86.         ; Initialize seed
  87.         (setq MyTime (getvar "CDATE"))
  88.         (setq temp (* 10000.0 (- MyTime (fix MyTime))))        
  89.         (setq #seed (fix (* 100.0 (- temp (fix temp)))))        ; make start value aka seed using time in seconds
  90.   )
  91. )
  92.  
  93. (setq m (expt 2.0 31.0))        ; modulus 2^31
  94. (setq a 214013.0)               ; multiplier
  95. (setq c 2531011.0)              ; increment aka constant
  96.  
  97. (setq temp1 (+ (* a #seed) c))
  98. (setq temp2 (/ temp1 m))
  99. (setq temp3 (fix temp2))
  100.  
  101. ; Make new seed for next time (global)
  102. (setq #seed (- temp1 (* m temp3)))
  103.  
  104. ; Convert to real between 0.0 and 1.0
  105. (setq OutVal (/ #seed m))
  106. OutVal
  107. )
  108.  
  109.  
  110.  
  111.  
  112. (defun Internal_GetStats (MyList RefItem /
  113.                         MyTotal CNT MyItem Count MyMin MyMax MyAverage Svalue Sum2 Sum3 Sum4
  114.                         SampleVariance SampleStanDev SampleSkewness OutList
  115.                         )
  116. ; Compute stats of a subentity of a list
  117. ; KJM - Dec 2002
  118. ; Mod KJM - Dec 2012, general cleanup
  119. ; Mod KJM - June 2013, renamed from Internal_GetAverage and added st dev & skew
  120. ; Input:
  121. ;       MyList - a list (or list of sublists)
  122. ;       RefItem - the number (0,1,2...) of the sublist to process i.e. (nth RefItem MyItem)
  123. ;               this is ignored if no sublist
  124. ; Output
  125. ;       Returns a list (0-Count 1-Min 2-Max 3-Average 4-SampleStDev 5-SampleSkew)
  126.  
  127. (setq MyTotal 0.0)
  128. (setq Count (length MyList))
  129.  
  130. ; Find Min, Max, Mean
  131. (setq CNT 0)
  132. (repeat (length MyList)
  133.  
  134.         (setq MyItem (nth CNT MyList))
  135.  
  136.         (if (eq (type MyItem) 'LIST)
  137.           (setq MyItem (nth RefItem MyItem))
  138.         )
  139.  
  140.         (if (eq CNT 0)
  141.                 (setq MyMin MyItem MyMax MyItem)
  142.         )
  143.        
  144.         (if (> MyItem MyMax)
  145.                 (setq MyMax MyItem)
  146.         )
  147.        
  148.         (if (< MyItem MyMin)
  149.                 (setq MyMin MyItem)
  150.         )      
  151.  
  152.         (setq MyTotal (+ MyTotal MyItem))
  153.         (setq CNT (1+ CNT))
  154. ) ;close repeat
  155.  
  156. ; find mean
  157. (setq MyAverage (/ MyTotal (float (length MyList))))
  158.        
  159. ; find variance and standard deviation, Skew
  160. (setq Sum2 0.0 Sum3 0.0 Sum4 0.0)
  161.  
  162. (setq CNT 0)
  163. (repeat (length MyList)
  164.  
  165.         (setq MyItem (nth CNT MyList))
  166.         (if (eq (type MyItem) 'LIST)
  167.           (setq MyItem (nth RefItem MyItem))
  168.         )
  169.  
  170.         (setq SValue (- MyItem MyAverage))
  171.         (setq Sum2 (+ Sum2 (expt SValue 2.0)))
  172.         (setq Sum3 (+ Sum3 (expt SValue 3.0))) 
  173.  
  174.         (setq CNT (1+ CNT))
  175. ) ;close repeat
  176.  
  177. (setq SampleVariance (/ Sum2 (- Count 1)))
  178. (setq SampleStanDev (expt SampleVariance 0.5))
  179.  
  180. (if (equal SampleVariance 0.0 0.001)
  181.   (progn
  182.         (setq SampleSkewness 0.0)
  183.   )
  184.   (progn
  185.         (setq SampleSkewness (* (/ count (* (- count 1) (- count 2))) (/ Sum3 (expt SampleStanDev 3.0))))
  186.   )
  187. ) ; close if
  188.  
  189. ; Output list
  190. (setq OutList (list count mymin mymax myaverage SampleStanDev SampleSkewness))
  191. OutList
  192. )
  193.  


well20152016

  • Newt
  • Posts: 130
Re: [challenge] A25 : Lottery draw numbers within range
« Reply #13 on: February 16, 2022, 06:21:35 AM »
return 12  27  38  50  57  67  76  81

Code - C++: [Select]
  1. static set<int> rand_N(int sta, int end,int n) {
  2.         set<int> s;
  3.         if (sta < end && n <= (end - sta) )
  4.         {
  5.                 int a = (rand() % (end-sta))+ sta;
  6.                 s.insert(a);
  7.                 while (s.size()!=n)
  8.                 {
  9.                         a = (rand() % (end-sta))+ sta;
  10.                         s.insert(a);
  11.                         }
  12.                 }
  13.                 else
  14.                         {
  15.                    acutPrintf(_T(" %s "), _T("data error"));
  16.                         }
  17.                         return s;
  18.                 }
  19.  
  20. static void MyGroupMyCommand4()
  21. {
  22. set<int> s;
  23. s=rand_N(10,100,8);
  24. set<int>::iterator it=s.begin();
  25. for(;it!=s.end();it++)
  26. acutPrintf(_T(" %d "), *it);     
  27. }
  28.  
  29.  




Code - Auto/Visual Lisp: [Select]
  1. (defun rand_N ( low high n / lst)
  2. (if (and (<= low high) (<= n ( - high low)))
  3. (while (< (length lst) n )
  4.   (setq rand (fix (rem (getvar "CPUTICKS") high)))
  5.   (if (and (null(apply 'or(mapcar '(lambda (x) (equal x rand 0.000001))lst)))(<= low rand high ) )(setq lst (cons rand lst)))
  6.   )
  7.   )
  8. lst  
  9. )
« Last Edit: February 16, 2022, 11:51:10 AM by well20152016 »

JohnK

  • Administrator
  • Seagull
  • Posts: 10140
Re: [challenge] A25 : Lottery draw numbers within range
« Reply #14 on: February 16, 2022, 09:49:57 AM »
I am still down the Random Number Generator rabbit hole but here was my submission before I messed it all up.

Code - Auto/Visual Lisp: [Select]
  1. (defun lotto ( low high / lotolist
  2.                    intdel getseed
  3.                    getrandomnum
  4.                    seed
  5.                    )
  6.   (defun getrandomnum (minNum maxnum / tmp)
  7.     (if (not (< minNum maxNum))
  8.       (progn
  9.         (setq tmp minNum
  10.               minNum maxNum
  11.               MaxNum tmp))
  12.       (fix (+ (* (randnum) (- maxNum minNum)) minNum))))
  13.   (defun randnum (/ modulus multiplier increment random)
  14.     (if (not seed)
  15.       (setq seed (getvar "DATE"))
  16.       )
  17.     (setq modulus    65536
  18.           multiplier 25173
  19.           increment  13849
  20.           seed  (rem (+ (* multiplier seed) increment) modulus)
  21.           random     (/ seed modulus)) )
  22.   (repeat 7 (setq lotolist (cons (getrandomnum low high) lotolist)))
  23.   )
TheSwamp.org (serving the CAD community since 2003)

Donate to TheSwamp.org