// Homework3 cs111a2
// grading program

#include 
#include 
#include 

using namespace std;

//function prototypes here

int input(char  [50][25], double []); // will take students, averages
void bin(int [], double [], int); // will take freq, averages, class size
void histogram(int [], int); // will take frequency array
void ClassAvg(double [], int);
void mode(int [], int);
void hundred(char [50][25], int, int, double [], int);
void lowest(char [50][25], int, int, double [], int);
void long_name(char [50][25],int, int,  int);



// begin main here

int main(){
  
 
char students[50][25];
double average[50];
int frequency[11] = {0};    // will use for histogram, etc.
int  num_students = 0; 

 num_students = input(students, average);

 if(num_students == 0)     // inform if no data
   {cout << "\n *** No data entered ***\n\n";
   return 0;
   }

 else
   {

 bin(frequency, average, num_students); //fill bins
 histogram(frequency, 11); //make histogram
 ClassAvg(average, num_students);
 mode(frequency, 11);   //i.e., modal interval
 hundred(students, 50, 25, average, num_students);
 lowest(students, 50, 25, average, num_students);
 long_name(students, 50, 25, num_students);


  return 0;
   }
}

 // functions
 

// input: fills names of students, calculates averages, returns size of class

int input(char pupils[][25], double avg_grades[])
{
 int grade1, grade2, grade3 =0;
 int i=0;

cin >> pupils[i] >> grade1 >> grade2 >> grade3;
 avg_grades[i] = (grade1 + grade2 + grade3)/3.0;

 while(avg_grades[i] != -1)
  {
      i++;

     cin  >> pupils[i]  >> grade1  >> grade2 >> grade3;
     avg_grades[i] = (grade1 + grade2 + grade3)/3.0; 

  }
  
  return i;    //size of class
}


// bin: calculates frequencies (i.e., fills bins 0-9, 10-19, etc.)

void  bin(int freq[],  double average_grade[],  int size)
{
  for(int i=0; i< size; i++)
    ++freq[static_cast(average_grade[i])/10]; 
    //will give 0-9 via integer disvision
}


//histogram: prints out histogram
 
void histogram(int freq[], int)
{
cout << "\nHistogram of students' averages\n\n";

for(int i=0; i < 11; i++)
  {    
    cout << 10*i  ;          //change bins back to 90-99 etc 

    if(i == 10)             // no range if grade is 100
      cout << setw(4);
    else cout << "-" << (10*i)+9;
    
if(i==0 || i == 10)                  //line up bar
      cout << setw(4);
    else cout << setw(2);

     cout << "|" ;

 for(int j=0; j < freq[i]; j++)   // print *'s
 cout << "*";
 cout << "\n";
   
  }
 cout << endl;

}


//ClassAvg: calculates and prints class average to 1 decimal place

void ClassAvg(double avgs[], int class_size)
{
double SumOfAverages = 0.0;

  for(int i=0; i < class_size; i++)
    SumOfAverages += avgs[i];

  cout << "The class average is: " 
       << setiosflags( ios::fixed | ios::showpoint)
       <<    setprecision(1) <<  SumOfAverages/class_size << endl;
  cout << endl;
}

//mode: calculates and prints modal interval, more than one ok

void mode(int freq[], int)
{
  int max=0, interval=0;
  for(int i=0; i<11; i++)
    if (freq[i] > max)
      {
	max = freq[i];
        interval = i; 
      }

  cout << "The interval with the most grades is: " <<
    10*interval;

  if(interval != 10)
cout  << "-" << (10*interval)+9; //convert back to proper intervals

  //check if any others have same value
  for(int j=0; j<11; j++)
    if (freq[j] == freq[interval] && j != interval)
      cout << " and " << 10*j << "-" << (10*j)+9;

  cout << "\n\n";
}

// hundred: print names of students with scores of 100

void hundred(char names[][25], int n1, int n2, double  scores[], int class_size)
{
  cout << "The following students had a perfect average: "; 

  int num_perfect = 0;      //counter for perfect scores  

  for(int i=0; i < class_size; i++)
    {
      if(scores[i] == 100)
	{
	cout << names[i] << " ";
      num_perfect++;
        } 
    }
 
  if(num_perfect == 0)
    cout << "(nobody)";

  cout << "\n\n";
}


//lowest: name(s) and average of lowest scoring student(s)

void lowest(char names[][25], int n1, int n2, double scores[], int class_size)
{
  double low_score = 100;                       //track score and index
  int index = 0;

  for(int i=0; i < class_size; i++)
   {   if (scores[i] < low_score)
     {
       low_score = scores[i];
       index = i;
     }
   }

  cout << "The lowest average grade was " << scores[index] <<
    ", held by " << names[index];

  //check if any others have same value
  for(int j=0; j < class_size; j++)
    if (scores[j] == scores[index] && j != index)
      cout << " and " << names[j];

  cout << "\n\n";
}



// longest name

void long_name(char names[][25], int n1, int n2, int class_size)
{
  int longest = 0;
  int hold = 0; 

  for(int i=1; i < class_size; i++)
    
      if( strlen(names[i]) > hold)
   {
     hold = strlen(names[i]);
     longest = i; 
   }

  cout << "The longest name(s) in the class are " << names[longest];

//check if others have same value

for(int j=0; j < class_size; j++)
  if( strlen(names[longest]) == strlen( names[j]) && j != longest)

    cout << " and " << names[j] << endl;

 cout << endl;




 }