I'm not very sure how to approach this problem. Basically, I have an algorithm that loops through 100 buttons (10 rows of 10) and assigns a number value based on a randomized start and end point. When clicked, the buttons should enter the next portion of a game, and take themselves off the map. To do this, I used this code:
public function createMap()
{
var startPointX:int = int(10 * Math.random()); //creates random values that set the x and y values of the start and end points
var startPointY:int = int(10 * Math.random());
var endPointX:int = int(10 * Math.random());
var endPointY:int = int(10 * Math.random());
var spaceDiffX:int = startPointX - endPointX; //the difference in X values
var spaceDiffY:int = startPointY - endPointY; //the difference in Y values
//Creation loop - loops through all of the buttons to create them
for (i = 0; i <= 9; i++)
{
mapY[i] = mapX; //Adds the rows into each column
for (j = 0; j <= 9; j++)
{
mapY[i][j] = new LocationButton(); //Creates a new button
mapY[i][j].x = 6 * 20 * i; //Sets X position
mapY[i][j].y = 6 * 10 * j; //Sets Y position
//places start point
if (i == startPointX && j == startPointY) //checks if this point on the grid is equal to the random start point
{
mapY[i][j].buttonType = 1; //sets it to the start point
}
//places end point
if (i == endPointX && j == endPointY) //checks if this point is equal to the random end point
{
mapY[i][j].buttonType = 2; //sets it to the end point
}
//finds path on x axis
if (i != startPointX && j == startPointY) //checks if this point is on the same Y value as the start point
{
if (spaceDiffX >= 0) //checks to see if the start point is on the left or right of the end point, left is negative, right is positive
{
if (i < startPointX && i >= endPointX) //checks if i is between the start X and end X
{
mapY[i][j].buttonType = 3; //sets it to a "shortest path point"
}
}
else
{
if (i > startPointX && i <= endPointX) //checks to see if i is between the start X and end X
{
mapY[i][j].buttonType = 3; //sets it to a "shortest path point"
}
}
}
if (j != startPointY && i == endPointX) //checks if this point is on the same X value as the end point
{
if (spaceDiffY >= 0) //checks to see if the start point is over or under the end point, above is positive, below is negative
{
if (j < startPointY && j >= endPointY) //checks if j is between the end Y and the start Y
{
mapY[i][j].buttonType = 3; //sets it to a "shortest path point"
}
}
else
{
if (j > startPointY && j <= endPointY)
{
mapY[i][j].buttonType = 3; //sets it to a "shortest path point"
}
}
}
if (mapY[i][j].buttonType != 0) //checks whether or not the button should be added
{
mapY[i][j].addEventListener(MouseEvent.CLICK, createBattleGUI); //adds event listener
stage.addChild(mapY[i][j]); //adds it to stage
}
}
}
}
The problem with this is how the code after the eventListener acts, however. The function it calls starts with this loop:
for (i = 0; i <= 9; i++)
{
for (j = 0; j <= 9; j++)
{
if (mapY[i][j].buttonType != 0)
{
stage.removeChild(mapY[i][j]);
}
}
}
Once that loop goes through, it -should- remove all of the buttons. However, it doesn't. I started tracing some variables, and noticed that in the second loop, it is actually looping through the same 10 objects 10 times, instead of looping through all 100 objects. The * denotes the trace statement in the first for loop (before the event), and those without it are the buttons being traced in the second for loop:
name - buttonType - i - j
*instance33 1 1 6
*instance53 3 2 6
*instance73 3 3 6
*instance93 3 4 6
*instance113 3 5 6
*instance133 3 6 6
*instance153 3 7 6
*instance173 3 8 6
instance181 0 0 0
instance183 0 0 1
instance185 0 0 2
instance187 0 0 3
instance189 0 0 4
instance191 0 0 5
instance193 0 0 6
instance195 0 0 7
instance197 0 0 8
instance199 0 0 9
instance181 0 1 0
instance183 0 1 1
instance185 0 1 2
instance187 0 1 3
instance189 0 1 4
instance191 0 1 5
instance193 0 1 6
instance195 0 1 7
instance197 0 1 8
instance199 0 1 9
I realize that it is a bit of a long question, but I can't figure this out for the life of me. Thanks for any help.
Related
I am trying to make a game of checkers, and right now I'm building the board. The board is a 2-dimensional array of integers that I'm changing based on where the pieces should be.
// Sets up Red Pieces
int k = 0;
for (i = 0; i < 3; i++)
{
for (j = k; j < 8; j += 2)
{
// Red piece is on square at coords [i][j]
Board_Squares[i][j] += 2;
}
printf("\n");
// k starts at 0, and in switch should alternate between 1 and 0,
switch (k)
{
case 0:
k = 1;
case 1:
k = 0;
}
}
However, this code only gives me this:
0 2 0 2 0 2 0
0 2 0 2 0 2 0
0 2 0 2 0 2 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
Any help would be dope. Warning: I might be dumb.
Also, is using the switch statement the right move here anyways?
the problem in your code comes from missing break statements: the code for a case fall through to the code for the next case.
Modify it this way:
switch (k) {
case 0:
k = 1;
break;
case 1:
k = 0;
break;
}
The same toggling effect can be obtained with simple expressions:
k = 1 - k;
k ^= 1;
k = !k;
k = k == 0;
Or some more convoluted and obscure ones:
k = !!!k;
k = k ? 0 : 1;
k = (k + 1) & 1;
k = "\1"[k];
k = k["\1"];
k = 1 / (1 + k);
The checker board cells can also be initialized directly to 0 and 1 as:
Board_Squares[i][j] = (i + j) & 1;
I found here an implementation for Hoshen-Kopelman Algorithm, But it checks neighbors only up and left, meaning that a diagonal connection is not considered a connection.
How can I improve this code so that even a diagonal connection will be considered a connection?
In the following example I expect 1 object and not 7 objects:
4 5
1 0 1 0 1
0 1 0 1 0
1 0 1 0 0
0 0 1 0 0
--input--
1 0 1 0 1
0 1 0 1 0
1 0 1 0 0
0 0 1 0 0
--output--
1 0 2 0 3
0 4 0 5 0
6 0 7 0 0
0 0 7 0 0
HK reports 7 clusters found
This is the implementation (full code can be found here):
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
/* Implementation of Union-Find Algorithm */
/* The 'labels' array has the meaning that labels[x] is an alias for the label x; by
following this chain until x == labels[x], you can find the canonical name of an
equivalence class. The labels start at one; labels[0] is a special value indicating
the highest label already used. */
int* labels;
int n_labels = 0; /* length of the labels array */
/* uf_find returns the canonical label for the equivalence class containing x */
int uf_find(int x)
{
int y = x;
while (labels[y] != y)
y = labels[y];
while (labels[x] != x)
{
int z = labels[x];
labels[x] = y;
x = z;
}
return y;
}
/* uf_union joins two equivalence classes and returns the canonical label of the resulting class. */
int uf_union(int x, int y)
{
return labels[uf_find(x)] = uf_find(y);
}
/* uf_make_set creates a new equivalence class and returns its label */
int uf_make_set(void)
{
labels[0] ++;
assert(labels[0] < n_labels);
labels[labels[0]] = labels[0];
return labels[0];
}
/* uf_intitialize sets up the data structures needed by the union-find implementation. */
void uf_initialize(int max_labels)
{
n_labels = max_labels;
labels = calloc(sizeof(int), n_labels);
labels[0] = 0;
}
/* uf_done frees the memory used by the union-find data structures */
void uf_done(void)
{
n_labels = 0;
free(labels);
labels = 0;
}
/* End Union-Find implementation */
#define max(a,b) (a>b?a:b)
#define min(a,b) (a>b?b:a)
/* print_matrix prints out a matrix that is set up in the "pointer to pointers" scheme
(aka, an array of arrays); this is incompatible with C's usual representation of 2D
arrays, but allows for 2D arrays with dimensions determined at run-time */
void print_matrix(int** matrix, int m, int n)
{
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
printf("%3d ", matrix[i][j]);
printf("\n");
}
}
/* Label the clusters in "matrix". Return the total number of clusters found. */
int hoshen_kopelman(int** matrix, int m, int n)
{
uf_initialize(m * n / 2);
/* scan the matrix */
for (int y = 0; y < m; y++)
{
for (int x = 0; x < n; x++)
{
if (matrix[y][x])
{ // if occupied ...
int up = (y == 0 ? 0 : matrix[y - 1][x]); // look up
int left = (x == 0 ? 0 : matrix[y][x - 1]); // look left
switch (!!up + !!left)
{
case 0:
matrix[y][x] = uf_make_set(); // a new cluster
break;
case 1: // part of an existing cluster
matrix[y][x] = max(up, left); // whichever is nonzero is labelled
break;
case 2: // this site binds two clusters
matrix[y][x] = uf_union(up, left);
break;
}
}
}
}
/* apply the relabeling to the matrix */
/* This is a little bit sneaky.. we create a mapping from the canonical labels
determined by union/find into a new set of canonical labels, which are
guaranteed to be sequential. */
int* new_labels = calloc(sizeof(int), n_labels); // allocate array, initialized to zero
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
if (matrix[i][j])
{
int x = uf_find(matrix[i][j]);
if (new_labels[x] == 0)
{
new_labels[0]++;
new_labels[x] = new_labels[0];
}
matrix[i][j] = new_labels[x];
}
int total_clusters = new_labels[0];
free(new_labels);
uf_done();
return total_clusters;
}
/* This procedure checks to see that any occupied neighbors of an occupied site
have the same label. */
void check_labelling(int** matrix, int m, int n)
{
int N, S, E, W;
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
if (matrix[i][j])
{
N = (i == 0 ? 0 : matrix[i - 1][j]);
S = (i == m - 1 ? 0 : matrix[i + 1][j]);
E = (j == n - 1 ? 0 : matrix[i][j + 1]);
W = (j == 0 ? 0 : matrix[i][j - 1]);
assert(N == 0 || matrix[i][j] == N);
assert(S == 0 || matrix[i][j] == S);
assert(E == 0 || matrix[i][j] == E);
assert(W == 0 || matrix[i][j] == W);
}
}
/* The sample program reads in a matrix from standard input, runs the HK algorithm on
it, and prints out the results. The form of the input is two integers giving the
dimensions of the matrix, followed by the matrix elements (with data separated by
whitespace).
a sample input file is the following:
8 8
1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 1
1 0 0 0 0 1 0 1
1 0 0 1 0 1 0 1
1 0 0 1 0 1 0 1
1 0 0 1 1 1 0 1
1 1 1 1 0 0 0 1
0 0 0 1 1 1 0 1
this sample input gives the following output:
--input--
1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 1
1 0 0 0 0 1 0 1
1 0 0 1 0 1 0 1
1 0 0 1 0 1 0 1
1 0 0 1 1 1 0 1
1 1 1 1 0 0 0 1
0 0 0 1 1 1 0 1
--output--
1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 1
2 0 0 0 0 2 0 1
2 0 0 2 0 2 0 1
2 0 0 2 0 2 0 1
2 0 0 2 2 2 0 1
2 2 2 2 0 0 0 1
0 0 0 2 2 2 0 1
HK reports 2 clusters found
*/
int main(int argc, char** argv)
{
int m, n;
int** matrix;
/* Read in the matrix from standard input
The whitespace-deliminated matrix input is preceeded
by the number of rows and number of columns */
while (2 == scanf_s("%d %d", &m, &n))
{ // m = rows, n = columns
matrix = (int**)calloc(m, sizeof(int*));
for (int i = 0; i < m; i++)
{
matrix[i] = (int*)calloc(n, sizeof(int));
for (int j = 0; j < n; j++)
scanf_s("%d", &(matrix[i][j]));
}
printf_s(" --input-- \n");
print_matrix(matrix, m, n);
printf(" --output-- \n");
/* Process the matrix */
int clusters = hoshen_kopelman(matrix, m, n);
/* Output the result */
print_matrix(matrix, m, n);
check_labelling(matrix, m, n);
printf("HK reports %d clusters found\n", clusters);
for (int i = 0; i < m; i++)
free(matrix[i]);
free(matrix);
}
return 0;
}
I tried to change the function hoshen_kopelman as described below, but I still get 2 objects instead of 1:
int hoshen_kopelman(int** matrix, int m, int n)
{
uf_initialize(m * n / 2);
/* scan the matrix */
for (int y = 0; y < m; y++)
{
for (int x = 0; x < n; x++)
{
if (matrix[y][x])
{ // if occupied ...
int up = (y == 0 ? 0 : matrix[y - 1][x]); // look up
int left = (x == 0 ? 0 : matrix[y][x - 1]); // look left
// ----------- THE NEW CODE -------------
if (x > 0)
{
if (up == 0 && y > 0) // left+up
up = matrix[y - 1][x - 1];
if (left == 0 && y < m - 1) // left+down
left = matrix[y + 1][x - 1];
}
// ---------- END NEW CODE --------------
switch (!!up + !!left)
{
case 0:
matrix[y][x] = uf_make_set(); // a new cluster
break;
case 1: // part of an existing cluster
matrix[y][x] = max(up, left); // whichever is nonzero is labelled
break;
case 2: // this site binds two clusters
matrix[y][x] = uf_union(up, left);
break;
}
}
}
}
/* apply the relabeling to the matrix */
/* This is a little bit sneaky.. we create a mapping from the canonical labels
determined by union/find into a new set of canonical labels, which are
guaranteed to be sequential. */
int* new_labels = calloc(sizeof(int), n_labels); // allocate array, initialized to zero
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
if (matrix[i][j])
{
int x = uf_find(matrix[i][j]);
if (new_labels[x] == 0)
{
new_labels[0]++;
new_labels[x] = new_labels[0];
}
matrix[i][j] = new_labels[x];
}
int total_clusters = new_labels[0];
free(new_labels);
uf_done();
return total_clusters;
}
The following output is now obtained (I am expecting 1 and got 2):
4 5
1 0 1 0 1
0 1 0 1 0
1 0 1 0 0
0 0 1 0 0
--input--
1 0 1 0 1
0 1 0 1 0
1 0 1 0 0
0 0 1 0 0
--output--
1 0 1 0 1
0 1 0 1 0
2 0 1 0 0
0 0 1 0 0
HK reports 2 clusters found
What is the correct way to correct the code to check all 8 neighbors?
I led you astray saying to check down-left. The algorithm relies on the current node it is examining being after all the neighbors it checks. So you need to check left, up, up-left, and up-right. You can use this in place of your new code:
if (y > 0)
{
if (left == 0 && x > 0) // left+up
left = matrix[y - 1][x - 1];
if (up == 0 && x < n-1) // right+up
up = matrix[y - 1][x + 1];
}
hello my task to write test, which checks if the Minesweeper board (after choosing replay option) is different than the previous one.
first of all i wrote the main function the replay.
after that I tested it locally if it works and every game, every board was different. there was no issue.
so i started to write test cases and now im here.
TEST replay_board() {
Game *game = create_game();
Board *board = create_board(9, 9, 9);
game->board = board;
int k = 0;
printf("\n");
char mine_list[100];
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (game->board->tiles[i][j]->is_mine == true) {
mine_list[k] = '1';
printf("1");
} else {
mine_list[k] = '0';
printf("0");
}
k++;
}
}
printf("\n");
mine_list[k] = '\0';
replay_game(replay, game);
char mine_list2[100];
k = 0;
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (game->board->tiles[i][j]->is_mine == true) {
mine_list2[k] = '1';
printf("1");
} else {
mine_list2[k] = '0';
printf("0");
}
k++;
}
}
printf("\n");
mine_list2[k] = '\0';
int same = 0;
if (strcmp(mine_list, mine_list2) != 0) {
same = 0;
} else {
same = 1;
}
ASSERT_EQ(same, 0);
PASS();
destroy_game(game);
}
in every test it writes that the old boar is the same as the previous one, but locally i can see that they aren't the same.
i dont know its ideal to compare two strings, but it was the easiest way to compare them from structure
replay function
void replay_game(char* replay, Game* game) {
while (strcmp(replay, "yes") != 0 && strcmp(replay, "no") != 0 ) {
scanf("%s", replay);
if (strcmp(replay, "yes") != 0 || strcmp(replay, "no") != 0) {
printf("invalid value\n");
}
}
if (strcmp(replay, "yes") == 0) {
destroy_board(game->board);
game->game_state = PLAYING;
game->board = create_board(9, 9, 9);
game->player->score = 0;
}
}
create_board function
int generate_random_coordinates(int upper_range) {
return rand() % upper_range;
}
/**
* Generates random coordinates to row and column according to mine count value
* Randomly sets mines to the Board pointer
*/
void set_mines_randomly(Board *board) {
assert(board != NULL);
int board_mine_count = 0;
srand(time(NULL));
while (board_mine_count != board->mine_count) {
int random_row = generate_random_coordinates(board->row_count);
int random_column = generate_random_coordinates(board->column_count);
if (board->tiles[random_row][random_column]->is_mine == false) {
board->tiles[random_row][random_column]->is_mine = true;
board_mine_count++;
}
}
}
Board *create_board(int row_count, int column_count, int mine_count) {
Board *board = (Board *) calloc(1, sizeof(Board));
board->row_count = row_count;
board->column_count = column_count;
board->mine_count = mine_count;
for (int row = 0; row < board->row_count; row++) {
for (int column = 0; column < board->column_count; column++) {
board->tiles[row][column] = (Tile *) calloc(1, sizeof(Tile));
board->tiles[row][column]->tile_state = CLOSED;
board->tiles[row][column]->is_mine = false;
}
}
set_mines_randomly(board);
set_tile_values(board);
return board;
}
main
#include <stdlib.h>
#include <string.h>
#include "game.h"
#include "user_interface.h"
#include "board.h"
int main() {
char replay[] = "yes";
Game *game = create_game();
Board *board = create_board(9, 9, 9);
game->board = board;
read_player_name(game);
// impleting the replay function
while(strcmp(replay, "yes") == 0) {
play_game(game);
printf("Chcel by si znova zahrat? (yes/no)\n");
scanf("%3s", replay);
printf("\n");
// new part
char mine_list[100];
int k = 0;
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (game->board->tiles[i][j]->is_mine == true) {
mine_list[k] = '1';
//printf("1");
} else {
mine_list[k] = '0';
//printf("0");
}
k++;
}
}
mine_list[k] = '\0';
replay_game(replay, game);
char mine_list2[100];
k = 0;
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (game->board->tiles[i][j]->is_mine == true) {
mine_list2[k] = '1';
//printf("1");
} else {
mine_list2[k] = '0';
//printf("0");
}
k++;
}
}
mine_list2[k] = '\0';
printf("%s\n", mine_list);
printf("%s\n", mine_list2);
// new part ending heree
}
destroy_game(game);
exit(EXIT_SUCCESS);
}
running the main after losing
output
1 2 3 4 5 6 7 8 9
1 1 1 0 0 0 0 0 0 0
2 X 1 0 1 1 1 0 0 0
3 - 1 0 1 X 1 0 0 0
4 - 1 1 1 1 1 1 1 1
5 - X 1 0 0 0 1 X -
6 - - 2 1 1 1 2 - -
7 - - X - - X - - -
8 - X - - X - - - -
9 - - - - - - X - -
Ľutujem tom. Riešenie je nesprávne!
Vaše skóre je: 13
Chcel by si znova zahrat? (yes/no)
yes
after playing that for 2 minutes
1 2 3 4 5 6 7 8 9
1 0 0 0 0 0 1 - 1 0
2 0 0 0 0 1 3 X 2 0
3 0 0 0 0 1 X X 3 1
4 1 1 0 0 1 2 2 2 X
5 X 1 0 0 0 0 0 1 -
6 - 2 1 2 2 3 2 1 -
7 - - X - X X X - -
8 - - - - - - - 1 -
9 - - - - - - - - -
Ľutujem tom. Riešenie je nesprávne!
Vaše skóre je: 19
Chcel by si znova zahrat? (yes/no)
FAILED test result:
* Suite test_board:
......
000000000000001100000010001000100000000000001000100000100010000000000000000000000
000000000000001100000010001000100000000000001000100000100010000000000000000000000
F
FAIL replay_board: same != 0 (tests/test_board.c:125)
game.h
typedef enum {
FAILED,
PLAYING,
SOLVED,
} GameState;
typedef struct {
Board *board; /* Struct of the play field */
Player *player; /* Struct of user who is playing the Game */
GameState game_state; /* Enum for status of the Game */
} Game;
* create_game()*
Game *create_game() {
Game *game = (Game *) calloc(1, sizeof(Game));
Player *player = (Player *) calloc(1, sizeof(Player));
game->player = player;
game->player->score = 1;
game->game_state = PLAYING;
return game;
}
new ouput after uptadting the main with printf
1 2 3 4 5 6 7 8 9
1 - 1 0 0 0 0 0 0 0
2 X 1 0 0 0 0 1 1 1
3 - 1 0 0 0 0 1 X -
4 - 1 1 0 0 1 2 - -
5 - X 2 1 1 1 X - X
6 1 1 2 X 1 1 2 X X
7 0 0 1 1 1 0 1 3 X
8 0 0 0 0 0 0 0 1 1
9 0 0 0 0 0 0 0 0 0
Ľutujem asd. Riešenie je nesprávne!
Vaše skóre je: 17
Chcel by si znova zahrat? (yes/no)
yes
000000000100000000000000010000000000010000101000100011000000001000000000000000000
000000001100000000000000000000100011000000000000000010010000000000001000000010000
1 2 3 4 5 6 7 8 9
1 - - - - - - - - -
2 - - - - - - - - -
3 - - - - - - - - -
4 - - - - - - - - -
5 - - - - - - - - -
6 - - - - - - - - -
7 - - - - - - - - -
8 - - - - - - - - -
9 - - - - - - - - -
Here's the problem:
char* mine_list[100];
You defined mine_list as an array of char * instead of an array of char. Your compiler should have given you a number of warnings wherever you used it. Change it to an array of char:
char mine_list[100];
Did you check that replay_game("yes", game); actually changes game?
Either way, there's a much easier and correct way to do this.
Allocate a new board* pointer,copy the content of board to the new allocated memory using memcpy, and then call replay_game. Assuming this actually changes board variable you can now simply compare the two boards inside one nested loop.
I have an array called int arr[10] = {1,2,3,4,5}
From my understanding the rest of the array is filled with 0's.
My questions is if its a fixed array length how can I put the first index behind the last index that is not a 0. For example
I believe the 0 is not shown in real printf but I am including it for illustration purposes
for (int i = 0 ; i < 10 ; i++)
{
print("%i" , arr[i]);
}
The output
1 2 3 4 5 0 0 0 0 0
If i move the first index to the back of the 5 like so
for (int i = -1 ; i < 10 ; i++)
{
arr[i] = arr[i + 1];
print("%i" , arr[i]);
}
Will the output put the 1 behind the 5 or at the back of the whole array?
2 3 4 5 1 0 0 0 0 0
or because there is 0s then
2 3 4 5 0 0 0 0 0 1
If my question is unclear please tell me and I will try explain it.
The output
1 2 3 4 5 0 0 0 0 0
No, the actual output is
1234500000
Your code has undefined behavior. The first iteration of the loop (with i = -1) tries to assign to arr[-1], which does not exist:
arr[i] = arr[i + 1];
Similarly, the last iteration (with i = 9) tries to read from arr[10], which also does not exist.
I'm not sure why you think your code will move the first element back.
From my understanding the rest of the array is filled with 0's
You are right.:)
If i move the first index to the back of the 5 like so
for (int i = -1 ; i < 10 ; i++)
{
arr[i] = arr[i + 1];
print("%i" , arr[i]);
}
then you will get undefined behavior because the indices -1 and 10 are not valid indices.
It seems what you are trying to do is the following
#include <stdio.h>
#include <string.h>
int main(void)
{
enum { N = 10 };
int a[N] = { 1, 2, 3, 4, 5 };
size_t pos = 0;
while ( pos < N && a[pos] != 0 ) ++pos;
if ( pos != N && !( pos < 3 ) )
{
int tmp = a[0];
pos -= 2;
memmove( a, a + 1, pos * sizeof( int ) );
a[pos] = tmp;
}
for ( size_t i = 0; i < N; i++ ) printf( "%d ", a[i] );
putchar( '\n' );
return 0;
}
The program output is
2 3 4 1 5 0 0 0 0 0
I'm trying to implement a two functions based on Depth First Search using a recursion method. I'm ultimately trying to compare the runtime against warshall's algorithm (which I already have working). When I print my matrix it's off by a couple off paths.
The recursion is what may be throwing me off, it's my weakness. Because of the top if statement if(iIndex1 == iIndex2) return TRUE;, when I try to find if there is a path from (A,A), (B,B), (C,C), etc. I will always get 1 even if there is no path from A to A.
typedef enum { FALSE, TRUE } bool;
/* Recursive function will determine if there is a path from index 1 to 2
* Based of DFS
*/
bool recPathExists( Graph G, int iIndex1, int iIndex2 )
{
int j;
G.nodeArray[iIndex1].visited = TRUE;
if(iIndex1 == iIndex2){
return TRUE;
}
for(j = 0; j < G.iNumNodes; j++){
if(!G.nodeArray[j].visited && G.adjMatrix[iIndex1][j]==1){
if(recPathExists(G, j, iIndex2))
return TRUE;
}
}
return FALSE;
}
/* Write a function to find all pairs of nodes which have paths between them.
* Store this information in the provided pathMatrix.
*/
void allPathsRecFunc( Graph G , int **pathMatrix )
{
int i, j;
for(i = 0; i < G.iNumNodes; i++){
for(j = 0; j < G.iNumNodes; j++){
if(recPathExists(G, i , j)== TRUE){
pathMatrix[i][j] = 1;
}
resetVisited(G); //resets all nodes to FALSE
}
}
}
what it should be
A 0 1 1 1 1 1 1 1
B 0 1 0 0 1 1 1 1
C 0 1 0 0 1 1 1 1
D 0 0 0 0 0 0 0 0
E 0 0 0 0 0 0 0 0
F 0 1 0 0 1 1 1 1
G 0 1 0 0 1 1 1 1
H 0 1 0 0 1 1 1 1
what I get
A 1 1 1 1 1 1 1 1
B 0 1 0 0 1 1 1 1
C 0 1 1 0 1 1 1 1
D 0 0 0 1 0 0 0 0
E 0 0 0 0 1 0 0 0
F 0 1 0 0 1 1 1 1
G 0 1 0 0 1 1 1 1
H 0 1 0 0 1 1 1 1
Your issue may be here:
for(j = 0; j < G.iNumNodes; j++)
{
if(!G.nodeArray[j].visited && G.adjMatrix[iIndex1][j] == 1)
{
return recPathExists(G, j, iIndex2);
}
}
By returning the result of recursing on recPathExists, you're not checking the other possible nodes that could be reachable in the loop (in essence, you're returning failure too early, and missing possible paths).
I believe you want just a little modification:
for(j = 0; j < G.iNumNodes; j++)
{
if(!G.nodeArray[j].visited && G.adjMatrix[iIndex1][j] == 1)
{
if (recPathExists(G, j, iIndex2))
return TRUE;
}
}
That is, "if a path does exist, return as we've found it. If not, keep looking".
My depth first search uses recursion but it outputs a parent array, though the functionality should be the same. It got a perfect grade so I know it works. Hope it helps.
https://github.com/grantSwalwell/Data-Structures/blob/master/Depth%20First%20Search.h
Algorithm~
bool array, visited for flagging nodes
search number array to measure the depth of access
depth to increment and come up with search num
Call DFS on 0,0
For each non visited neighbor
DFS depth + 1, search = depth, visited = true
return parent array, showing the search pattern
// Depth First Search recursive helper method
void DFS(Graph& G, int v0, Array<bool>* visited, Array<int>* search, int
depth)
{
// set visited
(*visited)[v0] = true;
// set search num
(*search)[v0] = depth;
// iterate through neighbors
for (int i = 0; i < G.nodes(); i++)
{
// if i is a neighbor
if (G.edge(i, v0))
{
// if it has not been visited
if (!(*visited)[i])
{
// call DFS
DFS(G, i, visited, search, depth + 1);
}
} // end if
} // end for
}
// Depth First Search
Array<int>* DFS(Graph& G, int v0)
{
// visited array
Array<bool>* visited = new Array<bool>(G.nodes());
// search number array, order of visitation
Array<int>* search = new Array<int>(G.nodes());
// initialize both arrays
for (int i = 0; i < G.nodes(); i++)
{
(*visited)[i] = false;
(*search)[i] = 1;
}
// create depth field
int depth = 1;
// call DFS
DFS(G, v0, visited, search, depth);
return search;
};