CS50 Tideman

David Centurion
Dev Genius
Published in
5 min readMar 28, 2022

--

Man, this problem is hard, I’m writing this before I solved it, I think I can get a better understanding of the problem by writing what I’m doing, I advise you do something similar, and in a sense is giving me some kind of accountability, because now I have to finish this article.

Let start with the first function called vote what this function does is it takes three arguments (rank, name and ranks), all that data is extracted from the second nested for loop in main, rank is the index of the current candidate that is being iterated through, name name of the candidate that the user chose, ranks how the user ranked the candidates which is the problem that we are going to solve in this function.

We loop through the candidates array, if one of the names in the array is the same as the name the user entered, we update the ranks array with the index that the name is entered at. For example, if we have candidates Alice Bob Charlie , their index is [0 1 2], if the user voted Rank 1: Alice | Rank 2: Charlie | Rank 3: Bob the Ranks array will look like this [0 2 1]after the first voter.

Now the record_preferences function, which is going to populate the preferences array preferences[i][j] is the number of candidates who prefer candidate i over j

The logic of this problem is very frustrating and hard. According to the walkthrough video, the preference array looks like this:

candidates
Alice Bob Charlie

voter preferences, n candidate is represented by n row
Alice [0 3 2]
Bob [2 0 3]
Charlie[1 4 0]
there is one preference array for each candidate

We need to make a nested for loop, the second one we start it from, i+1 since we only need to add to the preferences array when j comes after i . I recommend you look through debug50 to understand this problem better, you can clearly see there how the numbers are added to the preferences array

I’m starting to hate this problem the previous ones were fun, but this idk man, but let's continue with add_pairs function. This function adds to the pairs array, which is composed of the pair structs that have a winner and aloser int values, that we will need to update, and we also need to update the pair_count variable.

We need the same nested for loop from the previous functions, because we don't want to compare the candidate by itself and to prevent a repeat check.

So we write a condition that compares which candidate is preferred compared to the next one. [i] [j] [0][1] would be the first one and [j][i] [1][0], if we had three candidates alice bob char and three voters. The values that are going to be compared are 3 > 0 here all three voters preferred candidate[i or 0] over candidate[j or 1] so we add [i] to the pairs[0].winner, [j] to pairs[0].loser and we add 1 to our pair_countbelow which is the variable that we use to access the index of pairs , if the condition is false then we check if it is less than, and the winner is [j] . This according to our voters preferences below:

Rank 1: alice
Rank 2: bob
Rank 3: char
Rank 1: alice
Rank 2: char
Rank 3: bob
Rank 1: char
Rank 2: alice
Rank 3: bob
The preferences array would look like this:
[0 3 2]
[0 0 1]
[1 2 0]

Now we are asked to sort the pairs, and we use the sort_pairs function, we need to sort the candidates by strength of victory, again we are using a nested for loop, but the first one goes backwards, is descending, the second one is “normal”, in the if statement we go to position [pairs.winner][pairs.loser] of the preferences array, which gives the number of people who prefer a candidate over another.

We will use bubble sort to sort the array, notice that i goes downward like we said, because in each pass through the array, we need to look at one less index.

The strength of victory is compared for each adjacent couple of pair structs in the pairsarray, if the pair and position [j+1] has a greater strength of victory than [j] the pairs are swapped using the temporary variable temp

For the next function lock_pairs which is purpose is to populate the locked 2d array.

Before we do that I created a new function called cycle that will return true if a cycle is created, we run it until it returns false, I recommend this article for a better understanding of these two functions in general.

In lock_pairs we loop through each pair, calling the cycle function for each loser and winner. If cycle returns false, then the locked array can be set to true for that pair

The print_winner function loops through each candidate, checking if it is locked, if locked is false increment the falseValuesvariable and check if it is equal to the candidate count, in other words it checks if there is an arrow pointing towards them.

This was the hardest problem so far, I could not solve it alone, I had to do a lot of googling and get help from other people, but as future developers we need to learn these skills, it is important that we go forward, because if we get stuck in a problem for so long we can get frustrated and stop studying, at least that is something that happened to me before, and I just stopped learning back then and even thought I got help I finished this problem in like 3 weeks, I spend a lot of time in the debugger trying to understand what was happening and explained here, and I think I still don't have a good grasp of it, but I feel like I need to move forward like I said before.

Thanks for reading :).

These 2 articles helped me tremendously: art1, art2.

--

--

I’m a software engineer and philosopher, writing about things that I learn or interest me, come and join me!