// difftab.cc (c) Kris COOLSAET, Belgium
// ============================================================
// More info: http://turing.hogent.be/~kc/cds/part2.htm
//
// Displays the difference table of a tentative CDS and indicates
// whether it is a CDS, and in that case, whether it is perfect.
//
// usage:    difftab el1 el2 el3 ... el modulus
//
// history:
//   97/01/10    First version

#include <stdlib.h>
#include <iostream.h>
#include <iomanip.h>

// ------------------------------------------------------------
// USAGE
// ------------------------------------------------------------

void usage (char *progname)
{
  cerr << "usage: " << progname << " el1 el2 ... el modulus\n";
  exit (1);
}

// ------------------------------------------------------------
// DIFFTAB
// ------------------------------------------------------------
// Displays difference table and counts in the meantime how 
// many times each difference occurs.

void difftab (int *diffset, int size, int modulus)
{
  // init frequency table
  int *freqtab = new int [modulus];
  for (int i=0; i < modulus; i++)
    freqtab[i] = 0;
  
  // compute differences, print them and update frequency table
  for (int i=0; i < size; i++) {
    for (int j=0; j < size; j++) {
      int diff = (diffset[j] % modulus) - (diffset[i] % modulus);
      if (diff < 0) diff += modulus;
      freqtab [diff]++;

      cout << setw (4) << diff;
    }
    cout << endl;
  }

  // check frequency table
  if (freqtab[0]!=size) 
    cout << "Not all elements are different.\n";
  else {
    int j;
    for (j=1; j < modulus && freqtab[j] <= 1; j++);
    if (j < modulus) 
      cout << "This is NOT a cyclic difference set.\n";
    else {
      cout << "This is a";
      if (modulus == size*(size-1)+1)
	cout << " PERFECT";
      cout << " cyclic difference set.\n";
    }
  }

  // cleanup
  delete [] freqtab;
}

// ------------------------------------------------------------
// MAIN
// ------------------------------------------------------------

int main (int argc, char **argv)
{
  // check usage
  if (argc < 3) usage (argv[0]);
  argc--; argv++;

  // parse arguments
  int modulus = atoi (argv[argc-1]);
  argc--; 
  int size = argc;

  int *diffset = new int [size];
  for (int i=0; i < size; i++)
    diffset[i] = atoi (argv[i]);

  // do it
  difftab (diffset, size, modulus);

  // cleanup
  delete [] diffset;
  return 0;
}




