/// <summary>
        /// Compares ~ 2N
        /// </summary>
        /// <param name="arr"></param>
        /// <param name="k"></param>
        /// <returns></returns>
        public int Select(int[] arr, int k)
        {
            Shuffling.Shuffle(arr);

            int low  = 0;
            int high = arr.Length - 1;

            while (low <= high)
            {
                int j = Partition(arr, low, high);
                if (j > k)
                {
                    high = j - 1;
                }
                else if (j < k)
                {
                    low = j + 1;
                }
                else
                {
                    return(arr[k]);
                }
            }

            return(arr[k]);
        }
 /// <summary>
 ///  1. Shuffle and array
 ///  2. Partition such that, for some j
 ///     2.1 Entry a[j] is in place
 ///     2.2 No larger element to left of j
 ///     2.3 No smaller item to right of j
 ///  3. Sort each piece recursively
 ///  4. 1 Parition element, 1 pointer that moves forward and 1 pointer that moves backward
 /// </summary>
 /// <param name="arr"></param>
 public void Sort(int[] arr)
 {
     Shuffling.Shuffle(arr);
     Sort(arr, 0, arr.Length - 1);
     Utilities.Print(arr);
 }