Shuffle Table

Feature requests for future versions of Hollywood can be voiced here
Post Reply
User avatar
fingus
Posts: 269
Joined: Fri Sep 16, 2011 9:53 am

Shuffle Table

Post by fingus »

A Table-Function that will shuffle the Table contents by random would be helpfull.

I´m not 100% sure, maybe this can be reached by using:

Sort(array[, sortfunc])

with a randomizer sortfunc.
Bugala
Posts: 1178
Joined: Sun Feb 14, 2010 7:11 pm

Re: Shuffle Table

Post by Bugala »

Code: Select all

nums = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
Sort(nums, Function(a, b) Return(Rnd(1)) EndFunction)
For k = 0 To 9
   DebugPrint(nums[k])
Next
It is not explained very clearly in the sort documentation, but function needs to return either FALSE or TRUE (which can also be 0 or 1).
PEB
Posts: 569
Joined: Sun Feb 21, 2010 1:28 am

Re: Shuffle Table

Post by PEB »

I don't really understand why, but the code Bugala suggested gives the exact same new list every time (so not really random).

This code does seem to work, though:

Code: Select all

nums = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
?Sort(nums, Function(a, b) Return(Rnd(2)) EndFunction)
For k = 0 To 9
	error=?DebugPrint(nums[k])
	If error<>Nil Then DebugPrint("Error")
Next
SamuraiCrow
Posts: 475
Joined: Fri May 15, 2015 5:15 pm
Location: Waterville, Minnesota USA

Re: Shuffle Table

Post by SamuraiCrow »

Rnd(1) gives 1 possible integer value of 0

Rnd(2) gives 1 of 2 possible values: 0 or 1. This is due to the range select value being applied as a modulo operation.
I'm on registered MorphOS using FlowStudio.
User avatar
jPV
Posts: 603
Joined: Sat Mar 26, 2016 10:44 am
Location: RNO
Contact:

Re: Shuffle Table

Post by jPV »

Hmm... there seems to be something hazy here... I just stumbled upon an issue like this.

If you use this code:

Code: Select all

nums = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
Sort(nums, Function(a, b) Return(Rnd(2)) EndFunction) 
It sometimes goes through fine, but often gives an error: "Invalid order function for sorting!"

Why it fails even though it should get valid values of 0 or 1 always?

Is this why PEB used the question mark in front of his Sort line? For a workaround for a bug?
SamuraiCrow
Posts: 475
Joined: Fri May 15, 2015 5:15 pm
Location: Waterville, Minnesota USA

Re: Shuffle Table

Post by SamuraiCrow »

Curiously, copying the two parameters to dummy variables alleviates the Sort check.

Code: Select all

@DISPLAY 0, {HIDDEN = True}

nums = {"One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten"}

Function Shuffler(x, y)
	Local a=x, b=y
	Return(Rnd(2) > 0)
EndFunction

Sort(nums, Shuffler)
ListRequest("Shuffled", "Click OK to continue or Cancel to also continue", nums)
I'm on registered MorphOS using FlowStudio.
User avatar
jPV
Posts: 603
Joined: Sat Mar 26, 2016 10:44 am
Location: RNO
Contact:

Re: Shuffle Table

Post by jPV »

@SamuraiCrow

I still get the errors with your code too...
SamuraiCrow
Posts: 475
Joined: Fri May 15, 2015 5:15 pm
Location: Waterville, Minnesota USA

Re: Shuffle Table

Post by SamuraiCrow »

This one won't crash and it includes another version for generic tables tested with a Unicode key value.

Code: Select all

@DISPLAY 0, {HIDDEN = True}
@VERSION 7,0

/*
 *	Table shuffler
 *
 *	Parameter:
 *	a	Table to shuffle
 *
 *	Returns:
 *		Shuffled table
 */
Function p_ShuffleTable(a)
	Local key, content, k, max, iter=Nil, Nil, {}, 0, Nil
	; create an array of the keys
	Repeat
		iter = NextItem(a, iter)
		If GetType(iter) = #NIL Then Break
		k[max] = iter
		max = max + 1
	Forever
	; Randomize table
	For key, content In Pairs(a)
		iter = k[ Rnd(max) ]
		; no point in skipping redundant keys if they are Unicode
		; the CompareStr function is probably more expensive than the swap
		a[key] = a[iter]
		a[iter] = content
	Next
	Return(a)
EndFunction

/*
 *	Array shuffler
 *
 *	Parameter:
 *	a	array to shuffle
 *
 *	Returns:
 *		Shuffled array
 */
Function p_ShuffleArray(a)
	Local key, content, iter, max=Nil, Nil, Nil, ListItems(a)
	; Randomize array
	For key, content In IPairs(a)
		iter = Rnd(max)
		If (iter <> key)
			a[key] = a[iter]
			a[iter] = content
		EndIf
	Next
	Return(a)
EndFunction


nums = {"One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten"}
letters = {}
strings={}
letters["a"] = "apple"
letters["b"] = "baking"
letters["c"] = "catapult"
letters["d"] = "destination"
letters["e"] = "eggplant"
letters["f"] = "farmer"
letters[0] = "what?"
letters[chr(228, #ENCODING_UTF8)] = "etc."

ListRequest("Shuffled", "Click OK or Cancel to continue", p_ShuffleArray(nums) )
letters = p_ShuffleTable(letters)
ForEach(letters, Function(k,v)
	InsertItem(strings, k.."="..v)
EndFunction)
Sort(strings, Function(a,b)
	CompareStr(a,b)
EndFunction)
ListRequest("Shuffled", "Click OK or Cancel to continue", strings)
I'm on registered MorphOS using FlowStudio.
User avatar
airsoftsoftwair
Posts: 5443
Joined: Fri Feb 12, 2010 2:33 pm
Location: Germany
Contact:

Re: Shuffle Table

Post by airsoftsoftwair »

jPV wrote: Thu Jan 16, 2020 4:17 pm Why it fails even though it should get valid values of 0 or 1 always?
Because it's not consistent. Using Rnd() inside the sort callback is a very bad idea because it will confuse the sort algorithm. Imagine it first compares 1<2 and the result is TRUE and the next time it does this comparison the result is FALSE. This will mess up things.
Post Reply