nonipal

Untitled

Jul 20th, 2021
130
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.61 KB | None | 0 0
  1. #include <cs50.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <stdlib.h>
  5.  
  6.  
  7. // Max voters and candidates
  8. #define MAX_VOTERS 100
  9. #define MAX_CANDIDATES 9
  10.  
  11. // preferences[i][j] is jth preference for voter i
  12. int preferences[MAX_VOTERS][MAX_CANDIDATES];
  13.  
  14. // Candidates have name, vote count, eliminated status
  15. typedef struct
  16. {
  17.     string name;
  18.     int votes;
  19.     bool eliminated;
  20. }
  21. candidate;
  22.  
  23. // Array of candidates
  24. candidate candidates[MAX_CANDIDATES];
  25.  
  26. // Numbers of voters and candidates
  27. int voter_count;
  28. int candidate_count;
  29.  
  30. // Function prototypes
  31. bool vote(int voter, int rank, string name);
  32. void tabulate(void);
  33. bool print_winner(void);
  34. int find_min(void);
  35. bool is_tie(int min);
  36. void eliminate(int min);
  37.  
  38. int main(int argc, string argv[])
  39. {
  40.     // Check for invalid usage
  41.     if (argc < 2)
  42.     {
  43.         printf("Usage: runoff [candidate ...]\n");
  44.         return 1;
  45.     }
  46.  
  47.     // Populate array of candidates
  48.     candidate_count = argc - 1;
  49.     if (candidate_count > MAX_CANDIDATES)
  50.     {
  51.         printf("Maximum number of candidates is %i\n", MAX_CANDIDATES);
  52.         return 2;
  53.     }
  54.     for (int i = 0; i < candidate_count; i++)
  55.     {
  56.         candidates[i].name = argv[i + 1];
  57.         candidates[i].votes = 0;
  58.         candidates[i].eliminated = false;
  59.     }
  60.  
  61.     voter_count = get_int("Number of voters: ");
  62.     if (voter_count > MAX_VOTERS)
  63.     {
  64.         printf("Maximum number of voters is %i\n", MAX_VOTERS);
  65.         return 3;
  66.     }
  67.  
  68.     // Keep querying for votes
  69.     for (int i = 0; i < voter_count; i++)
  70.     {
  71.  
  72.         // Query for each rank
  73.         for (int j = 0; j < candidate_count; j++)
  74.         {
  75.             string name = get_string("Rank %i: ", j + 1);
  76.  
  77.             // Record vote, unless it's invalid
  78.             if (!vote(i, j, name))
  79.             {
  80.                 printf("Invalid vote.\n");
  81.                 return 4;
  82.             }
  83.         }
  84.  
  85.         printf("\n");
  86.     }
  87.  
  88.     // Keep holding runoffs until winner exists
  89.     while (true)
  90.     {
  91.         // Calculate votes given remaining candidates
  92.         tabulate();
  93.  
  94.         // Check if election has been won
  95.         bool won = print_winner();
  96.         if (won)
  97.         {
  98.             break;
  99.         }
  100.  
  101.         // Eliminate last-place candidates
  102.         int min = find_min();
  103.         bool tie = is_tie(min);
  104.  
  105.         // If tie, everyone wins
  106.         if (tie)
  107.         {
  108.             for (int i = 0; i < candidate_count; i++)
  109.             {
  110.                 if (!candidates[i].eliminated)
  111.                 {
  112.                     printf("%s\n", candidates[i].name);
  113.                 }
  114.             }
  115.             break;
  116.         }
  117.  
  118.         // Eliminate anyone with minimum number of votes
  119.         eliminate(min);
  120.  
  121.         // Reset vote counts back to zero
  122.         for (int i = 0; i < candidate_count; i++)
  123.         {
  124.             candidates[i].votes = 0;
  125.         }
  126.     }
  127.     return 0;
  128. }
  129.  
  130. // Record preference if vote is valid
  131. bool vote(int voter, int rank, string name)
  132. {
  133.     // TODO
  134.     for (int i = 0; i < candidate_count; i++)
  135.     {
  136.         if (strcmp(candidates[i].name, name) == 0)       // Takes duplicate candidate names too
  137.         {
  138.             preferences[voter][rank] = i;
  139.  
  140.             return true;                                 // Funtion is okay
  141.         }
  142.     }
  143.    
  144.     return false;
  145. }
  146.  
  147. // Tabulate votes for non-eliminated candidates
  148. void tabulate(void)
  149. {
  150.     // TODO
  151.  
  152.     printf("a:%i b:%i c:%i \n", candidates[1].votes, candidates[2].votes, candidates[3].votes);           //Testing
  153.  
  154.    
  155.     for (int i = 0; i < voter_count; i++)
  156.     {
  157.         for (int j = 0; j < candidate_count; j++)    
  158.         {
  159.             if (!candidates[preferences[i][j]].eliminated)  
  160.             {
  161.                 candidates[preferences[i][j]].votes++;
  162.                
  163.                 break;
  164.             }
  165.         }  
  166.     }
  167.  
  168.     printf("a:%i b:%i c:%i \n", candidates[1].votes, candidates[2].votes, candidates[3].votes);           //Testing
  169.  
  170.     return;
  171. }
  172.  
  173. // Print the winner of the election, if there is one
  174. bool print_winner(void)
  175. {
  176.     // TODO
  177.  
  178.     for (int i = 0; i < voter_count; i++)
  179.     {
  180.         if (candidates[i].votes >= voter_count / 2)
  181.         {
  182.             printf("%s \n", candidates[i].name);
  183.            
  184.             return true;
  185.         }
  186.         else
  187.         {
  188.             return false;
  189.         }
  190.     }
  191.  
  192.     return 0;
  193. }
  194.  
  195.  
  196. // Return the minimum number of votes any remaining candidate has
  197. int find_min(void)
  198. {
  199.     // TODO
  200.     int minimum = 100;
  201.    
  202.     for (int i = 0; i < candidate_count; i++)
  203.     {  
  204.         if (!candidates[i].eliminated)
  205.         {
  206.             if (candidates[i].votes < minimum)
  207.             {
  208.                 minimum = candidates[i].votes;            // Check if this is right
  209.             }
  210.         }
  211.     }
  212.     return minimum;
  213. }
  214.  
  215. // Return true if the election is tied between all candidates, false otherwise
  216. bool is_tie(int min)
  217. {
  218.     // TODO
  219.     for (int i = 0; i < candidate_count; i++)
  220.     {
  221.         if (candidates[i].eliminated == false)        // Smells bad
  222.         {
  223.             if (!(candidates[i].votes == min))
  224.             {
  225.                 return false;
  226.             }
  227.             else if (candidates[i].votes == min)
  228.             {
  229.                 return true;
  230.             }
  231.         }
  232.     }
  233.    
  234.    
  235.     return 2;
  236. }
  237.  
  238. // Eliminate the candidate (or candidates) in last place
  239. void eliminate(int min)
  240. {
  241.     // TODO
  242.     for (int i = 0; i < candidate_count; i++)
  243.     {
  244.         if (candidates[i].votes == min)
  245.         {
  246.             candidates[i].eliminated = true;
  247.         }
  248.     }
  249.     return;
  250. }
  251.  
Advertisement
Add Comment
Please, Sign In to add comment