CS50 tideman struggling - c

I'm new to this site and I have been trying to do Tideman of the problem set 3 of CS50 course and have been struggling to this problem for days, please help me find the logical error in my code but please don't post the solution. Any help would be much appreciated. Thanks in advance
// Lock pairs into the candidate graph in order, without creating cycles
void lock_pairs(void)
{
int compare[MAX * (MAX - 1)];
int locked_count = 0;
for (int n=0; n < pair_count; n++)
{
circle_check(pairs[n], compare, 0, locked_count);
if(circle_check_out != 0)
{
locked[pairs[n].winner][pairs[n].loser]=true;
locked_count++;
}
}
return;
}
// Check wether circle
void circle_check( pair check, int compare[], int comp_numb, int locked_count)
{
if (compare[comp_numb+1] == compare[0] && comp_numb == locked_count)
{
circle_check_out = 0;
return;
}
else if (compare[comp_numb+1] != compare[0] && comp_numb == locked_count && comp_numb != 0)
{
circle_check_out = 1;
return;
}
for (int n=0; n < locked_count; n++)
{
if (locked[pairs[n].winner][check.winner] == true)
{
circle_check(pairs[n], compare, comp_numb+1, locked_count);
compare[comp_numb] = check.loser;
compare[comp_numb+1] = check.winner;
}
}
}
// Print the winner of the election
void print_winner(void)
{
bool dominate=true;
for (int win=0; win < candidate_count; win++)
{
for (int lose=0; lose < candidate_count; lose++)
{
if(locked[lose][win]==true)
dominate=false;
}
if (dominate==true)
printf("%s",candidates[win]);
}
return;
}

Related

CS50 Tideman - lock_pairs skips final pair if it creates cycle

I have no prior coding experience and i've been on this pset ofr like 3+ days now...very challenging and rewarding, but this last check is driving me crazy.
This is the lock_pairs function i wrote
void lock_pairs(void)
{
for (int i = 0 ; i < pair_count ; i++)
{
int og_win = pairs[i].winner;
int temp = pairs[i].loser;
if (i < 1)
{
locked[pairs[i].winner][pairs[i].loser] = true;
}
else if(creates_cycle(i, og_win, temp) != true)
{
locked[pairs[i].winner][pairs[i].loser] = true;
}
}
return;
}
And this is the function i wrote to check if locking this pair would create a cycle
bool creates_cycle(int n, int original_winner, int temp_win_los)
{
for (int j = 0 ; j < n ; j++)
{
if (locked[pairs[j].winner][pairs[j].loser] == true)
{
if ( pairs[j].winner == temp_win_los )
{
if ( pairs[j].loser == original_winner )
{
return true;
}
else
{
temp_win_los = pairs[j].loser;
creates_cycle(n, original_winner, temp_win_los);
}
}
}
}
return false;
}
I am pretty satisfied of being able to reach this point in the pset, but i really don't understand why and where my code is faulty.
Any help is appreciated.
Thanks!

Getting maze algorithm to work on open maze

first time using the site. I am trying to figure out how to solve a 'maze' using the shortest path. The code works for traditional mazes but the path I am trying to work on is essentially more open. When run the current path goes right, then down, then left and goes up then turns right before finally reaching B. My solution needs to go right then up then left to B. Any help would be appreciated!
9,11
xxxxxxxxxxx
x......B..x
x...xxxx..x
x...xxxx..x
x....A....x
x..xx.xx..x
x.........x
x.........x
xxxxxxxxxxx
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>
char** maze;
int** checked;
int rows;
int cols;
int start_row;
int start_col;
enum area
{
space,
wall,
end,
trail,
};
void alloc_maze() {
maze = malloc(rows * sizeof(char*));
for (int i = 0; i < rows; i++) {
maze[i] = malloc(cols * sizeof(char*));
}
}
void alloc_checked() {
checked = malloc(rows * sizeof(char*));
for (int i = 0; i < rows; i++) {
checked[i] = malloc(cols * sizeof(char*));
}
}
void get_maze(const char* file_name)
{
char c;
char rows_t[3] = { '\0' };
char cols_t[3] = { '\0' };
int rows_i = 0;
int cols_i = 0;
int swap = 0;
FILE* file = fopen(file_name, "r");
if (file) {
while ((c = getc(file)) != EOF) {
if (c == '\n') {
break;
} else if (c ==',')
{
swap = 1;
}
else if (!swap) {
rows_t[rows_i] = c;
rows_i++;
}
else {
cols_t[cols_i] = c;
cols_i++;
}
}
}
rows = atoi(rows_t);
cols = atoi(cols_t);
alloc_maze();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
c = getc(file);
if (c == '\n') {
c = getc(file);
}
maze[i][j] = c;
if (c == 'A') {
start_row = i;
start_col = j;
}
}
}
fclose(file);
}
void get_checked() {
alloc_checked();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (maze[i][j] == 'x') {
checked[i][j] = wall;
}
else if (maze[i][j] == 'B') {
checked[i][j] = end;
}
else {
checked[i][j] = space;
}
}
}
}
int search(int row, int col) {
int* current = &checked[row][col];
if (*current == end) {
printf("\n congrats you found the shortest path is");
return 1;
}
if (*current == space) {
*current = wall;
if (search(row, col + 1)) {
*current = trail;
printf("E");
return 1;
}
if (search(row + 1, col)) {
*current = trail;
printf("N");
return 1;
}
if (search(row - 1, col)) {
*current = trail;
printf("S");
return 1;
}
if (search(row, col - 1)) {
*current = trail;
printf("W");
return 1;
}
}
return 0;
}
void add_trail() {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (maze[i][j] != 'A'){
if (checked[i][j] == trail) {
maze[i][j] = 'O';
}
}
}
}
}
void print_checked() {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
printf("%d ", checked[i][j]);
}
printf("\n");
}
printf("\n");
}
void print_maze() {
printf("\n");
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
printf("%c", maze[i][j]);
}
printf("\n");
}
printf("\n");
}
int main()
{
get_maze("quickest_route_4.txt");
get_checked();
print_maze();
search(start_row, start_col);
add_trail();
print_maze();
return 0;
}
You have implemented a DFS - Depth First Search maze searching algorithm. This means that your searching algorithm is going to explores as far as possible along a direction before trying another one.
In your code this means that it will always try all of the options going right and then all of the options that are going down and this causes your code to not find the shortest path but just finding a path.
If you do want to find the shortest path you should implement a BFS - Breadth First Search algorithm, it will find you the shortest path since it is progressing the search in all of the active nodes at the same time. It will be a bit harder to implement though since it uses a queue data structure.
Good luck
Also notice that the path you are printing is coming out in reverse order.

CS50 Runoff program is working but check50 says it doesn't

So basically my program is supposed to make some sort of a runoff election( Here you can see what is it: https://cs50.harvard.edu/x/2020/psets/3/runoff/). I needed to implement 6 functions in order to do it and I did it. My program works perfectly fine but check50 says that function print_winner doesn't work ( though it only costs 4/24 possible points). This function must print the candidate of an election if he has a majority of all votes (>50%). The error says just "print_winner must print name when someone has a majority, print_winner did not print winner of election" and 3 more of such errors.
Here is the whole code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <cs50.h>
#include <math.h>
#define MAX 9
typedef struct
{
string name;
int votes;
bool eliminated;
}
candidate;
candidate candidates[MAX];
int voter_count;
int candidate_count;
int preferences[MAX][MAX];
float winner_vote;
//void check_preference(void);
bool is_tie(int min);
bool vote(int voter, int rank, string name);
bool print_winner(void);
void tabulate(void);
int find_min(void);
void eliminate(int min);
int main(int argc, string argv[])
{
if (argc < 2)
{
printf("Usage: plurality [candidate ...]\n");
return 1;
}
candidate_count = argc - 1;
if (candidate_count > MAX)
{
printf("Maximum number of candidates is %i\n", MAX);
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: ");
winner_vote = voter_count / 2;
int integer = winner_vote;
if (winner_vote == integer)
{
winner_vote++;
}
else
{
winner_vote = ceil(winner_vote);
}
for (int i = 0; i < voter_count; i++)
{
for (int j = 0; j < candidate_count; j++)
{
string name = get_string("Rank %i ", j + 1);
if (!vote(i, j, name))
{
printf("Invalid vote\n");
j--;
}
}
printf("\n");
}
//check_preference();
while (true)
{
tabulate();
if (print_winner())
{
return 1;
}
else if (is_tie(find_min()))
{
return 1;
}
else
{
eliminate(find_min());
}
}
}
void eliminate(int min)
{
for (int i = 0; i < candidate_count; i++)
{
if (candidates[i].eliminated)
{
continue;
}
else if (min == candidates[i].votes)
{
candidates[i].eliminated = true;
}
}
}
int find_min(void)
{
int min = MAX;
for (int i = 1; i < candidate_count; i++)
{
if (candidates[i].eliminated)
{
continue;
}
else if (min > candidates[i].votes)
{
min = candidates[i].votes;
}
}
return min;
}
bool is_tie(int min)
{
for (int i = 0; i < candidate_count; i++)
{
if (candidates[i].eliminated)
{
continue;
}
else if (min == candidates[i].votes)
{
continue;
}
else
{
return 0;
}
}
return 1;
}
bool vote(int voter, int rank, string name)
{
bool exist = false;
for (int i = 0; i < candidate_count; i++)
{
if (strcmp(name, candidates[preferences[voter][i]].name) == 0 && rank > 0)
{
return 0;
}
if (strcmp(name, candidates[i].name) == 0)
{
preferences[voter][rank] = i;
exist = true;
break;
}
}
return exist;
}
bool print_winner(void)
{
// candidate candidateHolder;
for (int f = 0; f < candidate_count; f++)
{
//candidateHolder = candidates[f];
if (candidates[f].votes >= winner_vote)
{
printf("%s\n", candidates[f].name);
return 1;
}
}
return 0;
}
void tabulate(void)
{
int check = 0;
for (int i = 0; i < voter_count; i++)
{
if (!candidates[preferences[i][check]].eliminated)
{
candidates[preferences[i][check]].votes++;
check = 0;
}
else
{
check++;
i--;
}
}
}
Here is the function that creates error:
bool print_winner(void)
{
// candidate candidateHolder;
for (int f = 0; f < candidate_count; f++)
{
//candidateHolder = candidates[f];
if (candidates[f].votes >= winner_vote)
{
printf("%s\n", candidates[f].name);
return 1;
}
}
return 0;
}
looks like you forgot
"If any candidate has a majority (more than 50%) of the first preference votes, that candidate is declared the winner of the election."
The variables that are used to determine winner_vote (aka) the majority have to be floats i.e voter_count / 2. Integers will not work if you have to divide 3/2 or 5/2
Additionally, in order to win the majority, the candidates[f].votes has to be > the majority, not >=. In the latter instance a tie between two candidates would be printed in the print_winner function. Ties are determined in the is_tie function later in the code.
Bool functions must have a return value of true or false.
The problem here is that your printer_winner will return a 0 or a 1.
check50 expects a TRUE or FALSE.
a simple statement will fix that for you:
printf("%s", winner_vote ? "true" : "false");
This will convert the 1 and 0 to TRUE ans FALSE.
Hope this helps. First time programmer here ;).
I declared winner_vote in the function and it worked
The problem is it puts my function inside of their code. So winner_vote variable is undefined there. There's nothing to do with 1 or 0. By the way, 1 in a bool means true and 0 means false. Why I put them instead of words because the explanation video said return 1 if ... and return 0 if ... I thought maybe this will change something.
And my other problem was that i forgot to mark my answer as a correct one. So people are still trying to help
You could init two global variables one integer, other floating(int max;
float pmax;) and delete your unnecessary code and variables in the beginning.
Below your function content:
bool print_winner(void)
{
for (int i = 0; i < candidate_count; i++)
{
if (max < candidates[i].votes)
{
max = candidates[i].votes;
pmax = ((float) max /(float) voter_count);
if (pmax > 0.5)
{
printf("%s\n", candidates[i].name);
return true;
}
}
}
return false;
}
bool print_winner(void)
{
int maj = voter_count / 2;
for (int i = 0; i < candidate_count; i++)
{
if (candidates[i].votes > maj)
{
printf("%s\n",candidates[i].name);
return true;
}
}
return false;
}
Why don't you try this instead??
Why do you return an int when type specified is bool?
you can use this as an alternative as well
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;
}
// Print the winner of the election, if there is one
bool print_winner(void)
{
int won;
win_score = voter_count / 2;
won = win_score;
if (win_score == won)
{
win_score++;
}
else
{
win_score = ceil(win_score);
}
// for each candidate sum the 1st choices
// if candidates[i].votes > voters / 2; win then quit
// else call find_min then is_tie if so everyone wins else eliminate min
// then tabulate next rank to candidate/s
for (int j = 0; j < candidate_count; j++)
{
if (candidates[j].votes >= win_score)
{
printf("%s\n", candidates[j].name);
return 1;
}
}
return 0;
}

School program tests not covering my code correctly and I'm not sure why

This might be inappropriate but I'm working on a school project in university and we use an automated test service called Web-Cat. When I upload my file (everything is correct as for the filename and method names etc.) the tests throw this at me:
hint: your code/tests do not correctly cover error: Cannot locate behavioral analysis output.
My code looks like this, I can't find any compile errors or anything that would cause such a problem.
#include <stdio.h>
double getPositiveAverage(double array[], int numItems)
{
double average = 0;
int numOfItems = 0;
for (int i = numItems-1; i >= 0; i--)
{
if (array[i] > 0)
{
average = average + array[i];
numOfItems++;
}
}
if (numOfItems == 0) {
return 0;
}
else {
return average / numOfItems;
}
}
int countRangeValues(double array[], int numItems, double count)
{
double countPlus = count + .5;
double countMinus = count - .5;
int counter = 0;
for (int i = numItems-1; i >= 0; i--)
{
if ((array[i] >= countMinus) && (array[i] < countPlus))
{
counter++;
}
}
return counter;
}
double getMaxAbsolute(double array[], int numItems)
{
double max = 0;
for (int i = numItems-1; i >= 0; i--)
{
if (array[i] == max * -1 && array[i] > 0)
{
max = array[i];
}
else if (array[i] < 0)
{
if (max < 0)
{
if ((array[i] * -1) > (max * -1))
{
max = array[i];
}
}
else
{
if ((array[i] * -1) > max)
{
max = array[i];
}
}
}
else
{
if (max < 0)
{
if ((array[i]) > (max * -1))
{
max = array[i];
}
}
else
{
if ((array[i]) > max)
{
max = array[i];
}
}
}
}
return max;
}
int countInverses(int array[], int numItems)
{
int negarray[numItems];
int negItems = 0;
int posarray[numItems];
int posItems = 0;
int counter = 0;
for (int i = numItems-1; i >= 0; i--)
{
if (array[i] < 0)
{
negarray[negItems] = array[i];
negItems++;
}
else if(array[i] > 0)
{
posarray[posItems] = array[i];
posItems++;
}
}
if (posItems == 0 || negItems == 0)
{
return 0;
}
else
{
if (posItems > negItems)
{
for (int i = posItems-1; i >= 0; i--)
{
for (int j = negItems-1; j >= 0; j--)
{
if ((negarray[j]*-1) == posarray[i] && negarray[j] != 0)
{
counter++;
negarray[j] = 0;
posarray[i] = 0;
}
}
}
}
}
return counter;
}
int getMaxCount(double array[], int numItems)
{
return countRangeValue(array, numItems, getMaxAbsolute(array, numItems));
}
If necessary, I can explain the purpose of all of these methods but the test also says "Your program failed before running any tests. Usually this is a compile problem or premature exit problem. Make sure your program compiles and runs before uploading." So I assume its syntax a compiling problem, I just don't know if anything I did would cause something like that.
Candidate problems:
Compilation error #fussel
// return countRangeValue(array, numItems, getMaxAbsolute(array, numItems));
return countRangeValues(array, numItems, getMaxAbsolute(array, numItems));
Missing main() #Bob__.
Variable length arrays are OK #Eric Postpischil in C99 and optionally in C11 yet do not attempt without insuring a positive array size.
int countInverses(int array[], int numItems) {
if (numItems <= 0) {
return 0;
}
int negarray[numItems];
....
Instead of if (posItems > negItems) { I'd expect if (posItems >= negItems) { or maybe even if (1), yet the goal of countInverses() lacks details for deep analysis.
countRangeValues(..., double count) is suspicious with double count. When count is a large value, countPlus == count and countMinus == count. The function always returns 0 as array[i] >= countMinus) && (array[i] < countPlus) is always false.
OP's getMaxAbsolute() looks too convoluted. Suggested alternative:
double getMaxAbsolute(const double array[], int numItems) {
double max = 0.0;
double amax = 0.0;
for (int i = numItems - 1; i >= 0; i--) {
double aelement = fabs(array[i]);
// If greater or the same, favor + over -
if (aelement > amax || (aelement == amax && array[i] > max)) {
max = array[i];
amax = aelement;
}
}
return max;
}

I need to determine if a random number is unique

I need to write a function that receives the number generated in fillArray and determine if it has already been generated. I need to return a true or false thus determining if the random number must be put into the array.
Here's what I am working on. Thanks for any help. I've searched for anything similar but unfortunately cannot find anything.
public class RandomGenerator {
int Arr[] = new int[6];
int size;
public void fillArray() {
int randNum = (int) (Math.random() * 49) + 1;
for (int i = 0; i < size; i++) {
Arr[i] = randNum;
alreadyThere(randNum);
}
size++;
}
public int alreadyThere(int randNum) {
int find = randNum;
boolean found = false;
int i = 0;
while (!found && i < size) {
if (Arr[i] == find) {
found = true;
}
i++;
}
if (!found) {
}
return randNum;
}

Resources