1

I'm getting the following fails when I check pset3 runoff (all the rest are coming up as correct)

:( tabulate counts votes when multiple candidates are eliminated 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

I've tried debugging, printf different things and I still can't figure out what's wrong. Here is my code and thank you in advance:

#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
    for(int k=0; k<candidate_count; k++)
    {
        if(strcmp(name, candidates[k].name)==0)
        {
            preferences[voter][rank]=k;
            return true;
        }
    }
    return false;
}

// Tabulate votes for non-eliminated candidates
void tabulate(void)
{
   //read preference(n)
   //if preference(n) candidate !eliminated candidates[i].votes++
   //if preference(n) candidate eliminated read preference(n+1)
   //preference(preference(n+1))

        //preferences column: int x=0
        int x=0;
        //preferences value: int val=0
        int val=0;
        int j=0;
        for(j=0; j<voter_count; j++)
        {
            val=preferences[j][x];
            if(!candidates[val].eliminated)
            {
                candidates[val].votes++;
            }
            else
            {
            while(candidates[val].eliminated)
            {
                x++;
                val=preferences[j][x];
            }
            candidates[val].votes++;
            }
        }

    return;
}

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

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

// Return true if the election is tied between all candidates, false otherwise
bool is_tie(int min)
{
    // TODO
    //for all candidates, if candidate not eliminated, if number of votes of each candidate is equal, return true
    int counter=0;
    int totalremaining=candidate_count;
    for(int i=0; i<candidate_count; i++)
    {
        if(!candidates[i].eliminated)
        {
            if(candidates[i].votes==min)
            {
                counter++;
            }
        }
    }
    for(int j=0; j<candidate_count; j++)
    {
        if(candidates[j].eliminated)
        {
            totalremaining--;
        }
    }
    if(counter==totalremaining)
    {
        return true;
    }
    return false;
}

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

Reading your tabulate(void) function, I have one criticism which may help out, that being using nested for loops. The first for loop should iterate through the first value in the preferences[][] array, and the second one should iterate through the second one(speaks for itself). Then put an if() statement checking if that candidate is not eliminated. If they are eliminated, you don't need an else, the loop will just move down that voter's preferences till it reaches one that is not eliminated, and if it does, it will set the "iterating value of the inner loop" to be greater than the limit, thereby moving onto the next voter's preferences(note: the limit you set should be the amount of candidates).

I don't know exactly what is wrong with the tabulate() function, but I have a sense it lies in that while loop you use.

As for the other functions, print_winner keeps the majority as an int, which means if you have 5 voters, the majority would be 3 votes( as it would need to be greater than half of 5, meaning 2.5), however since you keep the maj variable as an int, that 2.5 has the .5 removed, leaving it as just 2.

The find_min(void) has an issue on line 226, you're making it as zero, and changing it any time a candidate has some amount of votes greater than the minimum(because of the way you have the sign pointed on line 231). This is counterproductive, instead, make the minimum the value of the first candidate's votes, and then cycle through the other candidates, looking for any candidate whose votes are less than the minimum. If it turns out the first candidate has the least amount of votes, the minimum will naturally stay that amount.

| improve this answer | |

You must log in to answer this question.

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