#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)); }