Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <cs50.h>
- #include <stdio.h>
- #include <string.h>
- // Max voters and candidates
- #define MAX_VOTERS 100
- #define MAX_CANDIDATES 9
- // preferences[i][j] is jth preference for voter i
- int preferences[MAX_VOTERS][MAX_CANDIDATES]; //x or row is voter and y or column is the prference so 100 rows and 9 columns
- // Candidates have name, vote count, eliminated status
- typedef struct
- {
- string name;
- int votes;
- bool eliminated;
- }
- candidate;
- // Array of candidates
- candidate candidates[MAX_CANDIDATES];
- // Numbers of voters and candidates
- int voter_count;
- int candidate_count;
- // Function prototypes
- bool vote(int voter, int rank, string name);
- void tabulate(void);
- bool print_winner(void);
- int find_min(void);
- bool is_tie(int min);
- void eliminate(int min);
- int main(int argc, string argv[])
- {
- //// line 38 - 43 is pretty self explanatory, checks that argc isn't less than 2, if so error code
- // Check for invalid usage
- if (argc < 2)
- {
- printf("Usage: runoff [candidate ...]\n");
- return 1;
- }
- ////line 45 - 57 1. gets the count of candidates, which is argc - 1, 2. checks if more candidates than there should be and returns error code if there is, 3. use the name from the argv and assign to .name object and .votes, .elminated
- // Populate array of candidates
- candidate_count = argc - 1;
- if (candidate_count > MAX_CANDIDATES)
- {
- printf("Maximum number of candidates is %i\n", MAX_CANDIDATES);
- return 2;
- }
- for (int i = 0; i < candidate_count; i++)
- {
- candidates[i].name = argv[i + 1];
- candidates[i].votes = 0;
- candidates[i].eliminated = false;
- }
- ////line 59 - 64 checks the num of voters
- voter_count = get_int("Number of voters: ");
- if (voter_count > MAX_VOTERS)
- {
- printf("Maximum number of voters is %i\n", MAX_VOTERS);
- return 3;
- }
- // Keep querying for votes
- for (int i = 0; i < voter_count; i++)
- {
- // Query for each rank
- for (int j = 0; j < candidate_count; j++)
- {
- string name = get_string("Rank %i: ", j + 1);
- // Record vote, unless it's invalid
- if (!vote(i, j, name))
- {
- printf("Invalid vote.\n");
- return 4;
- }
- }
- printf("\n");
- }
- // Keep holding runoffs until winner exists
- while (true)
- {
- // Calculate votes given remaining candidates
- tabulate();
- // Check if election has been won
- bool won = print_winner();
- if (won)
- {
- break;
- }
- // Eliminate last-place candidates
- int min = find_min();
- bool tie = is_tie(min);
- // If tie, everyone wins
- if (tie)
- {
- for (int i = 0; i < candidate_count; i++)
- {
- if (!candidates[i].eliminated)
- {
- printf("%s\n", candidates[i].name);
- }
- }
- break;
- }
- // Eliminate anyone with minimum number of votes
- eliminate(min);
- // Reset vote counts back to zero
- for (int i = 0; i < candidate_count; i++)
- {
- candidates[i].votes = 0;
- }
- }
- return 0;
- }
- // Record preference if vote is valid
- bool vote(int voter, int rank, string name)
- {
- bool flag = false;
- for (int i = 0; i < candidate_count; i++)
- {
- if (strcmp(candidates[i].name, name) == 0)
- {
- flag = true;
- preferences[voter][rank] = i;
- }
- }
- return flag;
- }
- // Tabulate votes for non-eliminated candidates
- void tabulate(void)
- {
- // what should it do?
- //How many things does it do?
- //how does it do it?
- // 1. update how many votes each candidate has in the first stage
- //if eliminated the second stage
- for (int i = 0; i < voter_count; i++)
- {
- for (int j = 0; j < candidate_count; j++)
- {
- int n = preferences[i][j];
- if (candidates[n].eliminated == false)
- {
- candidates[n].votes++;
- break;
- }
- }
- }
- return;
- }
- // Print the winner of the election, if there is one
- bool print_winner(void)
- {
- //consider the total number of votes and the number of votes in the first round. if the winner has 50 percent of the vote, win, else they loose
- bool result = false;
- for (int i = 0; i < candidate_count; i++)
- {
- if (candidates[i].votes > voter_count / 2)
- {
- printf("%s\n", candidates[i].name);
- result = true;
- }
- }
- return result;
- }
- // Return the minimum number of votes any remaining candidate has
- int find_min(void)
- {
- // TODO
- int min = candidates[0].votes;
- for (int i = 0; i < candidate_count; i++)
- {
- if (candidates[i].votes < min && candidates[i].eliminated == false)
- {
- min = candidates[i].votes;
- }
- }
- return min;
- }
- // Return true if the election is tied between all candidates, false otherwise
- bool is_tie(int min)
- {
- bool isTie = false;
- int count = 0;
- int i = 0, j = 1;
- for (i = 0; i < candidate_count; i++)
- {
- for (j = 1; j < candidate_count - i; j++)
- {
- if (candidates[i].votes == candidates[j + i].votes && candidates[i].votes == min)
- {
- count++;
- isTie = true;
- }
- }
- }
- //printf("%i", candidates[i].votes);
- //printf("%i", candidates[j+i].votes);
- //printf("\n");
- //printf("%i\n", count);
- return isTie;
- }
- // Eliminate the candidate (or candidates) in last place
- void eliminate(int min)
- {
- for (int i = 0; i < candidate_count; i++)
- {
- if (candidates[i].votes == min && candidates[i].eliminated == false)
- {
- candidates[i].eliminated = true;
- }
- }
- return;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement