Daaaaaang. Bringing Pi into the mix is tasty! I'll need to study that one more.
I also love @steve_ssh 's idea to sort a bunch of random values and shuffle in one swing, taking the original values along for the ride.
Here's my quick'n'dirty stab:
While ([
~vals = "1¶2¶3¶4¶5¶6¶7¶8¶9" ;
~len = ValueCount ( ~vals ) ;
~res = ""
];
~len > 0 ;
[
// get a random 1-based idx within remaining range
~idx = Ceiling ( random * ~len ) ;
// pluck out the value
~val = GetValue ( ~vals ; ~idx ) ;
~vals = LeftValues ( ~vals ; ~idx - 1 ) & RightValues ( ~vals ; ~len - ~idx ) ;
~len = ~len - 1 ;
// append it to the result
~res = list ( ~res ; ~val )
];
~res
)
And here's a comparably quick'n'dirty visual of the algo
EDIT: After eyeballing my picture above, I realized you could feasibly shuffle "in place" (though I think FM lacks the ability to do that efficiently under the hood), by appending the plucked value to the end of ~vals
and still decrement ~len
on each iteration.