0

For an online game I create an initial PHP array with 36 values: A-Z 0-9. A random script remix the array, i.e

[0] R
[1] 4
[2] N
[3] d
...
[35] 8

Once done the script assigns 6 signs to each of the 6 players via a chunk($arr,6).

Player 1 [0] = [R,4,n,d,O,M]
Player 2 [1] = [p,2,s,Z,k,u]
...
Player 6 [5] = [J,r,V,5,z,8]

The question is: once the table of players has been reordered alphabetically, is there an algorithmic way to recreate the initial distribution?

To simplify the question:

Initial array

[0] = abc
[1] = def
[2] = ghi
[3] = jkl
[4] = mno
[5] = pqr

Random order permutation [0,1,2,3,4,5] -> [2,5,0,3,1,4]:

[2] = ghi
[5] = pqr
[0] = abc
[3] = jkl
[1] = def
[4] = mno

Result:

new order     [0]   [1]   [2]   [3]   [4]   [5] 
value         ghi   pqr   abc   jkl   def   mno
former order  [2]   [5]   [0]   [3]   [1]   [4] -> random permutation

To retrieve former order I must find the way to produce the array [2,4,0,3,5,1]:

 new order   [2]   [4]   [0]   [3]   [5]   [1]          
 value       abc   def   ghi   jkl   mno   pqr  -> initial array order

How to obtain this array [2,4,0,3,5,1] from random permutation [2,5,0,3,1,4] ?

4

2 Answers 2

2

Yes, there is a way to do that. Let's assume that you have an array called $array and you shuffle it inside a function to which (very important!) you pass your array by value rather than by address. Example:

?php

$array = ['a','b','c','d','e','f'];

function shuffleMyArray($array) {
    shuffle($array);
    return $array;
}

$shuffled = shuffleMyArray($array);

echo json_encode([
    'original' => $array,
    'shuffled' => $shuffled
]);

Output example:

{"original":["a","b","c","d","e","f"],"shuffled":["a","d","c","f","b","e"]}
Sign up to request clarification or add additional context in comments.

18 Comments

Wouldn't $shuffled = $array; and then shuffle the new array achieve the same thing?
@NigelRen the reason why I create this as a function is that it's reusable then. If you want the same pattern, then it makes more sense to delegate the shuffling into a function instead of duplicating it many times, because if you would need to do some further stuff for the shuffled array, then you can implement the change exactly once inside the function instead of doing it as many times as many usages there are. But you are technically correct, the example you have given would do the job too, but if I see something like that in a PR, then I would request for changes.
Premature optimization doesn't have the best of rep's - still.
@NigelRen this is not a matter of optimization but it is a matter of organization. We separate the concern of shuffling from the usages of said shuffling. This will not improve performance, nor memory usage. It will actually use more memory by adding a function call to the stack, but it's worth it, because it will make the function reusable with almost no additional cost. Whereas, if you do not organize your code well, then you will later on spend hours refactoring your duplicated code and trying to figure out where you missed doing it.
Optimization is not just about performance (IMHO). But bloating a 2 line piece of code for something that may never happen in this limited scenario adds extra complexity which is simply not needed.
|
0
  1. Store your former order using array_flip
  2. Shuffle the array (you may use lajos-arpad suggestion to preserve the original array)
  3. Obtain the new order using array_map by mapping shuffled value to its original position
    $array = ['abc','def','ghi','jkl','mno','pqr'];
    $former_order = array_flip($array);
    // ['abc' => 0, 'def' => 1, 'ghi' => 2, 'jkl' => 3, 'mno' => 4, 'pqr' => 5]
    shuffle($array);
    // ['abc','mno','def','ghi','pqr','jkl']
    $new_order = array_map(fn($item) => $former_order[$item], $array);
    // [0,4,1,2,5,3]

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.