summaryrefslogtreecommitdiff
path: root/wk3/pset/runoff
diff options
context:
space:
mode:
Diffstat (limited to 'wk3/pset/runoff')
-rw-r--r--wk3/pset/runoff/runoff.c167
1 files changed, 167 insertions, 0 deletions
diff --git a/wk3/pset/runoff/runoff.c b/wk3/pset/runoff/runoff.c
new file mode 100644
index 0000000..3d3152e
--- /dev/null
+++ b/wk3/pset/runoff/runoff.c
@@ -0,0 +1,167 @@
+#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];
+
+// 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[])
+{
+ // Check for invalid usage
+ if (argc < 2)
+ {
+ printf("Usage: runoff [candidate ...]\n");
+ return 1;
+ }
+
+ // 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;
+ }
+
+ 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)
+{
+ // TODO
+ return false;
+}
+
+// Tabulate votes for non-eliminated candidates
+void tabulate(void)
+{
+ // TODO
+ return;
+}
+
+// Print the winner of the election, if there is one
+bool print_winner(void)
+{
+ // TODO
+ return false;
+}
+
+// Return the minimum number of votes any remaining candidate has
+int find_min(void)
+{
+ // TODO
+ return 0;
+}
+
+// Return true if the election is tied between all candidates, false otherwise
+bool is_tie(int min)
+{
+ // TODO
+ return false;
+}
+
+// Eliminate the candidate (or candidates) in last place
+void eliminate(int min)
+{
+ // TODO
+ return;
+}