import java.util.Map;
import java.util.TreeMap;

public class LiangArrayShuffleTest {

	public static void main(String[] args) {
        // Show frequencies of letter orders for the text's naive shuffle algorithm:
        Map<String, Integer> naiveFreq = new TreeMap<>();
        for (int trial = 0; trial < 10000000; trial++) {
               char[] myList = {'a', 'b', 'c'};
               
               // Liang shuffle
               for (int i = 0; i < myList.length - 1; i++) {
            	   int j = (int)(Math.random() * myList.length);
            	   char temp = myList[i];
            	   myList[i]= myList[j];
            	   myList[j] = temp;
               }
               
               StringBuilder sb = new StringBuilder();
               for (char ch : myList)
            	   sb.append(ch);
               String order = sb.toString();
               naiveFreq.put(order, naiveFreq.containsKey(order) ? naiveFreq.get(order) + 1 : 1);
        }
        System.out.println("Liang shuffle order frequencies are non-uniform with predictable bias:");
        for (String order : naiveFreq.keySet())
               System.out.println(order + " " + naiveFreq.get(order));
        
        // My unbiased Knuth/Fisher-Yates shuffle generalization:
        Map<String, Integer> knuthFreq = new TreeMap<>();
        for (int trial = 0; trial < 10000000; trial++) {
            char[] myList = {'a', 'b', 'c'};
               
            // Knuth shuffle
            for (int i = myList.length - 1; i > 0; i--) {
            	int j = (int)(Math.random() * (i + 1));
            	char temp = myList[i];        
            	myList[i] = myList[j];
            	myList[j] = temp;
            }
            
            StringBuilder sb = new StringBuilder();
            for (char ch : myList)
            	sb.append(ch);
            String order = sb.toString();
            knuthFreq.put(order, knuthFreq.containsKey(order) ? knuthFreq.get(order) + 1 : 1);
        }
        System.out.println("Knuth order frequencies are uniform and unbiased:");
        for (String order : knuthFreq.keySet())
               System.out.println(order + " " + knuthFreq.get(order));
	}

}
