Wave Algorithm (Lee's Algorithm): incorrect final matrix - c

I'm writing a program calculating the shortest way from point A to point B.
I have a map (matrix) with values:
0 is block (wall, no way to pass);
1 is free way (you can pass);
2 is start point;
In the code below I declare 2 arrays: an array " map"and changed array "visited" while running program demonstrating visited points.
I check the cells in 4 directions (not diagonals) for 1 or 0. If it's 1 (possible to pass), I increase the counter for 1. For do not count the previous cell I'm trying to avoid it by the condition. I realized that in two one-dimensional arrays {1 0 -1 0} and { 0, 1, 0, -1 } to check neighbor points (what mean i check [i+1][j], [i-1][j], [i][j+1] and [i][j-1]).
As a result I wanna see "visited" matrix with a few lines which shows the way to reach to the point B (1, 2, 3, ... 15). I wanna find the way to map[7][7] point.
Right now the error here that I do count++ for the previous position. How to avoid that?
Thank you.
P.S. I wrote a few functions implementing a new array with 0 values, counting free to go cells and printing arrays.
main.c:
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#define WIDTH 8
#define HEIGHT 8
int mapZero(int map[WIDTH][HEIGHT]);
int mapPrint(int map[WIDTH][HEIGHT]);
int mapInit(int map[WIDTH][WIDTH]);
int findFreeToGoCells(int map[WIDTH][HEIGHT]);
int main(int argc, char * argv[])
{
bool stop;
unsigned int count;
unsigned int max;
int visited[WIDTH][HEIGHT];
int map[WIDTH][HEIGHT] =
{
{ 1, 1, 1, 1, 1, 0, 0, 1 },
{ 0, 1, 1, 1, 1, 1, 0, 1 },
{ 0, 0, 1, 0, 1, 1, 1, 0 },
{ 1, 0, 1, 1, 1, 0, 1, 1 },
{ 0, 0, 0, 1, 0, 0, 0, 1 },
{ 1, 0, 1, 1, 1, 0, 0, 1 },
{ 0, 0, 0, 0, 1, 0, 0, 1 },
{ 0, 1, 1, 1, 1, 1, 1, 1 },
};
mapZero(visited);
printf("Matrix of zeroed-visited cells:\n\n");
mapPrint(visited);
printf("Matrix of the map:\n\n");
mapPrint(map);
printf("Free to go cells: %d\n\n", findFreeToGoCells(map));
max = WIDTH * HEIGHT - 1;
visited[0][0] = map[0][0];
count = 0;
visited[0][0] = 0;
int di[4] = { 1, -1, 0, 0 };
int dj[4] = { 0, 0, 1, -1 };
//do
{
for (int i = 0; i < WIDTH; ++i)
{
for (int j = 0; j < HEIGHT; ++j)
{
if (visited[i][j] == count)
{
for (int k = 0; k < 4; ++k)
{
int i_check = i + di[k];
int j_check = j + dj[k];
if ((i_check >= 0 && i_check < WIDTH) && (j_check >= 0 && j_check < HEIGHT) && (map[i_check][j_check] != 0))
{
visited[i_check][j_check] = count + 1;
}
}
count++;
}
}
}
}// while (visited[7][7] == 0);
if (count > max + 99999)
printf("The way couldn't be found\n");
else
{
printf("Matrix of visited cells:\n\n");
mapPrint(visited);
printf("Free to go cells from [0][0] to [7][7]: %d\n", findFreeToGoCells(visited));
}
/*************************************************************************************/
/*************************************************************************************/
int len;
int x = 7;
int y = 7;
int x_path[WIDTH * HEIGHT];
int y_path[WIDTH * HEIGHT];
len = visited[7][7];
count = len;
while (count > 0)
{
x_path[count] = x;
y_path[count] = y;
count--;
for (int k = 0; k < 4; ++k)
{
int i_check = x + di[k];
int j_check = y + dj[k];
if ((i_check >= 0 && i_check < WIDTH) && (j_check >= 0 && j_check < HEIGHT) && (map[i_check][j_check] == count))
{
x = x + di[k];
y = y + dj[k];
break;
}
}
}
x_path[0] = 0;
y_path[0] = 0;
printf("\nThe shortest way consist of %d cells\nThere are %d the shortest way to reach th the final point\n\n", len, findFreeToGoCells(visited)-len);
system("pause");
return 0;
}
int mapZero(int map[WIDTH][HEIGHT])
{
for (int i = 0; i < WIDTH; ++i)
{
for (int j = 0; j < HEIGHT; ++j)
{
map[i][j] = 0;
}
}
return 0;
}
int mapPrint(int map[WIDTH][HEIGHT])
{
for (int i = 0; i < WIDTH; ++i)
{
for (int j = 0; j < HEIGHT; ++j)
{
printf("%2d ", map[i][j]);
}
printf("\n\n");
}
printf("\n");
return 0;
}
int findFreeToGoCells(int map[WIDTH][HEIGHT])
{
int count = 0;
for (int i = 0; i < WIDTH; ++i)
{
for (int j = 0; j < HEIGHT; ++j)
{
if (map[i][j] != 0) count++;
}
}
return count;
}
Result:

Related

Converting 2D array into a greyscale image in C

I imported the 2d array of Lena using a header file (LenaArray.h); int lena [511][511] = {162,162,162,etc...},
but now I want to convert it into a greyscale image and I don't know how please help? Image of Lena I'm trying to print
#include <stdio.h>
#include "LenaArray.h"
int main () {
int i,j;
int width = 511;
int height = 511;
for (i = 0; i < height; i ++ )
{
for(j = 0; j < width; j ++)
{
printf("%d",&lena[i][j]);
}
}
}
#include <stdio.h>
typedef unsigned char U8;
typedef struct { U8 p[4]; } color;
U8 lena[511][511];
void save(char* file_name,int width,int height)
{
FILE* f = fopen(file_name, "wb");
color tablo_color[256];
for (int i = 0; i < 256; i++)
tablo_color[i] = { (U8)i,(U8)i,(U8)i,(U8)255 };//BGRA 32 bit
U8 pp[54] = { 'B', 'M', 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0 ,
40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 32 };
*(int*)(pp + 2) = 54 + 4 * width * height; //file size
*(int*)(pp + 18) = width;
*(int*)(pp + 22) = height;
*(int*)(pp + 42) = height * width * 4; //bitmap size
fwrite(pp, 1, 54, f);
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
U8 indis = lena[i][j];
fwrite(tablo_color+indis,4,1,f);
}
}
fclose(f);
}
int main()
{
for (int i = 0; i < 511; i++)
{
for (int j = 0; j < 511; j++)
{
lena[i][j]=i+j;
}
}
save("test.bmp", 511, 511);
}

C language isMagicsquare function: What logic error is in my function code?

Although the output with the my current examples is correct, my code seems to have a logic error that doesn't give the right output for other cases.
I have previously addressed this issue:
"What would happen in your code if there are no repeated numbers, all numbers are used, your last column sum is correct, but your second-last column sum is incorrect?"
Any help would be very much appreciated.
My current code:
/* Magic Square */
#include <stdio.h>
#define MAX_N 100
#define TRUE 1
#define FALSE 0
int isMagicSquare(int square[MAX_N][MAX_N], int n);
int main(void) {
int square1[MAX_N][MAX_N] = {
{4, 9, 2},
{3, 5, 7},
{8, 1, 6}};
// should print TRUE
int check1 = isMagicSquare(square1, 3);
if (check1 == TRUE) {
printf("TRUE\n");
} else {
printf("FALSE\n");
}
int square2[MAX_N][MAX_N] = {
{20, 6, 7, 17},
{ 9, 15, 14, 12},
{13, 11, 10, 16},
{ 8, 18, 19, 5} };
/*{ 1 , 2 , 3 , 4 , },
{ 5 , 6 , 7 , 8 , },
{ 9 , 10, 11, 12, },
{ 13, 14, 15, 16,} };*/
/*{16, 2, 3, 13,},
{5, 11, 10, 8 ,},
{9, 7, 6, 12 ,},
{4, 14, 15, 1, } };*/
// should print FALSE
int check2 = isMagicSquare(square2, 4);
if (check2 == TRUE) {
printf("TRUE\n");
} else {
printf("FALSE\n");
}
int square3[MAX_N][MAX_N] = {
{17, 24, 1, 15, 8},
{23, 5, 7, 16, 14},
{ 4, 6, 13, 22, 20},
{10, 12, 19, 3, 21},
{11, 18, 25, 9, 2}};
// should print FALSE
int check3 = isMagicSquare(square3, 5);
if (check3 == TRUE) {
printf("TRUE\n");
} else {
printf("FALSE\n");
}
return 0;
}
int isMagicSquare(int square[MAX_N][MAX_N], int n) {
int row, col;
int drow, dcol;
int sum, sum1, sum2, sum3;
int boolean = 0;
//For Diagonals
sum = 0;
for (row = 0; row < n; row++) {
for (col = 0; col < n; col++) {
if (row == col)
sum += square[row][col];
}
}
for (row = 0; row < n; row++) {
sum3 = 0;
for (col = 0; col < n; col++) {
sum3 += square[n-row-1][col];
}
if (sum == sum3)
boolean = 1;
else {
return FALSE;
}
}
//For Rows
for (row = 0; row < n; row++) {
sum1 = 0;
for (col = 0; col < n; col++) {
sum1 = sum1 + square[row][col];
}
if (sum == sum1)
boolean = 1;
else {
return FALSE;
}
}
//For Columns
for (row = 0; row < n; row++) {
sum2 = 0;
for (col = 0; col < n; col++) {
sum2 = sum2 + square[col][row];
}
if (sum == sum2)
boolean = 1;
else {
return FALSE;
}
}
if (boolean == 1) {
//Check if All Numbers is used
for (row = 0; row < n; row++) {
for (col = 0; col < n; col++) {
if(square[row][col] > n*n || square[row][col] < 0) {
boolean = 0;
break;
}
}
}
//Check for Repeating Numbers
for (row = 0; row < n; row++) {
for(col = 0; col < n; col++) {
for(drow = row + 1; drow < n; drow++){
for(dcol = col + 1; dcol < n; dcol++) {
if(square[row][col] == square[drow][dcol]) {
boolean = 0;
break;
}
}
}
}
}
// if Statement End
}
else {
boolean = 0;
}
if (boolean == 1)
return TRUE;
else
return FALSE;
}
it seems the sum3 var is reinitialized to 0 inside the computation loop, plus the diagonal sum equality check should be outside of the loop.
I would rework it this way:
//For Diagonals
sum = 0;
sum3 = 0;
for (row = 0; row < n; row++) {
sum += square[row][row];
sum3 += square[row][n - 1 - row];
}
if (sum == sum3)
boolean = 1;
else {
return FALSE;
}
BTW I simplified a bit the diagonal calculation since it is linear, there is no need for 2 nested loops.
I found some other bugs in the final checks:
-0 should not be a valid value
-return instead of just breaking (break only exists the inner loop, the outer loop continues)
for (row = 0; row < n; row++) {
for (col = 0; col < n; col++) {
if(square[row][col] > n*n || square[row][col] <= 0) {
return FALSE;
}
}
}
//Check for Repeating Numbers
int storedNumbers[n * n];
for (row = 0; row < n; row++) {
for(col = 0; col < n; col++) {
storedNumbers[row + n * col] = square[row][col];
}
}
Then scan storedNumbers for duplicates.
Searching for duplicate values in an array
cheers
You can use a more compact scheme to check that all numbers 1 .. (n*n) are used with no duplicates using code such as:
int counts[n * n]; // Can't use an initializer with a VLA
memset(counts, '\0', sizeof(counts));
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
if (square[i][j] <= 0 || square[i][j] > n * n)
return FALSE;
counts[square[i][j] - 1]++; // Map 1..n*n to 0..n*n-1
// if (++counts[square[i][j] - 1] > 1)
// return FALSE;
}
}
for (int i = 0; i < n * n; i++)
{
if (counts[i] != 1)
return FALSE;
}
Since there are n*n elements to check, this code uses space and time that is linear with respect to the number of elements in the magic square, which is within a constant factor of optimal.

N-Queen Beginner Backtracking

To practice what I've learned about backtracking algorithms, I'm trying to solve the N-Queen problem.
I've written some functions to check if a move is legal, but I can't see how to implement those using backtracking.
bool manger_ligne (int a[][4],int i) {
for (int j=0;j<4;j++) {
if (a[i][j] == 1)
return false ;
}
return true;
}
bool manger_col (int a[][4],int j) {
for (int i=0;i<4;i++) {
if (a[i][j] == 1)
return false ;
}
return true ;
}
bool isTrue (int a[][4],int i,int j,int k) {
if (k==0) {
return 1;
}
if (i > 3 && j > 3) {
return 0;
}
if (manger_diagonal(a, i, j) == true && manger_col(a, j) == true &&
manger_ligne(a, i) == true) {
a[i][j] = 1;
if (isTrue(a, i, j+1 ,k) == true) {
if (isTrue(a, i+1,j ,k) == true) //backtracking problem
return true;
}
a[i][j] = 0;
}
return false ;
}
a few days ago I had to accomplish this task as a school task. This is a solution with 8 Queens. I solved it as follows:
In the main I call the function solveQn. Then the program does everything on it's own.
Bool solveNQ:
bool solveNQ(){
int board[N][N] = {
{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}
};
if ( solveNQUtil(board, 0) == false )
{
printf("Solution does not exist");
return false;
}
printSolution(board);
return true;
}
Bool solveNQUntil:
bool solveNQUtil(int board[N][N], int col){
if (col >= N)
return true;
for (int i = 0; i < N; i++)
{
if ( isSafe(board, i, col) )
{
board[i][col] = 1;
if ( solveNQUtil(board, col + 1) )
return true;
board[i][col] = 0;
}
}
return false;
}
Bool isSafe:
bool isSafe(int board[N][N], int row, int col){
int i, j;
for (i = 0; i < col; i++)
if (board[row][i])
return false;
for (i=row, j=col; i>=0 && j>=0; i--, j--)
if (board[i][j])
return false;
for (i=row, j=col; j>=0 && i<N; i++, j--)
if (board[i][j])
return false;
return true;
}
Output the solution:
void printSolution(int board[N][N]){
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
printf(" %d ", board[i][j]);
printf("\n");
}
}
At the beginning of the code you need to define a global variable N with the value 8, in this case.
You need to include the header stdbool.h as well, because here you would use Booleans.

Why does strcpy work in the first for-loop, but not the second?

So to start this off, this is not the complete program. I am working on it and just ran into this problem. The first 3 times I call strcpy (in the first for-loop) it compiles without problem. However, the fourth through sixth times (in the second for-loop) I get the error message "too few arguments in function to call", even though the arguments are the same as in the first for-loop.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
#include <string.h>
#define ESC 27
struct lag {
char namn[20];
int gjorda;
int inslappta;
int poang;
};
int main(void) {
struct lag temp, serie[] = {
{ "Bryn\204s", 0, 0, 0 },
{ "Djurg\206rden", 0, 0, 0 },
{ "Fr\224lunda", 0, 0, 0 },
{ "F\204rjestad", 0, 0, 0 },
{ "HV 71", 0, 0, 0 },
{ "Link\224ping", 0, 0, 0 },
{ "Lule\206 ", 0, 0, 0 },
{ "MODO ", 0, 0, 0 },
{ "R\224gle", 0, 0, 0 },
{ "Skellefte\206", 0, 0, 0 },
{ "S\224dert\204lje", 0, 0, 0 },
{ "Timr\206", 0, 0, 0 }
};
int i, j, k, hemma, borta;
srand((unsigned)time(NULL));
do {
for (k = 0; k <= 10; k += 2)
{
hemma = rand() % 8;
borta = rand() % 8;
serie[k].gjorda = +hemma;
serie[k].inslappta = +borta;
serie[k + 1].gjorda = +borta;
serie[k + 1].inslappta = +hemma;
printf("%s - %s \t \t %d - %d \n", serie[k].namn, serie[k + 1].namn, hemma, borta);
}
if (hemma > borta)
serie[i].poang = +3;
else if (hemma == borta)
{
serie[i].poang = +1;
serie[i + 1].poang = +1;
}
else if (hemma < borta)
serie[i + 1].poang = +3;
for (i= 0; i < 11; i++)
for (j = i+1;j< 12; j++)
if (serie[j].poang < serie[i].poang)
{
temp.poang = serie[i].poang;
serie[i].poang = serie[j].poang;
serie[j].poang = temp.poang;
temp.gjorda = serie[i].gjorda;
serie[i].gjorda = serie[j].gjorda;
serie[j].gjorda = temp.gjorda;
temp.inslappta = serie[i].inslappta;
serie[i].inslappta = serie[j].inslappta;
serie[j].inslappta = temp.inslappta;
strcpy(temp.namn, serie[i].namn); //These compile
strcpy(serie[i].namn, serie[j].namn);
strcpy(serie[j].namn, temp.namn);
}
for (i = 0; i < 11; i++)
for (j = i + 1; j< 12; j++)
if (serie[j].poang == serie[i].poang)
if ((serie[j].gjorda - serie[j].inslappta) < (serie[i].gjorda - serie[i].inslappta))
{
temp.poang = serie[i].poang;
serie[i].poang = serie[j].poang;
serie[j].poang = temp.poang;
temp.gjorda = serie[i].gjorda;
serie[i].gjorda = serie[j].gjorda;
serie[j].gjorda = temp.gjorda;
temp.inslappta = serie[i].inslappta;
serie[i].inslappta = serie[j].inslappta;
serie[j].inslappta = temp.inslappta;
strcpy_s(temp.namn, serie[i].namn); //These don't
strcpy_s(serie[i].namn, serie[j].namn);
strcpy_s(serie[j].namn, temp.namn);
}
} while (_getch() != ESC);
return 0;
}

How to print all square submatrices of square matrix in C?

Please, help me to find and print all square submatrices of square matrix from big to small square matrices in C programming language
I wrote code that works wrong:
int main() {
int mtrx_size = 8;
int mat[8][8] = {
{ 1, 2, 3, 4, 5, 6, 7, 8},
{ 9,10,11,12,13,14,15,16},
{17,18,19,20,21,22,23,24},
{25,26,27,28,29,30,31,32},
{33,34,35,36,37,38,39,40},
{41,42,43,44,45,46,47,48},
{49,50,51,52,53,54,55,56},
{57,58,59,60,61,62,63,64}
};
int i,j;
int sub_mtrx_size;
for(sub_mtrx_size = mtrx_size; sub_mtrx_size > 1 ; sub_mtrx_size--)
{
for(i = 0; i < sub_mtrx_size; i++)
{
for(j = 0; j < sub_mtrx_size; j++)
{
printf("%3d ", mat[i][j]);
}
printf("\n");
}
printf("\n");
}
return 0;
Here I need to find all 8x8, 7x7, 6x6, 5x5, 4x4, 3x3 and 2x2 submatrices.
Your code was just printing a single sub-matrix for each size, positioned in the upper-left corner of the matrix. You need to add i and j offsets to get the sub-matrices at all positions:
#include <stdio.h>
int main() {
int mtrx_size = 8;
int mat[8][8] = {
{ 1, 2, 3, 4, 5, 6, 7, 8},
{ 9,10,11,12,13,14,15,16},
{17,18,19,20,21,22,23,24},
{25,26,27,28,29,30,31,32},
{33,34,35,36,37,38,39,40},
{41,42,43,44,45,46,47,48},
{49,50,51,52,53,54,55,56},
{57,58,59,60,61,62,63,64}
};
int i, j, ioff, joff, off_cnt;
int sub_mtrx_size;
for(sub_mtrx_size = mtrx_size; sub_mtrx_size > 1 ; sub_mtrx_size--) {
off_cnt = mtrx_size - sub_mtrx_size + 1;
for (ioff = 0; ioff < off_cnt; ioff++) {
for (joff = 0; joff < off_cnt; joff++) {
for (i = 0; i < sub_mtrx_size; i++) {
for (j = 0; j < sub_mtrx_size; j++) {
printf("%3d ", mat[i+ioff][j+joff]);
}
printf("\n");
}
printf("\n");
}
}
}
return 0;
}
Java implementation for a general nxm matrix:
private static void printSubMatrix(int[][] mat) {
int rows=mat.length;
int cols=mat[0].length;
//prints all submatrix greater than or equal to 2x2
for (int subRow = rows; subRow >= 2; subRow--) {
int rowLimit = rows - subRow + 1;
for (int subCol = cols; subCol >= 2; subCol--) {
int colLimit = cols - subCol + 1;
for (int startRow = 0; startRow < rowLimit; startRow++) {
for (int startCol = 0; startCol < colLimit; startCol++) {
for (int i = 0; i < subRow; i++) {
for (int j = 0; j < subCol; j++) {
System.out.print(mat[i + startRow][j + startCol] + " ");
}
System.out.print("\n");
}
System.out.print("\n");
}
}
}
}
}
#include <stdio.h>
int main() {
int mtrx_size = 8;
int mat[8][8] = {
{ 1, 2, 3, 4, 5, 6, 7, 8},
{ 9,10,11,12,13,14,15,16},
{17,18,19,20,21,22,23,24},
{25,26,27,28,29,30,31,32},
{33,34,35,36,37,38,39,40},
{41,42,43,44,45,46,47,48},
{49,50,51,52,53,54,55,56},
{57,58,59,60,61,62,63,64}
};
int i, j, ioff, joff, off_cnt;
int sub_mtrx_size;
/* if we make terminating condition sub_mtrx_size>=1 then we will have all
possible square sub matrices */
for(sub_mtrx_size = mtrx_size; sub_mtrx_size >= 1 ; sub_mtrx_size--) {
off_cnt = mtrx_size - sub_mtrx_size + 1;
for (ioff = 0; ioff < off_cnt; ioff++) {
for (joff = 0; joff < off_cnt; joff++) {
for (i = 0; i < sub_mtrx_size; i++) {
for (j = 0; j < sub_mtrx_size; j++) {
printf("%3d ", mat[i+ioff][j+joff]);
}
printf("\n");
}
printf("\n");
}
}
}
return 0;
}

Resources