/* Program to print tables of metric equivalents */
#include <stdio.h>

#define NUM_CONVERSIONS 2

/* Liquid measure conversion factors */
const double QUARTS_PER_GALLON = 4.0;
const double QUARTS_PER_PINT = 2.0;
const double LITERS_PER_QUART = 1.056710;

/* Linear measure conversion factors */
const double INCHES_PER_FOOT = 12.0;
const double CENTIMETERS_PER_INCH = 2.54;
/* Note: according to the National Bureau of Standards, effective July 1, 1959,
     an inch was defined as exactly 2.54 centimeters */

/* Convert gallons and pints to liters
 *
 * Preconditions:
 *  gallons >= 0
 *  pints >= 0
 * Postconditions:
 *  Returns the equivalent volume in liters
 */
double
toLiters (double gallons, double pints)
{
  return (gallons * QUARTS_PER_GALLON +
          pints   * QUARTS_PER_PINT ) / LITERS_PER_QUART;
    
} // toLiters

/* Convert feet and inches to centimeters
 *
 * Preconditions:
 *  feet >= 0
 *  inches >= 0
 * Postconditions:
 *  Returns the equivalent length in centimeters
 */
double
toCentimeters (double feet, double inches)
{
  return (feet * INCHES_PER_FOOT + inches) * CENTIMETERS_PER_INCH;
} // toCentimeters


/* Print a table of metric equivalents
 *
 * Preconditions:
 *   func accepts two non-negative doubles
 * Postconditions:
 *   Prints two-dimensional table of f(x,y) over the domain [0,10]x[0,10]
 */
void
printTable (double func (double, double))
{
  double row, col;
  double rowStart = 0.0;
  double rowEnd  = 10.0;
  double colStart = 0.0;
  double colEnd  = 10.0;

  /* print column titles */
  printf ("         ");  /* space at start of row */
  for (col = colStart; col <= colEnd; col++)
    {
      printf (" %5.1lf", col);
    }
  printf ("\n\n");

  /* iterate over series of rows */
  for (row = rowStart; row <= rowEnd; row++)
    {
      /* print row label */
      printf ("  %4.1lf   ", row);

      /* print table entries */
      for (col = colStart; col <= colEnd; col++)
        {
          printf (" %5.1lf", func (row, col));
        }

      /* end of row */
      printf ("\n");
    }
} // printTable

/* Print tables of English to metric equivalents for volume and distance */
int
main (void)
{
  char * titles [NUM_CONVERSIONS] = 
    {"Table of gallon/pint to liter equivalents\n",
     "\n\nTable of feet/inch to centimenter equivalents\n"};

  double (*conversions[NUM_CONVERSIONS]) (double, double) = 
    {toLiters, toCentimeters};

  for (int i = 0 ; i < NUM_CONVERSIONS ; i++)
    {
      printf ("%s", titles[i]);
      printTable (conversions[i]);
    }

 return 0;
} // main

