1997 ACM South Central USA
Programming Contest

 

Problem #6: Stats
 
Source File: stats.{pas,cpp,c,ss}
Input File: stats.dat
Output File: stats.out

As with most team sports, certain statistics can be accumulated during play. For this problem, you are to write a program that reads play descriptions for a volleyball game and produces a report of player and team statistics for one of the teams.

Your program will read in a series of input lines that describe a "play" of a volleyball game. Table 1 lists the types of plays that your program will use for input.
 
Key
Play
Play Description
C
CHECKIN
An indication of the beginning of a new game. The beginning of any game will contain one "CHECKIN" play that lists all the players in the game from one team.
H
HIT
A hit that was successfully defended by the opponent.
K
KILL
A hit that was not successfully defended by the opponent.
E
ERR
An erroneous hit that went into the net or out of bounds.
B
BLOCK
A successful defense of a hit at the net.
D
DIG
A successful defense of a hit behind the net.
R
REPORT
Command to your program to generate a report. After generating a report, your program should discard all collected play records and begin processing anew on the rest of the input file.
 

Table 1: Real-Time Plays

Each play (except CHECKIN and REPORT) has exactly one 2-digit player number associated with it. Player digit numbers are limited to 0 through 5 allowing referees to indicate player numbers using 0 to 5 fingers off of each hand.

Your program is to compute the following statistics for each player that has participated in any game as well as statistics for the entire team. Descriptions of all statistics that your program is to compute from the collected plays are listed in Table 2.
 
 
Label
Formula
Description
Sample
Hit % (sum(KILL)-sum(ERR)) / 

(sum(KILL)+sum(ERR)+sum(HIT))

Hitting percentage 0.461
KPG sum(KILL) / #Games Kills per game 5.613
BPG sum(BLOCK) / #Games Blocks per game 3.100
DPG sum(DIG) / #Games Digs per game 2.050
 

Table 2: Computed Statistics

Input Format

Input to your program will consist of a series of input lines each with exactly one play. Column 1 will contain one of the play keys from Table 1. If the play is a REPORT, there is no additional input on the line.

If the play is a CHECKIN, there will be a blank in column 2, followed by a single integer (06 <= NP <= 15) in columns 3 and 4 which indicates the number of players participating in the game. The remainder of the line contains a series of 2-digit (including leading zeros) player numbers (each with exactly 1 preceding blank) indicating the players who participated in the game. You can be confident that the CHECKIN is accurate and that no player will be mentioned in any play in that game who does not appear on the preceding CHECKIN line.

For the plays HIT, KILL, ERR, BLOCK, and DIG, there will be blank in column 2 and exactly one player number (including leading a leading zero as required) in columns 3 and 4.

Required Output Format

Each time your program reads in a "REPORT" play, you should print a report with the following format.

The first two lines of each report must contain the following strings each starting in column 1.

Player  Hit Pct    KPG      BPG      DPG
-----------------------------------------

Your program should then print, for each player who has played in at least one game, a single line in the following format:

55      s0.000   99.999   99.999   99.999

with the lines in ascending order of player number. In the player report line, s is the sign of the hitting percentages and is '+' if the hitting percentage >= 0.000 and is '-' otherwise. Note the hitting percentage should be 0.000 if the user has not made any hits, kills, nor errors.

After printing a report for each player, your program should print a single line containing the team statistics in the following format.

team    s0.000   99.999   99.999   99.999

You can be confident that no statistic's magnitude will exceed 99.999 in value. After printing the team statistics, your program should print exactly one blank line.

Sample Input
 
Sample Input
Sample Input
Continued
Sample Input
Continued
Sample Input
Continued
C 8 01 23 45 54 00 32 10 14 

B 32 

E 32 

D 01 

E 01 

D 45 

B 54 

B 23 

D 45 

B 32 

K 00 

E 32 

K 32 

K 32 

D 45 

D 10 

H 10 

D 14 

D 14 

B 45 

B 54 

D 54 

D 01 

D 01 

H 14 

K 14 

H 01 

H 10 

H 10 

B 14 

D 01 

B 00 

D 00 

B 54 

E 32 

K 01 

H 10 

H 14 

E 14 

E 00 

D 01 

H 01 

B 23 

D 23 

B 00 

D 00 

H 10 

B 10 

B 14 

H 14 

D 00 

K 00 

D 00 

B 23 

K 01 

D 01 

K 01 

E 01 

D 23 

K 01 

E 01 

K 00 

K 14 

D 00 

B 00

K 14 

E 23 

K 00 

K 45 

B 01 

B 01 

K 32 

K 45 

K 23 

C 7 14 00 45 23 31 25 22 

H 00 

K 00 

K 14 

K 14 

H 14 

B 23 

B 23 

K 23 

H 23 

D 45 

H 14 

E 23 

D 45 

B 45 

B 23 

D 23 

E 23 

E 45 

K 45 

B 25 

K 00 

B 00 

K 14 

D 14 

D 00 

B 00 

D 00 

D 14 

E 22 

E 00 

K 45 

D 23 

B 14 

B 23 

H 25 

D 00 

D 14 

K 14 

B 45 

B 45 

D 14 

B 14 

K 14 

D 22 

E 00 

H 00 

D 23 

H 23 

E 23 

H 45 

D 45 

E 00 

K 45 

K 45 

B 25

D 25 

H 25 

B 31 

E 00 

H 00 

B 00 

K 14 

E 14 

K 22 

K 22 

K 00 

B 22 

E 22 

D 00 

D 23 

K 45 

E 45 

B 25 

B 25 

E 25 

H 31 

K 22 

E 31 

K 31 

K 22 

K 22 

B 31 

K 31 

D 45 

B 22 

K 22 

K 23 

H 00 

K 31 

B 45 

D 45 

H 22 

D 00 

K 00 

H 25 

H 31 

K 31 

D 31 

B 25 

E 31 

B 00 

B 00 

H 22 

K 22 

H 22 

B 25 

D 25 

B 25 

D 22 

D 31 

K 45 

K 31 

C 7 45 23 14 01 22 25 11 

E 01 

B 45 

E 01 

H 11 

K 11 

D 14 

B 14

E 14 

K 45 

K 22 

B 22 

D 45 

K 45 

H 14 

B 14 

E 22 

D 23 

D 11 

E 11 

D 11 

K 25 

K 22 

B 22 

D 01 

E 01 

D 11 

K 14 

D 01 

K 14 

D 01 

K 23 

H 23 

B 25 

K 25 

H 45 

B 22 

K 01 

E 01 

C 6 13 04 40 14 15 22 

D 04 

B 04 

B 04 

K 14 

B 14 

B 14 

K 14 

K 14 

K 14 

B 14 

D 14 

D 14 

B 14 

H 15 

D 15 

E 15 

H 15 

H 15 

H 15 

H 15 

E 15 

B 22 

B 22 

K 22 

E 22 

H 22 

K 22 

D 40 

D 40 

 

 

Sample Output

Player  Hit Pct    KPG      BPG      DPG
-----------------------------------------
00      +0.176    4.000    4.000    5.000
01      -0.143    2.500    1.000    4.500
10      +0.000    0.000    1.000    1.000
11      +0.000    1.000    0.000    3.000
14      +0.400    3.667    2.000    2.333
22      +0.400    4.500    2.500    1.000
23      +0.000    1.333    2.333    2.333
25      +0.167    1.000    4.000    1.000
31      +0.333    5.000    2.000    2.000
32      +0.000    3.000    2.000    0.000
45      +0.571    3.333    2.000    3.000
54      +0.000    0.000    3.000    1.000
team    +0.225   19.333   16.667   17.667

Player  Hit Pct    KPG      BPG      DPG
-----------------------------------------
04      +0.000    0.000    2.000    1.000
13      +0.000    0.000    0.000    0.000
14      +1.000    4.000    4.000    2.000
15      -0.286    0.000    0.000    1.000
22      +0.250    2.000    2.000    0.000
40      +0.000    0.000    0.000    2.000
team    +0.200    6.000    8.000    6.000

Judge's Input

C 8 01 23 45 54 00 32 10 14
B 32
E 32
D 01
E 01
D 45
B 54
B 23
D 45
B 32
K 00
E 32
K 32
K 32
D 45
D 10
H 10
D 14
D 14
B 45
B 54
D 54
D 01
D 01
H 14
K 14
H 01
H 10
H 10
B 14
D 01
B 00
D 00
B 54
E 32
K 01
H 10
H 14
E 14
E 00
D 01
H 01
B 23
D 23
B 00
D 00
H 10
B 10
B 14
H 14
D 00
K 00
D 00
B 23
K 01
D 01
K 01
E 01
D 23
K 01
E 01
K 00
K 14
D 00
B 00
K 14
E 23
K 00
K 45
B 01
B 01
K 32
K 45
K 23
C 7 14 00 45 23 31 25 22
H 00
K 00
K 14
K 14
H 14
B 23
B 23
K 23
H 23
D 45
H 14
E 23
D 45
B 45
B 23
D 23
E 23
E 45
K 45
B 25
K 00
B 00
K 14
D 14
D 00
B 00
D 00
D 14
E 22
E 00
K 45
D 23
B 14
B 23
H 25
D 00
D 14
K 14
B 45
B 45
D 14
B 14
K 14
D 22
E 00
H 00
D 23
H 23
E 23
H 45
D 45
E 00
K 45
K 45
B 25
D 25
H 25
B 31
E 00
H 00
B 00
K 14
E 14
K 22
K 22
K 00
B 22
E 22
D 00
D 23
K 45
E 45
B 25
B 25
E 25
H 31
K 22
E 31
K 31
K 22
K 22
B 31
K 31
D 45
B 22
K 22
K 23
H 00
K 31
B 45
D 45
H 22
D 00
K 00
H 25
H 31
K 31
D 31
B 25
E 31
B 00
B 00
H 22
K 22
H 22
B 25
D 25
B 25
D 22
D 31
K 45
K 31
C 7 45 23 14 01 22 25 11
E 01
B 45
E 01
H 11
K 11
D 14
B 14
E 14
K 45
K 22
B 22
D 45
K 45
H 14
B 14
E 22
D 23
D 11
E 11
D 11
K 25
K 22
B 22
D 01
E 01
D 11
K 14
D 01
K 14
D 01
K 23
H 23
B 25
K 25
H 45
B 22
K 01
E 01
R
C 6 13 04 40 14 15 22
D 04
B 04
B 04
K 14
B 14
B 14
K 14
K 14
K 14
B 14
D 14
D 14
B 14
H 15
D 15
E 15
H 15
H 15
H 15
H 15
E 15
B 22
B 22
K 22
E 22
H 22
K 22
D 40
D 40
R
C 6 13 04 40 14 15 22
E 22
E 04
D 04
B 04
B 04
E 15
K 14
B 14
B 14
K 14
K 14
K 14
B 14
D 14
D 14
B 14
E 14
B 13
H 15
D 15
E 15
H 15
H 15
H 15
H 15
E 15
E 40
B 22
B 22
K 22
E 22
H 22
K 22
D 40
D 40
C 6 13 04 40 14 15 22
E 22
E 04
D 04
B 04
B 04
E 15
K 14
B 14
B 14
K 14
K 14
K 14
B 14
D 14
D 14
B 14
E 14
B 13
H 15
D 15
E 15
H 15
H 15
H 15
H 15
E 15
E 40
B 22
B 22
K 22
E 22
H 22
K 22
D 40
D 40
R

Judge's Output

Player  Hit Pct    KPG      BPG      DPG
-----------------------------------------
00      +0.176    4.000    4.000    5.000
01      -0.143    2.500    1.000    4.500
10      +0.000    0.000    1.000    1.000
11      +0.000    1.000    0.000    3.000
14      +0.400    3.667    2.000    2.333
22      +0.400    4.500    2.500    1.000
23      +0.000    1.333    2.333    2.333
25      +0.167    1.000    4.000    1.000
31      +0.333    5.000    2.000    2.000
32      +0.000    3.000    2.000    0.000
45      +0.571    3.333    2.000    3.000
54      +0.000    0.000    3.000    1.000
team    +0.225   19.333   16.667   17.667
 
Player  Hit Pct    KPG      BPG      DPG
-----------------------------------------
04      +0.000    0.000    2.000    1.000
13      +0.000    0.000    0.000    0.000
14      +1.000    4.000    4.000    2.000
15      -0.286    0.000    0.000    1.000
22      +0.250    2.000    2.000    0.000
40      +0.000    0.000    0.000    2.000
team    +0.200    6.000    8.000    6.000
 
Player  Hit Pct    KPG      BPG      DPG
-----------------------------------------
04      -1.000    0.000    2.000    1.000
13      +0.000    0.000    1.000    0.000
14      +0.600    4.000    4.000    2.000
15      -0.375    0.000    0.000    1.000
22      +0.000    2.000    2.000    0.000
40      -1.000    0.000    0.000    2.000
team    -0.100    6.000    9.000    6.000

Solution

#include <stdio.h>

typedef struct player_t
{ int active, hits, kills, errors, blocks, digs, games;
} player_t;

player_t players[56];
FILE *infp, *outfp;
int total_games;

void clear_players(void)
{ int i;

  for (i=0; i<56; i++)
  { players[i].active = 0;
    players[i].hits   = 0;
    players[i].kills  = 0;
    players[i].errors = 0;
    players[i].blocks = 0;
    players[i].digs   = 0;
    players[i].games  = 0;
  }
  total_games=0;
}

void print_report(void)
{ int i, total_hits, total_kills, total_errors, total_blocks, total_digs;
  float hit_stat, kill_stat, block_stat, dig_stat;
 
  total_hits   = 0;
  total_kills  = 0;
  total_errors = 0;
  total_blocks = 0;
  total_digs   = 0;

  fprintf(outfp, "Player  Hit Pct    KPG      BPG      DPG\n");
  fprintf(outfp, "-----------------------------------------\n");

  for (i=0; i<56; i++)
  { if (players[i].games)
    { if (players[i].kills + players[i].errors + players[i].hits)
      { hit_stat = ( (float)players[i].kills - (float)players[i].errors) /
        (float) (players[i].kills + players[i].errors + players[i].hits);
      }
      else
      { hit_stat = (float) 0.000; }
      kill_stat  = (float)players[i].kills  / (float)players[i].games;
      block_stat = (float)players[i].blocks / (float)players[i].games;
      dig_stat   = (float)players[i].digs   / (float)players[i].games;
 
      fprintf(outfp, "%02d      %+5.3f  % 7.3f  % 7.3f  % 7.3f\n",
                     i, hit_stat, kill_stat, block_stat, dig_stat);
 
      total_hits   += players[i].hits;
      total_kills  += players[i].kills;
      total_errors += players[i].errors;
      total_blocks += players[i].blocks;
      total_digs   += players[i].digs;
    }
  }

  hit_stat = ( (float)total_kills - total_errors) /
               (float) (total_kills + total_errors + total_hits);
  kill_stat  = (float)total_kills  / (float)total_games;
  block_stat = (float)total_blocks / (float)total_games;
  dig_stat   = (float)total_digs   / (float)total_games;
  fprintf(outfp, "team    %+5.3f  % 7.3f  % 7.3f  % 7.3f\n\n",
             hit_stat, kill_stat, block_stat, dig_stat);

}

void read_stats(void)
{ char play;
  int  i, num_players, player;
 
  fscanf(infp, "%c", &play);
 
  switch(play)
  { case 'C':
    { fscanf(infp, "%d", &num_players);
      for (i = 0; i < num_players; i++)
      { fscanf(infp, "%d", &player);
        players[player].games++;
      }
      fscanf(infp, "\n");
      total_games++;
      break;
    }
    case 'H':
    { fscanf(infp, "%d\n", &player);
      players[player].hits++;
      break;
    }
    case 'K':
    { fscanf(infp, "%d\n", &player);
      players[player].kills++;
      break;
    }
    case 'E':
    { fscanf(infp, "%d\n", &player);
      players[player].errors++;
      break;
    }
    case 'B':
    { fscanf(infp, "%d\n", &player);
      players[player].blocks++;
      break;
    }
    case 'D':
    { fscanf(infp, "%d\n", &player);
      players[player].digs++;
      break;
    }
    case 'R':
    { fscanf(infp, "\n");
      print_report();
      clear_players();
      return;
    }
 
  }
}

int main(void)
{
  infp=fopen("stats.dat", "r");
  outfp=fopen("stats.out","w");
 
  clear_players();
  while (!feof(infp))
  { read_stats(); }
 
  fclose(infp);
  fclose(outfp);
  return(0);
}