/******** Problem 6--Hamming It Up ************************************
 This was another easy problem provided you knew C's built-in bitwise
 operators.
 **********************************************************************/

#include <fstream>
#include <cstdlib>
using namespace std;

#define MIN(a,b) ((a)<(b)?(a):(b))

int main (int argc, char **argv);
int hamming (int a, int b);
int minhamming (int *code, int len);

ifstream in ("prob6.in");
ofstream out ("prob6.out");

/**** main ************************************************************
 This program continally reads in a line of integers.  The first integer
 tells us the number of integers that will follow.  We compute and
 print out the Hamming distance for these following integers.
 **********************************************************************/

int main (int argc, char **argv) {

  int code[20], len, // the set of integers and their length
      cs=0;          // the case number

 while (1) {
  in >> len;
              // read in the length and stop if length is zero
  if (len==0) break;
  for (int i=0;i<len;i++) // read in the line of integers
   in >> code[i];
                      // Compute and print the hamming distance
  out << "Case " << ++cs << ".  Hamming distance = " <<
         minhamming (code,len) << "." << endl;
 }
 return EXIT_SUCCESS;
}

/****** hamming *******************************************************
 hamming accepts two integers and prints out the hamming distance
 between the two integers.  It uses C's bitwise exclusive-or operator.
 **********************************************************************/

int hamming (int a, int b) {

  int ct=0;            // The number of bits in the difference
                       // (to be returned)

  // bitwise exclusive or operator: ^
 for (unsigned int c=a^b;c>0;ct+=c%2,c>>=1);
                 // loop until we run out of bits to check
                 // if rightmost bit is one, increment our count
                 // right shift
 return ct;
}

/***** minhamming *****************************************************
 minhamming accepts an array of integers and its length and returns
 the minimum hamming distance of any pair of integers in the list.
 It simply uses a nested loop to hit all of the combinations.
 **********************************************************************/

int minhamming (int *code, int len) {

  int mind;   // The minimum hamming distance (that will be returned)

 mind = 32;  // 32 is the limit given in the problem description
             // i iterates from 0 to len-2
 for (int i=0;i<len-1;i++)
                  // j iterates from i+1 to len-1
  for (int j=i+1;j<len;j++) {
   int h = hamming (code[i],code[j]);
   mind = MIN (mind, h);  // if this code is smaller, replace it
  }
 return mind;
}
