Random list of numbers within a custom list of numbers

I want to be able to get 6 sets of number from a custom list of numbers and display the result in order.

Example:

1.Custom list of numbers. 1,4,6,8,12,14,17,19,25,27,29,31,33,38,50 ( I can change it when ever I want too)
2.The script will then give me 6 random number from the list of numbers on top.
3.and list the result in order from low to greater.

After some research I was able to use list command and this is what I have.


set the_values_list to {"12", "14", "18", "21","25", "27", "48", "67"} as list 
set the list_count to the count of the_values_list 
set pick to random number from 1 to list_count 
set generated_choice to item pick of the_values_list as string
return generated_choice

But it only gives me 1 number and not a set of 6 numbers

*would love to have the result also be non reparative.

anyone has any ideas on how to get it this working?

Hi Born. Welcome to MacScripter.

The main problems, as you’ve realised, are choosing numbers which haven’t been chosen before (the most efficient way being to eliminate them from the source iist as they’re chosen) and arranging them in order when you’ve got them. AppleScript doesn’t have a sort command, but sorting’s possible by various means.


set the_values_list to {1, 4, 6, 8, 12, 14, 17, 19, 25, 27, 29, 31, 33, 38, 50}

set generated_choice to {}
set list_count to (count the_values_list)
repeat 6 times
	set pick to (random number from 1 to list_count)
	set end of generated_choice to item pick of the_values_list
	-- Replace the integer in this position with a missing value.
	set item pick of the_values_list to missing value
	-- Get the remaining integers.
	set the_values_list to the_values_list's integers
	set list_count to list_count - 1
end repeat
sort(generated_choice)
return generated_choice

-- Simple insertion sort.
on sort(l)
	repeat with i from 2 to (count l)
		set v to item i of l
		repeat with j from (i - 1) to 1 by -1
			set w to item j of l
			if (v < w) then
				set item (j + 1) of l to w
			else
				set j to j + 1
				exit repeat
			end if
		end repeat
		set item j of l to v
	end repeat
end sort

Edit: Unnecessary ‘here’ variable removed from the insertion sort. it was a hangover from a more efficient but more complex version of the code.

If the original numbers are already in order, as in your examples, another approach would be to choose all but six for elimination. The remaining numbers then wouldn’t need to be sorted:


set the_values_list to {1, 4, 6, 8, 12, 14, 17, 19, 25, 27, 29, 31, 33, 38, 50}

copy the_values_list to generated_choice
set list_count to (count generated_choice)
repeat while (list_count > 6)
	set pick to (random number from 1 to list_count)
	-- Replace the integer in this position with a missing value.
	set item pick of generated_choice to missing value
	-- Get the remaining integers.
	set generated_choice to generated_choice's integers
	set list_count to list_count - 1
end repeat
return generated_choice

But the “numbers” in your script are explicity text, so you’d need to use that class instead of ‘integer’ in the code:


set the_values_list to {"12", "14", "18", "21", "25", "27", "48", "67"}

copy the_values_list to generated_choice
set list_count to (count generated_choice)
repeat while (list_count > 6)
	set pick to (random number from 1 to list_count)
	-- Preplace the text in this position with a missing value
	set item pick of generated_choice to missing value
	-- Get the remaining texts.
	set generated_choice to generated_choice's text
	set list_count to list_count - 1
end repeat
return generated_choice

And if using the sort method with textual numbers, you’d not only have to change ‘integers’ to ‘text’ but put the sort() call in a ‘considering numeric strings’ statement to ensure that the sort is numeric rather than lexical:

considering numeric strings
	sort(generated_choice)
end considering

In addition to Nigel’s examples you can also pick an item using some, or more specifically some integer in this case:

set the_values_list to {"12", "14", "18", "21", "25", "27", "48", "67"}
-- create an index list
set freeItems to {}
repeat with x from 1 to count the_values_list
	set end of freeItems to x
end repeat

-- pick items by index list
set picks to {}
repeat 6 times
	set pick to some integer of freeItems
	set item pick of freeItems to missing value
	set end of picks to item pick of the_values_list
end repeat

--sort the list using AppleScript Toolbox.osax
set picks to AST copy list picks with sorting items and numeric sorting

If you don’t have AppleScript Toolbox.osax installed you can copy and paste Nigel’s sort handler and the code would look like:

set the_values_list to {"12", "14", "18", "21", "25", "27", "48", "67"}
-- create an index list
set freeItems to {}
repeat with x from 1 to count the_values_list
	set end of freeItems to x
end repeat

-- pick items by index list
set picks to {}
repeat 6 times
	set pick to some integer of freeItems
	set item pick of freeItems to missing value
	set end of picks to item pick of the_values_list
end repeat

considering numeric strings
   sort(picks)
end considering
return picks

on sort(l)
	repeat with i from 2 to (count l)
		set here to 1
		set v to item i of l
		repeat with j from (i - 1) to 1 by -1
			set w to item j of l
			if (v < w) then
				set item (j + 1) of l to w
			else
				set here to j + 1
				exit repeat
			end if
		end repeat
		set item here of l to v
	end repeat
end sort

Hi DJ.

Just to point out that when sorting numeric strings, the calls in your scripts should ideally be:

--sort the list using AppleScript Toolbox.osax
set picks to AST copy list picks with sorting items and numeric sorting

. and .

considering numeric strings
	sort(picks)
end considering

I wasn’t aware that the string could contain other characters than integers. Thanks, I have updated my code.

Ungh? :wink:

I was refering to the fact that the “numbers” in {“12”, “14”, “18”, “21”, “25”, “27”, “48”, “67”} aren’t numbers at all but textual representations of numbers. Without the ‘numeric sorting’ or ‘numeric strings’ considerations, they’re sorted lexically and only end up in the corresponding numerical order because they all happen to have the same number of digits. If the list were to include, say, “7” and “104”, the “7” would be sorted to the end (because “7” comes after “6”) and the “104” to the beginning (because “10” comes before “12”). So it’s necessary to specify that the strings are sorted on the numerical values they represent, not on the digit characters they contain.

Just laughing out loud at myself here :lol: it even says so in the dictionary of AST (With this parameter enabled “2” is before “10”.). This made my day even if I come off really bad right now.

Again, you’re right :slight_smile:

NG,

Referring to your first script***

------Your right, one of mine biggest problem was trying to find away to not allow reparative numbers. Mainly I think it was because I was so mind set in finding away that I forgot to look outside the box or I’m just not experienced enough :slight_smile:

    set pick to (random number from 1 to list_count) ***
set end of generated_choice to item pick of the_values_list ***
-- Replace the integer in this position with a missing value.
set item pick of the_values_list to missing value
-- Get the remaining integers.
set the_values_list to the_values_list's integers
set list_count to list_count - 1

------Masterful… So simple but yet so hard, I was literally ready to pick my eyes out lol

Referring to your 2nd script***

----Since the numbers are explicitly, why did you use “integer” ?

Regarding all of the scrips*****

Is there a difference in the probability of which number will get chosen between all 3 scrips?

**for example if all 3 scripts are using the same number and the same amount of number?

(I believe it doesn’t because we’re telling the scrip to choose a random number from a list of explicit text.)

DJ, Thank you for your help :smiley:

Hi Born.

I’m not sure what you’re asking.

  1. The method in all the scripts involves replacing each chosen item in the list with a ‘missing value’ token. This means that instead of the chosen item, the list now contains a value which is of a different class (integer or text) from all the other values in the list. Getting the list’s integers (or the list’s text, if appropriate) returns another list containing only those other values, from which the next choice is made.

  2. There’s an ambiguity in your original query in that it talks about a list of numbers .

. but the script with it deals with a list of texts ” albeit texts containing digit characters:

DJ’s solutions and mine all depend on knowing the type of the items in the list. Their class distinguishes them from the ‘missing value’ and a special condition needs to be applied to the sort if they’re text and you want them ordered according to the numbers they represent rather than on a character-by-character basis.

My first two scripts take you at your word and deal with a list of numbers ” specifically integers. (1 is an integer, 1.0 is a real, “1” is a text.) The rest of my post describes the differences in the event that you actually do mean a list of texts.

I don’t think so. In my first script, each item has six chances in (length of list) of being chosen. In the other two, each item has six chances in (length of list) of not being eliminated. It’s possible that the different number of random choices made in each case might influence the sequence produced by the pseudo-random number generator, but I don’t know what this implies for probabilites. Since the object of the exercise is to choose six numbers at random, I’d be inclined to go for one of the scripts which do precisely that: my first script, its text-handling equivalent (described but not shown at the bottom of my post above), or DJ’s second script, which is also set up for text. (DJ’s first script requires the installation of his AppleScript Toolbox OSAX (link at the bottom of his posts), which contains many useful functions.)