Hi Mark,
On Apr 13, 2008, at 2:45 PM, Mark J. Reed wrote:
> You can simplify that code quite a bit with a counting loop and
> multiple assignment.
>
> on shuffle (aList)
> set length to count aList
> repeat with i from count to 2 by -1
> set j to random number between 1 and i
> if j is not I then
> tell aList to set {item i, item j} to {item j, item i}
> end if
> end repeat
> end shuffle
Truly elegant code, there. But for us neophytes who are not all that
confident with such higher forms of math....
> A common error is to replace the random number bounds to (1..i-1),
> eliminating the if conditional and guaranteeing a swap on each step,
> but then the distribution of resulting permutations is no longer even.
Thanks for pointing out my potential error.
I've changed the code to read as follows....
on ShuffleList(thisList)
set iCount to (count of items in thisList) -- get number of items in
the list
set itCount to iCount
repeat until itCount < 2
set randNumb to (random number from 1 to itCount)
if randNumb is not equal to itCount then
set i1 to item itCount of thisList
set i2 to item randNumb of thisList
set item itCount of thisList to i2
set item randNumb of thisList to i1
set itCount to itCount - 1 // moved to inside the IF-ENDIF to
avoid the problem you mentioned
end if
end repeat
return thisList
end ShuffleList
>
>
>
> On 4/13/08, Chuck Pelto <[log in to unmask]> wrote:
>> On Apr 13, 2008, at 1:26 PM, Chuck Pelto wrote:
>>
>>>
>>> On Apr 13, 2008, at 1:12 PM, Chuck Pelto wrote:
>>>
>>>>
>>>> On Apr 13, 2008, at 1:01 PM, Mark J. Reed wrote:
>>>>
>>>>> On Sun, Apr 13, 2008 at 2:51 PM, Chuck Pelto <[log in to unmask]>
>>>>> wrote:
>>>>>> Does anyone have a good suggestion on how to shuffle the
>>>>>> contents of a list?
>>>>>
>>>>> Fisher-Yates is a good algorithm. What language?
>>>>
>>>> Working with AppleScript; ScriptDebugger.
>>>>
>>>> Where can I find the Fisher-Yates?
>>>
>>> Found it. Looks simple enough.
>>
>> Here's what I've done.....
>>
>> on ShuffleList(thisList)
>>
>> set iCount to (count of items in thisList) -- get number of items in
>> the list
>>
>> set itCount to iCount
>>
>> repeat until itCount < 2
>>
>> set randNumb to (random number from 1 to itCount)
>>
>> if randNumb is not equal to itCount then
>>
>> set i1 to item itCount of thisList
>> set i2 to item randNumb of thisList
>>
>> set item itCount of thisList to i2
>> set item randNumb of thisList to i1
>>
>> end if
>>
>> set itCount to itCount - 1
>>
>> end repeat
>>
>> return thisList
>>
>> end ShuffleList
>>
>>
>> It's not particularly elegant, but it works.
>>
>
> --
> Sent from Gmail for mobile | mobile.google.com
>
> Mark J. Reed <[log in to unmask]>
>
|