Shuffle an array so that no two of the same elements are adjacent
<p>I have an array which contains strings. Several of those strings can be the same and that is fine. They can be in any order to start of, but most likely they are in alphabetical order.  I have the following <code>shuffle</code> function which will shuffle all the elements. However, I want to add a condition that no two of the same string can be adjacent in the array.</p>

<p>For example, this is fine: <code>ook eek ook monkey ook</code> but this is not: <code>ook ook eek ook monkey</code> as two <code>ook</code> are adjacent. It is assumed that the input has been checked so that any duplicates are less than half the total number of elements so a set of non-adjacent solutions exists. For example, <code>ook ook ook eek</code> would be rejected. The strings could contains spaces and UTF-8 characters but not new lines -- the strings are actually file name of images.</p>

<p>How can I modify the <code>shuffle</code> function to achieve this goal?</p>

<p>Or is there a better way to do that?</p>

<pre><code>shuffle() {
    # This function shuffles the elements of an array in-place using the
    # Knuth-Fisher-Yates shuffle algorithm. 
    local i tmp size max rand

    # $RANDOM % (i+1) is biased because of the limited range of $RANDOM
    # Compensate by using a range which is a multiple of the array size.
    size=${#array[*]}
    max=$(( 32768 / size * size ))
    for ((i=size-1; i&gt;0; i--)); do
        while (( (rand=$RANDOM) &gt;= max )); do :; done
            rand=$(( rand % (i+1) ))
            tmp=${array[i]} array[i]=${array[rand]} array[rand]=$tmp
    done
}
</code></pre>