#include<stdlib.h>
#include<stdio.h>
#include<math.h>

/* function prototypes */
void printArray(int *array, int size);
double average(int *array, int size);
int *onesArray(int size);
void selectionSort ( int *a, int size );
int *sortedCopy(int *array, int size);
int **identityMatrix(int n);
void printMatrix(int **array, int rows, int columns);
/* additional exercises */
int minimum(int *array, int size);
int *sortedDescendingCopy(int *array, int size); 
void reverse(int *array, int size);

int main(void)
{

  int a[] = {21, 42, 61, 12, 4, 8, 3, 4, 10, 7};
  int i;
  printArray(a,10);
  double myAve = average(a,10);
  printf("The average of these elements is %f\n",myAve);
  int *myOnesArray = onesArray(14);
  printf("Ones Array:\n");
  printArray(myOnesArray,14);

  printf("Testing the copy sort: original array:\n");
  printArray(a, 10);

  int *sortedA = sortedCopy(a,10);
  printf("Sorted array:\n");
  printArray(sortedA,10); 
  printf("Original Array is unaltered:\n");
  printArray(a,10);

  int **ptrsToB;
  int b[][3] = { {1, 2, 3},
                 {9, 8, 7},
                 {5, 6, 4}};
  ptrsToB = (int **) malloc(3 * sizeof(int *)); 
  for(i=0; i<3; i++)
    ptrsToB[i] = b[i];

  printMatrix(ptrsToB, 3, 3);

  //  printf("to here");
  int **myIdentityMatrix = identityMatrix(6);
  printMatrix(myIdentityMatrix, 6, 6);
  
  free(myOnesArray);

  for(i=0; i<6; i++)
    free(myIdentityMatrix[i]);
  free(myIdentityMatrix);  

  printf("The minimum element in a is %d\n", minimum(a,10));
  int *c = sortedDescendingCopy(a,10);
  printArray(c,10);
  return 0;
}

void printArray(int *array, int size)
{
   int i;
   printf("----------\n");
   for(i=0; i<size; i++)
     printf("%10d\n", array[i]);
   printf("----------\n");
   return;
}

double average(int *array, int size)
{
   double theAverage = 0.0;
   int theSum = 0;
   int i;
   for(i=0; i<size; i++)
   {
     theSum += array[i];
   }
   theAverage = ((double) theSum / (double) size);
   return theAverage;
}

int *onesArray(int size)
{
  int * myDynamicArray = NULL;
  myDynamicArray = ( int *) malloc (size * sizeof ( int ));
  if(myDynamicArray == NULL)
  {
    printf("Mem allocation failed, quitting...\n");
    exit(-1);
  }
  int i;
  for(i=0; i<size; i++)
    myDynamicArray[i] = 1;
  return myDynamicArray;
}

int *sortedCopy(int *array, int size)
{
  int *myCopy = ( int *) malloc (size * sizeof ( int ));
  int i;
  for(i=0; i<size; i++)
    myCopy[i] = array[i];
  selectionSort(myCopy,size);
  return myCopy;
}

void selectionSort ( int *a, int size )
{
 int i, j, minimum_index , temp ;
 for (i=0; i<size -2; i++)
 {
 minimum_index = i;
 for (j=i+1; j< size ; j++)
 {
 if(a[ minimum_index ] > a[j])
 {
 minimum_index = j;
 }
 }
 temp = a[i];
 a[i] = a[ minimum_index ];
 a[ minimum_index ] = temp ;
}
}

void printMatrix(int **array, int rows, int columns)
{
  int i, j;
  for(i=0; i<rows; i++)
  {
    printf("[ ");
    for(j=0; j<columns; j++)
    {
	printf("%5d ", array[i][j]);
    }
    printf("]\n");
  }
}

int **identityMatrix(int n)
{
  int ** myMatrix = NULL ;
  myMatrix = (int **) malloc (n * sizeof (int *));
  int i=0, j=0;
  for(i=0; i<n; i++)
    myMatrix[i] = (int *) malloc (n * sizeof (int ));
  for(i=0; i<n; i++)
    for(j=0; j<n; j++)
    {
	if(i==j)
	  myMatrix[i][j] = 1;
	else
	  myMatrix[i][j] = 0;
    }
  return myMatrix;
}

int minimum(int *array, int size)
{
  int min = array[0];
  int i;
  for(i=1; i<size; i++)
  {
    if(array[i] < min)
      min = array[i];
  }
  return min;
}

int *sortedDescendingCopy(int *array, int size)
{
  int *myArray = NULL;
  myArray = sortedCopy(array, size);
  reverse(myArray,size);
  return myArray;
}

void reverse(int *array, int size)
{
  /* To do */
  return;
} 
