#include <stdio.h>
#define MAXVOTE 100
#define MAXCAND 5
#define MAXCANDP1 6
void readElection(FILE *instream, int votes[][MAXCAND], int numCands, int numVotes) {
int v;
int c;
for (v = 0; v < numVotes; v++)
for (c = 0; c < numCands; c++)
fscanf(instream,"%d",&(votes[v][c]));
}
int validVote(int votes[], int numCands) {
int candUse[MAXCANDP1];
int i;
for (i = 0; i < numCands; i++)
if ((votes[i] < 1) || (votes[i] > numCands)) return 0;
for (i = 1; i <= numCands; i++)
candUse[i] = 0;
for (i = 0; i < numCands; i++)
candUse[votes[i]] += 1;
for (i = 1; i <= numCands; i++)
if (candUse[i] != 1)
return 0;
return 1;
}
void countBallots(int votes[][MAXCAND], int candVotes[], int valid[], int numCands, int numVotes) {
int c;
int v;
for (c = 1; c <= numCands; c++)
candVotes[c] = 0;
for (v = 0; v < numVotes; v++)
if (valid[v])
candVotes[votes[v][0]] += 1;
}
void determineMaxMin(int candVotes[], int candInRace[], int numCands, int *minC, int *maxC) {
int c;
for (c = numCands; (c >= 1) && (!candInRace[c]); c--);
if (c < 1) {
*minC = 0;
*maxC = 0;
}
else {
*minC = c;
*maxC = c;
for (c = c - 1; c >= 1; c--)
if (candInRace[c]) {
if (candVotes[c] < candVotes[*minC]) *minC = c;
if (candVotes[c] > candVotes[*maxC]) *maxC = c;
}
}
}
int electionDone(int candVotes[], int candInRace[], int numCands, int minC, int maxC, int needed) {
int c;
if (candVotes[maxC] >= needed) {
printf(" Candidate %d is elected.\n",maxC);
return 1;
}
else if (candVotes[maxC] == candVotes[minC]) {
printf(" The following candidates are tied:");
for (c = 1; c <= numCands; c++)
if ((candInRace[c]) && (candVotes[c] == candVotes[maxC]))
printf(" %d",c);
printf("\n");
return 1;
}
return 0;
}
void elimCandidate(int votes[][MAXCAND], int valid[], int elimC, int numVotes, int numCands) {
int v;
int c;
for (v = 0; v < numVotes; v++)
if (valid[v]) {
for (c = 0; votes[v][c] != elimC; c++);
for (; c < (numCands - 1); c++)
votes[v][c] = votes[v][c + 1];
}
}
void determineWinner(int elnum, int votes[][MAXCAND], int numCands, int numVotes) {
int valid[MAXVOTE];
int numInvalid = 0;
int candVotes[MAXCANDP1];
int candInRace[MAXCANDP1];
int minC;
int maxC;
int needed;
int done = 0;
int v;
int c;
printf("Election #%d\n",elnum);
for (v = 0; v < numVotes; v++) {
valid[v] = validVote(votes[v],numCands);
if (!valid[v]) numInvalid++;
}
if (numInvalid > 0)
printf(" %d bad ballot(s)\n",numInvalid);
needed = (numVotes - numInvalid) / 2 + 1;
for (c = 1; c <= numCands; c++)
candInRace[c] = 1;
do {
countBallots(votes,candVotes,valid,numCands,numVotes);
determineMaxMin(candVotes,candInRace,numCands,&minC,&maxC);
if (electionDone(candVotes,candInRace,numCands,minC,maxC,needed))
done = 1;
else {
candInRace[minC] = 0;
elimCandidate(votes,valid,minC,numVotes,numCands);
}
} while (!done);
printf("\n");
}
void main() {
FILE *instream;
int elnum = 1;
int numCands;
int numVotes;
int votes[MAXVOTE][MAXCAND];
if ((instream = fopen("election.dat","r")) == NULL) {
printf("Unable to open file election.dat\n");
exit(-1);
}
do {
fscanf(instream,"%d%d",&numCands,&numVotes);
if ((numCands != 0) && (numVotes != 0)) {
readElection(instream,votes,numCands,numVotes);
determineWinner(elnum++,votes,numCands,numVotes);
}
} while ((numCands != 0) && (numVotes != 0));
}