0

So I am still working on Runoff and I am having some weird results. It will return an obvious victory but any ties end up in weird loops and such. This has been apparent by adding printf functions in my print_winner function. I have been banging on my keyboard for a couple days with this and would appreciate some more help. I have used help50 and debug50 with no results to speak of(fair to say, not really great at interpreting debug50)

here is the code

#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)
{
for (int c=0;c<candidate_count;c++)
    {
        int match = strcmp(name, candidates[c].name);//compares the name provided by voter with the candideate[c]

            if(match==0)//if the name is the name of a candidate fill index preference [voter][rank] with candidates[c]
            {
                preferences[voter][rank]=c;
                return true;
            }
    }
    return false;
}

// Tabulate votes for non-eliminated candidates
void tabulate(void)
{

    for (int ballot=0; ballot<voter_count;ballot++)
    {
        for(int can=0;can<candidate_count;can++)
        {
            if(candidates[preferences[ballot][can]].eliminated==true)
            {
                continue;
            }
            if(candidates[preferences[ballot][can]].eliminated==false)
            {
                candidates[preferences[ballot][can]].votes++;
                break;
            }
        }
    }
    // TODO
    return;
}

// Print the winner of the election, if there is one
bool print_winner(void)
{
    candidate swap={0,0,false};
    int cc = candidate_count;

    for (int i=0;i<cc; i++)
    {
        for(int j=i; j<cc-1; j++)
        {
        if(candidates[j].votes>candidates[j+1].votes)
            {
                swap=candidates[j];
                candidates[j]=candidates[j+1];
                candidates[j+1]=swap;
            }
        }
    }

    if(candidates[cc-1].votes>(voter_count*.5))
    {
        printf("The winner is: %s\n",candidates[cc-1].name);
        printf("number of votes: %i\n,", candidates[cc-1].votes);
        return true;
    }
    if(candidates[cc-1].votes==candidates[cc-2].votes)
    {
        printf("tie\n");
        return false;
    }

    return false;
}


// Return the minimum number of votes any remaining candidate has
int find_min(void)
{
   int small =0;

    for(int i=0; i<candidate_count-1; i++)
    {
        if(candidates[i].votes && candidates[i].eliminated==false>candidates[i+1].votes&&candidates[i+1].eliminated==false)
        {
            small=candidates[i+1].votes;
        }
    }
    return small;
}

// Return true if the election is tied between all candidates, false otherwise
bool is_tie(int min)
{
    int tie = 0; //counter for candidates with minimum votes who are still in the race
    int in =0;//counter for candidates who are still eligible

    for(int i=0; i <candidate_count; i++)
    {
        if(candidates[i].votes==min && candidates[i].eliminated ==false)
        {
            tie++;
        }
        if( candidates[i].eliminated==false)
        {
            in++;
        }
    }
    if (tie==in)
    {
        return true;
    }
return false;
}

// Eliminate the candidate (or candidiates) 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;
        }
    }
    // TODO
    return;
}

You must log in to answer this question.

Browse other questions tagged .