-
-
Save AnimeshRy/489d3c19db9d179c7c562bad24c4b3ee to your computer and use it in GitHub Desktop.
#include <cs50.h> | |
#include <stdio.h> | |
#include <string.h> | |
#include <stdbool.h> | |
#include <math.h> | |
// Max voters and candidates | |
#define MAX_VOTERS 100 | |
#define MAX_CANDIDATES 9 | |
// preferences[i][j] is jth preference for voter i(2d array) | |
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 | |
//passed i,j and name of the candidate the user entered, look at line 77 | |
bool vote(int voter, int rank, string name) | |
{ | |
bool exist = false; | |
for (int i = 0; i < candidate_count; i++) | |
{ | |
//check if name is present in the candidates entered by the user by camparing two strings | |
//strcmp is checking for the name and camparing it to the candidates array location 'i' which starts according to the for loop above | |
if (strcmp(name, candidates[i].name) == 0) | |
{ | |
//if you found the person is present then add that number as a rank of the candidate in the preferences array | |
//suppose this is a 2d array and the preference array is adding the preference number on a specific poistion so | |
// here ex - preferences[0][0] = i (the rank preferences from the candidate count) | |
// [i][][][] | |
// [][][][] | |
// [][][][] | |
// [][][][] | |
preferences[voter][rank] = i; | |
exist = true; | |
break; | |
//This is a bool conditions which will become true, again look at line 77 | |
} | |
} | |
return exist; | |
} | |
// Tabulate votes for non-eliminated candidates | |
void tabulate(void) | |
{ | |
// TODO | |
for (int i = 0; i < voter_count; i++) | |
{ | |
for (int j = 0; j < candidate_count; j++) | |
{ | |
if (candidates[preferences[i][j]].eliminated == false) | |
{ | |
candidates[preferences[i][j]].votes += 1; | |
break; | |
} | |
} | |
} | |
return; | |
} | |
// Print the winner of the election, if there is one | |
bool print_winner(void) | |
{ | |
// TODO | |
for (int i = 0; i < candidate_count; i++) | |
{ | |
string most = candidates[i].name; | |
if (candidates[i].votes > voter_count / 2) | |
{ | |
printf("%s\n", most); | |
return true; | |
} | |
} | |
return false; | |
} | |
// Return the minimum number of votes any remaining candidate has | |
int find_min(void) | |
{ | |
int minvotes = voter_count; | |
for (int i = 0; i < candidate_count; i++) | |
{ | |
if (candidates[i].eliminated == false && candidates[i].votes < minvotes) | |
{ | |
minvotes = candidates[i].votes; | |
} | |
} | |
return minvotes; | |
} | |
// Return true if the election is tied between all candidates, false otherwise | |
bool is_tie(int minvotes) | |
{ | |
for (int i = 0; i < candidate_count; i++) | |
{ | |
if (candidates[i].eliminated == false && candidates[i].votes != minvotes) | |
{ | |
return false; | |
} | |
} | |
return true; | |
} | |
// Eliminate the candidate (or candidiates) in last place | |
void eliminate(int minvotes) | |
{ | |
for (int i = 0; i < candidate_count; i++) | |
if (candidates[i].votes == minvotes) | |
{ | |
candidates[i].eliminated = true; | |
} | |
return; | |
} |
can anyone tell me what this message mean ?
linker command failed with exit code 1 (use -v to see invocation)
: recipe for target 'runoff' failed
make: *** [runoff] Error 1
Maybe you are not using the make statement right. Select the right directory and use make runoff
to make it work. Make files is like a automation tool where the compilation and execution is done together rather than using clang -o file file.o
. If these steps don't work, make a new file in a new dir and try again.
can anyone tell me what this message mean ?
linker command failed with exit code 1 (use -v to see invocation)
: recipe for target 'runoff' failed
make: *** [runoff] Error 1Maybe you are not using the make statement right. Select the right directory and use
make runoff
to make it work. Make files is like a automation tool where the compilation and execution is done together rather than usingclang -o file file.o
. If these steps don't work, make a new file in a new dir and try again.
i'll try again ty so much
Make sure you made your runoff.c in runoff and not just out in pset2 or whatever it is. It should be indented under runoff, not in line with the pset number. Best regards Tara Green-Webber Administrative Manager - Xconditioning [email protected] 250.617.9838
…
On Oct 16, 2020, at 9:24 AM, Animesh @.***> wrote: @AnimeshRy commented on this gist. can anyone tell me what this message mean ? linker command failed with exit code 1 (use -v to see invocation) : recipe for target 'runoff' failed make: *** [runoff] Error 1 Maybe you are not using the make statement right. Select the right directory and use make runoff to make it work. Make files is like a automation tool where the compilation and execution is done together rather than using clang -o file file.o. If these steps don't work, make a new file in a new dir and try again. — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.
will make sure of it thank you really !
In line 165 and 167, why do you use candidates[preferences[i][j]].eliminated instead of candidates[i].eliminated?
See above, we used two loops and are iterating over all voters who gave votes to all the candidates and where did we save the votes on these voters? preferences[i][j]
Shouldn't we only be updating preferences[i][0].votes
since second-place votes shouldn't be counted the first time around?
I had applied the similar logic for find_min() function but it shows error in check 50 command. Isn't your code showing the error
:( 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
Because you didn't set candidates[i].eliminated == true.
In this case, it will return true if you have already eliminated some candidates.
try this
bool is_tie(int min) { for (int c = 0; c < candidate_count; c++) { if (candidates[c].eliminated == false && candidates[c].votes != min) { return false; } else if (candidates[c].eliminated == true) { return false; } } return true; }
candidates[preferences[i][j]].votes
Can someone explain how these two things got combined? I thought preferences array was separate, and not totally understanding how we can just put it into the candidate struct variable. I am very new to any kind of programming, and wasn't sure what to even google to find this answer.
Also, if anyone has a good site they can recommend for some of the basic functions/rules of C.I remember being very confused as well with programming, but it will definitely get better :).
Now, for your question. With candidates[preferences[i][j]].votes, you are indicating the number of votes the candidates has, in each voters preference.
Let me implement this more graphically!
So, when implementing the below function:void tabulate(void)
{
// TODO
for (int i = 0; i < voter_count; i++)
{
for (int j = 0; j < candidate_count; j++)
{
if (candidates[preferences[i][j]].eliminated == false) \ if your candidate's elimination status in voters [i][j] is FALSE, thus not eliminated, do the below
{
candidates[preferences[i][j]].votes += 1; \ this just increments the above candidates votes by 1.
break;
}
}} return;
}
Now, candidates[preference[i][j]].votes indicates the amount of votes each candidate has in each voters preference array.
I hope I explained that clearly, but if you have any questions, please, please, please DO NOT hesitate to add another reply. @tara8970
Won't that make you add votes for all the [voters,candidates] array not only [voters,0] in the first iteration?
i'm getting this when making runoff
runoff.c:78:20: error: implicit declaration of function 'print_winnner' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
bool won = print_winnner();
why you include #include <stdbool.h> & #include <math.h>????
I really appreciate your work man, you are helping students to solve mind-boggling problem sets. And your explanation is very easy to understand.
but, there is only one thing I am facing a problem with, I took references from many other answers as well but the same issues I am having. I am unable to visualize the pseudo code for the is_tie function, I mean, I can't able to visualize what it is doing. Can you elaborate on the pseudo-code for it?
When it will give true or when false.
It will be very helpful.
thanks for your work on this mind-boggling problem! Can someone explain why is_tie works though? I really could not understand your reasoning behind this function :/
Check CS50 is giving me this response:
:( 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 did not return false
:( print_winner returns false when leader has exactly 50% of vote
print_winner did not return false
and this is my print_winner function:
bool print_winner(void)
{
for ( int i = 0; i < candidate_count; i++ )
{
if (candidates[i].votes > (candidate_count / 2))
{
printf("%s\n", candidates[i].name);
return true;
}
}
return false;
}
I am not able to understand where the problem is, if anybody can point it out for me it'll be a huge help.
Thanks in advance for your help
please help me because as I run this code it is not compiling properly instead after entering one rank is giving the output of invalid .
can anyone tell me what this message mean ?
linker command failed with exit code 1 (use -v to see invocation)
: recipe for target 'runoff' failed
make: *** [runoff] Error 1