// This is coding from some Major Programming Problems in Appendix F


// MPP 8.1 GradeHistogram

     public GradeHistogram ();  // constructor; set all values to 0
     public void setGrades (String grades);  
          // count how many of each of A,B,C,D,F appears in grades
     public char mode();       // query which of the capital letters
                              // A,B,C,D,F has the highest frequency
     public void showHistogram (Graphic page, int xcor, int ycor);  
          // display histogram for the counts of the five characters 
          // A,B,C,D,F with (xcor, ycor) as its bottom-left corner


     public void paint (Graphics page) 
     {    GradeHistogram cs1 = new GradeHistogram();
          cs1.setGrades ("ABC ABCD ABCBc  eABCF");
          System.out.println ("The mode is " + cs1.mode());
          cs1.showHistogram (page, 50, 110);
          cs1.showHistogram (page, 180, 120);
          cs1.setGrades ("AAAFFFFCCBBB");
          cs1.showHistogram (page, 50, 300);
     }




// MPP 11.1  UltraLong

     public UltraLong (int mantissa, int expo)
     {    super();
          if (mantissa <= 0 || expo < 0)
               itsItem = {0};
          else
          {    long mant = mantissa;
               for (int i = expo % 9;  i > 0;  i--)
                    mant *= 10;

               if (mant < LONGBILL)
               {    itsItem = new int [expo / 9 + 1];
                    itsItem[itsItem.length - 1] = (int) mant;
               }
               else
               {    itsItem = new int [expo / 9 + 2];
                    itsItem[itsItem.length -1] = (int) (mant / LONGBILL);
                    itsItem[itsItem.length -2] = (int) (mant % LONGBILL);
               }
          }
     }




// MPP 12.4  GameOfLife

     public class World
     {
          private Being[][] itsCurrentState;
          private Being[][] itsFutureState;
          private final int[] itsCount;
          private final int itsSize;


          public World (int dimension)
          {    super();
               itsSize = dimension > 2  ?  dimension  :  20;
               itsCurrentState = new Being [itsSize + 2][itsSize + 2];
               itsFutureState = new Being [itsSize + 2][itsSize + 2];
               // add coding to put Being.EMPTY_ONE in each border cell
               for (int row = 1;  row <= itsSize;  row++)
               {    for (int col = 1;  col <= itsSize;  col++)
                         itsCurrentState[row][col] = Being.random();
               }
               itsCount = new int [Being.NUM_CATEGORIES];
          }


          public void liveOneCycle()
          {    for (int row = 1;  row <= itsSize;  row++)
               {    for (int col = 1;  col <= itsSize;  col++)
                    {    countNeighbors (row, col);
                         itsFutureState[row][col] 
                                   = itsCurrentState[row][col].next (itsCount);
                    }
               }
               Being[][] save = itsFutureState;
               itsFutureState = itsCurrentState;
               itsCurrentState = save;
          }


          private void countNeighbors (int row, int col)
          {    for (int k = 0;  k < itsCount.length;  k++)
                    itsCount[k] = 0;
               for (int i = row - 1;  i <= row + 1;  i++)
               {    for (int j = col - 1;  j <= col + 1;  j++)
                         itsCount[itsCurrentState[i][j].getID()]++;
               }
          }
     }




// MPP 15.4  PolynomialLinks

public class Polynomial extends Numeric // partial listing
{
     private Node itsFirst;
     

     public Polynomial()
     {    itsFirst = null;
     } //================================================

     
     public Numeric valueOf (String par)
     {    Polynomial answer = new Polynomial();
          answer.itsFirst = convert (new StringTokenizer (par));
          return answer;
     } //================================================

     
     private static Node convert (StringTokenizer strit)
     {    try
          {    double co = Double.parseDouble (strit.getNextToken());
               int expo = Integer.parseInt (strit.getNextToken());
               return new Node (co, expo, convert (strit));
          }catch (RuntimeException e)
          {    return null;
          }
     } //================================================

     
     public Numeric add (Numeric par)
     {    Polynomial sum = new Polynomial();
          sum.itsFirst = add (itsFirst, ((Polynomial) par).itsFirst);
          return sum;
     } //================================================

     
     private static Node add (Node p, Node q)
     {    if (p == null && q == null)
               return null;
          else if (p == null)  // so q != null
               return new Node (q.itsCoef, q.itsExpo, add (p, q.itsNext));
          else if (q == null || p.itsExpo > q.itsExpo)   
               return new Node (p.itsCoef, p.itsExpo, add (q, p.itsNext));
          else if (q.itsExpo > p.itsExpo)
               return new Node (q.itsCoef, q.itsExpo, add (p, q.itsNext));
          else if (p.itsCoef + q.itsCoef == 0)   // same exponent 
               return add (p.itsNext, q.itsNext);
          else
           return new Node (p.itsCoef + q.itsCoef, p.itsExpo, 
                                add (p.itsNext, q.itsNext));
     } //================================================

     
     public void timesConstant (double multiplier)
     {    if (itsFirst != null)   // an executor must always be non-null
               itsFirst.timesConstant (multiplier);
     } //================================================
     

     private static class Node  // inside Polynomial; partial listing
     {
          public void timesConstant (double given)
          {    itsCoef *= given;
               if (itsNext != null)
                    itsNext.timesConstant (given);
          } //================================================
     }
}