// Most significant digit radix sort (recursive)
void msd_radix_sort(int *first, int *last, int msb = 31)
{
    if (first != last && msb >= 0)
    {
        int *mid = std::partition(first, last, radix_test(msb));
        msb--; // decrement most-significant-bit
        msd_radix_sort(first, mid, msb); // sort left partition
        msd_radix_sort(mid, last, msb); // sort right partition
    }
}
int main(void)
{
  out("starting ...\n");
  std::cout << " MSD radix sort " << std::endl;

  std::vector<std::string> strings;
  
  int N = 0;

  //start from 
  char str[256] = {0};
  while( scanf("%s",&str) != EOF ) {
      strings.push_back(str);
  }
  N = strings.size();

  std::vector<int> v(N); //map to sorted strings
  for(int i = 0; i < N; i++)
      v[i] = i; //all v's entries point to initial respective locations 

  std::vector<int> aux(N); //map to sorted strings
  msd_radix_sort(strings, v, aux, 0, N, 0);

  out("SORTED strings\n");
  for(int i = 0; i < N; i++) {
      std::cout << strings[v[i]] << std::endl;
  }

  return 0;
}
//recursive call, first we count sort on the leftmost column,
//then we proceed to recursively sort the next column
//aux is passed so we dont reallocate every time the helper array
void msd_radix_sort(const std::vector<std::string> & strings, std::vector<int> &v, std::vector<int> &aux, int start, int end, int chrindx)
{
    out("msd_radix_sort %d, %d, %d\n", start, end, chrindx);
    if(end - start < 2) return;
    if(end - start < 24) {
        insertion_sort(strings, v, aux, start, end, chrindx);
        return;
    }

    for(int i = start; i < end; i++) {
        out("h %s\n", strings[v[i]].c_str());
    }

    int counts[R + 1] = {0};
    counting_sort(strings, v, aux, start, end, chrindx, counts);

    for(int r = 0; r < R; r++) {
        if(counts[r+1] - counts[r] > 1) {
            msd_radix_sort(strings, v, aux, start + counts[r], 
                    start + counts[r + 1], chrindx + 1);
        }
    }

    for(int i = start; i < end; i++) {
        out("s %s\n", strings[v[i]].c_str());
    }
}