(Not very) random numbers

Rob,

I’d considered something like that, but hadn’t really come to a conclusion until now. I reckon that your script would add to the small range of number I’m getting (BTW, the ones I posted are a selection, out of the many I tried to generate, then deleted, because they were just generating the same numbers again and again), but I think it’d only generate about 2-3 times the unique numbers I’m getting, because of the amount of duplicates.
What I’m going to try is this:

set theNumb1 to random number from 0 to 9
set theNumb2 to random number from 0 to 9
set theNumb3 to random number from 0 to 9
set theNumb to theNumb1 & theNumb2 & theNumb3 as string

Which seems to be a quite a bit more random than just using the random number command.

You might like to play around with the attached code. I didn’t write it and can’t remember how it got into my “snippets” file - so don’t know who to thank. I have no idea if it will be any more ‘random’ than what you are already using.

set nbrList to {}
repeat with i from 1 to 100
    set nbrList to nbrList & i
end repeat
set randomList to {}
repeat with i from 100 to 2 by -1
    set j to (random number from 1 to i)
    set randomList to randomList & (contents of item j of nbrList)
    if j = 1 then
        set nbrList to rest of nbrList
    else if j = i then
        set nbrList to (items 1 thru (j - 1) of nbrList)
    else
        set nbrList to (items 1 thru (j - 1) of nbrList) & (items (j + 1) thru i of nbrList)
    end if
end repeat
set randomList to randomList & item 1 of nbrList

And then, obviously, choose a number (at random!) from the list.

Just to throw a couple more into the mix, here are 2 of my favorites:

set theList to {}
repeat with i from 1 to 1000
	set theList to (theList & i)
end repeat
set thenumber to (some item of theList) as integer

obviously slower if the list isn’t already generated, and:

set theSeed to (text -5 thru -4 of (time string of (current date))) as integer
set thenumber to random number from 1 to 1000 with seed theSeed

Ellis, that 2nd one was written by someone with a sense of humour - it’s great!

There are two main points to consider here.

Firstly, “random number” means “number chosen at random” - not “number chosen at random but excluding any that were chosen on previous occasions”.

Secondly, if I remember rightly, random number functions are only quasi random. They’re based on an algorithm that produces a random effect. They can be “seeded” to change the start point for this algorithm. Ellis has already posted a script that seeds the Standard Additions function with either the minutes or the seconds (depending on your Date & Time settings) of the current time. This depends on the time that the script’s run, and is thus about as random as you can get. It would probably be faster, more universally applicable, and even more random to base the seed on the time itself, rather than the time string:

  set thenumber to random number from 1 to 1000 with seed (time of (current date))

If you’re as interested in non-repetition as in randomness, you can either keep a list of the numbers that have gone previously and keep repeating the random number command until you get a number that isn’t in the list, or (if the range isn’t too great) you can have a list of all the numbers in the range, select one at random, and then eliminate it from the list:

property numberList : {}

  -- Restock the list of numbers if it contains less than two items (or whenever you think appropriate)
  if (count numberList) is less than 2 then
    repeat with i from 1 to 1000
      set the end of numberList to i
    end repeat
  end if

  -- Select a number at random from the number list
  set randIndex to random number from 1 to (count numberList) with seed time of (current date)
  set theNumber to item randIndex of numberList

  -- Preplace the selected number in the list with a non-number
  set item randIndex of numberList to missing value
  -- Rebuild the list with just the remaining numbers
  set numberList to numberList's numbers

  -- Do something with theNumber

I’ve just noticed from the Standard Additions’ dictionary that the upper number in the specified range is not included in the range for some reason, so if you want a number in the range 1 to 1000 you have to ask for a ‘random number from 1 to 1001’.

NG

I’ve noticed the same. But, also noticed that was not true. Because, I get 1000 as a random number even with random number from 1 to 1000.

Hmmm. Maybe it’s been true at some point in the past and the dictionary hasn’t been updated. :-
NG

Probably. It seems that the text part of the dictionary has been forgotten to be changed. If it is true, the following script would run forever.

set theNumb to 0
repeat until theNumb is equal to 1000
	set theNumb to random number from 1 to 1000
end repeat