Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
random number
#1
Does anyone know how I can mimic a random number generator? I'd like to mimic the Excel fundtion which would find a random number between to numbers.

Code:
Copy      Help
RANDBETWEEN(1,3)


Thanks.
#2
Try the following function called "Uniform".
To use, code: "int r=Uniform(mn mx)" to return a value between numbers "mn" and "mx".

Or you could just use the msvcrt function: rand
Code:
Copy      Help
;;Uniform:  L'Ecuyer Random number generator

;Global (or thread specific) integer variables s1 and s2
;hold the current state of the generator and must be
;initialised with values in the range [1-2147483562]
;and [1-2147483398] respectively.  The generator has a
;period of ~ 2.3 x 10^18.

function^ [mn] [mx]
int z k
dll msvcrt clock
int+ s1 s2
if(!s1 || !s2)
,s1 = clock() / (1 << 16)
,s2 = clock() % (1 << 16)
,if(s1 <= 0 || s1 > 2147483562) s1 = 1
,if(s2 <= 0 || s2 > 2147483398) s2 = 2147483398

k = s1/53668
s1 = 40014*(s1-(k*53668))-(k*12211)
if(s1 < 0) s1+2147483563
k = s2 / 52774
s2 = 40692 * (s2-(k*52774))-(k*3791)
if(s2<0) s2=s2+2147483399
z = s1 - s2
if(z<1) z=z+2147483562
double random = z * 4.65661305956E-10

if(mx)
,ret (mn+ ((mx-mn+1)*random))
else ret random


;For more information, visit:
;http://xarch.tu-graz.ac.at/autocad/lisp/xlisp21gbc/sources/xlrand.c.bak
;http://www.sct.gu.edu.au/~anthony/info/C/RandomNumbers
;http://www.orthogonal.com.au/hobby/random/
;http://cgm.cs.mcgill.ca/~luc/rng.html
#3
Wow this looks great but I thini I jacked up the paste.
The compiler didn"t like the commas in front of the lines so I took them out.
However, this is what I got when I ran it for rand #s between 1 and 10 a bunch of times:
9 9 9 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
6 5 5 5 5 5 5 5 5 5 5 5

Any ideas why?
#4
I think you have older QM release. In QM 209 and later, commas in front of lines ar interpreted in same way as tabs. Function works ok.
#5
It says I have 2.0.9
does it copy/paste ok for you?
#6
Maybe it is beta. In any case, replace commas to tabs. Your result is like commas have been deleted.

What is wrong with copy/paste?
#7
WOW!!!!!
This worked great.
I ran a quick 4,500 items list and everything was distributed within expected ranges...
Thanks MU and thanks Gintaras for helping me figure out what was going on.
#8
Lets say I have a list of numerical numbers 0 to 100, and i want to make that list random without repeating any of the numbers what would be the best way to do this ?
#9
This is what i came up with if anyone has a better way of doing it please post it.

Code:
Copy      Help
int cnt
str lines=
;line0
;line1
;line2
;line3
;line4
;line5
:;;etc
;line95
;line96
;line97
;line98
;line99
;line100

ARRAY(str) arr=lines
;top
rep
,if arr.len=0;break
,cnt=Uniform(0 arr.len)
,out arr[cnt];err goto top
,arr.remove(cnt);err goto top
#10
[John_ : i edited your posting in the code part, to make the posting a little bit shorter]

i tried to make your code at least shorter with using
the array example in Pointer , reference , array .

but now i stumble over a problem.
Code:
Copy      Help
lines.remove(cnt)
does not work.

how do i remove and redim my array lines ?

Code:
Copy      Help
int i cnt
str* lines._new(101)
for(i 0 lines._len) lines[i] = _s.from("line" i)
;top
rep 5
,;if lines._len<0;break
,;cnt=Uniform(0 lines._len)        
,out lines[cnt];cnt+1;err goto top
,;lines.remove(cnt);err goto top

lines._delete
pi
#11
Quote:how do i remove and redim my array lines ?

At low level. Use memmove. When calculating offset etc, multiply by sizeof(str).
#12
_pi Wrote:[John_ : i edited your posting in the code part, to make the posting a little bit shorter]

Thats fine _pi I should have thought of that.
#13
I found a problem in my code I'm sure it's the only one lol.

Code:
Copy      Help
,if arr.len<0;break

should be:

Code:
Copy      Help
,if arr.len=0;break
#14
Gintaras Wrote:At low level. Use memmove. When calculating offset etc, multiply by sizeof(str).

thats a bit to much for me today to investigate.
can you please show how to use it in my code for John_ ?
pi
#15
Don't use pointer-based arrays of str type, because it is too difficult, because you must not only move memory but also properly clear str elements. This is example:

Code:
Copy      Help
;create array
str* p._new(10)
int i
for i 0 p._len
,p[i].from("line" i)

;remove element 3
int rem=3
int nelementstomove=p._len-rem-1
if(nelementstomove)
,p[rem].all
,memmove &p[rem] &p[rem+1] nelementstomove*sizeof(str)
,p[p._len-1].lpstr=0
p._resize(p._len-1)

;results
out
for i 0 p._len
,out p[i]

p._delete



There are 7 lines of code to remove str element. Unless you put it in a function.
#16
Google for "randomize array" and you will find how it can be done. My version:


Code:
Copy      Help
;create array
str lines=
;line0
;line1
;line2
;line3
;line4
;line5
;;;etc
;line95
;line96
;line97
;line98
;line99
;line100

ARRAY(str) arr=lines

;randomize array
int randomization_depth=2
rep arr.len*randomization_depth
,;swap two random elements
,;g1
,int i1=Uniform(0 arr.len-1)
,int i2=Uniform(0 arr.len-1)
,if(i1=i2) goto g1
,str tmp=arr[i1]
,arr[i1]=arr[i2]
,arr[i2]=tmp

;results
out
lines=arr
out lines
,

Another version:
Code:
Copy      Help
;create array
str lines=
;line0
;line1
;line2
;line3
;line4
;line5
;;;etc
;line95
;line96
;line97
;line98
;line99
;line100

ARRAY(str) arr=lines
if(arr.len<3) ret

;randomize array
int randomization_depth=2
rep randomization_depth
,int i
,for i 0 arr.len
,,;swap with a random element
,,;g1
,,int i2=Uniform(0 arr.len-1)
,,if(i2=i) goto g1
,,str tmp=arr[i]
,,arr[i]=arr[i2]
,,arr[i2]=tmp

;results
out
lines=arr
out lines
,
#17
What do you think of this ?

UPDATED
Code:
Copy      Help
int cnt;str ranlines linex lines=
;line0
;line1
;line2
;line3
;line4
;line5
;line6
;line7
;line8

out
rep
,if lines="";break
,cnt=Uniform(0 numlines(lines));if cnt=numlines(lines);cnt-1
,linex.getl(lines cnt)
,lines.RemoveLineN(cnt)
,ranlines.formata(linex)
,ranlines+"[]"
out ranlines






Member function str.RemoveLineN
Code:
Copy      Help
function# lineindex [nlines]

;Removes specified line(s).
;Returns index of first character of lineindex-th line, or -1 if lineindex is too big.


;lineindex - zero-based line index.
;nlines - number of lines to remove. Default or 0: 1 line.


;EXAMPLE
;str s="zero[]one[]two"
;s.RemoveLineN(1)
;out s



if(nlines<1) nlines=1
int i=findl(this lineindex)
if(i>=0) this.remove(i findl(this+i nlines))
ret i
#18
is there any way to do this with the alphabet and only output random 5 letters?
#19
Member function str.Random. Create it using menu File New New Member Function.
Code:
Copy      Help
function minlen maxlen [$charset]

;Creates random string.

;minlen, maxlen - minimal and maximal number of characters that must be in the string.
;charset - characters that must be in the string.
;;;By default are included all characters between ASCII 33 and 127. This does not include space characters.
;;;Use hyphen between two characters to include all characters whose ASCII codes are more than of the first character and less than of the second.


;EXAMPLES
;str s
;s.Random(5 5) ;;5 characters ASCII 33-127
;out s
;s.Random(8 16 "a-zA-Z0-9") ;;8 to 16 alphanumeric characters
;s.Random(8 8 "[1]-[255]") ;;8 any characters



this.all(Uniform(minlen maxlen) 2)

int i j c
if(!len(charset))
,for(i 0 this.len) this[i]=Uniform(33 127)
else
,str s(charset) ss
,;replace hyphens
,for i s.len-2 0 -1
,,if(s[i]='-')
,,,c=s[i+1]-s[i-1]-1
,,,if(c<0) continue
,,,ss.all(c 2)
,,,c=s[i-1]
,,,for(j 0 ss.len) c+1; ss[j]=c
,,,s.replace(ss i 1)
,,,i-2
,;find min and max char
,int minchar(255) maxchar(1)
,for(i 0 s.len)
,,if(s[i]<minchar) minchar=s[i]
,,if(s[i]>maxchar) maxchar=s[i]
,;generate random chars between min and max, and reject chars not in charset
,for(i 0 this.len)
,,rep
,,,c=Uniform(minchar maxchar)
,,,if(findc(s c)>=0) this[i]=c; break
#20
I dont understand what to do i tryed that but got nothing? is there any other functions or anything i need?
#21

Make sure you have this.
Download the file off the link.


is this the best way? (repeat code random number of times)
Taking on Quick Macros one day at a time
#22
yes i have that but i dont understand why its not working? can anyone plz explain what i ned and exactly the steps? thanks
#23
Create function Uniform, create member function str.Random, create a macro, put the EXAMPLE code int the macro, uncomment the code, run the macro to test how it works.
#24
OK, worked perfect except what do i need to change to make it only use A-Z Letters and any Numbers?
#25
Nevermind change it to 65-90 now its only letters but is there a way to do numbers and letters with out the stuff inbetween?
#26
For example i found this

Numbers (0-9) = 48-57

Letters (A-Z) = 65-90

I would like to include both sets but not whats inbetween? Can it be done?
#27
Updated. Now instead of minchar and maxchar use single string, like in examples.
#28
OK, Thanks Gint got it now works perfect Big Grin!!
#29
Hmm, nevermind it didnt work? can you give another example of how to use anything A-Z and 0-9 ?? Thanks


Forum Jump:


Users browsing this thread: 1 Guest(s)