C27 Answer


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

/* Puzzle C27 -- check if an array contains anywhere both a
|  value x and a value y. Return the number of elements
|  between them.
|
|  Return the smallest number of elements between x and y
|  if one or more or them are both in the array,
|  and -1 if they are not both there.
|
|  If x and y are the same value, look for two elements of that
|  value and return the smallest number of elements between them.
*/
int distBetweenElts( int arr[], int size, int x, int y )
{
  int jx, jy;
  int minimum;         /* current minimum separation */
  int dist;            /* distance between current pair of elements */
  int start, end;      /* interval in which to search for a new min */
  
  minimum = size;      /* separation will never be this large */
  
  /* look thru the array for each instance of x */
  for ( jx=0; jx < size; jx++ )
  {
    if ( arr[jx] == x )
    {
      /* for each instance of x, look for a y that is */
      /* closer than the current min separation       */
      start = jx-minimum-1;
      if (start < 0) start=0;

      end   = jx+minimum+1;
      if ( end >= size ) end = size;

      for (jy=start; jy < end; jy++ )
      {

        /* if a y is found, check that it is at a new */
        /* location, and find the separation from the current x */
        if ( arr[jy] == y && jy != jx )
        {
          dist = jx - jy;
          if ( dist < 0 ) dist = -dist;
          dist -= 1; /* number of separating elements */
          
          /* if the separation is a new min, remember it */
          if ( dist < minimum )
            minimum = dist;
        }
      }
    }
  }

  /* if the minimum has not changed since initialization */
  /* the array lacks both elements, so return -1 */
  if ( minimum != size )
    return minimum;
  else
    return -1;
}

void printArray( int arr[], int size )
{
  const int N = 10;
  int j;
  
  for ( j=0; j < size; j++ )
  {
    if ( j%N == N-1 )
      printf("%4d\n", arr[j] );
    else
      printf("%4d ", arr[j] );    
  }
}

/* Get user input, x and y. Return 0 if
|  the user wants to quit, otherwise return 1
*/
int userInput( int *x, int *y )
{
  char inputX[32], inputY[32];

  printf("x y: ");
  scanf("%s", inputX );
  
  if ( !isdigit((int)inputX[0]) && inputX[0] != '-' )
    return 0;
  else
  {
    scanf("%s", inputY );
    *x = atoi( inputX );
    *y = atoi( inputY );
    return 1;
  }
}

int main(int argc, char *argv[])
{
  const int SIZE = 10;
  int arr[] = { -5, -3, 0, 6, 4, 16, -3, 0, 7, 9 };
  int min, x, y;
   
  printArray( arr, SIZE );
  
  while ( userInput( &x, &y ) )
  {
    min = distBetweenElts( arr, SIZE, x, y );
    
    if ( min != -1 )
      printf("minimum distance %d\n", min );
    else
      printf("Failed to find both elements.\n");
  }
  
  system("PAUSE");	
  return 0;
}