PDA

View Full Version : Is there a way to generate a random number?


boesiii
2006-03-03, 06:11 PM
I would to write a fun routine. The routine will display a joke when a user initiates the command? Each joke will be associated to a number hence random number.

CadDog
2006-03-03, 06:24 PM
(setq #fname (rtos (getvar "date") 2 8))

lspbox
2006-03-04, 02:22 AM
; Random number generator
(defun ran ()
(setq seed (if seed (rem (+ (* seed 15625.7) 0.21137152) 1) 0.3171943)))

.T.
2006-03-04, 03:16 AM
You can also check out this (http://www.theswamp.org/forum/index.php?topic=8203.0) link.


Take care,

lspbox
2006-03-04, 03:41 AM
You can also check out this (http://www.theswamp.org/forum/index.php?topic=8203.0) link.


Take care,

Yep... there is my function again.... LE

kennet.sjoberg
2006-03-04, 10:35 AM
I tested a few random generators, and here is the result

Random number generator test

(defun ran () (setq seed (if seed (rem (+ (* seed 15625.7) 0.21137152) 1) 0.3171943)))
100 calculations 0 duplication
500 calculations 1 duplication
1 000 calculations 1 duplication
5 000 calculations 16 duplications
10 000 calculations 48 duplications
50 000 calculations 1136 duplications


(defun ran ( )
(if (not seed) (setq seed 0 ) ( ) )
(setq seed (+ (getvar "TDUSRTIMER" ) seed ) seed (+ seed (* seed (+ seed pi ) 0.731 )) seed (rem seed 1 ))
)
100 calculations 0 duplication
500 calculations 0 duplication
1 000 calculations 1 duplication
5 000 calculations 8 duplications
10 000 calculations 43 duplications
50 000 calculations 1127 duplications


(defun ran ( ) (setq seed (rtos (getvar "date") 2 8 ) ) )
100 calculations 99 duplication


And I think the first one is the winner, simple and safe enough

: ) Happy Computing !

kennet

peter
2006-03-04, 03:40 PM
Test this one. If you wouldn't mind.

Peter Excuse the jumbing of the code, I really get frustrated by this interface adding tabs to my code.


(defun Random (/ sngNumber)
(atoi (chr (car (reverse
(vl-string->list
(rtos (vlax-invoke
(vla-get-activedocument
(vlax-get-acad-object))
"getvariable"
"cdate") 2 16))))))
)

kennet.sjoberg
2006-03-04, 05:01 PM
Test this one. If you wouldn't mind.Ok,

100 calculations 96 duplication
500 calculations 490 duplication

Why ? the random number only shows 0 - 9 ( the others do not show integers )
and to just use the system time as a generator do not work so well
even with a slow computer as mine, there must also be a mathematic scrambling function.
I have tested to include pi, sin, log and exp to avoid duplication
but it is not wort a more complex code, I am pleased with 16 duplications in 5000 calculations.

: ) Happy Computing !

kennet

BTW, if you use Vlide there is already tabs, I always use TextPad to reformat my code

dmarcotte4
2006-03-05, 03:18 AM
Give this one a shot

(defun randnum (/ increment modulus multiplier random)
(if (not *seed*)
(setq *seed* (getvar "DATE")))
(setq modulus 65536
multiplier 25173
increment 13849
*seed* (rem (+ (* multiplier *seed*) increment) modulus)
random (/ *seed* modulus)))
(defun getrandnum (minNum maxNum / random tmp)
(if (not (< minNum maxNum))
(progn
(setq tmp minNum
minNum maxNum
maxNum tmp)))
(setq random (+ (* (randnum) (- maxNum minNum)) minNum))
)[ Moderator Action = ON ] What are [ CODE ] tags... (http://forums.augi.com/misc.php?do=bbcode#code) [ Moderator Action = OFF ]

kennet.sjoberg
2006-03-05, 09:51 AM
Give this one a shot. . . Ok, Great routines

(randnum)
100 calculations 0 duplication
500 calculations 0 duplication
1000 calculations 0 duplication
5000 calculations 8 duplications
10000 calculations 42 duplications
50000 calculations 1085 duplications

(getrandnum 0 1 )
100 calculations 0 duplication
500 calculations 0 duplication
1000 calculations 0 duplication
5000 calculations 13 duplications
10000 calculations 47 duplications
50000 calculations 1066 duplications

(getrandnum 0 100 )
100 calculations 0 duplication
500 calculations 0 duplication
1000 calculations 0 duplication
5000 calculations 2 duplications
10000 calculations 46 duplications
50000 calculations 1108 duplications


if you need limits getrandnum is the best choice here, but of course more code.

: ) Happy Computing !

kennet


BTW, I do not think we have to find a random generator with 0 duplications in 50000 calculations

boesiii
2006-03-05, 08:54 PM
Thanks, now i just need to write the rest of the code

CadDog
2006-03-06, 06:40 PM
Thanks Kennet...

I thought I had a great simple one... :(

Thanks for the tests...

kennet.sjoberg
2006-03-06, 06:56 PM
Thanks Kennet...

I thought I had a great simple one... :(

Thanks for the tests... Simple yes, but now you can choice. . .

: ) Happy Computing !

kennet

Terry Cadd
2006-06-16, 07:26 AM
Hi boesiii,
This is a fun topic and I would like to present my function GetRnd which I wrote about three years ago. GetRnd has one argument, an integer greater than or less than 0. Pi and cdate are part of the equation, and it will never return the previous number returned. Here are a few examples:
(1+ (GetRnd 5));Roll the dice
(* (GetRnd 6283) 0.001);A radian angle between 0 and (2 x pi)
(+ 10 (* (GetRnd 200000) 0.0001));Real number between 10 and 30

As related to the original question posted in this thread, here is a fun function that I included in our AutoLISP code at work. I told the Drafting Department, “If there’s any problem with any program just type “TECH” to get an answer from AutoCAD Tech Support.”

; [Tech.lsp - AutoCAD Tech Support]
(defun c:Tech (/ Num# Response$)
(princ "\nAutoCAD Tech Support")
(setq Num# (GetRnd 6));Get a random number between 0 and 6
(setq Response$
(cond
((= Num# 0)"Did you call in a ticket?")
((= Num# 1)"It's not a Bug it's a new feature.")
((= Num# 2)"It's a Beta version. What did you expect?")
((= Num# 3)"It worked yesterday! Must be a user error.")
((= Num# 4)"It'll be fixed in the next release.")
((= Num# 5)"Did you reboot your computer?")
((= Num# 6)"We can't test everything!")
);cond
);setq
(princ (strcat "\n" Response$))(princ)
(alert (strcat "AutoCAD Tech Support is aware of\n"
"the problem and has responded with:\n\n" Response$))
(princ)
);defun c:Tech

; [GetRnd.lsp - Generates a random number]
; Syntax: (GetRnd Num#)
; Num# = Maximum random integer number range greater than or less than 0.
; Returns: Random integer number between 0 and Num#.
(defun GetRnd (Num# / MaxNum# PiDate$ RealNum~ RndNum# Minus Loop)
(if (or (/= (type Num#) 'INT)(= Num# 0))
(progn
(princ "\nSyntax: (GetRnd Num#) Num# = Maximum random integer number range\ngreater than or less than 0.")
(exit)
);progn
);if
(if (< Num# 0)
(setq MaxNum# (abs (1- Num#)) Minus t)
(setq MaxNum# (1+ Num#))
);if
(if (not *RndNum*) (setq *RndNum* 10000))
(setq Loop t)
(while Loop
(if (or (null *int*)(> *int* 100))
(setq *int* 1)
(setq *int* (1+ *int*))
);if
(setq RealNum~ (* (getvar "cdate") (* pi *int*)))
(setq PiDate$ (rtos RealNum~ 2 8 ))
(cond
((>= MaxNum# 10000) (setq RndNum# (fix (* (atof (substr PiDate$ 13 5)) (* MaxNum# 0.00001)))))
((>= MaxNum# 1000) (setq RndNum# (fix (* (atof (substr PiDate$ 14 4)) (* MaxNum# 0.0001)))))
((>= MaxNum# 100) (setq RndNum# (fix (* (atof (substr PiDate$ 15 3)) (* MaxNum# 0.001)))))
((>= MaxNum# 10) (setq RndNum# (fix (* (atof (substr PiDate$ 16 2)) (* MaxNum# 0.01)))))
((>= MaxNum# 1) (setq RndNum# (fix (* (atof (substr PiDate$ 17 1)) (* MaxNum# 0.1)))))
(t (setq RndNum# 0))
);cond
(if (/= RndNum# *RndNum*) (setq Loop nil))
);while
(setq *RndNum* RndNum#)
(if Minus (setq RndNum# (* RndNum# -1)))
RndNum#
);defun GetRnd

And what would games be without a random function? Check out Troy.lsp!
Troy is an Asteroid AutoLISP game driven by the grread function.
[Troy Program] http://web2.airmail.net/terrycad/LISP/Troy.lsp
[Troy Image] http://web2.airmail.net/terrycad/Images/Troy.jpg

[ Moderator Action = ON ] What are [ CODE ] tags... (http://forums.augi.com/misc.php?do=bbcode#code) [ Moderator Action = OFF ]

kennet.sjoberg
2006-06-25, 09:03 PM
. . .and it will never return the previous number returned. . .
Never say never. . .
If you repeat the function a couple of times you will see repeated numbers
like this

(repeat 100
(princ (GetRnd (1+ (GetRnd 5 )))) ; Integer
)
;;; 0222222210142021014204202102142130113201114213110013122022031022132130114213113231031110210311320204


The other examples do the same
(* (GetRnd 6283) 0.001) ; Real must fix to Integer and not allow zero.
(+ 10 (* (GetRnd 200000) 0.0001 ) ) ; Real must fix to Integer.

: ) Happy Computing !

kennet

Terry Cadd
2006-06-26, 04:31 PM
It's working as intended. GetRnd stores a global variable *RndNum* and "per each call to" GetRnd it will not return that same *RndNum*, as it is in a loop. A nested call to GetRnd as in (GetRnd(1+ (GetRnd 5))) is not the way I intended it to be used, use (1+ (GetRnd 5)) instead. Here are a few test runs per those examples.

Command: (repeat 30 (princ (1+ (GetRnd 5)))(princ" "))(princ)
5 1 3 5 1 3 5 1 2 4 6 2 4 6 2 4 5 1 3 5 1 3 5 1 3 4 1 2 4 6

Command: (repeat 30 (princ (* (GetRnd 6283) 0.001))(princ" "))(princ)
4.298 2.995 1.691 0.387 5.367 4.064 2.759 1.456 0.152 5.133 3.83 2.528 1.224
6.204 4.901 3.596 2.293 0.989 5.969 4.666 3.361 2.058 0.755 5.734 4.43 3.128
1.824 0.52 5.499 4.195

Command: (repeat 30 (princ (+ 10 (* (GetRnd 200000) 0.0001)))(princ" "))(princ)
21.7878 29.3814 16.9752 29.3816 21.8762 17.8144 13.7526 29.6908 25.6288 21.5668
17.505 13.4432 29.3814 25.3194 21.2576 17.196 13.1338 29.0718 11.501 19.0948
26.6886 14.2824 21.8762 29.47 17.0638 24.6576 12.2514 19.8454 27.4392 15.033

Check out how I used GetRnd in the TROY.lsp Asteroid AutoLISP game.
http://web2.airmail.net/terrycad/LISP/Troy.lsp
It's fun and there moving in all sorts or random paths.

Have fun,
Terry Cadd

kennet.sjoberg
2006-06-26, 05:45 PM
. . .Here are a few test runs per those examples. . .
Command: (repeat 30 (princ (1+ (GetRnd 5)))(princ" "))(princ)

Ok, I tested this one 1000 cycles, and if I have to bet I know what to not put money on ;)
Here is the result: 196:1 185:2 106:3 178:4 197:5 138:6 and I miss 7 8 9 they do never occur.

: ) Happy Computing !

kennet

Terry Cadd
2006-06-26, 11:23 PM
Here's the syntax for GetRnd again (GetRnd Num#).
Where Num# = Maximum random integer number range greater than or less than 0.
It returns a random integer number between 0 and Num#. As per the example:
(repeat 30 (princ (1+ (GetRnd 5)))(princ" "))(princ)
(GetRnd 5) will return a random number from 0 to 5, and (1+ (GetRnd 5)) will add 1 to the result, returning a number from 1 to 6.
You will never get a number greater than 6 with (1+ (GetRnd 5)).
If you're needing to also include 7, 8, 9
try (1+ (GetRnd 8 )).

I just joined recently, and didn't know I was entering a contest.
Regards,
Terry Cadd

kennet.sjoberg
2006-06-27, 08:36 AM
. . .try (1+ (GetRnd 8 )). . .
Ok, I tested this one again 1000 cycles,

195:1 ( x 2 ? )
89:2
109:3
100:4
99:5
109:6
83:7
112:8
104:9

: ) Happy Computing !

kennet