Язык Си: голосование с несколькими турами выборов


На третьей неделе курса Computer Science CS50 (Harvard) предлагается выполнить домашнее задание в Problem Set 3 под названием runoff.c — нужно написать код программы, которая не просто подсчитывает, какой кандидат набрал наибольшее количество голосов, как в прошлый раз, в программе runoff нужно реализовать голосование до набора более 50% голосов всех избирателей.

Победитель будет объявлен только тогда, когда один из кандидатов наберет более половины голосов. Чтобы это можно было сделать, каждый голосующий ранжирует всех кандидатов от наибольшего предпочтения (ранг 1) до наименьшего (последний ранг). Далее подсчитывается сумма голосов в первом туре (ранг 1). Если кто-то из кандидатов наберет на этом этапе более 50% голосов, его объявляют победителем.

Если в первом туре не будет победителя, то нужно найти кандидата, который набрал наименьшее количество голосов и удалить его из списка кандидатов, чтобы в следующем туре участвовали в подсчете голосов только оставшиеся кандидаты. И так продолжать до тех пор, пока не появится победитель. Если выясняется, что у всех на выборах одинаковое количество голосов, то объявляется ничья и они все являются победителями.

Первое решение Игроглаза. Исходные тесты прошло, но на проверке cs50 показало много косяков:

#include <stdio.h>
#include <string.h>
#include <stdbool.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
{
    char name[1000];
    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, char *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, char *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++)
    {
        strcpy (candidates[i].name, argv[i + 1]);
        candidates[i].votes = 0;
        candidates[i].eliminated = false;
    }

    printf("Number of voters: ");
    scanf("%d", &voter_count);
    while (getchar() != '\n') ; // clear buffer

    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++)
        {

        char name[1000]; // there user enters name of candidate when voting

            printf("Rank %i: ", j + 1);
            scanf("%s", name);

            // 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;
        }
    }
    getchar();
    getchar();
    return 0;
}

// Record preference if vote is valid
bool vote(int voter, int rank, char *name)
{
    for (int i = 0; i < candidate_count; i++)
    {
        if (!strcmp(name, candidates[i].name))
        {
            preferences[voter][rank] = i;
    //debug printf("%c - voter:%d rank:%d pref:%d\n", *name, voter, rank, preferences[voter][rank]);
            return true;
        }

    }

    return false;
}

// Tabulate votes for non-eliminated candidates
void tabulate(void)
{
    // go through all voters and check whom they give highest preference
    // 1) take voter
    // 2) find this voter 'rank 0' preffered candidate
    // 3) increase votes number of this candidate

    for (int i = 0; i < voter_count; i++)
    {
        for (int j = 0; j < candidate_count; j++)
        {
            if (preferences[i][0] == j && !candidates[j].eliminated)
            {
                candidates[j].votes++;
                break;
            }
        }
    }
}

//dubug printf("%c - votes:%d\n", *candidates[j].name, candidates[j].votes);

// Print the winner of the election, if there is one
bool print_winner(void)
{
    // 1) go through candidates array and check who got highest vote
    // 2) if there is a candidate who > 1/2 votes - he wins

    int top = 0; // candidate who has most votes

    for (int i = 0; i < candidate_count; i++)
    {
        if (candidates[i].votes > top)
            top = i;
    }

    if (candidates[top].votes > (voter_count / 2))
    {
        printf("Winner: %s", candidates[top].name);
        return true;
    }
    else
        return false;

}

// Return the minimum number of votes any remaining candidate has
int find_min(void)
{
    // go through all candidates and find out who has least votes
    // 1) take 1st candidate and store it's number of votes
    // 2) compare 1st candidate with further candidates to find min

    int first = 0; // flag which indicate first possible 'min' candidate
    int min;

    for (int i = 1; i < candidate_count; i++)
    {
        if (!first && !candidates[i].eliminated)
        {
            first = 1; // 1st min candidate found, so check flag
            min = candidates[i].votes;
        }

        if (first && !candidates[i].eliminated && candidates[i].votes < min)
        {
            min = candidates[i].votes;
            return min;
        }
    }

    return 0;
}

// Return true if the election is tied between all candidates, false otherwise
bool is_tie(int min)
{
    // find out is there candidates with the same vote number
    // 1) go through candidates
    // 2) if candidate eliminated or got 'min' votes - ignore it
    // 3) if all 'active' candidates got same number of votes - tie
    //    a) compare votes numbers with == between each other.
    //    b) if even one isn't the same - false

    int cmpvote = 0;

    for (int i = 1; i < candidate_count; i++)
    {
        if (!cmpvote && !candidates[i].eliminated && (candidates[i].votes != min))
            cmpvote = candidates[i].votes; // 1st valid candidate found

        if (cmpvote && !(candidates[i].votes == cmpvote))
            return false;
    }
    return true;
}

// Eliminate the candidate (or candidates) in last place
void eliminate(int min)
{
    // check which candidate got 'min' and eliminate him
    for (int i = 1; i < candidate_count; i++)
    {
        if (candidates[i].votes == min)
            candidates[i].eliminated = true;
    }

    return;
}

Второе решение от Игроглаза, исправленное:

#include <stdio.h>
#include <string.h>
#include <stdbool.h>
// I prefer to write code with vanilla C libraries,
// but this time I had to include cs50.h cause without it this program fails to compile for 'check50'
#include <cs50.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; // had to change it from 'char name[1000]' to 'string' to make 'check50' work...
    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, char *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, char *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++)
    {
        strcpy (candidates[i].name, argv[i + 1]);
        candidates[i].votes = 0;
        candidates[i].eliminated = false;
    }

    printf("Number of voters: ");
    scanf("%d", &voter_count);
    while (getchar() != '\n') ; // clear buffer

    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++)
        {

        char name[1000]; // there user enters name of candidate when voting

            printf("Rank %i: ", j + 1);
            scanf("%s", name);

            // 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, char *name)
{
    for (int i = 0; i < candidate_count; i++)
    {
        if (!strcmp(name, candidates[i].name))
        {
            preferences[voter][rank] = i;
    //debug printf("%c - voter:%d rank:%d pref:%d\n", *name, voter, rank, preferences[voter][rank]);
            return true;
        }

    }

    return false;
}

// Tabulate votes for non-eliminated candidates
void tabulate(void)
{
    // go through all voters and check whom they give highest preference
    // 1) take voter
    // 2) find this voter 'rank 0' preffered candidate
    // 3) increase votes number of this candidate

    for (int voter = 0; voter < voter_count; voter++)
    {
        // 'flag' - to show that next valid candidate after elimineted one is found
        // and it's time to break cycle
        for (int r = 0, flag = 0; r < candidate_count; r++) // cycle through ranks
        {
            for (int c = 0; c < candidate_count; c++) // cycle through possible candidates
            {
                if (preferences[voter][r] == c && !candidates[c].eliminated)
                {
                    candidates[c].votes++;
                    flag = 1;
                    break;
                }
            }
            if (flag == 1)
            {
                break;
            }
        }
    }
}

//dubug printf("%c - votes:%d\n", *candidates[j].name, candidates[j].votes);

// Print the winner of the election, if there is one
bool print_winner(void)
{
    // 1) go through candidates array and check who got highest vote
    // 2) if there is a candidate who > 1/2 votes - he wins

    int top_votes = 0; // biggest number of votes for particular candidate at election
    int c; // id of candidate with biggest number of votes

    for (int i = 0; i < candidate_count; i++)
    {
        if (candidates[i].votes > top_votes)
        {
            top_votes = candidates[i].votes;
            c = i;
        }
    }

    if (candidates[c].votes > (voter_count / 2))
    {
        printf("%s\n", candidates[c].name);
        return true;
    }
    else
        return false;
}

// Return the minimum number of votes any remaining candidate has
int find_min(void)
{
    // go through all candidates and find out who has least votes
    // 1) take 1st candidate and store it's number of votes
    // 2) compare 1st candidate with further candidates to find min

    int first = 0; // flag which indicate first possible 'min' candidate
    int min = 0;

    for (int i = 0; i < candidate_count; i++)
    {
        if (!first && !candidates[i].eliminated)
        {
            first = 1; // 1st min candidate found, so check flag
            min = candidates[i].votes;
        }

        if (first && !candidates[i].eliminated && 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)
{
    // find out is there candidates with the same vote number
    // 1) go through candidates
    // 2) if candidate eliminated - ignore it
    // 3) if all 'active' candidates got same number of votes - tie
    //    a) compare votes numbers with == between each other.
    //    b) if even one isn't the same - false

    int cmpvote = 0; // flag; to find 1st valid candidate for comparing

    for (int i = 0; i < candidate_count; i++)
    {
        if (!candidates[i].eliminated)
        {
            if (!cmpvote)
                cmpvote = candidates[i].votes; // 1st valid candidate for comparison is found
            else
            {
                if (candidates[i].votes != cmpvote && candidates[i].votes != min)
                    return false;
            }
        }
    }
    return true;
}

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

    return;
}

Решение (Штукенция)

Для меня эта задача оказалась одной из самых сложный на текущий момент. Я несколько часов потратила на то, чтобы понять, что именно нужно сделать. Я не догадалась посмотреть видео с объяснениями, и в итоге целый день вникала в суть задачи. В этом мне помогли схемы на бумаге:

Если бы я посмотрела видео, то можно было бы сэкономить несколько часов мучений. Как только я примерно поняла задачу, появилась вторая проблема: разобраться в отдельных функциях. Первую функцию bool vote(int voter, int rank, string name) мне удалось сделать более и менее быстро.

А вот со второй я оказалась в тупике. Я целый день пыталась придумать алгоритм для void tabulate(void), и в итоге написала жутко длинный код со множеством вложенных циклов. Я думаю, что это совершенно неоптимальное решение, но по-другому не получилось.

Еще важный момент по поводу варианта, когда в голосовании получается «ничья», если ввести два кандидата A и B, и проголосовать сначала A B, а потом B A, то моя программа выдавала странную ошибку floating point exception (core dumped), это связано с арифметическим исключением, когда делишь на ноль, либо если идет переполнение целого числа со знаком.

Пока я отлаживала программу, оказалось, что проблема в функции void eliminate(int min), которая должна удалять кандидатов с наименьшим количеством голосов. Ведь если у нас два кандидата A и B, и голосуют за них два человека (первый: A B; второй B A), то получается что на первом шаге у каждого по 1 голосу, и 1 — это наименьшее количество голосов.

Получился вот такой код программы:

#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);
                }
            }
            printf("Tie!\n");
            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 i = 0; i < candidate_count; i++)
    {
        if (!strcmp(name,candidates[i].name))
        {
            preferences[voter][rank]=i;
            return true;
        }
    }
    return false;
}

// Tabulate votes for non-eliminated candidates
void tabulate(void)
{
    for (int j=0; j<candidate_count; j++)
         {
             for (int i=0; i<candidate_count; i++)
             {
                for (int z=0; z<voter_count; z++)
                {
                    int prefer_name_index = preferences[z][j];
                    if (!candidates[prefer_name_index].eliminated)
                    {
                        candidates[prefer_name_index].votes+=1;
                    }
                    if (candidates[prefer_name_index].eliminated)
                    {
                        for (int runoff_j = 1; runoff_j<candidate_count;runoff_j++)
                        {
                            prefer_name_index = preferences[z][runoff_j];
                            if (!candidates[prefer_name_index].eliminated)
                            {
                                candidates[prefer_name_index].votes+=1;
                            }
                        }
                    }
                }
                break;
             }
             break;
         }
    return;
}

// Print the winner of the election, if there is one
bool print_winner(void)
{
    float half_votes = (voter_count*0.5);
    string winner;

    for (int i = 0; i < candidate_count; i++)
    {
        if(candidates[i].votes>half_votes)
        {
            printf("Winner: %s\n", candidates[i].name);
            return true;
        }
    }
    return false;
}

// Return the minimum number of votes any remaining candidate has
int find_min(void)
{
    int find_min = voter_count;
    for (int i = 0; i<candidate_count; i++)
    {
        if(candidates[i].votes < find_min && !candidates[i].eliminated)
        {
            find_min = candidates[i].votes;
        }
    }
    return find_min;
}

// Return true if the election is tied between all candidates, false otherwise
bool is_tie(int min)
{
    int sum_votes = voter_count-min;
    int still_in = 1;
    int still_in_cand[candidate_count];

    for (int i = 0; i<candidate_count; i++)
    {
        if(!candidates[i].eliminated)
        {
            still_in_cand[i]=i;
            still_in+=1;
        }
    }

    int tie_vote=sum_votes/still_in;

    for (int j = 0; j<still_in; j++)
        {
            if(still_in_cand[j]!=tie_vote)
            return false;
        }
    return true;
}

// 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=true;
    }
    return;
}

Тестируем программу при голосовании вничью:

Мне показалось, что программа работает хорошо, пока я не протестировала с 5 голосующими:

Результат получился странный.

Поэтому я решила проверить код через дебагер, и нашла множество багов. Оказалось, что две функции у меня работают неправильно — расчет голосов текущего раунда и проверка на ничью. Пришлось переписывать их полностью заново. Вот что получилось:

#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);
                }
            }
            printf("Tie!\n");
            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 i = 0; i < candidate_count; i++)
    {
        if (!strcmp(name, candidates[i].name))
        {
            preferences[voter][rank] = i;
            return true;
        }
    }
    return false;
}

// Tabulate votes for non-eliminated candidates
void tabulate(void)
{
    for (int i = 0; i < voter_count; i++)
    {
        for (int j = 0; j < candidate_count; j++)
        {
            int id = preferences[i][j];

            if (!candidates[id].eliminated)
            {
                candidates[id].votes += 1;
                break;
            }

            else
            {
                for (int z = 1; z < candidate_count; z++)
                {
                    int id_elim = preferences[i][z];

                    if (!candidates[id_elim].eliminated)
                    {
                        candidates[id_elim].votes += 1;
                        break;
                    }
                }
                break;
            }
        }
    }

    return;
}

// Print the winner of the election, if there is one
bool print_winner(void)
{
    float half_votes = voter_count * 0.5;
    string winner;

    for (int i = 0; i < candidate_count; i++)
    {
        if (candidates[i].votes > half_votes)
        {
            printf("Winner: %s\n", candidates[i].name);
            return true;
        }
    }
    return false;
}

// Return the minimum number of votes any remaining candidate has
int find_min(void)
{
    int find_min = voter_count;
    for (int i = 0; i < candidate_count; i++)
    {
        if (candidates[i].votes < find_min && !candidates[i].eliminated)
        {
            find_min = candidates[i].votes;
        }
    }
    return find_min;
}

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

// 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 = true;
        }
    }
    return;
}

Тестируем программу:

Ура, теперь все работает правильно!

Это задание оказалось очень сложным для моего уровня, так что я разбиралась в нем несколько дней, возможно даже около недели. Множество раз мне хотелось бросить все, так как было ощущение, что мне такое задание не по зубам. Медведь меня очень поддерживал и верил, что все получится. И мы продолжали шаг за шагом продвигаться вперед. И сейчас, когда программа заработала, я очень рада и горжусь нами, что мы такие молодцы!

Задание придумано очень необычно и интересно, так что ты многому учишься, пока их выполняешь. Важно делать все самостоятельно, и не ориентироваться на идеи других людей. Мы с Медведем посмотрели код друг друга только после того, как наши программы полностью заработали. И оказалось, что у каждого из нас совершенно свой уникальный подход к написанию кода. Не подсматривайте чужие готовые решения, это не поможет вам научиться программировать. Если у вас что-то не выходит, не отчаивайтесь и дайте себе больше времени.

Все получится!


Запись опубликована в рубрике С (Си). Добавьте в закладки постоянную ссылку.

Добавить комментарий

🇬🇧 Attention! Comments with URLs/email are not allowed.
🇷🇺 Комментарии со ссылками/email удаляются автоматически.