/* P-2.1 */
/* "Hello, world." */

#include <stdio.h>
#define PI 3.14159

main()
{
	double two_pi;

	printf("Hello, world!\n");
	two_pi=2.0*PI;
	printf("%lf %lf",PI,two_pi);
	return(0);
}

/* P-2.2 */
/* Calculate the area and circumference of a circle
   of specified radius */

#include <stdio.h>
#define PI 3.14159

int main(void)
{
  double radius,        /* input - radius of a circle, cm         */
	 area,          /* output - area of a circle, cm^2        */
	 circumference; /* output - circumference of a circle, cm */
  /* Get the radius. */

  printf("Enter the radius in cm: ");
  scanf("%lf",&radius);

  /* Calculate the area and circumference. */

  area = PI*radius*radius;
  circumference = 2*PI*radius;

  /* Display the output. */

  printf("The area is %f cm^2.\n",area);
  printf("The circumference is %f cm.\n",circumference);
  return (0);
}

/* P-2.3 */
#include <stdio.h>

int main(void)
{
  int i;

  printf("Give integer: ");
  scanf("%i",&i);
  printf("%i %d\n",i,i);
  printf("Give integer: ");
  scanf("%d",&i);
  printf("%i %d\n",i,i);

  return 0;
}

/* P-2.4 */
/* Calculate the area and circumference of a circle
   of specified radius, using an external file. */

#include <stdio.h>
#define PI 3.14159

int main(void)
{
  double radius,           /* input - radius of a circle         */
	 area,             /* output - area of a circle          */
	 circumference;    /* output - circumference of a circle */
  FILE   *inp, *outp;      /* pointers to input and output files */

  /* Open the input and output files. */

  inp  = fopen("circle.dat","r"); /* Can't use full path name! */
  outp = fopen("circle.out","w");

  /* Read the radius. */

  fscanf(inp,"%lf",&radius);
  fprintf(outp,"The radius is %.2f\n",radius);
  printf("The radius is %.2f\n",radius);
  fclose(inp); /* Close the input file. */

  /* Calculate the area and circumference. */

  area = PI*radius*radius;
  circumference = 2*PI*radius;

  /* Store the output. */

  fprintf(outp,"The area is %.2f\n",area);
  fprintf(outp,"The circumference is %.2f\n",circumference);
  printf(      "The area is %.2f\n",area);
  printf(      "The circumference is %.2f\n",circumference);

  fclose(outp); /* Close the output file. */

  return (0);
}

/* P-2.5 */
/* Demonstrate reading a file of unknown length. STRUCTUR.C */

#include <stdio.h>
#define FILE_NAME "structur.dat" /* MS-DOS file names are case-insensitive. */

main()
{
     FILE *Infile;
     int count=0;
     int hr,min,sec;
     float x;
     int status=0;

     Infile=fopen(FILE_NAME,"r");
     while (1)
     {
       status=fscanf(Infile,"%i %i %i %f",&hr,&min,&sec,&x);
       if (status == EOF) break;
       printf("%2i %2i %2i %6.2f\n",hr,min,sec,x);
       count++;
     }
     fclose(Infile);
     printf("Lines in file = %i",count);
     return(0);
}

/* P-2.6 */
#include <stdio.h>
#define FILE_NAME "structur.dat"

main()
{
     FILE *Infile;
     char one_line[100];
     int count=0;
     int hr,min,sec;
     float x;
     char *line_ptr;

     Infile=fopen(FILE_NAME,"r");
     while (1){
       /* First read the line into a string. */
       line_ptr=fgets(one_line,sizeof(one_line),Infile);

       /* Quit if at end-of-file. */
       if (line_ptr == NULL) break;

       /* Otherwise, remove the end-of-line mark. */
       one_line[strlen(one_line)-1]='\0';

       /* Optionally, print the string just as a test. */
       printf("%s\n",one_line);

       /* Then scan the line to get numerical data. */
       (void) sscanf(one_line,"%i %i %i %f",&hr,&min,&sec,&x);
       printf("%2i %2i %2i %6.2f\n",hr,min,sec,x);

       /* Optionally, keep track of number of lines. */
       count++;
     }
     fclose(Infile);
     printf("Lines in file = %i",count);
     return(0);
}

/* P-2.7 */
/* Demonstrate reading a file of unknown length. FILETES2.C */

#include <stdio.h>
#define FILE_NAME "structr2.dat" /* MS-DOS file names are case-insensitive. */

main()
{
     FILE *Infile;
     char month[10];
     int count=0;
     int hr,min,sec;
     float x;
     int status=0;

     Infile=fopen(FILE_NAME,"r");
     while (1)
     {
       status=fscanf(Infile,"%s %i %i %i %f",month,&hr,&min,&sec,&x);
       if (status == EOF) break;
       printf("%3s %2i %2i %2i %6.2f\n",month,hr,min,sec,x);
       count++;
     }
     fclose(Infile);
     printf("Lines in file = %i",count);
     return(0);
}

/* P-2.8 */
#include <stdio.h>

int main(void)
{
  FILE *in;
  int ID,status=0,n_reports=0,n_measurements=0;
  char *line_ptr;
  char one_line[80];
  float x;

  in=fopen("stations.dat","r");
  while (1) {
    line_ptr=fgets(one_line,sizeof(one_line),in);
    if (line_ptr == NULL) break;
    status=sscanf(one_line,"%i %f %f %f %f %f %f %f %f",
		  &ID,&x,&x,&x,&x,&x,&x,&x,&x);
    n_reports++;
    n_measurements+=status-1;
  }
  fclose(in);
  printf("There are %i records and %i measurements.\n",
	  n_reports,n_measurements);
  return 0;
}

/* P-2.9 */
/* FILEVIEW.C */
/* Displays contents of a text file character-by-character. */

#include <stdio.h>
#include <stdio.h>

int main(void)
{
  FILE *in;
  char name[20];
  int ch;

  printf("Give file to fix: ");
  scanf("%s",name);

  in=fopen(name,"r");
  if (in == NULL) {
    printf("Can't find file.  Abort program.");
    exit();
  }
  while (!feof(in)) {
    ch=fgetc(in);
    printf("%3i",ch);
    if (ch == 10) printf("\n");
  }
  fclose(in);

  return 0;
}

/* P-2.10 */
/* BEAM.C */
/* Calculate deflection of supported beam under a central load
   from data supplied in an external text file. */

#include <stdio.h>
#define FILENAME "beam.dat"

int main(void)
{
  double length,force,elasticity,mom_of_inertia;
  FILE *infile;

  infile=fopen(FILENAME,"r");

  fscanf(infile,"%lf %lf",&length,&force);
  fscanf(infile,"%lf %lf",&elasticity,&mom_of_inertia);
  fclose(infile);
  printf("Length of beam (feet) and central force (lb): %.1lf %.1lf\n",
	  length,force);
  length=length*12.0;
  printf("Elasticity (lb/in^2) and moment of inertia (in^4): %e %.1lf\n",
	  elasticity,mom_of_inertia);
  printf("deflection = %lf in\n",
      -force*length*length*length/48.0/elasticity/mom_of_inertia);

  return 0;
}

/* P-2.11 */
/* REL_MASS.C */
/* Calculate speed and relativistic mass of an accelerated electron. */

#include <stdio.h>
#include <math.h>

#define E 1.602e-19 /* Coulomb */
#define C 2.9979e8 /* m/s */
#define REST_MASS 9.109e-31 /* kg */
#define FILENAME "rel_mass.dat"

int main(void)
{
  double voltage,speed,rel_mass;
  FILE *infile;
  int status=0;

  infile=fopen(FILENAME, "r");
  while (1) {
    status=fscanf(infile,"%lf",&voltage);
    if (status == EOF) break;
    printf("for voltage of : %e V\n",voltage);
    rel_mass=(voltage*E+REST_MASS*C*C)/(C*C);
    speed=C*sqrt(1.0-(REST_MASS/rel_mass)*(REST_MASS/rel_mass));
    printf("relativistic mass and speed: %g %g\n",rel_mass,speed);
  }
  fclose(infile);

  return 0;
}

/* P-3.1 */
/* Find ranges for numeric data. */
#include <stdio.h>
#include <limits.h>
#include <float.h>
#include <stdlib.h>
#include <math.h>
int main(void)
{
	printf("Range of short integer: %d %d\n",SHRT_MAX,SHRT_MIN);
	printf("Range of integer: %d %d\n",INT_MAX,INT_MIN);
	printf("Range of long integer: %ld %ld\n",LONG_MAX,LONG_MIN);
	printf("max unsigned short integer: %u\n",USHRT_MAX);
	printf("max unsigned integer: %u\n",UINT_MAX);
	printf("max unsigned long integer: %lu\n",ULONG_MAX);
	printf("Range of float: %e %e\n",FLT_MAX,FLT_MIN);
	printf("precision of float: %i\n",FLT_DIG);
	printf("range of double: %E %E\n",DBL_MAX,DBL_MIN);
	printf("precision of double: %i\n",DBL_DIG);
	printf("range of long double: %LG %LG\n",LDBL_MAX,LDBL_MIN);
	printf("precision of long double: %i\n",LDBL_DIG);
	printf("%e\n",HUGE_VAL);
	return(0);
}

/* P-3.2 */
/* Demonstrate some of C's operators. */
/* OPERATOR.C */
#include <stdio.h>

int main()
{
  int x,y;
  x=7;
  y=4;
  printf("%i %i\n",x%y,x/y);    /* (1) */
  x+=y;
  printf("%i\n",x);             /* (2) */
  x=y--;
  printf("x= %i, y= %i\n",x,y); /* (3) */
  x=--y;
  printf("x= %i, y= %i\n",x,y);  /* (4) */
  printf("%i\n",x*=y);          /* (5) */
  return 0;
}

/* P-3.3 */
/* Demonstrate effect of explicit type casting. */
#include <stdio.h>

main()
{
	int total_score,num_students;
	float average;

	printf("Enter sum of scores: ");
	scanf("%d",&total_score);
	printf("Enter number of students: ");
	scanf("%d",&num_students);

	average=total_score/num_students;
	printf("Average score (no type casting) is %.2f\n",average);

	average=total_score/(float)num_students;
	printf("Average score (with type casting) is %.2f\n",average);
	return(0);
}

/* P-3.4 */
/* Demonstrate use of math functions. */
#include <stdio.h>
#include <math.h>
#include <stdlib.h>

void main()
{
	double pi,x,y;

	pi=atan(1.0)*4.0;
	printf("acos(0.5)  %lf\n",acos(0.5));
	printf("asin(0.5)  %lf\n",asin(0.5));
	printf("atan2(-2.0,1.0)  %lf\n",atan2(-2.0,1.0));
	printf("cos(3.0)  %lf\n",cos(3.0));
	printf("cosh(0.5)  %lf\n",cosh(0.5));
	printf("sin(0.5)  %lf\n",sin(0.5));
	printf("sinh(0.5)  %lf\n",sinh(0.5));
	printf("tan(0.5)  %lf\n",tan(0.5));
	printf("tanh(0.5)  %lf\n",tanh(0.5));
	printf("abs(-7)  %d\n",abs(-7));
	printf("ceil(-3.3)  %lf\n",ceil(-3.3));
	printf("exp(0.5)  %lf\n",exp(0.5));
	printf("fabs(-3.3)  %lf\n",fabs(-3.3));
	printf("floor(-3.3)  %lf\n",floor(-3.3));
	printf("log(0.5)  %lf\n",log(0.5));
	printf("log10(0.5)  %lf\n",log10(0.5));
	printf("pow(2.0,3.5)  %lf\n",pow(2.0,3.5));
	printf("%d  %d\n",RAND_MAX,rand());
	printf("sqrt(0.5)  %lf\n",sqrt(0.5));
	printf("%e\n",HUGE_VAL);
}

/* P-3.5 */
/* Create simple functions. */
#include <stdio.h>
#define PI 3.14159265

/* function prototypes */
double area_func(double radius);
double circumference_func(double radius);

main()
{
  double radius=3.0;
  printf("From area_func: %8.3lf\n",area_func(radius));
  printf("from circumference_func: %8.3lf\n",circumference_func(radius));
}

double area_func(double radius)
/* PI must be available as a global constant. */
{
  return(PI*radius*radius);
}

double circumference_func(double radius)
/* PI must be available as a global constant. */
{
  return(2.0*PI*radius);
}

/* P-3.6 */
/* Create simple functions, without separate function prototypes. */
#include <stdio.h>
#define PI 3.14159265

/* function definitions */

double area_func(double radius)
/* PI must be available as a global constant. */
{
  return(PI*radius*radius);
}

double circumference_func(double radius)
/* PI must be available as a global constant. */
{
  return(2.0*PI*radius);
}

main()
{
  double radius=3.0;
  printf("From area_func: %8.3lf\n",area_func(radius));
  printf("from circumference_func: %8.3lf\n",circumference_func(radius));
}

/* P-3.7 */
/* Calculate table of atmospheric pressure.  */
#include <stdio.h>
#include <math.h>

double Pressure(double h);

main()
{
     int height;

     printf("height   pressure\n");
     printf("    km    gm/cm^2\n");
     printf("-----------------\n");
     for (height=0; height <= 80; height += 10)
          printf("%6i %10.3f\n",height,Pressure((double)height));
     return(0);
}

double Pressure(double height)
{
     return(1035.0*exp(-0.12*height));
}

/* P-3.8 */
/* REFRACT.C */
/* Do refraction calculations using Snell's Law */

#include <stdio.h>
#include <math.h>

int main(void)
{
  double ni,nr;              /* indices of refraction (dimensionless) */
  double incident,refracted; /* angles from perpendicular (deg) */
  double pi,deg_to_rad;

  pi=4.0*atan(1.0);
  deg_to_rad=pi/180.0;
  printf("Give indices of refraction for incident and refracting medium,\n");
  printf("separated by one or more spaces: ");
  scanf("%lf %lf",&ni,&nr);
  printf("What is the angle of incidence? ");
  fflush(stdin);
  scanf("%lf",&incident);

  refracted=asin(ni/nr*sin(incident*deg_to_rad));
  printf("refracted angle = %.2lf degrees",refracted/deg_to_rad);

  return 0;
}

/* P-3.9 */
/* HYPERBOL.C */
/* Calculate inverse hyperbolic functions. */

#include <stdio.h>
#include <math.h>

double inv_sinh(double z)
{
  return log(z+sqrt(z*z+1.0));
}
double inv_cosh(double z)
{
  double sign=1.0;

  if (z < 0.0) sign=-1.0;
  return sign*log(z+sqrt(z*z-1.0));
}
double inv_tanh(double z)
{
  return log((1.0+z)/(1.0-z))/2.0;
}

int main(void)
{
  double x,hyperbolic_sin,hyperbolic_cos,hyperbolic_tan,sign;

  printf("Give a real number: ");
  scanf("%lf",&x);
  hyperbolic_sin=sinh(x);
  hyperbolic_cos=cosh(x);
  hyperbolic_tan=hyperbolic_sin/hyperbolic_cos;
  printf("        Hyperbolic sin, cos, tan: %10.5lf %10.5lf %10.5lf\n",
	  hyperbolic_sin,hyperbolic_cos,hyperbolic_tan);
  printf("Inverse hyperbolic sin, cos, tan: %10.5lf %10.5lf %10.5lf\n",
	  inv_sinh(hyperbolic_sin),inv_cosh(hyperbolic_cos),
	  inv_tanh(hyperbolic_tan));

  return 0;
}

/* P-4.1 */
/* Demonstrate various selection structures */

# include <stdio.h>
# define TRUE 1
# define FALSE 0

main()
{
  int resting_heart_rate,temperature,raining;
  char plane_type,rain;

  printf("What is your resting heart rate? ");
  scanf("%d",&resting_heart_rate);
  if (resting_heart_rate > 56 )
	printf("You need more exercise.\n");
  else
	printf("You are in good shape.\n");

  printf("What is the aircraft type, [b]omber or [c]argo? ");
  fflush(stdin);
  scanf("%c",&plane_type);
  if ( (plane_type == 'b') || (plane_type == 'B') )
	printf("The aircraft is a bomber.\n");
  else if ( (plane_type == 'c') || (plane_type == 'C') )
	printf("The aircraft is a cargo plane.\n");
  else
	printf("I don't know what this aircraft is.\n");
  printf("How hot is it (deg F)? ");
  scanf("%i",&temperature);
  printf("Is it raining (y or n)? ");
  fflush(stdin);
  scanf("%c",&rain);
  if ( (rain == 'y') || (rain == 'Y') )
    raining=TRUE;
  else raining=FALSE;
  if ( (temperature > 85) && !raining )
    printf("Let's go swimming!\n");
  else
    printf("We'll stay inside.\n");
  return(0);
}

/* P-4.2 */
/* Simple decision structure.  TAXES.C */

#include <stdio.h>
#define LOW_RATE 0.07
#define HIGH_RATE 0.10
#define CUTOFF_INCOME 50000.0

int main()
{
  double income, tax;

  printf("Give income: $");
  scanf("%lf",&income);
  if (income <= CUTOFF_INCOME)
    tax=income*LOW_RATE;
  else
    tax=CUTOFF_INCOME*0.07+(income-CUTOFF_INCOME)*HIGH_RATE;
  printf("On an income of $%.2lf, the tax is $%.2lf\n",income,tax);
  return 0;
}

/* P-4.3 */
/* Illustrate multiple-alternative decisions */

#include <stdio.h>

main()
{
  int noise_db;

  printf("Enter the noise level as integer decibels: ");
  scanf("%i",&noise_db);
  if ( noise_db <= 50)
	printf("%i is quiet",noise_db);
  else if (noise_db <= 70)
	printf("%i is intrusive",noise_db);
  else if (noise_db <= 90)
	printf("%i is annoying",noise_db);
  else if (noise_db <= 110)
	printf("%i is very annoying",noise_db);
  else
	printf("%i is uncomfortable",noise_db);
  return(0);
}

/* P-4.4 */
#include <stdio.h>

int main(void) {
  char plane_type;
  printf("What is the aircraft type, [b]omber, [c]argo, [f]ighter? ");
/* NOTE: correction in conversion specifier (%s in text). */
  scanf("%c",&plane_type);
  switch(plane_type) {
    case 'b':
    case 'B':
	 printf("bomber\n");
	 break;
    case 'c':
    case 'C':
	 printf("cargo\n");
	 break;
    case 'f':
    case 'F':
	 printf("fighter\n");
	 break;
    default:
	 printf("unknown\n");
  }
  return 0;
}

/* P-4.5 */
/* Generate a table of trig values.  Demonstrates count-controlled loops. */
#include <stdio.h>
#include <math.h>

main()
{
  double angle,deg_to_rad;
  int i;

  deg_to_rad=4.0*atan(1.0)/180.0;
  printf(" i    x   sin(x)   cos(x)   tan(x)\n");
  printf("-------------------------------\n");
  for (i = 0; i <= 36; i++) {
    angle=i*5.0;
    printf("%3i %4.0f",i,angle);
    angle=angle*deg_to_rad;
    if (i*5 != 90) {
      printf("%9.4lf%9.4lf%9.4lf\n",sin(angle),cos(angle),tan(angle));
    }
    else {
      printf("%9.4lf%9.4lf\n",sin(angle),cos(angle));
    } /* end if... */
  }   /* end for... */
  return(0);
}

/* P-4.6(a) */
/* Print information about earth orbits. */
/* Uses pre-test loop. */

#include <stdio.h>
#include <math.h>

#define PI 3.1415927
#define G 398601.2        /* km^3/s^2 */
#define EARTH_RADIUS 6378 /* km */
#define DAY 86400.0       /* seconds */

void main()
{

	double period,altitude,total_time=0.0;
	int orbit_number=0;

	printf("What is the altitude (km)? ");
	scanf("%lf",&altitude);
	period=2.0*PI*(EARTH_RADIUS+altitude)*sqrt((EARTH_RADIUS+altitude)/G);
	printf("The orbital period is %.1f seconds.\n",period);
	while (total_time < DAY)
	  {
	    orbit_number++;
	    printf("Orbit #%2i starts at time %7.1f seconds.\n",
		   orbit_number,total_time);
	    total_time+=period;
	  }
}

/* P-4.6(b) */
/* Print information about earth orbits. */
/* Uses post-test loop. */

#include <stdio.h>
#include <math.h>

#define PI 3.1415927
#define G 398601.2        /* km^3/s^2 */
#define EARTH_RADIUS 6378 /* km */
#define DAY 86400.0       /* seconds */

main()
{
  double period,altitude,total_time=0.0;
  int orbit_number=0;

  printf("What is the altitude (km)? ");
  scanf("%lf",&altitude);
  period=2.0*PI*(EARTH_RADIUS+altitude)*sqrt((EARTH_RADIUS+altitude)/G);
  printf("The orbital period is %.1f seconds.\n",period);
  do
  {
    orbit_number++;
    printf("Orbit #%2i starts at time %7.1f seconds.\n",
	    orbit_number,total_time);
    total_time+=period;
  }
  while (total_time < DAY);
  return(0);
}

/* P-4.7 */
/* ELEVATOR.C
  Purpose: To allow individuals to enter an elevator as long as the
  total weight doesn't exceed a specified maximum.
*/
#include <stdio.h>
#define MAX 500

int main(void)
{
  int total_load=0,wt,proposed_load;

  do {
    printf("Give new proposed weight: ");
    scanf("%i",&wt);
    proposed_load=total_load+wt;
    if (proposed_load <= MAX) {
      total_load=proposed_load;
      printf("new = %4i total = %4i\n",wt,total_load);
    }
    else
      printf("NOT ALLOWED. This will give a total load of %i.\n",
	     total_load+wt);
  } while (proposed_load < MAX);

  return 0;
}

/* P-4.8 */
/* Perform input validation on numerical data. */

#include <stdio.h>
#define TRUE 1
#define FALSE 0

main()
{
	double dollars;
	char test_string[80];
	int i,good_data;

	do
	{
	  good_data=TRUE;
	  printf("Give a dollar amount with no commas: $");
	  scanf("%s",&test_string);
	  for (i=0; i < strlen(test_string); i+=1)
	  {
	      if ( (test_string[i] == ',') || (test_string[i] == '$') )
	      {
		good_data=FALSE;
		printf("Your input of %s is unacceptable.  Try again.\n",
			test_string);
		break;
	      } /* end if... */
	  } /* end for... */
	}
	while (! good_data);
	return(0);
}

/* P-4.9 */
/* Quadratic equation with test for discriminant. */

#include <stdio.h>
#include <math.h>

int main(void)
{
  double a,b,c,discriminant,root1,root2,LIMIT=1e-6;

  printf("Enter coefficients for ax^2+bx+c: ");
  scanf("%lf %lf %lf",&a,&b,&c);
  discriminant=b*b-4.0*a*c;
  printf("discriminant = %lf\n",discriminant);
  if (discriminant > LIMIT ) {
    root1=(-b+sqrt(discriminant))/2.0/a;
    root2=(-b-sqrt(discriminant))/2.0/a;
    printf("root1 = %lf, root2 = %lf\n",root1,root2);
  }
  else if (fabs(discriminant) <= LIMIT) {
    root1=-b/2.0/a;
    root2=0.0;
    printf("The single real root = %lf\n",root1);
  }
  else
    printf("There are no real roots.\n");
    root1=0.0;
    root2=0.0;

  return 0;
}

/* P-4.10 */
/* BEAM2.C */
/* Calculate deflection of beam under user-supplied
   conditions of support and loading. */

#include <stdio.h>

char MakeChoice(void);
double CalculateDeflection(char ch,double L,double F,
			   double E,double I);

int main(void)
{
  double length,force,elasticity,mom_of_inertia,deflection;
  char choice,more='y';
  do {
    printf("Give length (ft), force (lb),\n");
    printf("elasticity (lb/in^2), moment of inertia (in4): ");
    scanf("%lf %lf %lf %lf",&length,&force,&elasticity,&mom_of_inertia);
    choice=MakeChoice();
    deflection=CalculateDeflection(choice,length*12.,force,
				   elasticity,mom_of_inertia);
    printf("\nThe deflection is %.3lf inches\n",deflection);
    printf("\nMore (y/n)? ");
    fflush(stdin);
    scanf("%c",&more);
  } while (more == 'y');

  return 0;
}

char MakeChoice(void)
{
  char ch;
  printf("\n");
  printf("1 - supported at both ends, central load\n");
  printf("2 - supported at both ends, distributed load\n");
  printf("3 - supported at one end, loaded at free end\n");
  printf("4 - supported at one end, distributed load\n");
  printf("\n");
  printf("Choose one... ");
  fflush(stdin);
  scanf("%c",&ch);
  return ch;
}

double CalculateDeflection(char ch,double L,double F,
			   double E,double I)
{
  printf("CHoice: %c %lf %lf %lf %lf\n",ch,L,F,E,I);
  switch(ch) {
    case '1':
      return -F*L*L*L/48./E/I;
    case '2':
      return -5.*F*L*L*L/384./E/I;
    case '3':
      return -F*L*L*L/3./E/I;
    case '4':
      return -F*L*L*L/8./E/I;
    default:
      printf("Inappropriate support/loading option.\n");
      return 0;
  }
}

/* P-4.11 */
/* LC.C  Oscillating frequency of an LC circuit. */

#include <stdio.h>
#include <math.h>
#define C0 0.0
#define nC 10
#define dC 2.0
#define L0 0.0005
#define nL 6
#define dL 0.0005
#define PI 3.141596

int main(void)
{
  int row,col;
  double L, C, f;

  printf("OSCILLATING FREQUENCY (kHz) OF AN LC CIRCUIT\n");
  printf("          C(pF)=\n");
  printf("L(H)= ");
  for (col=1; col<=nC; col++) {
    C=C0+dC*col;
    printf("%5.0lf",C);
  }
  printf("\n");
  for (row=1; row<=nL; row++) {
    L=L0+dL*row;
    printf("%6.4lf",L);
    for (col=1; col<=nC; col++) {
      C=C0+dC*col;
      f=0.5/PI/sqrt(L*C*1e-12);
      printf(" %4.0lf",f/1000.0);
    }
    printf("\n");
  }
  return 0;
}

/* P-4.12 */
/* DOSE.C  Simulate radiation dose experiment. */

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX_TOTAL 1000.0
#define MAX_DOSE 200.0

int main(void)
{
  int i;
  double total_dose=0.0, proposed_total, dose;

  srand((unsigned)time(NULL)); /* initialize random # generator */
  printf("R A D I A T I O N    S I M U L A T I O N    T E S T\n");
  printf("     The maximum total dose for this test is %5.0lf.\n",
     MAX_TOTAL);
  printf("The maximum individual dose for this test is %5.0lf.\n\n",
     MAX_DOSE);
  printf("    dose   total\n");
  printf("----------------\n");
  do {
    dose=MAX_DOSE*rand()/RAND_MAX;
    proposed_total=total_dose+dose;
    if (proposed_total <= MAX_TOTAL) {
      total_dose+=dose;
      printf("%8.0lf%8.0lf\n",dose,total_dose);
    }
    else
      printf(
     "The proposed dose of %.0lf will exceed the max.  End test.\n",
     dose);
  } while ( proposed_total < MAX_TOTAL);
  return 0;
}

/* P-5.1 */
/* Demonstrates use of pointers to achieve the equivalent */
/* of passing variables by reference in Pascal. */
#include <stdio.h>
#define PI 3.14159265

/* function prototypes */
void circle_stuff(double radius, double *a_ptr, double *c_ptr);

main()
{
  double radius=3.0;
  double area, circumference;

  circle_stuff(radius, &area, &circumference);
  printf("%8.3f %8.3f\n",area, circumference);
  return(0);
}

void circle_stuff(double radius, double *a_ptr, double *c_ptr)
{
  *a_ptr=PI*radius*radius;
  *c_ptr=2.0*PI*radius;
}

/* P-5.2 */
#include <stdio.h>

int main(void) {
  int i=2,j=3,*i_ptr,*j_ptr;

  *i_ptr=i;
  *j_ptr=j;
  printf("%i %i %i %i %i %i\n",i,j,*i_ptr,*j_ptr,
	  *i_ptr+*j_ptr,(*i_ptr)*(*j_ptr));

  return 0;
}

/* P-5.3 */
/* Newton's Law of Cooling */

#include <stdio.h>
#include <math.h>

/* function prototypes */
void get_k(double T1, double T2, double T3,
	   double *k, double *T_ambient, double *T0);
double get_t(double T0, double T_ambient, double k, double t);

int main()
{
  char flag,again;
  double T0,T_ambient,T1,T2,t1,t2,T3,t3,k,t;

  do {
    again='n';
    printf("[k]: Solve for k, initial T, and ambient T,\n");
    printf("     given T at three equally spaced times.\n");
    printf("[t]: Solve for T at specified time, given intial T, ambient T, and k.\n");
    fflush(stdin);
    scanf("%c",&flag);
    switch (flag) {
      case 't':
      case 'T':
	printf("Give initial T, ambient T, k, and time: ");
	fflush(stdin);
	scanf("%lf %lf %lf %lf",&T0,&T_ambient,&k,&t);
	printf("T = %lf\n",get_t(T0,T_ambient,k,t));
	break;
      case 'k':
      case 'K':
	printf("Give T1, T2, T3: ");
	fflush(stdin);
	scanf("%lf %lf %lf",&T1,&T2,&T3);
	get_k(T1,T2,T3,&k,&T_ambient,&T0);
	printf("k = %lf, T_ambient =  %lf, To = %lf\n",k,T_ambient,T0);
	break;
      default:
	printf("INPUT ERROR.  Try again...\n");
    }
    printf("Do again (y or n)?\n");
    fflush(stdin);
    scanf("%c",&again);
  } while (again == 'y');
  return 0;
}

double get_t(double T0, double T_ambient, double k, double t)
{
  return(T_ambient+(T0-T_ambient)*exp(-k*t));
}

void get_k(double T1, double T2, double T3, double *k, double *Ta, double *T0)
{
  *k = -log((T2-T3)/(T1-T2));
  *Ta = (T3*T1-T2*T2)/(T1+T3-2.0*T2);
  *T0 = (T1+exp(-*k)**Ta-*Ta)/exp(-*k);
}

/* P-5.4 */
/* Demonstrate use of output parameters as arguments in call
   to a function within a function */
#include <stdio.h>
#define PI 3.14159265

/* function prototypes */
void circle_stuff(double *radius, double *area, double *circumference);

main()
{
  double radius, area, circumference;

  circle_stuff(&radius, &area, &circumference);
  printf( "%8.3lf %8.3lf %8.3lf\n",radius,area,circumference);
  return(0);
}

void circle_stuff(double *radius_ptr,
		  double *area_ptr, double *circumference_ptr)
{
  printf("Give radius: ");
  scanf("%lf",radius_ptr);
  *area_ptr=PI*(*radius_ptr)*(*radius_ptr);
  *circumference_ptr=2.0*PI*(*radius_ptr);
}

/* P-5.5 */
/* Demonstrate use of output parameters as arguments in call
   to a function with a function */
#include <stdio.h>
#define PI 3.14159265

/* function prototypes */
void circle_stuff(double *radius, double* area, double *circumference);

main()
{
  double radius, area, circumference;

  circle_stuff(&radius, &area, &circumference);
  printf( "%8.3lf %8.3lf %8.3lf\n",radius,area,circumference);
}

void circle_stuff(double *radius_ptr,
		  double *area_ptr, double *circumference_ptr)
{
  double r;

  printf("Give radius: ");
  scanf("%lf",&r);
  *area_ptr=PI*r*r;
  *circumference_ptr=2.0*PI*r;
  *radius_ptr=r;
}

/* P-5.6 */
/* Demonstrate recursion-- with n!. */
#include <stdio.h>

long factorial(int n);

main()
{
  int n;

  printf("Give an integer: ");
  scanf("%i",&n);
  printf("%ld\n",factorial(n));
  return(0);
}

long factorial(int n)
{
  if (n <=1 )
     return (long)1;
  else
     return (long)n*factorial(n-1);
}

/* P-5.7 */
/* Fibonacci function.  FIBONACI.C */
#include <stdio.h>

int fibonacci(int n);

int main(void)
{
  int n;

  printf("Which term? ");
  scanf("%i",&n);
  printf("%i\n",fibonacci(n));
  return 0;
}

int fibonacci(int n)
{
  int fib;
  if (n <= 2) return(1);
  else
    return fibonacci(n-1)+fibonacci(n-2);
}

/* P-5.8(a)
/* Fibonacci function driver program. */
#include <stdio.h>
#include "fib_func.c"

int main(void)
{
  int n;

  printf("Which term? ");
  scanf("%i",&n);
  printf("%i\n",fibonacci(n));
  return 0;
}

/* P-5.8(b)
/* Fibonacci function. */

int fibonacci(int n)
{
  if (n <= 2) return(1);
  else return(fibonacci(n-1)+fibonacci(n-2));
}

/* P-5.9(a)
/* Fibonacci function driver program. */
#include <stdio.h>

extern int fibonacci(int n);

int main(void)
{
  int n;

  printf("Which term? ");
  scanf("%i",&n);
  printf("%i\n",fibonacci(n));
  return 0;
}

/* P-5.9(b) see text */
/* P-5.10(a)
#include <stdio.h>
#include <math.h>
#define PI 3.14159

void print_f(int lower,int upper,int di,double conversion);

int main(void)
{
  print_f(0,10,1,5.*PI/180.);
  return 0;
}

void print_f(int lower,int upper,int di,double conversion) {
  int i;
  double x;

  for(i=lower; i<=upper; i+=di) {
    x=i*conversion;
    printf("%2i %5.2lf %10.3lf\n",i,x,sin(x));
  }
}

/* P-5.10(b)
#include <stdio.h>
#include <math.h>

void print_f(int lower,int upper,int di,double conversion);
double f_of_x(double x);

int main(void)
{
  print_f(0,10,1,.5);
  return 0;
}

double f_of_x(double x) {
  return sqrt(x);
}

void print_f(int lower,int upper,int di,double conversion) {
  int i;
  double x;

  for(i=lower; i<=upper; i+=di) {
    x=i*conversion;
    printf("%2i %5.2lf %10.3lf\n",i,x,f_of_x(x));
  }
}

/* P-5.10(c) */
#include <stdio.h>
#include <math.h>

void print_f(int lower,int upper,int di,double conversion,
	     double (*f)(double x));
double f_of_x(double x);

int main(void)
{
  print_f(0,10,1,.5,f_of_x);
  return 0;
}

double f_of_x(double x) {
  return sqrt(x);
}

void print_f(int lower,int upper,int di,double conversion,
	     double (*f)(double x)) {
  int i;
  double x;

  for(i=lower; i<=upper; i+=di) {
    x=i*conversion;
    printf("%2i %5.2lf %10.3lf\n",i,x,f(x));
  }
}

/* P-5.11 */
#include <stdio.h>
#include <stdlib.h>

int main(int argc,char *argv[])
{
  int n1,n2,display;
  if (argc < 4) {
    printf("Please enter two integers on the command line,\n");
    printf("then -s or -l to return smaller or larger value.\n");
    printf("Separate command line arguments by spaces.\n");
    return -1;
  }
  else {
    n1=atoi(argv[1]);
    n2=atoi(argv[2]);
    printf("%i %i\n",n1,n2);
    switch (argv[3][1]) {
      case 's':
      case 'S':
	if (n1 <= n2) printf("%i\n",n1);
	else printf("%i\n",n2);
	break;
      case 'l':
      case 'L':
	if (n1 >=n2) printf("%i\n",n1);
	else printf("%i\n",n2);
	break;
      default:
	printf("Unknown command line option.\n");
	return -2;
    }
    return 0;
  }
}

/* P-5.12 */
/* Quadratic equation with test for discriminant. */

#include <stdio.h>
#include <math.h>

int GetRoots(double a,double b,double c,double *r1,double *r2);

int main(void)
{
  double a,b,c,root1,root2;
  int n_roots;

  printf("Enter coefficients for ax^2+bx+c: ");
  scanf("%lf %lf %lf",&a,&b,&c);
  n_roots=GetRoots(a,b,c,&root1,&root2);
  printf("%i\n",n_roots);
  switch(n_roots) {
    case 2:
      printf("The 2 real roots are: %lf %lf\n",root1,root2);
      break;
    case 1:
      printf("The 1 real root is: %lf %lf\n",root1);
      break;
    case 0:
      printf("There are no real roots.\n");
  }
  return 0;
}

int GetRoots(double a,double b,double c,double *r1,double *r2) {
/* Returns single root in r1, assigns non-existent roots
   a value of 0. */
  double discriminant;
  int n_roots;

  discriminant=b*b-4.0*a*c;
  printf("discriminant = %e\n",discriminant);
  if (discriminant > 0.0 ) {
    *r1=(-b+sqrt(discriminant))/2.0/a;
    *r2=(-b-sqrt(discriminant))/2.0/a;
    n_roots=2;
  }
  else if (discriminant == 0.0) {
    *r1=-b/2.0/a;
    *r2=0.;
    n_roots=1;
  }
  else {
    *r1=0.;*r2=0.;
    n_roots=0;
  }
  return n_roots;
}

/* P-5.13 */
/* Determine if an integer is prime.  PRIME.C */

#include <stdio.h>
#include <math.h>
#define TRUE 1

int IsPrime(int n, int trial);

int main()
{
  int prime,n;
  do {
    printf("Give an integer, 0 to quit: ");
    scanf("%i",&n);
    if (n == 0) break;
    prime=IsPrime(n,3);
    if (prime == TRUE)
      printf("%i is prime.\n",n);
    else
      printf("%i isn't prime.\n",n);
  } while (n != 0);

  return 0;
}

int IsPrime(int n, int trial)
{
  if (n <= 3)
    return 1;
  else if (n%trial == 0)
    return 0;
  else if (trial >= (int)sqrt((double)n) )
    return 1;
  else
    return IsPrime(n,trial+2);
}

/* P-14 */
/* Towers of Hanoi */

#include <stdio.h>

void MoveRings(int n_rings, int start, int finish, int aux);

main()
{
  int n_rings;

  printf("Give number of rings to move: ");
  scanf("%i",&n_rings);
  MoveRings(n_rings,1,3,2);
  return(0);
}

void MoveRings(int n, int start,int finish,int aux)
{
  if (n > 0)
  {
    MoveRings(n-1,start,aux,finish);
    printf("Move ring %i from %i to %i\n",n,start,finish);
    MoveRings(n-1,aux,finish,start);
  }
}

/* P-5.15 */
/* Use Trapezoidal Rule integration. */
#include <stdio.h>
#include <math.h>

double pdf(double x);
double Trapezoidal_Rule(double x1,double x2,double (*f)(double));
double t(double x1,double x2,double (*f)(double)) {
  int i,n=100;
  double sum=0.,dx;
  dx=(x1+x2)/n;
  for (i=1; i<=n; i++)
    sum+=f(x1+(i-1)*dx)+f(x1+i*dx);
  return sum*dx/2.;
}

int main(void)
{
  double z;

  printf("Give value of standard normal variable, >0: ");
  scanf("%lf",&z);
  printf("%lf\n",Trapezoidal_Rule(0.,z,pdf));
  printf("%lf\n",t(0.,z,pdf));
  return 0;
}

double pdf(double x) {
  return exp(-x*x/2.)/sqrt(8.*atan(1.));
}

double Trapezoidal_Rule(double x1,double x2,double (*f)(double)) {
  int i,n=100;
  double sum=0.,dx;

  dx=(x2-x1)/n;
  for (i=1; i<n; i++)
    sum+=f(x1+i*dx);
  return (f(x1)+f(x2))*dx/2.+sum*dx;
}

/* P-6.1 */
/* A typical array-based problem. */
#include <stdio.h>
#define FILENAME "arrays.dat"
#define MAX_SIZE 20

int main(void)
{
  float x[MAX_SIZE],avg;
  int n=0,status=0,i;
  FILE *infile;

  infile=fopen(FILENAME,"r");
  while (1) {
    status=fscanf(infile,"%f",&x[n]);
    if (status == EOF) break;
    avg+=x[n];
    printf("%i %lf\n",n,x[n]);
    n++;
  }
  fclose(infile);
  printf("There are %i values.\n",n);
  avg/=(double)n;
  printf("The average value is %f\n",avg);
  printf("Values >= average:\n");
  for (i=0; i<n; i++)
    if (x[i] >= avg) printf("%i %f\n",i+1,x[i]);

  return 0;
}

/* P-6.2 */
/* Sort an array using prewritten Selection Sort algorithm. */

#include <stdio.h>
#define MAX_SIZE 10

void SelectionSort(double a[],int n);
void Swap(double *x,double *y);

int main(void)
{

  int i;
  double x[MAX_SIZE];
  FILE *infile;

  infile=fopen("arrays.dat","r");
  for (i=0; i < MAX_SIZE; ++i) {
    fscanf(infile,"%lf",&x[i]);
    printf("%d  %lf\n",i,x[i]);
  }
  fclose(infile);
  SelectionSort(x,MAX_SIZE);
  for (i=0; i<MAX_SIZE; i+=1)
    printf("%d  %lf\n",i,x[i]);

  return 0;
}

void SelectionSort(double a[],int n)
{
	int i,j,min;

	for (i=0; i < (n-1); i++) {
	  min=i;
	  for (j=i+1; j < n; j++)
	    if (a[j] < a[min]) min=j;
	  if (a[i] != a[min]) Swap(&a[i],&a[min]);
	}
}

void Swap(double *x,double *y) {
  double temp;
  temp=*x;
  *x=*y;
  *y=temp;
}

/* P-6.3 */
/* PLANETS.C */
#include <stdio.h>
#include <string.h>
#include <math.h>

/* function prototypes */
int get_one_line(FILE *inptr, int max_char, char put_here[]);
void parse_line(char temp[81], int start, char v[81]);

void main()
{
  FILE *inptr;
  float distance[9],diameter[9];
  char temp[81],v[81];
  int ch;
  int index = 0;
  char planet[81][9];

  if( (inptr=fopen("planets.dat","rt")) != NULL) {
    printf("Opening file...\n");
    fgets(temp,sizeof(temp),inptr);
    ch = 0;
    while (ch != EOF)
    {
      ch = get_one_line(inptr,81,temp);
      if (ch != EOF) {
	/* printf("%s  %i\n",temp,strlen(temp)); */
	parse_line(temp,0,v);
	strcpy(planet[index],v);
	printf("%3i %10s ",index,planet[index]);
	parse_line(temp,8,v);
	diameter[index] = atof(v);
	printf("%10.0f ",diameter[index]);
	parse_line(temp,15,v);
	distance[index] = atof(v);
	printf("%10.1f\n",distance[index]);
	index++;
      }
    }
    printf("done...\n");
  }
  else printf("Trouble opening file...\n");
}

int get_one_line(FILE *inptr, int max_char, char put_here[])
{
  int ch, index = 0;
  while (index < max_char &&
	 (ch = fgetc(inptr)) != EOF &&
	  ch != '\n')
  {
    put_here[index] = ch;
    index++;
  }
  put_here[index] = '\0';
  while(ch != EOF && ch != '\n') ch = fgetc(inptr);
  return(ch);
}

void parse_line(char temp[81], int start, char v[81])
{
  int index = start;
  int new_index = 0;
  while (temp[index] == ' ') index++; /* remove leading blanks */
  while (index < strlen(temp) && temp[index] != ' ') /* build new string */
  {
    v[new_index]=temp[index];
    index++;
    new_index++;
  }
  v[new_index]='\0';  /* add terminating character to new string */
}

/* P-6.4 */
/* Calculate basic statistics. */

#include <stdio.h>
#include <stdlib.h> /* for random number generator */
#include <math.h>
#include <time.h> /* for initializing random number generator */
#define N_SAMPLES 100

/* function prototypes */
void get_data(double array[]);

void main()
{
  double data_array[N_SAMPLES];
  double sum_x=0.0, sum_x2=0.0;
  double average, std_dev;
  int i;

  get_data(data_array);
  for (i=0; i < N_SAMPLES; ++i)
  {
    printf("%lf\n",data_array[i]);
    sum_x=sum_x+data_array[i];
    sum_x2=sum_x2+data_array[i]*data_array[i];
  }
/*  printf("%lf  %lf  %lf\n",sum_x,sum_x2,(double)N_SAMPLES); */
  std_dev=sqrt((sum_x2-sum_x*sum_x/(double)N_SAMPLES)/((double)N_SAMPLES-1.0));
  average=sum_x/(double)N_SAMPLES;
  printf("average = %lf, standard deviation =  %lf\n",average,std_dev);
}

void get_data(double data_array[])
{
  int i;

  srand((unsigned)time(NULL)); /* Reinitializes rand each time, using */
			       /* seed from system clock. */
	    /* get different values each time. */
  for (i=0; i < N_SAMPLES; ++i)
    data_array[i]=(double)rand()/(double)RAND_MAX;
}

/* P-6.5 */
/* READARAY.C */
/* Demonstrate reading data into 2-D array. */
/* The data can be either one value per line (READARAY.DA1) or */
/* row-by-row (3 rows of 4 values each, see READARAY.DA2). */
#include <stdio.h>
#define N_ROWS 3
#define N_COLS 4
void main()
{
  FILE *infile;
  float data_array[3][4];
  int row,col;

  infile = fopen("READARAY.DA2","r");
  for (row=0; row < N_ROWS; row+=1)
  {
    for (col=0; col < N_COLS; col+=1)
      {
	fscanf(infile,"%f",&data_array[row][col]);
	printf("%5.1f",data_array[row][col]);
      }
    printf("\n");
  }
  fclose(infile);
}

/* P-6.6(a) */
/* Process ozone data.  OZONE.C */

#include <stdio.h>
#define MAX_DAYS 31
#define MAX_HOURS 24
#define FILE_NAME "ozone.dat"

void main()
{
  char one_line[100];
  int day, hour, n_days;
  static int ozone[MAX_DAYS][MAX_HOURS];
  FILE *infile;

  infile=fopen(FILE_NAME,"r");
/* Read and print two header lines. */
  (void)fgets(one_line,sizeof(one_line),infile);
  printf("%s\n",one_line);
  (void)fgets(one_line,sizeof(one_line),infile);
  printf("%s\n",one_line);
/* Get days in month. */
  fscanf(infile,"%d",&n_days);
  printf("There are %d days in this month.\n",n_days);
/* Read ozone data. */
  for (day=0; day < n_days; ++day)
    for (hour=0; hour < MAX_HOURS; ++hour)
      fscanf(infile,"%i",&ozone[day][hour]);
  fclose(infile);
/* Display ozone data. */
  for (day=0; day < n_days; ++day)
  {
    printf("(%2i)",day+1);
    for (hour=0; hour < MAX_HOURS; ++hour)
      printf("%3i",ozone[day][hour]);
    printf("\n");
  }
}

/* P-6.6(b) */
/* Process ozone data.  OZONE.C */

#include <stdio.h>
#define MAX_DAYS 31
#define MAX_HOURS 24
#define FILE_NAME "ozone.dat"
#define NULL_CHAR '\0'

void Display(int O[][24],int n);
void main()
{
  char one_line[100];
  int day, hour, n_days;
  static int ozone[MAX_DAYS][MAX_HOURS];
  FILE *infile;

  infile=fopen(FILE_NAME,"r");
/* Read and print two header lines. */
  (void)fgets(one_line,sizeof(one_line),infile);
  printf("%s\n",one_line);
  (void)fgets(one_line,sizeof(one_line),infile);
  printf("%s\n",one_line);
/* Get days in month. */
  fscanf(infile,"%d",&n_days);
  printf("There are %d days in this month.\n",n_days);
/* Read ozone data. */
  for (day=0; day < n_days; ++day)
    for (hour=0; hour < MAX_HOURS; ++hour)
      fscanf(infile,"%i",&ozone[day][hour]);
  fclose(infile);
/* Display ozone data. */
  Display(ozone,n_days);
}
void Display(int O[][24],int n) {
  int day,hour;

  for (day=0; day < n; ++day)
  {
    printf("(%2i)",day+1);
    for (hour=0; hour < MAX_HOURS; ++hour)
      printf("%3i",O[day][hour]);
    printf("\n");
  }
}

/* P-6.7 */
/* Array demonstration */
#include <stdio.h>
#define MAX_SIZE 10

void ArrayMod_ptr(double a[]);
void ArrayModify(double a[]);

void main()
{

	int i;
	double x[MAX_SIZE];
	double *ptr=x; /* Initialize to beginning of array. */
	FILE *infile;

	infile=fopen("arrays.dat","r");
	for (i=1;i <= MAX_SIZE;i+=1)
	{
	  fscanf(infile,"%lf",ptr++);
	}
	fclose(infile);
	ptr=x; /* Point to beginning of array. */
	for (i=1; i <= MAX_SIZE; i+=1)
	  printf("%d %d %lf\n",i,ptr,*ptr++);
	ArrayModify(x);
	ptr=x;
	for (i=1; i <= MAX_SIZE; i++)
	  printf("%d  %lf\n",i,*ptr++);
	ArrayMod_ptr(x);
	for (i=0; i< MAX_SIZE; i++)
	  printf("%d  %lf\n",i,x[i]);
}

void ArrayMod_ptr(double *ptr)
{
	int i;

	for (i=1; i <= MAX_SIZE; i++)
	{
	  *ptr=-(*ptr); /* The parentheses are optional. */
	  ptr++;
	}
}
void ArrayModify(double a[])
{
  int i;
  for (i=0; i< MAX_SIZE; i++)
    a[i]*=-1.;
}

/* P-6.8 */
/* STRINGS.C */

#include <stdio.h>
#include <string.h>

int main(void)
{
  char name[15];
  int i;

  printf("Enter your first and last name: ");
  scanf("%s",name);
  printf("length: %i\n",strlen(name));
  for (i=0; i<strlen(name); i++)
    printf("%c",name[i]);
  printf("\n");
  for (i=0; i<15; i++) {
    printf("%4i",(int)name[i]);
    if (name[i] == '\0')printf("NUL");
  }
  printf("\n");
  printf("Enter your first and last name: ");
  fflush(stdin);
  fgets(name,sizeof(name),stdin);
  printf("%s %i\n",name,strlen(name));
  for (i=0; i<15; i++) {
    printf("%4i",(int)name[i]);
    if (name[i] == '\0')printf("NUL");
  }
  return 0;
}

/* P-6.9 */
/* SIERPINS.C */
/* One-dimensional cellular automata with rule that generates
   a Sierpinski triangle. */

#include <stdio.h>
#define SIZE 40
#define N_CYCLES 15

void Display(int a[],int size);
void Update(int a[],int size);

int main(void)
{
  int a[SIZE],i;

  for (i=0; i<SIZE; i++)
    a[i]=0;
  a[SIZE/2]=1;
  printf("Generation  0:  ");
  Display(a,SIZE);
  for (i=1; i<= N_CYCLES; i++) {
    Update(a,SIZE);
    printf("Generation %2i:  ",i);
    Display(a,SIZE);
  }
  return 0;
}
void Update(int a[], int size)
{
  int old_a[SIZE],a_1,a0,a1,i;

  for (i=0; i<size; i++)
    old_a[i]=a[i];
  for (i=1; i<size-1; i++)
    a[i]=(old_a[i-1] && !old_a[i] && !old_a[i+1])
      || (!old_a[i-1] && old_a[i+1]);
}
void Display(int a[],int size)
{
  int i;
  for (i=0; i<size; i++)
    if (a[i] == 1) printf("*");
    else printf(" ");
  printf("\n");
}

/* P-6.10 */
/* PROB.C */
/* Evaluate probabilities by parsing a string expression and
   performing the implied calculations. */

#include <stdio.h>
#include <string.h>
#include <math.h>

double ParseString(char a[]);
void SubString(char a[],int left,int right,char new_a[]);

long unsigned Fact(int n) {
  long unsigned prod=(long unsigned)1;
  int i;

  if (n>1) for (i=2; i<=n; i++) prod*=(long unsigned)i;
  return prod;
}
int C(int n,int k) {
  int c;

  c=(int)(Fact(n)/Fact(k)/Fact(n-k));
  printf("C(%3i,%3i) = %3i\n",n,k,c);
  return c;
}

int main(void)
{
  char a[80];
  double probability;

  printf("Enter expression to be evaluated (no syntax checking).\n");
  printf("Example: 1-c(10,0,.2)-c(10,1,.2)\n");
  printf("----> ");
  scanf("%s",a);
  probability=ParseString(a);
  printf("probability = %lf\n",probability);
  return 0;
}
double ParseString(char a[])
{
  int sign,left,right,i,n,k;
  char b[10];
  double probability=0.,prob_a;

  if (a[0] == '1') probability=1.;
  sign=1;
  for (i=0; i<strlen(a); i++) {
    switch(a[i]) {
      case '+':
	sign=1;
	break;
      case '-':
	sign=-1;
	break;
      case '(':
	left=i;
	break;
      case ')':
	SubString(a,left+1,i-1,b);
	sscanf(b,"%i,%i,%lf",&n,&k,&prob_a);
	probability+=sign*(double)C(n,k)*pow(prob_a,(double)k)*
		     pow(1.-prob_a,(double)(n-k));
	break;
      default:; /* Ignore everything else. */
    }
  }
  return probability;
}
void SubString(char a[],int left,int right, char b[])
{
  int i,i_b=-1;
  for (i=left; i<=right; i++) {
    i_b++;
    b[i_b]=a[i];
  }
  b[i_b+1]='\0';
}

/* P-6.11 */
#include <stdio.h>
#include <string.h>

int main(void) {
  char a[80],separators[]=" ",*p;
  int ID;
  float x;
  FILE *in;

  in=fopen("stations.dat","r");
  while (1) {
    p=fgets(a,sizeof(a),in);
    if (p == NULL) break;
    sscanf(p,"%i",&ID);
    printf("%i",ID);
    p+=strspn(p,separators);

    while (1) {
      p+=strcspn(p,separators);
      if (*p == 0) break;
      sscanf(p,"%f",&x);
      printf(" %5.1f",x);
      p+=strspn(p,separators);
    }
    printf("\n");
  }
  fclose(in);

  return 0;
}

/* P-7.1 */
/* Demonstrate use of structures. */
/* Program file name STRUCTUR.C */

#include <stdio.h>
#define FILE_NAME "structur.dat"
/* NOTE: The typedef's are INSIDE main in the text. Although the
   program will work as printed in the text, the typedef's should
   be defined before main. If they're not, they won't be visible to
   the user-defined functions in any program that includes such functions.
*/
/*  typedef struct
  {
    int hr,min,sec;
    float measurement;
  }data_record_type;*/

  struct data_record
  {
    int hr,min,sec;
    float measurement;
  };

void main()
{
  typedef struct data_record data_record_type;
  FILE *Infile;
  int count=0;
  int status=0;
  data_record_type measurements;

  Infile=fopen(FILE_NAME,"r");
  while (status != EOF)
  {
    status=fscanf(Infile,"%i %i %i %f",&measurements.hr,
		  &measurements.min,&measurements.sec,
		  &measurements.measurement);
    if (status != EOF)
    {
      printf("%2i %2i %2i %6.2f\n",measurements.hr,measurements.min,
	      measurements.sec,measurements.measurement);
      count++;
    }
  }
  printf("There are %d records.",count);
  fclose(Infile);
}

/* P-7.2 */
/* PLANETS4.C */
#include <stdio.h>
#define NAME_LENGTH 8

typedef struct {
  char name[NAME_LENGTH];
  double diameter, distance;
} planet_type;

void main()
{
  FILE *InFile;
  int status=0;
  int index=0;
  planet_type planets[11];
  char header_line[81];

  if( (InFile=fopen("planets.dat","rt")) != NULL) {
    printf("Opening file...\n");
    (void)fgets(header_line,sizeof(header_line),InFile);
    while (1) {
      status=fscanf(InFile,"%s %lf %lf",planets[index].name,
		    &planets[index].distance,&planets[index].diameter);
      if (status == EOF) break;
      printf("%-8s %10.0lf %10.1lf\n",planets[index].name,
		planets[index].distance,planets[index].diameter);
      index++;
    }
    printf("done...\n");
    /* Note that "index" is number of records, not last accessible
       array element, which is index-1. */
    printf("Found %i records.\n",index);
  }
  else printf("Trouble opening file...\n");
  fclose(InFile);
}

/* P-7.3 */
/* Calculate the area and circumference of a circle
   of specified radius, using a structure to hold all values. */

#include <stdio.h>
#define PI 3.14159

typedef struct {
  double radius,area,circumference;
} circle_type;

circle_type circle_stuff(circle_type c);

int main(void)
{
  circle_type circle;

  printf("Give radius: ");
  scanf("%lf",&circle.radius);

  /* Calculate the area and circumference. */

  circle=circle_stuff(circle);

  printf("The area is %.2f\n",circle.area);
  printf("The circumference is %.2f\n",circle.circumference);

  return (0);
}
circle_type circle_stuff(circle_type c) {
  c.area=PI*c.radius*c.radius;
  c.circumference=PI*2.*c.radius;
  return c;
}

/* P-7.4 */
/* BOUNDARY.C*/

#include <stdio.h>
#include <math.h>
#define FILENAME "boundary.dat"
#define MAX 15

typedef struct {
  double x,y,L;
} land_type;

void ReadData(char filename[],land_type a[],int *n);
void Calculate(land_type a[],int n,double *perimeter,double *area);
void DisplayData(land_type a[],int n);

int main()
{
  land_type a[MAX];
  int n;
  double perimeter,area;

  ReadData(FILENAME,a,&n);
  Calculate(a,n,&perimeter,&area);
  printf("%i coordinate pairs\n",n);
  DisplayData(a,n);
  printf("%lf %lf\n",perimeter,area);

  return 0;
}
void Calculate(land_type a[],int n, double *perimeter,double *area) {
  int i;
  *perimeter=0.;
  *area=0.;
  for (i=1; i<n; i++) {
    a[i].L=sqrt((a[i].x-a[i-1].x)*(a[i].x-a[i-1].x)+
	   (a[i].y-a[i-1].y)*(a[i].y-a[i-1].y));
    *perimeter+=a[i].L;
  }
  a[0].L=sqrt((a[n-1].x-a[0].x)*(a[n-1].x-a[0].x)+
		     (a[n-1].y-a[0].y)*(a[n-1].y-a[0].y));
  *perimeter+=a[0].L;
  for (i=0; i<(n-1); i++)
    *area+=a[i].x*a[i+1].y-a[i].y*a[i+1].x;
  *area=(*area+a[n-1].x*a[0].y-a[n-1].y*a[0].x)/2.;
}
void ReadData(char filename[],land_type a[],int *n) {
  FILE *in;
  int status=0;

  in=fopen(filename,"r");
  *n=-1;
  while (1) {
    (*n)+=1;
    status=fscanf(in,"%lf %lf",&a[*n].x,&a[*n].y);
    if (status == EOF) break;
    /* printf("%lf %lf\n",a[*n].x,a[*n].y); */
  }
  fclose(in);
}
void DisplayData(land_type a[],int n)
{
  int i;
  for (i=0; i<n; i++)
    printf("%8.4lf %8.4lf %8.4lf\n",a[i].x,a[i].y,a[i].L);
}

/* P-7.5 */
/* COMPLEX.C */

#include <stdio.h>
#include <math.h>
typedef struct{
  double a,b;
} complex_t;

int scan_c(complex_t *c) {
  int status=0;
  printf("Give components of complex number a+bi in format a b: ");
  status=scanf("%lf %lf",&(*c).a,&(*c).b);
  if (status == 2) return 1;
  else return 0;
}
void print_c(complex_t c) {
  printf("%+lf%+lfi\n",c.a,c.b);
}
complex_t add_c(complex_t c1,complex_t c2) {
  complex_t c;
  c.a=c1.a+c2.a;
  c.b=c1.b+c2.b;
  return c;
}
complex_t subtract_c(complex_t c1,complex_t c2) {
  complex_t c;
  c.a=c1.a-c2.a;
  c.b=c1.b-c2.b;
  return c;
}
complex_t multiply_c(complex_t c1,complex_t c2) {
  complex_t c;
  c.a=c1.a*c2.a-c1.b*c2.b;
  c.b=c1.a*c2.b+c2.a*c1.b;
  return c;
}
complex_t divide_c(complex_t c1,complex_t c2) {
  complex_t c;
  double d;
  d=c2.a*c2.a+c2.b*c2.b;
  c.a=(c1.a*c2.a+c1.b*c2.b)/d;
  c.b=(c2.a*c1.b-c1.a*c2.b)/d;
  return c;
}
double mag_c(complex_t c) {
  return sqrt(c.a*c.a+c.b*c.b);
}
double angle_c(complex_t c) {
  return atan2(c.b,c.a);
}


int main(void)
{
  complex_t c1,c2,c;

  (void)scan_c(&c1);
  (void)scan_c(&c2);
  print_c(c1);
  print_c(c2);
  printf("addition and subtraction:\n");
  print_c(add_c(c1,c2));
  print_c(subtract_c(c1,c2));
  printf("multiplication and division:\n");
  print_c(multiply_c(c1,c2));
  print_c(divide_c(c1,c2));
  printf("polar coordinates (length, radians):\n");
  printf("%lf %lf\n",mag_c(c1),angle_c(c1));
  printf("%lf %lf\n",mag_c(c2),angle_c(c2));
  return 0;
}

/* P-7.6 */
#include <stdio.h>
void round_time(int *h,int *m,int *s);

int main(void)
{
  int mon,d,y,h,m,s,count=0,time,i,n,status;
  float s_float;
  float x[4],avg[]={0.,0.,0.,0};
  FILE *in,*out;
  char one_line[100],*line_ptr,filename[20],outname[20];

  printf("Give  input file name: ");
  (void)scanf("%s",filename);
  printf("Give output file name: ");
  fflush(stdin);
  (void)scanf("%s",outname);

  in=fopen(filename,"r");
  if (in != NULL)
  {
  out=fopen(outname,"w");
  fgets(one_line,sizeof(one_line),in); /* read header line */
  while (1) {
    line_ptr=fgets(one_line,sizeof(one_line),in);
    if (line_ptr == NULL) break;
    status=sscanf(one_line,"%d/%d/%d,%d:%d:%f,%f,%f,%f,%f",
       &mon,&d,&y,&h,&m,&s_float,&x[0],&x[1],&x[2],&x[3]);
    s=(int)s_float;
    round_time(&h,&m,&s);
    count++;
    n=status-6;
    for (i=0; i<n; i++) avg[i]+=x[i];
    if ((m == 30) || (m == 0)) {
      for (i=0; i<n; i++) avg[i]/=count;
      time=h*60+m-15;
      if (time < 0) time+=1440;
      printf(     "%2i,%2i,%2i,%4i",mon,d,y,time);
      fprintf(out,"%2i,%2i,%2i,%4i",mon,d,y,time);
      for (i=0; i<n; i++) {
	printf(     ",%6.3f",avg[i]);
	fprintf(out,",%6.3f",avg[i]);
      }
      printf(     "\n");
      fprintf(out,"\n");
      count=0;
      for (i=0; i<n; i++) avg[i]=0.;
    }
  }
  fclose(in);
  }
  else printf("File not found.\n");
  return 0;
}
void round_time(int *h,int *m,int *s) {
/* Rounds times to the nearest minute. Rolls 60 minutes to 0
   minutes and advances hour by 1. Rolls 24 hours to 0 hours.
*/
  if (*s >= 30) *m=(*m)+1;
  *s=0;
  if (*m == 60) {
    *m=0;
    *h=(*h)+1;
  }
  if (*h == 24) *h=0;
}

/* P-8/1(a) */
void FindAll(data_type a[],int lo,int hi,data_type what,int found[],
	     int (*compare)(data_type a,data_type b)) {
  int i,index=0,n_items;

  n_items=hi-lo+1;
  for (i=0; i<n_items; i++)
    found[i]=-1;
  for (i=lo; i<=hi; i++)
    if (compare(a[i],what) == 0) {
      found[index]=i;
      index++;
    }
}

void FindOne(data_type a[],int lo,int hi,data_type what,int *found,
	     int (*compare)(data_type a,data_type b)) {
  int i=lo;

  *found=-1;
  do {
    if (compare(a[i],what) == 0) *found=i;
    i++;
  } while ( (*found == -1) && (i<=hi) );
}

void BinarySearch(data_type a[], int lo, int hi, data_type what,int *found,
		  int (*compare)(data_type a,data_type b)) {
  int mid,compare_value;

  if (lo > hi) *found=-1;
  else
    {
      mid=(lo+hi)/2;
      compare_value=compare(a[mid],what);
      if (compare_value == 0)
	*found=mid;
      else if (compare_value < 0)
	BinarySearch(a,mid+1,hi,what,found,compare);
      else
	BinarySearch(a,lo,mid-1,what,found,compare);
    }
}

void Swap(data_type *x,data_type *y) {
  data_type temp;
  temp=*x;
  *x=*y;
  *y=temp;
}

void SelectionSort(data_type a[],int lo,int hi,
   int (*compare)(data_type a,data_type b))
{
  int i,j,min;

  for (i=lo; i<hi; i++) {
    min=i;
    for (j=i+1; j <=hi ; j++)
      if (compare(a[j],a[min]) == -1) min=j;
	Swap(&a[i],&a[min]);
  }
}

void InsertOne(data_type a[],int i,
   int (*compare)(data_type,data_type)) {
  data_type temp;

  temp=a[i];
  while ( (compare(temp,a[i-1]) == -1) && (i > 0) ) {
    a[i]=a[i-1];
    i--;
  }
  a[i]=temp;
}
void InsertionSort(data_type a[],int lo,int hi,
		   int (*compare)(data_type a,data_type b)) {
  int i;

  for (i=lo+1; i<=hi; i++)
    InsertOne(a,i,compare);
}


void MakePartition(data_type a[],
		       int lower, int upper, int *right, int *left,
		       int (*compare)(data_type a,data_type b))
{
  int mid,flag;

  mid=(lower+upper)/2;
  *left=lower;
  *right=upper;
  while (compare(a[*left],a[mid]) < 0) *left+=1;
  while (compare(a[mid],a[*right]) < 0) *right-=1;
  while (*left < (*right-1))
  {
    Swap(&a[*right],&a[*left]);
    (*left)+=1;
    (*right)-=1;
    while (compare(a[*left],a[mid]) < 0) (*left)+=1;
    while (compare(a[mid],a[*right]) < 0) (*right)-=1;
  }
  if (*left <= *right)
  {
    if (compare(a[*left],a[*right]) < 0) Swap(&a[*right],&a[*left]);
    (*left)+=1;
    (*right)-=1;
  }
}

void QuickSort(data_type a[], int lower, int upper,
	  int (*compare)(data_type a,data_type b)) {
  int upper_left, lower_right;

  if (lower < upper)
  {
    MakePartition(a,lower,upper,&upper_left,&lower_right,compare);
    if (lower < upper_left) QuickSort(a,lower,upper_left,compare);
    if (upper > lower_right) QuickSort(a,lower_right,upper,compare);
  }
}

/* P-8.1(b)
#include <stdio.h>
#define N 10

typedef int data_type;

#include "srchsort.h"
#include "srchsort.c"

void MakeArray(data_type a[],int n);
int SearchCompare(data_type a,data_type b);

int main(void)
{
  data_type a[N],what;
  int found[N],found_one,i;
  char yes_no;

  srand(3);
  MakeArray(a,N);
/* Test linear sort routine. */
  while (1) {
    printf("Look for what? ");
    fflush(stdin);scanf("%i",&what);
    FindOne(a,0,N-1,what,&found_one,SearchCompare);
    if (found_one != -1)
      printf("Found one match at (%i) %i\n",found_one,a[found_one]);
    else
      printf("Didn't find any match.\n");
    FindAll(a,0,N-1,what,found,SearchCompare);
    printf("Found matches at:\n");
    for (i=0; i<N; i++)
      if (found[i] != -1) printf("(%i) %i\n",found[i],a[found[i]]);
    printf("More (y/n)? ");
    fflush(stdin);scanf("%c",&yes_no);
    if (yes_no == 'n') break;
  }
  return 0;
}

void MakeArray(data_type a[],int n) {
  int i;

  for (i=0; i<n; i++) {
    a[i]=rand()%20;
    printf("(%2i) %i\n",i,a[i]);
  }
}

int SearchCompare(data_type a,data_type b) {
  if (a == b) return 0;
  else if (a < b) return -1;
  else return 1;
}

/* P-8.2 */
/* Program file name STRUCTU2.C */
/* Search for measurements made between two specified times. */

#include <stdio.h>
#define FILE_NAME "structur.dat"
#define MAX 20

typedef struct {
  int hr,min,sec;
  float measurement;
}data_type;

#include "srchsort.h"
#include "srchsort.c"

int SearchTime(data_type a,data_type b);

void main()
{

  FILE *Infile;
  int status=0,count=0,found[MAX],i;
  data_type measurements[MAX],time_rec;
  char yes_no;

  Infile=fopen(FILE_NAME,"r");
  while (1)
  {
    status=fscanf(Infile,"%d %d %d %f",
		  &measurements[count].hr,
		  &measurements[count].min,
		  &measurements[count].sec,
		  &measurements[count].measurement);
    if (status == EOF) break;
    {
      printf("%2d %2d %2d %f\n",measurements[count].hr,
				measurements[count].min,
				measurements[count].sec,
				measurements[count].measurement);
      count++;
    }
  }
  printf("There are %d records.\n",count);
  fclose(Infile);
/* Get search hour. */
  while (1) {
    printf("Which hour (0-24)? ");
    fflush(stdin); scanf("%i",&time_rec.hr);
    FindAll(measurements,0,count-1,time_rec,found,SearchTime);
    for (i=0; i<count; i++)
      if (found[i] != -1)
	printf("%2d %2d %2d %f\n",measurements[found[i]].hr,
				  measurements[found[i]].min,
				  measurements[found[i]].sec,
				  measurements[found[i]].measurement);

    printf("More (y/n)? ");
    fflush(stdin); scanf("%c",&yes_no);
    if (yes_no != 'y') break;
  }
}

int SearchTime(data_type a,data_type b) {
  if (a.hr == b.hr) return 0;
  else return 1;
}

/* P-8.3(a) see P-8.1(a) */
/* P-8.3(b) */
#include <stdio.h>
#define N 10

typedef int data_type;

#include "srchsort.h"
#include "srchsort.c"

int SearchCompare(data_type a,data_type b);

int main(void)
{
  data_type a[]={-17,-3,0,1,4,9,7,18,39,30};
  data_type what;
  int found_one,i;
  char yes_no;

  srand(3);
/* Test binary sort routine. */
  for (i=0; i<N; i++) printf("%i\n",a[i]);
  while (1) {
    printf("Look for what? ");
    fflush(stdin);scanf("%i",&what);
    BinarySearch(a,0,N-1,what,&found_one,SearchCompare);
    if (found_one != -1)
      printf("Found one match at (%i) %i\n",found_one,a[found_one]);
    else
      printf("Didn't find any match.\n");

    printf("More (y/n)? ");
    fflush(stdin);scanf("%c",&yes_no);
    if (yes_no == 'n') break;
  }
  return 0;
}

int SearchCompare(data_type a,data_type b) {
  if (a == b) return 0;
  else if (a < b) return -1;
  else return 1;
}

/* P-8.4 */
#include <stdio.h>
#include <string.h>
#define N 20

typedef struct {
		 char name[20];
	       } data_type;

#include "srchsort.h"
#include "srchsort.c"

int SearchCompare(data_type a,data_type b);
void GetData(data_type a[],int *n_rec);

int main(void)
{
  data_type a[N];
  data_type what;
  int found_one,i,n_recs;
  char yes_no;

  GetData(a,&n_recs);
  for (i=0; i<n_recs; i++) printf("%s\n",a[i].name);
  while (1) {
    printf("Look for what? ");
    fflush(stdin);scanf("%s",what.name);
    BinarySearch(a,0,n_recs-1,what,&found_one,SearchCompare);
    if (found_one != -1)
      printf("Found one match at (%i) %s\n",found_one,a[found_one].name);
    else
      printf("Didn't find any match.\n");

    printf("More (y/n)? ");
    fflush(stdin);scanf("%c",&yes_no);
    if (yes_no == 'n') break;
  }
  return 0;
}

void GetData(data_type a[],int *n) {
  FILE *in;
  int i=0,status=0;

  in=fopen("names.dat","r");
  while (1) {
    status=fscanf(in,"%s",a[i].name);
    if (status == EOF) break;
    printf("%s\n",a[i].name);
    i++;
  }
  fclose(in);
  *n=i;
}

int SearchCompare(data_type a,data_type b) {
  if (strcmp(a.name,b.name) == 0) return 0;
  else if (strcmp(a.name,b.name) < 0) return -1;
  else return 1;
}

/* P-8.5(a) see P-8.1(a) */
/* P-8.5(b) */
#include <stdio.h>
#include <math.h>
#define MAX_SIZE 20

typedef float data_type;

#include "srchsort.h"
#include "srchsort.c"

void GetData(data_type a[],int *n);
int compare(data_type a,data_type b);

int main(void)
{

  int i,n_recs,where;
  float a[MAX_SIZE],what;

  GetData(a,&n_recs);
/*  SelectionSort(a,0,n_recs-1,compare); */
  InsertionSort(a,0,n_recs-1,compare);
/*  QuickSort(a,0,n_recs-1,compare); */
  printf("After sort:\n");
  for (i=0; i<n_recs; i++)
    printf("%d  %lf\n",i,a[i]);
  printf("Find what? ");
  scanf("%f",&what);
  BinarySearch(a,0,n_recs-1,what,&where,compare);
  if (where == -1)
    printf("Can't find it.");
  else
    printf("%i %f\n",where,a[where]);

  return 0;
}

void GetData(data_type a[],int *n) {
  FILE *infile;
  int i=0,status=0;

  infile=fopen("arrays.dat","r");
  while (1) {
    status=fscanf(infile,"%f",&a[i]);
    if (status == EOF) break;
    printf("%d  %f\n",i,a[i]);
    i++;
  }
  fclose(infile);
  *n=i;
}

int compare(data_type a,data_type b) {
  if (fabs(a-b) < 1e-6) return 0;
  else if (a < b) return -1;
  else return 1;
}

/* P-8.6 see P-8.1(a) */
/* P-8.7 see P-8.1(a) */
/* P-8.8 */
#include <stdio.h>
#define A_LIST "lista.dat"
#define B_LIST "listb.dat"

typedef int list_type;

void MergeFiles(char a_list[],char b_list[],
		int (*ReadOne)(FILE*,list_type*),
		void (*ReadAll)(FILE*),
		int (*compare)(list_type a,list_type b));
int ReadOne(FILE *in_a,list_type *a);
void ReadAll(FILE *in);
int compare(list_type a,list_type b);

int main(void)
{

  MergeFiles(A_LIST,B_LIST,ReadOne,ReadAll,compare);

  return 0;
}
void MergeFiles(char a_list[],char b_list[],
		int (*ReadOne)(FILE*,list_type*),
		void (*ReadAll)(FILE*),
		int (*compare)(list_type a,list_type b)) {
  FILE *in_a, *in_b;
  int status_a,status_b,compare_value;
  list_type a,b;


  in_a=fopen("lista.dat","r");
  if (in_a != NULL) printf("List a is open.\n");
  in_b=fopen("listb.dat","r");
  if (in_b != NULL) printf("List b is open.\n");
  status_a=ReadOne(in_a,&a);
  status_b=ReadOne(in_b,&b);
  while ( (status_a == 0) && (status_b == 0) ) {
    compare_value=compare(a,b);
    if (compare_value == -1) {
      printf("%i\n",a);
      if (status_a == 0) status_a=ReadOne(in_a,&a);
      if (status_b != 0) printf("%i\n",b);
    }
    else if (compare_value == 0) {
      printf("%i\n%i\n",a,b);
      if (status_a == 0) status_a=ReadOne(in_a,&a);
      if (status_b == 0) status_b=ReadOne(in_b,&b);
    }
    else {
      printf("%i\n",b);
      if (status_b == 0) status_b=ReadOne(in_b,&b);
      if (status_a != 0) printf("%i\n",a);
    }
  }
  if (status_a == 0) {
    printf("%i\n",a);
    ReadAll(in_a);
  }
  if (status_b == 0) {
    printf("%i\n",b);
    ReadAll(in_b);

  }
  fclose(in_a);
  fclose(in_b);
}
int ReadOne(FILE *in,list_type *x) {
  int status=0;
  list_type a;

  (void)fscanf(in,"%i",&a);
  *x=a;
  status=feof(in);
  return status;
}
void ReadAll(FILE *in) {
  list_type x;
  int status=0;

  while (1) {
    status=fscanf(in,"%i",&x);
    if (status == EOF) break;
    printf("%i\n",x);
  }
}
int compare(list_type a,list_type b) {
  if (a < b) return -1;
  else if (a == b) return 0;
  else return 1;
}

/* P-9.1 */
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#define SIZE 50

int NormalStats(double a[],int n,char flag,
		double *avg,double *std_dev);
void NormalArray(double a[],int n);
void LinearRegression(double x[],double y[],int n,char flag,
		 double *a,double *b,double *s_yx,double *r);
int main(void)
{
  double x[SIZE],y[SIZE],avg,std_dev;
  double a,b ; /* intercept and slope for linear regression */
  double s_yx; /* standard error of estimate of y on x */
  double corr; /* correlation coefficient */
  int n=SIZE,i;

  NormalArray(x,n);
  printf("array generated\n");
  NormalStats(x,n,'p',&avg,&std_dev);
  printf("population mean and std dev: %lf %lf\n",avg,std_dev);
  NormalStats(x,n,'s',&avg,&std_dev);
  printf("    sample mean and std dev: %lf %lf\n",avg,std_dev);
  NormalArray(y,n);
  for (i=0; i<n; i++) {
    x[i]=(double)i;
    y[i]=2.*i+10.*y[i];
    printf("%8.3lf %8.3lf\n",x[i],y[i]);
  }
/* Set a != 0 for full regression analysis. */
  a=1.;
  LinearRegression(x,y,n,'s',&a,&b,&s_yx,&corr);
  printf("FOR FULL REGRESSION...\n");
  printf("regression coefficients: %lf %lf\n",a,b);
  printf("standard error of estimate of y on x : %lf\n",s_yx);
  printf("correlation coefficient: %lf\n",corr);
/* Set a=0 for regression forced through (0,0). */
  a=0.;
  LinearRegression(x,y,n,'s',&a,&b,&s_yx,&corr);
  printf("FOR REGRESSION FORCED THROUGH (0,0)...\n");
  printf("regression coefficients: %lf %lf\n",a,b);
  printf("standard error of estimate of y on x : %lf\n",s_yx);
  printf("correlation coefficient: %lf\n",corr);
  return 0;
}

int NormalStats(double a[],int n,char flag,
		double *avg,double *std_dev) {
  double sum=0.,sum_sq=0.,variance;
  int i,return_value=1;

  for (i=0; i<n; i++) {
    sum+=a[i];
    sum_sq+=a[i]*a[i];
  }
  switch (flag) {
    case 'p': printf("variance for population statistics\n");
	      variance=(sum_sq-sum*sum/n)/n;
	      break;
    case 's': printf("variance for sample statistics\n");
	      variance=(sum_sq-sum*sum/n)/(n-1.);
	      break;
    default : printf("From NormalStats: FLAG ERROR, 's' assumed.\n");
	      variance=(sum_sq-sum*sum/n)/(n-1.);
	      return_value=0;
  }
  if (variance < 0.) {
    printf("From NormalStats: NEGATIVE VARIANCE %lf\n",variance);
    *std_dev=-1.;
    return_value=-1;
  }
  else
    *std_dev=sqrt(variance);
  *avg=sum/n;
  return return_value;
}

void LinearRegression(double x[],double y[],int n,char flag,
		      double *a,double *b,double *s_yx,double *r) {
  double avg,std_dev;
  double sum_x=0.,sum_y=0.,sum_xy=0.,sum_xx=0.,sum_yy=0.,temp;
  int i;

  for (i=0; i<n; i++) {
    sum_x+=x[i];
    sum_y+=y[i];
    sum_xy+=x[i]*y[i];
    sum_xx+=x[i]*x[i];
    sum_yy+=y[i]*y[i];
  }
  if ((*a) != 0.) { /* calculate full regression */
    temp=n*sum_xx-sum_x*sum_x;
    *a=(sum_y*sum_xx-sum_x*sum_xy)/temp;
    *b=(n*sum_xy-sum_x*sum_y)/temp;
    *s_yx=sqrt((sum_yy-(*a)*sum_y-(*b)*sum_xy)/n);
  }
  else { /* just calculate slope */
    *b=sum_y/sum_x;
    *s_yx=sqrt((sum_yy-2.*(*b)*sum_xy+(*b)*(*b)*sum_xx)/n);
  }

  switch (flag) {
    case 'p':
      printf("Linear regression for population statistics\n");\
      break;
    case 's':
      printf("Linear regression for sample statistics\n");
      *s_yx=(*s_yx)*sqrt((double)n/(n-2.));
      break;
    default:
      printf("FROM LinearRegression: FLAG ERROR, 'p' assumed\n");
  }
/*  Use NormalStats to get standard deviation of y. */
  NormalStats(y,n,flag,&avg,&std_dev);
  if (std_dev > 0.) {
	temp=1.-(*s_yx)*(*s_yx)/std_dev/std_dev;
	if (temp >= 0.)
	  *r=sqrt(temp);
	else { /* an error condition exists */
	  *r=0.;
	  printf("FROM LinearRegression: ERROR CONDITION %lf\n",temp);
	}
   }
   else { /* an error condition exists */
    printf("FROM LinearRegression: ERROR CONDITION %lf\n",std_dev);
    *r=0.;
   }
}
void NormalArray(double a[],int n) {
  int i;
  double two_pi=8.*atan(1.),u1,u2;

  srand((unsigned)time(NULL));
  for (i=0; i<n; i+=2) {
    u1=(double)rand()/RAND_MAX;
    u2=(double)rand()/RAND_MAX;
    if (u1 == 0.) u1=1e-15; /* u1 must not be 0. */
    a[i]=sqrt(-2.*log(u1))*cos(two_pi*u2);
    a[i+1]=sqrt(-2.*log(u1))*sin(two_pi*u2);
  }
  if (n%2 == 1) { /* Create one more value. */
  u1=(double)rand()/RAND_MAX;
  u2=(double)rand()/RAND_MAX;
  if (u1 == 0.) u1=1e-15;
  a[n-1]=sqrt(-2.*log(u1))*cos(two_pi*u2);
  }
}

/* P-9.2 */
/* WINDSPD.C */
/* Calculates cumulative statistics for experimental data assumed
   to be lognormal. */

#include <stdio.h>
#include <math.h>
#define FILENAME "windspd.dat"
#define N_HIST 50

void ReadFile(char filename[],
	      double *sum_ln,double *sum_ln_sq,int *n,int hist[]);

int main(void)
{
  int hist[N_HIST];
  double sum_ln,sum_ln_sq;
  double mean,std_dev;

  int i,n;
  FILE *out;

  ReadFile(FILENAME,&sum_ln,&sum_ln_sq,&n,hist);
  mean=sum_ln/n;
  std_dev=sqrt((sum_ln_sq-sum_ln*sum_ln/n)/(n-1.0));
  printf("             Number of hourly values: %1i\n",n);
  printf("      Mean and std. dev. of ln(data): %10.3lf %10.3lf\n",
	 mean,std_dev);

  for (i=0; i<N_HIST; i++) {
    printf("%4.1lf %i\n",i/2.,hist[i]);
  }
  return 0;
}

void ReadFile(char filename[],
	      double *sum_ln,double *sum_ln_sq,int *n, int hist[]) {
  int mon,day,hr;
  int m,yr,n_days,index;
  FILE *infile;
  int status=0;
  double ln_x,x;

  infile=fopen(filename,"r");
  for (index=0; index<N_HIST; index++)
    hist[index]=0.0;
  *sum_ln=0.0; *sum_ln_sq=0.0; *n=0;
  for (mon=0; mon<12; mon++) {
    status=fscanf(infile,"%i %i %i",&m,&yr,&n_days);
/*    printf("%i %i %i\n",m,yr,n_days); */
    for (day=0; day<n_days; day++) {
      for (hr=0; hr<24; hr++) {
	status=fscanf(infile,"%lf,",&x);
	/* printf("%5.1f",x); */
	if (x >= 0.0) {
/* Accumulate data for statistics. */
	  (*n)++;
	  if (x == 0.0) x=1e-6;
	  ln_x=log(x);
	  *sum_ln+=ln_x;
	  *sum_ln_sq+=ln_x*ln_x;
/* Generate histogram data. */
	  index=x*2.0;
	  hist[index]+=1;
	}
      }
      /* printf("\n"); */
    }
  }
  fclose(infile);
}

/* P-9.3 */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define G 9.8  /* m/s^2 (gravitational acceleration) */
#define DT 0.2 /* range for time error, s */
#define N 21
#define FILENAME "falling.dat"

typedef struct {
  float true_time,measured_time,
	true_distance,true_speed,measured_speed;
} fall_data;


float Stirling(float x1,float x2,float x3,float y1,float y2,float y3) {
  return ((y2-y1)/(x2-x1)+(y3-y2)/(x3-x2))/2.;
}

int main(void) {
  fall_data fall[N];
  float g,x,speed;
  int i,n,status;
  FILE *in;
  char one_line[80];

  in=fopen(FILENAME,"r");

  /* Get data. */
  fgets(one_line,sizeof(one_line),in); /* Read past header line. */
  srand((unsigned)time(NULL));
  n=0;
  while (1) {
    status=fscanf(in,"%f %f %f",&fall[n].true_time,&fall[n].true_distance,
      &fall[n].true_speed);
    if (status == EOF) break;
    fall[n].measured_time=fall[n].true_time+(rand()%5-2.)*DT;
  /*  printf("%6.2f %8.2f %6.2f\n",fall[n].true_time,fall[n].true_distance,
	   fall[n].measured_time); */
    n++;
  }
  fclose(in);
  printf("  true     true measured     true measured\n");
  printf("  time distance     time    speed    speed\n");
  for (i=0; i<n; i++) {
    fall[i].true_speed=fall[i].true_time*G;
    if ((i > 0) && (i < (n-1))) {
      fall[i].measured_speed=Stirling(fall[i-1].measured_time,
				      fall[i  ].measured_time,
				      fall[i+1].measured_time,
      fall[i-1].measured_time*fall[i-1].measured_time*G/2.,
      fall[i  ].measured_time*fall[i  ].measured_time*G/2.,
      fall[i+1].measured_time*fall[i+1].measured_time*G/2.);
      printf("%6.2f %8.2f %8.2f %8.2f %8.2f\n",fall[i].true_time,
	     fall[i].true_distance,fall[i].measured_time,
	     fall[i].true_speed,fall[i].measured_speed);
    }
    else
      printf("%6.2f %8.2f %8.2f %8.2f\n",fall[i].true_time,
	     fall[i].true_distance,fall[i].measured_time,
	     fall[i].true_speed);
  }
}

/* P-9.4 */
#include <stdio.h>
#include <math.h>
#define N 100

double simpson(double a,double b,int n,double (*f)());
double f_of_x(double x);
double pdf(double x);

int main(void)
{
  printf("Integral of x^2 from 1 to 5: %lf\n",simpson(1.,5.,N,f_of_x));
  printf("Integral of pdf from 0 to 2: %lf\n",simpson(0.,2.,N,pdf));
  return 0;
}
double simpson(double a,double b,int n,double (*f)()) {
  double h,odd,even;
  int i;
  odd=0.;even=0.;
  h=(b-a)/(double)n;
  for (i=2; i<=n; i+=2)
    odd+=f(a+(i-1)*h);
  for (i=2; i<=n-2; i+=2)
    even+=f(a+i*h);
  return h/3.*(f(a)+f(b)+4.*odd+2.*even);
}
double f_of_x(double x) {
  return x*x;
}
double pdf(double x) {
  return exp(-x*x/2.)/sqrt(8.*atan(1.));
}

/* P-9.5 */
#include <stdio.h>
#include <math.h>

double gamma_integrand(double x,double z);
double gamma(double z);

int main(void) {
  double g;

  g=gamma(0.5);
  printf("gamma(0.5) = %lf\n",g);
  g=gamma(1.5);
  printf("gamma(1.5) = %lf %lf %lf\n",g,g*2.,sqrt(4.*atan(1.)));
}
double gamma_integrand(double x,double z) {
  return exp(-x)*pow(x,z-1.);
}
double gamma(double z) {
  int n=20000,i;
  double dx,sum=0.,x_max=20.;

  dx=x_max/n;
  for (i=2; i<=(n-2); i+=2)
    sum+=2.*gamma_integrand(i*dx,z);
  for (i=1; i<=(n-1); i+=2)
    sum+=4.*gamma_integrand(i*dx,z);
  sum=(sum+gamma_integrand(x_max,z))*dx/3.;
  return sum;
}

/* P-9.6 */
/* Gaussian elimination */
/* GAUSS.C */

#include <stdio.h>
#include <math.h>
#define MAX_ROWS 4
#define MAX_COLS 5
#define FILENAME "gauss.dat"

void GaussianElimination(double a[][MAX_COLS],int n_rows,
			int n_cols, double solutions[]);
void PrintMatrix(double a[][MAX_COLS],int n_rows,int n_cols);

int main()
{
  double a[MAX_ROWS][MAX_COLS],solutions[MAX_COLS];
  int n_rows,n_cols,rows,cols;
  FILE *in;

  in=fopen(FILENAME,"r");
  (void)fscanf(in,"%i",&n_rows);
  n_cols=n_rows+1;
  for (rows=0; rows < n_rows; rows++)
    for (cols=0; cols < n_cols; cols++)
      fscanf(in,"%lf",&a[rows][cols]);
  PrintMatrix(a,n_rows,n_cols);
  GaussianElimination(a,n_rows,n_cols,solutions);
  printf("solutions: ");
  for (rows=0; rows < n_rows; rows++)
    printf("%8.2lf",solutions[rows]);
  printf("%\n");
}

void GaussianElimination(double a[][MAX_COLS],int n_rows,
			int n_cols, double solutions[])
{
/* Solve system of linear equations using Gaussian
   elimination with partial (row) pivoting. */

  int row,col,pivot_row,i,j;
  double divide_by,temp;

  for (row=0; row < n_rows; row++) {
/* Search for pivot row. */
    if (row < n_rows-1) {
      pivot_row=row;
      for (i=row+1; i < n_rows; i++)
	    if (fabs(a[i][row]) > fabs(a[pivot_row][pivot_row]))
	      pivot_row=i;

/* Swap pivot row if required. */
      if (pivot_row != row) {
	for (col=row; col < n_cols; col++) {
	  temp=a[pivot_row][col];
	  a[pivot_row][col]=a[row][col];
	  a[row][col]=temp;
	} /* for... */
      } /* if... */
    } /* if... */

/* Divide by pivot. */
    divide_by=a[row][row];
    for (i=row; i < n_cols; i++)
	a[row][i]=a[row][i]/divide_by;

/* Reduce the (row)th column to 0. */
    if (row < (n_rows-1)) {
      for (i=row+1; i < n_rows; i++) {
	for (j=row+1; j < n_cols; j++)
	a[i][j]=a[i][j]-a[row][j]*a[i][row];
	a[i][row]=0.0;
      }
    }

/* Print reduced matrix. */
    PrintMatrix(a,n_rows,n_cols);
  } /* end for... */

/* Backsolve for solutions. */
  solutions[n_rows-1]=a[n_rows-1][n_cols-1];
  for (row=n_rows-2; row >= 0; row--) {
    solutions[row]=a[row][n_cols-1];
    for (i=row+1; i < n_rows; i++)
      solutions[row]=solutions[row]-a[row][i]*solutions[i];
  }
}

void PrintMatrix(double a[][MAX_COLS],int n_rows,int n_cols)
{
  int rows,cols;

  printf("From PrintMatrix\n");
  for (rows=0; rows < n_rows; rows++) {
    for (cols=0; cols < n_cols; cols++)
      printf("%8.2lf",a[rows][cols]);
    printf("\n");
  }
}

/* P-9.7 */
/* Bisection algorithm.  BISECT2.C */
/* Uses a function parameter in the bisection function. */

#include <stdio.h>
#include <math.h>
#define N_STEPS 10
#define LIMIT 1e-6

double f_of_x(double x);
int bisect(double left, double right,double (*f)(double),double *root);

int main(void)
{
  double left,right,dx,x1,x2,root;
  int i,found;

  printf("Give left and right search limits: ");
  scanf("%lf %lf",&left,&right);
  dx=(right-left)/N_STEPS;
  for (i=1; i<=N_STEPS; i++) {
    x1=left+dx*(i-1);
    x2=left+dx*i;
    found=bisect(x1,x2,f_of_x,&root);
    if (found)
      printf("There is  a root between %8.2lf and %8.2lf: %lf\n",x1,x2,root);
    else
      printf("There is no root between %8.2lf and %8.2lf.\n",x1,x2);
  }
  return 0;
}

double f_of_x(double x)
{
  return x*x-3.0;
}

int bisect(double left, double right,double (*f)(double),double *root)
{

  double mid;
  int found;

  if (f(left)*f(right) > 0.) /* There is no root in this interval. */
    found=0;
  else {
    if (fabs(f(left)) < LIMIT) {
      *root=left;
      found=1;
    }
    else if (fabs(f(right)) < LIMIT) {
      *root=right;
      found=1;
    }
    else {
      mid=(left+right)/2.;
      if (fabs(f(mid)) < LIMIT) {
	*root=mid;
	found=1;
      }
      else if (f(left)*f(mid) < 0.)
	found=bisect(left,mid,f,root);
      else
	found=bisect(mid,right,f,root);
    }
  }
  return found;
}

/* P-9.8 */
#include <stdio.h>
#include <math.h>

double AofT(double x,double v,double D,double K,double M,double F) {
  return -(-F+D*v+K*x)/M;
}
void MassAndSpring(double *x,double *v,double D,double K,
		   double M,double F,double dt) {
  double k1_x,k2_x,k3_x,k4_x,k1_v,k2_v,k3_v,k4_v;

/* Runge-Kutta coefficients... */
      k1_x=*v;
      k2_x=*v+AofT(*x,*v,D,K,M,F)*dt/2.;
      k3_x=*v+AofT(*x,*v,D,K,M,F)*dt/2.;
      k4_x=*v+AofT(*x,*v,D,K,M,F)*dt;
      k1_v=AofT(*x,*v,D,K,M,F);
      k2_v=AofT(*x+(*v)*dt/2.,(*v)+k1_v*dt/2.,D,K,M,F);
      k3_v=AofT(*x+(*v)*dt/2.,(*v)+k2_v*dt/2.,D,K,M,F);
      k4_v=AofT(*x+(*v)*dt,(*v)+k3_v*dt,D,K,M,F);
/* Propagate solution... */
      *x=*x+(k1_x+2.*k2_x+2.*k3_x+k4_x)*dt/6.;
      *v=*v+(k1_v+2.*k2_v+2.*k3_v+k4_v)*dt/6.;
}

int main(void)
{
/*
Use Runge-Kutta method to solve LRC circuit problems.
Variable equivalences with mass-and-spring problem:
V   => force F
q   => displacement x
i   => velocity v
L   => mass m
R   => damping constant D
1/C => spring constant K
*/
 double i,q,L,C,R,V,t,dt,t_final;
 double k1_i,k2_i,k3_i,k4_i;
 int j,n;
 char choice;

/* Choose circuit type... */
  printf("Specify [o]scillating or [n]o oscillating term...\n");
  scanf("%c",&choice);
  switch (choice) {
    case 'o':
    case 'O':
/* Ld^2q/dt^2+Rdq/dt+q/C=V */
      do {
	printf(" Give V, L, R, C (4L/C-R^2) > 0:\n");
	scanf("%lf %lf %lf %lf",&V,&L,&R,&C);
	printf("one period at t=%lf s\n",4.*3.14159*L/sqrt(4.*L/C-R*R));
	printf("Give t_final and number of points: ");
	scanf("%lf %i",&t_final,&n);
      } while ((4.*L/C-R*R) <= 0.);
	q=0.; i=C*V*R/2./L; t=0.; /* Initial values */
	dt=t_final/(double)n;
	printf("        time           q           i  analytic q\n");
	for (j=1; j<=n; j++) {
	  MassAndSpring(&q,&i,R,1./C,L,V,dt);
	  t=t+dt;
	  printf("%12.6e %12.4e %12.4e %12.4e\n",
	  t,q,i,C*V*(1.-exp(-R*t/2./L)*cos(sqrt(4.*L/C-R*R)*t/2./L)));
	}
	break;
    case 'n':
    case 'N':
/* Ldi/dt+Ri=V (no oscillating term)... */
      printf("Give V, L, R: ");
	scanf("%lf %lf %lf",&V,&L,&R);
	printf("time constant at t= %lf s\n",L/R);
	printf("Give t_final and number of points: \n");
	scanf("%lf %i",&t_final,&n);
	i=0.; t=0.; /* Initial values */
	dt=t_final/(double)n;
	printf("       time          i        analytic i\n");
	for (j=1; j<=n; j++) {
/* Runge-Kutta coefficients... */
	  k1_i=(V-R*i             )/L;
	  k2_i=(V-R*(i+k1_i*dt/2.))/L;
	  k3_i=(V-R*(i+k2_i*dt/2.))/L;
	  k4_i=(V-R*(i+k3_i*dt)   )/L;
/* Propagate solution... */
	  i=i+(k1_i+2.*k2_i+2.*k3_i+k4_i)*dt/6.;
	  t=t+dt;
	  printf("%12.6e %12.4e %12.4e\n",t,i,V/R*(1.-exp(-R*t/L)));
	}
	break;
    default:
      printf("No such choice.  Try again...\n");
  }
  return 0;
}

/* P-10.1 */
/* Read data from reporting stations.
   Save as binary file. */
#include <stdio.h>
#define FILENAME "stations.dat"
#define FILEOUT  "stations.bin"
#define MAX_REPORTS 8

typedef struct {
  int ID;
  float measurement;
}
station_type;

int main(void)
{
  FILE *in,*out;
  float m[MAX_REPORTS];
  int i,status,n_values,tot_values=0;
  station_type station;
  char *line_ptr,one_line[80];

  in=fopen(FILENAME,"r");
  out=fopen(FILEOUT,"wb+");
/* Start main data processing loop. */
  while (1) {
    line_ptr=fgets(one_line,sizeof(one_line),in);
    if (line_ptr == NULL) break;
    status=sscanf(one_line,"%i %f %f %f %f %f %f %f %f",&station.ID,
		  &m[0],&m[1],&m[2],&m[3],&m[4],&m[5],&m[6],&m[7]);
    n_values=status-1;
    for (i=0; i<n_values; i++) {
      station.measurement=m[i];
      tot_values++;
      printf("%5i %6.1f\n",station.ID,station.measurement);
      fwrite(&station,sizeof(station_type),1,out);
    }
  }
  fclose(in);
  printf("Total values: %i\n",tot_values);
  rewind(out);
  printf("Reading from binary file.\n");
  for (i=1; i<=tot_values; i++) {
    fread(&station,sizeof(station_type),1,out);
    printf("%5i %6.1f\n",station.ID,station.measurement);
  }
  fclose(out);
}

/* P-10.2 */
/* Read data from stations.bin in reverse order. */
#include <stdio.h>
#define FILENAME  "stations.bin"

typedef struct {
  int ID;
  float measurement;
}
station_type;

int main(void)
{
  FILE *in;
  int n_recs,i,status;
  station_type station;

  in=fopen(FILENAME,"rb");
  fseek(in,0,SEEK_END);
  n_recs=ftell(in)/sizeof(station_type);
  for (i=n_recs-1; i>=0; i--) {
    fseek(in,i*sizeof(station_type),SEEK_SET);
    fread(&station,sizeof(station_type),1,in);
    printf("%5i %6.1f\n",station.ID,station.measurement);
  }
  fclose(in);
  return 0;
}

/* P-10.3 */
#include <stdio.h>
#include <stdlib.h>

void make_array(double *ptr,int n);

int main(void) {

  int i,n;
  double *ptr;

  printf("Give number of elements: ");
  scanf("%i",&n);
  ptr=(double *)calloc(n,sizeof(double));
  make_array(ptr,n);
  for (i=1; i<=n; i++) {
    printf("%lf\n",*ptr);
    ptr++;
  }

  return 0;
}
void make_array(double x[],int n) {
  int i;

  for (i=0; i<n; i++)
    x[i]=100.*rand()/RAND_MAX;
}

/* P-10.4 */
/* Demonstrate linked lists.  LINKLIST.C */

#include <stdio.h>
#include <string.h>
struct data_type
{
  double data_field;
  struct data_type *next_ptr;
};
typedef struct data_type data_type;

data_type *create_list();
void access_list(data_type *first_ptr);
void append_end(data_type *first_ptr,data_type new_data);
void append_post(data_type *first_ptr,data_type what,data_type new_data,
		   int (*compare)(data_type,data_type));
void delete_post(data_type *first_ptr,data_type what,
		   int (*compare)(data_type,data_type));
int compare(data_type x,data_type y);

main()
{
  data_type *first_ptr,new_data,what;

  first_ptr=create_list();
  access_list(first_ptr);
  new_data.data_field=9999.;
  append_end(first_ptr,new_data);
  printf("After append:\n");
  access_list(first_ptr);
  what.data_field=9999.;
  new_data.data_field=8888.;
  append_post(first_ptr,what,new_data,compare);
  printf("After insert:\n");
  access_list(first_ptr);
  what.data_field=1000.;
  delete_post(first_ptr,what,compare);
  printf("After delete:\n");
  access_list(first_ptr);

  return(0);
}
int compare(data_type x,data_type y) {
  if (x.data_field > y.data_field)
    return 1;
  else if (x.data_field < y.data_field)
    return -1;
  else return 0;
}

void access_list(data_type *ptr)
{
  while (ptr != NULL)
  {
    printf("%lf\n",ptr->data_field);
    ptr=ptr->next_ptr;
  }
}

data_type *create_list()
{
  data_type *current_ptr, *first_ptr;
  int i;

  printf("Creating node 1\n");
  current_ptr=(data_type *)malloc(sizeof(data_type));
  current_ptr->data_field=100.0;
  current_ptr->next_ptr=NULL;
  first_ptr=current_ptr;
  for (i=2; i <= 10; i+=1)
  {
    printf("Creating node %i\n",i);
    current_ptr->next_ptr=(data_type *)malloc(sizeof(data_type));
    current_ptr=current_ptr->next_ptr;
    current_ptr->data_field=100.0*i;
    current_ptr->next_ptr=NULL;
  }
  return(first_ptr);
}
void append_end(data_type *ptr,data_type new_data) {
  while (ptr->next_ptr != NULL)
    ptr=ptr->next_ptr;
  ptr->next_ptr=(data_type *)malloc(sizeof(data_type));
  ptr=ptr->next_ptr;
  *ptr=new_data;
  ptr->next_ptr=NULL;
}
void append_post(data_type *ptr,data_type what,data_type new_data,
		 int (*compare)(data_type,data_type)) {

  data_type *temp;

  while ( (ptr != NULL) && (compare(*ptr,what) != 0) )
    ptr=ptr->next_ptr;
  if (compare(*ptr,what) == 0) {
    temp=(data_type *)malloc(sizeof(data_type));
    *temp=new_data;
    temp->next_ptr=ptr->next_ptr;
    ptr->next_ptr=temp;
  }
}
void delete_post(data_type *ptr,data_type what,
		 int (*compare)(data_type,data_type)) {
  data_type *temp;
  while ( (ptr != NULL) && (compare(*ptr,what) != 0) )
    ptr=ptr->next_ptr;
  if ( (ptr != NULL) && (ptr->next_ptr != NULL) ) {
    temp=ptr;
    ptr->next_ptr=ptr->next_ptr->next_ptr;
  }
  free(temp);
}

/* P-10.5 */
/* Demonstrate queues.  QUEUE.C */

#include <stdio.h>
#include <string.h>
struct data_type
{
  double data_field;
  struct data_type *next_ptr;
};
typedef struct data_type data_type;

void create_queue(data_type **head_ptr,data_type **tail_ptr);
void access_queue(data_type *head_ptr);
void push_queue(data_type **tail_ptr,data_type new_data);
void pop_queue(data_type **head_ptr);

main()
{
  data_type *head_ptr,*tail_ptr,new_data;

  create_queue(&head_ptr,&tail_ptr);
  access_queue(head_ptr);
  new_data.data_field=9999.;
  push_queue(&tail_ptr,new_data);
  printf("After push:\n");
  access_queue(head_ptr);
  pop_queue(&head_ptr);
  printf("After pop:\n");
  access_queue(head_ptr);

  return(0);
}

void access_queue(data_type *ptr)
{
  while (ptr != NULL)
  {
    printf("%lf\n",ptr->data_field);
    ptr=ptr->next_ptr;
  }
}

void create_queue(data_type **head_ptr,data_type **tail_ptr)
{
  data_type *current_ptr;
  int i;

  printf("Creating node 1\n");
  current_ptr=(data_type *)malloc(sizeof(data_type));
  current_ptr->data_field=100.0;
  current_ptr->next_ptr=NULL;
  *head_ptr=current_ptr;
  for (i=2; i <= 10; i+=1)
  {
    printf("Creating node %i\n",i);
    current_ptr->next_ptr=(data_type *)malloc(sizeof(data_type));
    current_ptr=current_ptr->next_ptr;
    current_ptr->data_field=100.0*i;
    current_ptr->next_ptr=NULL;
  }
  *tail_ptr=current_ptr;
}
void push_queue(data_type **tail_ptr,data_type new_data) {
  data_type *ptr;

  ptr->next_ptr=(data_type *)malloc(sizeof(data_type));
  ptr=ptr->next_ptr;
  *ptr=new_data;
  ptr->next_ptr=NULL;
  *tail_ptr=ptr;
}
void pop_queue(data_type **head_ptr) {
  data_type *ptr,*temp;

  ptr=*head_ptr;
  temp=*head_ptr;
  ptr=ptr->next_ptr;
  *head_ptr=ptr;
}

/* P-10.6 */
/* Read data from reporting stations. */
/* Includes individual station report summaries. */
#include <stdio.h>
#include <stdlib.h>
#define FILENAME "stations.dat"
#define N_STATIONS 11
#define MAX_REPORTS 8

struct data_type {
  float measurement;
  struct data_type *next;
};
typedef struct data_type data_type;

typedef struct {
  int reports,measurements;
  data_type *first, *last;
} summary_type;

void Initializations(summary_type A[],int n);
void StationDisplay(summary_type A[]);
void ProcessingLoop(char filename[],summary_type A[]);

int main(void)
{
/* Declare array to hold initial pointers and summary. */
  summary_type A[N_STATIONS];

  int i;

/* Initialize summary/pointer array. */
  Initializations(A,N_STATIONS);
  ProcessingLoop(FILENAME,A);
  for (i=0; i<N_STATIONS; i++)
    printf("%4i %2i %2i\n",i+1000,A[i].reports,A[i].measurements);
/* Search through array of stations. */
  StationDisplay(A);
  return 0;
}

void StationDisplay(summary_type A[])
{
  int i;
  data_type *current;

  for (i=0; i<N_STATIONS; i++)
    if (A[i].first != NULL) {
      printf("%4i ",i+1000);
      current=A[i].first;
      while (current != NULL) {
        printf("%5.1f",(*current).measurement);
        current=(*current).next;
      }
      printf("\n");
    }
}
void Initializations(summary_type A[],int n) {
  int i;

  for (i=0; i<n; i++) {
    A[i].reports=0; A[i].measurements=0.;A[i].first=NULL;
    A[i].last=NULL;
  }
}
void ProcessingLoop(char filename[],summary_type A[]) {
  FILE *in;
  int ID,status=0,n_lines=0,n_values=0,index,i,tot_values;
  double x;
  char *line_ptr;
  char one_line[80],seps[]=" \0";
  float m;
  data_type *new;

  in=fopen(FILENAME,"r");

/* Start main data processing loop. */
  tot_values=0;
  while (1) {
    line_ptr=fgets(one_line,sizeof(one_line),in);
    if (line_ptr == NULL) break;
    sscanf(line_ptr,"%i",&ID);
    line_ptr+=strspn(line_ptr,seps);
/* Update report summary fields. */
    index=ID%1000;
    A[index].reports+=1;
    n_lines++;
    n_values=0;
    while (1) {
      line_ptr+=strcspn(line_ptr,seps);
      if (*line_ptr == 0) break;
      sscanf(line_ptr,"%f",&m);
      line_ptr+=strspn(line_ptr,seps);
      A[index].measurements++;
      n_values++;
      tot_values++;
      if (n_values == 1) {
/* Allocate space for first data node. */
	new=malloc(sizeof(data_type));
	new->measurement=m;
	new->next=NULL;
/* If this is the first node for this station, assign first ptr. */
	if (A[index].first == NULL) {
	  A[index].first=new;
	}
/* Otherwise, set current pointer to previous last pointer. */
	else
	  A[index].last->next=new;
      }
/* Allocate more space as needed. */
      else {
	new->next=malloc(sizeof(data_type));
	new=new->next;
	new->measurement=m;
	new->next=NULL;
      }
    }
    A[index].last=new;
  }
  fclose(in);
  printf("There are %i records and %i values.\n",n_lines,tot_values);

}

