0

#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; int position; } 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;
    candidates[i].position = i;
}

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
        // vote(int voter, int rank, string name)
        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 for (int i = 0; i < candidate_count; i++) { if (strcmp(candidates[i].name, name) == 0 && candidates[i].eliminated == false) { preferences[voter][rank] = i; return true; } } //printf("%i", preferences[0][0]); return false; }

// Tabulate votes for non-eliminated candidates void tabulate(void) { // TODO for ( int i = 0; i < voter_count;) { if (i > voter_count-1) { break; } for (int j = 0; j < candidate_count; j++) { if (i > voter_count-1) { break; } for (int k = 0; k < candidate_count;) { if (k > candidate_count || i > voter_count-1) { break; } if (preferences[i][j] == k && candidates[k].eliminated == false) { candidates[k].votes++; i++; } else if (candidates[k].eliminated == true ) { break; } else if (preferences[i][j] != candidates[k].position) { k++; } } } } //printf ("%i", candidates[0].votes); return; }

// Print the winner of the election, if there is one bool print_winner(void) { // TODO int max = 0; for (int i = 0; i < candidate_count; i++) { if ( max < candidates[i].votes) { max = candidates[i].votes; } } for (int i = 0; i < candidate_count; i++) { if ( max == (candidate_count/2) + 1 && max == candidates[i].votes) { printf("%s\n", candidates[i].name); return true; } } return false; }

// Return the minimum number of votes any remaining candidate has int find_min(void) { // TODO int min = 9999999; for ( int i = 0; i < candidate_count; i++) { if (min > candidates[i].votes) { min = candidates[i].votes; } } //printf ("%i", min); return 0; }

// Return true if the election is tied between all candidates, false otherwise bool is_tie(int min) { // TODO for (int i = 0; i < candidate_count; i++) { if ( min != candidates[i].votes && candidates[i].eliminated == false) return false; } return true; }

// Eliminate the candidate (or candidates) in last place void eliminate(int min) { // TODO for (int i = 0; i < candidate_count; i++) { if (min == candidates[i].votes) { candidates[i].eliminated = true; } } return; }

My program is working as intended.

/workspaces/.codespaces/runoff/ $ ./runoff Alice Bob Charlie Number of voters: 5 Rank 1: Alice Rank 2: Charlie Rank 3: Bob

Rank 1: Alice Rank 2: Charlie Rank 3: Bob

Rank 1: Bob Rank 2: Charlie Rank 3: Alice

Rank 1: Bob Rank 2: Charlie Rank 3: Alice

Rank 1: Charlie Rank 2: Alice Rank 3: Bob

Alice /workspaces/.codespaces/runoff/ $

:) runoff.c exists :) runoff compiles :) vote returns true when given name of candidate :) vote returns false when given name of invalid candidate :) vote correctly sets first preference for first voter :) vote correctly sets third preference for second voter :) vote correctly sets all preferences for voter :( tabulate counts votes when all candidates remain in election tabulate function did not produce correct vote totals :( tabulate counts votes when one candidate is eliminated tabulate function did not produce correct vote totals :( tabulate counts votes when multiple candidates are eliminated tabulate function did not produce correct vote totals :( tabulate handles multiple rounds of preferences tabulate function did not produce correct vote totals :( print_winner prints name when someone has a majority print_winner did not print winner of election :( print_winner returns true when someone has a majority print_winner did not print winner and then return true :) print_winner returns false when nobody has a majority :) print_winner returns false when leader has exactly 50% of vote :( find_min returns minimum number of votes for candidate find_min did not identify correct minimum :( find_min returns minimum when all candidates are tied find_min did not identify correct minimum :( find_min ignores eliminated candidates find_min did not identify correct minimum :) is_tie returns true when election is tied :) is_tie returns false when election is not tied :) is_tie returns false when only some of the candidates are tied :) is_tie detects tie after some candidates have been eliminated :) eliminate eliminates candidate in last place :) eliminate eliminates multiple candidates in tie for last :) eliminate eliminates candidates after some already eliminated

1 Answer 1

0

From the spec [emphasis added]

You should complete the implementations of the vote, tabulate, print_winner, find_min, is_tie, and eliminate functions, and you should not modify anything else in runoff.c (and the inclusion of additional header files, if you’d like).

You added position element to the candidate struct.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .