Shortest path to any point in a maze - c

So I have to scan a maze number of rows and columns for a file, bit I got that part.
File have a form like this
3
4
....
.#.#
....
Where the first number is a number of rows and the second is the number of columns. Character '#' is a wall and I can't go there but I can go through '.'
Now I have to, using structures and pointers, find a shortest path to any point in a maze. Example structure is in my code (Cell).
I have no idea how to do this. I've created a array 'visited' to track which cell I've been to and function to check if a point is valid.
Somehow I have to point to other points in NORTH, WEST, EAST, SOUTH directions.
#include "stdafx.h"
#include "stdlib.h"
//Starting point
#define START_X 0
#define START_Y 0
//example structure I have to use
struct Cell
{
struct Cell *north;
struct Cell *east;
struct Cell *south;
struct Cell *west;
char value;
int distance;
};
//function that prints a maze
void printMap(char **charMaze, int row, int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
printf_s("%c", charMaze[i][j]);
}
printf_s("\n");
}
}
// functions that check if a point is valid
bool isValid(int x, int y, int row, int col)
{
if (x < row && y < col && x >= 0 && y >= 0)
return true;
return false;
}
bool isSafe(char **charMaze, int **visited, int x, int y)
{
if (charMaze[x][y] == '#' || visited[x][y]==true)
return false;
return true;
}
//My attempt at solving this
int BFS(char **maze,int END_X, int END_Y,int row, int col, bool **visited)
{
isValid(END_X, END_Y, row, col);
}
int main()
{
FILE *map;
int row, col;
// I open a file with a maze
fopen_s(&map, "test1.txt", "r");
// I scan a row number and column number
fscanf_s(map, "%d", &row);
fscanf_s(map, "\n%d\n", &col);
char** charMaze;
charMaze = (char**)malloc(row * sizeof(char*));
for (int i = 0; i < row; i++)
charMaze[i] =(char*)malloc(col * sizeof(char));
bool** visited;
visited = (bool**)malloc(row * sizeof(bool*));
for (int i = 0; i < row; i++)
visited[i] = (bool*)malloc(col * sizeof(bool));
//set staring point as true and other points as false
visited[START_X][START_Y] = true;
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
visited[i][j] = false;
}
}
// I scan a maze and I put it in a array
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
fscanf_s(map, "%c", &charMaze[i][j],1);
}
fscanf_s(map, "\n");
}
fclose(map);
//printMap(charMaze, row, col);
return 0;
}

You could use the Dijkstra algorithm to find the shortest path.
As result, suppose you have to return a path from the starting point to every dot in the maze.
You have here an implementation of the Dijkstra algorithm.
You would need to adapt it your maze map.
You could use a matrix of structs where each struct contains the x,y coordinate of the previous node, the distance to the starting node, and the flag done.
Edit
If fact you don’t even need to implement the Dijkstra algorithm. A simple flooding algorithm will do because the weight of all vertex of the graph is one.
Here is how I would do it.
#include <stdbool.h>
#include <stdlib.h>
enum State { Wall, Unvisited, WaveBorder, NewWaveBorder, Done };
// define the structure holding coordinates of previous cell in path and state
typedef struct Cell {
int i,j; // coordinates of predecessor in path
enum State state;
} Cell;
// visit cell (vi,vj) from neighbor cell (i,j)
void visitCell(Cell **m, int vi, int vj, int i, int j) {
if m[vi][vj].state == Unvisited {
m[vi][vj].state = NewWaveBorder;
m[vi][vj].i = i;
m[vi][vj].j = j;
}
}
Cell** findShortestPath(char **maze, int row, int col, int iStart, int jStart) {
Cell **m = malloc(sizeof(Cell*)*row);
for (int i = 0; i < row; i++)
m[i] = malloc(sizeof(Cell)*col);
for (int i = 0; i < row; i++)
for (int j = 0; j < col; j++)
if (maze[i][j] == '.') {
m[i][j].state = Unvisited;
m[i][j].i = m[i][j].j = -1;
} else {
m[i][j].state = Wall;
m[i][j].i = m[i][j].j = -2;
}
m[iStart][jStart].state = WaveBorder;
bool done = false;
while (!done) {
for (int i = 0; i < row; i++)
for (int j = 0; j < col; j++) {
if (m[i][j].state != waveBorder)
continue;
if (i > 0)
visitCell(m, i-1, j, i, j);
if (j > 0)
visitCell(m, i, j-1, i, j);
if (i < row)
visitCell(m, i+1, j, i, j);
if (j < col)
visitCell(m, i, j+1, i, j);
m[i][j].state = Done;
}
done = true;
for (int i = 0; i < row; i++)
for (int j = 0; j < col; j++)
if (m[i][j].state == Unvisited)
done = false;
else if (m[i][j].state == NewWaveBorder)
m[i][j].state == WaveBorder;
}
return m;
}
The path from cell (i,j) is stored in the matrix of Cell structures. Each cell has the coordinates of the predecessor in the path toward (iStart, jStart). The cell (iStart,jStart) will have (-1,-1) as predecessor in the path. Walls will have (-2,-2) as predecessors.

Okay I did something like this. But it doesn't work for some reason.
#include "stdafx.h"
#include "stdlib.h"
//Starting point
#define START_X 0
#define START_Y 0
#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y))
//example structure I have to use
struct Cell
{
struct Cell *north;
struct Cell *east;
struct Cell *south;
struct Cell *west;
char value;
int distance;
};
//function that prints a maze
void printMap(char **charMaze, int row, int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
printf_s("%c", charMaze[i][j]);
}
printf_s("\n");
}
}
void printMap2(int **intMaze, int row, int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
printf_s("%d", intMaze[i][j]);
}
printf_s("\n");
}
}
// functions that check if a point is valid
bool isValid(int x, int y, int row, int col)
{
if (x < row && y < col && x >= 0 && y >= 0)
{
printf("Dobry punkt");
return true;
}
else
{
printf("Nieprawidlowy");
}
return false;
}
bool isSafe(char **charMaze, int **visited, int x, int y)
{
//char wall = '#';
//char character = charMaze[x][y];
if (charMaze[x][y] =='#' || visited[x][y])
{
printf("unsafe");
return false;
}
else
{
printf("safe");
}
return true;
}
bool canGo(Cell *cell, int d)
{
if (cell == NULL)
{
return 0;
}
if (cell->value == '#')
return 0;
if (cell->value == '.')
return 1;
if (cell->distance > d)
return 1;
return 0;
}
void findShortestPath(char **maze, int start_X, int start__Y, int i, int j, int row, int col, int **visited, int minDist, int dist)
{
if (j = start__Y && i == start_X)
{
minDist = MIN(dist, minDist);
return;
}
visited[start_X][start__Y] = 1;
//bottom
if (isValid(start_X + 1, start__Y, row, col) && isSafe(maze, visited, start_X + 1, start__Y))
findShortestPath(maze, start_X + 1, start__Y, i, j, row, col, visited, minDist, dist + 1);
//right
if (isValid(start_X, start__Y + 1, row, col) && isSafe(maze, visited, start_X, start__Y + 1))
findShortestPath(maze, start_X, start__Y + 1, i, j, row, col, visited, minDist, dist + 1);
//top
if (isValid(start_X - 1, start__Y, row, col) && isSafe(maze, visited, start_X + 1, start__Y))
findShortestPath(maze, start_X + 1, start__Y, i, j, row, col, visited, minDist, dist + 1);
//left
if (isValid(start_X, start__Y - 1, row, col) && isSafe(maze, visited, start_X, start__Y - 1))
findShortestPath(maze, start_X, start__Y - 1, i, j, row, col, visited, minDist, dist + 1);
visited[start_X, start__Y] = 0;
}
int main()
{
FILE *map;
int start_X = 0;
int start_Y = 0;
int row, col;
struct Cell cell;
// I open a file with a maze
fopen_s(&map, "test1.txt", "r");
// I scan a row number and column number
fscanf_s(map, "%d", &row);
fscanf_s(map, "\n%d\n", &col);
char** charMaze;
charMaze = (char**)malloc(row * sizeof(char*));
for (int i = 0; i < row; i++)
charMaze[i] = (char*)malloc(col * sizeof(char));
int** visited;
visited = (int**)malloc(row * sizeof(int*));
for (int i = 0; i < row; i++)
visited[i] = (int*)malloc(col * sizeof(int));
memset(visited, 0, sizeof visited);
int minDist = INT_MAX;
// I scan a maze and I put it in a array
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
fscanf_s(map, "%c", &charMaze[i][j], 1);
}
fscanf_s(map, "\n");
}
findShortestPath(charMaze, start_X, start_Y, 2, 3, row, col, visited, minDist, 0);
if (minDist != INT_MAX)
{
printf("Najkrotsza droga z poczatku do konca to %d", minDist);
}
else
{
printf("Can't get to the point");
}
printMap(charMaze, row, col);
fclose(map);
return 0;
}

Related

I want to show elements of a matrix that appear only once

I got this but it I can't seem to make it work, tried everything I could think of.
#include <stdio.h>
#include <stdlib.h>
void alocare_vector(int *v, int nr, int elem)
{
int *v1;
if ((v1 = realloc(v, nr * sizeof(int))) == NULL)
{
printf("Memorie insuficienta");
free(v);
exit(EXIT_FAILURE);
}
v = v1;
v[nr - 1] = elem;
}
int main()
{
int a[100][100];
int n, *v = NULL, i, j, k, l, ok = 0, nr = 0;
printf("Number de elements n:");
scanf("%d", &n);
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
scanf("%d", &a[i][j]);
for (k = 0; k < n; k++)
{
for (l = 0; l < n; l++)
{
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
if (a[k][l] == a[i][j] && (k != i && l != j))
ok = 1;
if (ok == 0)
{
nr++;
alocare_vector(v, nr, a[k][l]);
}
ok = 0;
}
}
if (nr > 0)
{
printf("Elements:");
for (i = 0; i < nr; i++)
{
printf("%d ", v[i]);
}
}
free(v);
}
Basically, I need to create a matrix, ans print the elements that appear only once using an array with dynamic memory allocation.
one simple fix is to declare the "int * v" as a global variable and modify the function as alocare_vector(int nr, int elem)
now using a hash table you can store the numbers in the array, below is the your implementation just a bit modified.
#include <stdio.h>
#include <stdlib.h>
int hash[1000]={0};
int * v=NULL;
void alocare_vector(int nr, int elem)
{
int *v1;
if ((v1 = (int*)realloc(v, nr * sizeof(int))) == NULL)
{
printf("Memorie insuficienta");
free(v);
exit(EXIT_FAILURE);
}
v = v1;
v[nr - 1] = elem;
}
int main()
{
int a[100][100];
int n, i, j, nr = 0;
printf("Number de elements n:");
scanf("%d", &n);
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
scanf("%d", &a[i][j]);
++hash[a[i][j]];
}
}
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
if(hash[a[i][j]]==1)
{
nr++;
alocare_vector(nr, a[i][j]);
}
}
}
if (nr > 0)
{
printf("Elements:");
for (i = 0; i < nr; i++)
{
printf("%d ", v[i]);
}
}
free(v);
}
When calling a your funtion you pass a copy of the pointer. Therfore any modifications to this local copy of the pointer will not affect the copy in main. Therfore you need a refrence or pointer to the pointer in main.
void alocare_vector(int **v, int nr, int elem)
{
...
*v = v1;
}
Here you have brut force example how to generate array of distinct elements of the 2D array:
typedef struct
{
size_t length;
int data[];
}data_t;
data_t *add_element(data_t *arr, int element)
{
size_t newsize = arr ? arr -> length : 0;
arr = realloc(arr, newsize * sizeof(arr -> data[0]) + sizeof(*arr));
if(arr)
{
arr -> length = newsize;
arr -> data[newsize - 1] = element;
}
return arr;
}
int isPresent(size_t rows, size_t cols, size_t vrow, size_t vcol, int (*array)[cols])
{
int val = array[vrow][vcol];
for(size_t row = 0; row < rows; row++)
for(size_t col = 0; col < cols; col++)
{
if(vcol == col && vrow == row) continue;
if(array[row][col] == val)
{
return 1;
}
}
return 0;
}
data_t *distinctElements(size_t rows, size_t cols, int (*array)[cols])
{
data_t *dist = NULL;
for(size_t row = 0; row < rows; row++)
{
for(size_t col = 0; col < cols; col++)
{
if(!isPresent(rows, cols, row, col, array))
{
data_t *tmp = add_element(dist, array[row][col]);
if(tmp) dist = tmp;
else { /* error handling */}
}
}
}
return dist;
}

Matrix manipulation to find biggest elements in their row & column

Our teacher asks to manipulate and search through a 25x15 matrix to find the biggest elements in their own Row & Column: if the (i,j) element is bigger than the mean value of i row, and bigger than the mean value of j column, then we can increment the counter that we'll return from the given function. After we found all of these so-called "Important Points" we search in them for the biggest of all, and pass the value and its coordinates to the Main by using the pointers passed to the function to modify the original variables.
The core of the exercise is the function to implement, with the given arguments:
int Importants(int a[ROW][COL], int *mi, int *mj, int *max);
I preferred to use more little functions to call when needed, than to implement everything in a big block, so I created the functions to find the mean value of a given column and row, the biggest element in a row.
We tried to use a supplementary array to store the positions, to bypass the pointers requisite, which contains a triplet of (i,j coordinate + value); anyway I'm not sure it's the right way.
Here's the full source-code
/*
In a matrix, the (i,j) couple is considered "IMPORTANT" is its value is
Bigger Than the Mean Value of the i row && Bigger Than the Mean Value of the j column
The exercise is to create, aside from Create (in the given interval) and Print functions, a function
named "Importants" which returns the number of Important points of the matrix; then search in these points
which one is the biggest and returns its value and coordinates by using the pointers defined in the function call.
FUNCTION DEFINITION CAN NOT BE ALTERED
*/
//import libraries
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//constant defines
#define ROW 25
#define COL 15
#define MIN 3
#define MAX 47
//vector with (i,j) positions and their value: every 3 elements you have 'i' row number, 'j' column number, and 'k' or 'max' value
int positions[COL*3];
//matrix generation with no first row element equal to the previous and next one
void create_matrix(int mat[][COL]) {
for (int i = 0; i < ROW; i++) {
for (int j = 0; j < COL; j++) {
//first generation try
mat[i][j] = rand() % (MAX - MIN + 1) + MIN;
//checks
if ((mat[i][j] == mat[i-1][j]) && (mat[i][j] == mat[i+1][j]) && (i >= 1)) {
if (j > 0){
j--;
continue;
}
else {
continue;
}
}
else if ((mat[i][j] == mat[i+1][j]) && i >= 1) {
if (j > 0){
j--;
}
else {
continue;
}
}
}
}
puts("Matrix Generated.\n\n");
}
//generate a vector with all zeros to avoid mistakes
void zero_vector(int vector[]) {
for (int i = 0; i < COL*3;i++) {
vector[i] = 0;
}
}
//print matrix
void print_matrix(int mat[][COL]) {
for (int i = 0; i < ROW; i++) {
for (int j = 0; j < COL; j++) {
printf("[ %2i ] ", mat[i][j]);
}
printf("\n");
}
}
//find max element in a given row
int max_in_row(int mat[][COL], int i) {
int max_value = 0, second_max = 0;
for (int r = i, c = 0; c < COL; c++) {
if (mat[r][c] > max_value) {
second_max = max_value;
max_value = mat[r][c];
}
}
return max_value;
}
//find max element in Positions vector
void max_in_positions_vector(int vector[]) {
int max_value = 0, second_max_value = 0;
for (int i = 2; i < COL*3; i=i+3) {
if (vector[i] > max_value) {
second_max_value = max_value;
max_value = vector[i];
}
}
printf("\n\nThe biggest of \'Important Positions\' is:\t%i", max_value);
}
//calculate mean value of a given row
int row_mean_value(int mat[][COL], int i, int j) {
int r_mean = 0, sum = 0;
for (int r = i, c = j; c < COL; c++){
sum += mat[r][c];
}
r_mean = sum / COL;
printf("\nMean value of Row %i:\t%i", i, r_mean);
return r_mean;
}
//calculate mean value of a given column
int column_mean_value(int mat[][COL], int i, int j) {
int c_mean = 0, sum = 0;
for (int r = i, c = j; r < ROW; r++){
sum += mat[r][c];
}
c_mean = sum / ROW;
printf("\nmedia colonna %i:\t%i", i, c_mean);
return c_mean;
}
int Importants(int a[ROW][COL], int *mi, int *mj, int *max){
int i = 0, j = 0, n_Importants = 0, max_value, k;
for (i,k = 0; i < ROW; i++) {
max_value = max_in_row(a, i);
//row_mean_value(a,i,j);
for (j = 0; j < COL; j++) {
if (max_value > row_mean_value(a,i,j) && max_value > column_mean_value(a,i,j)){
n_Importants++;
positions[k] = i;
positions[k+1] = j;
positions[k+2] = max_value;
k += 3;
//debug prints
printf("\nMax Value n. %i:\t%i", j, max_value);
printf("\ni = %i\tj = %i\tk = %i\n\n", i, j, k);
}
}
}
return n_Importants;
}
//main function
int main() {
srand(time(NULL));
int mat[ROW][COL];
int mi = 0, mj = 0, max = 0, *mi_p = &mi, *mj_p = &mj, *max_p = &max;
create_matrix(mat);
print_matrix(mat);
zero_vector(positions);
int n_Importants = Importants(mat, mi_p, mj_p, max_p);
max_in_positions_vector(positions);
return 0;
}
I've updated the k cycle to iterate every k+3 as suggested only inside the if block; As noted, mi, mj are not used, and that's part of the problem and why I chose to use an array of positions: the "Importants" function definition can not be altered, and so I would have to use the variable pointers. Also I've edited the call to the max_in_vector function to the correct max_in_row function name.
Updates
I've worked on it, removed the positions array and used the pointers to pass back the coordinates, by implementing a search in the matrix from within the Importants function; I've adjusted the search because I think I have to check every element, else it would only check for the maximum of the row && column. I don't know how to explain it well, so I'll post the updated code:
//imports
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//global constants
#define ROW 25
#define COL 15
#define MIN 3
#define MAX 47
//int posizioni[COL*3];
int importants_vect[ROW*COL];
//create matrix with no duplicates for the first element of 2 adjacent rows (a[i][j] != a[i-1][j] AND a[i][j] != a[i+1][j])
void create_matrix(int mat[][COL]) {
for (int i = 0; i < ROW; i++) {
for (int j = 0; j < COL; j++) {
mat[i][j] = rand() % (MAX - MIN + 1) + MIN;
if ((mat[i][j] == mat[i-1][j]) && (mat[i][j] == mat[i+1][j]) && (i >= 1)) {
if (j > 0){
j--;
continue;
}
else {
continue;
}
}
else if ((mat[i][j] == mat[i+1][j]) && i >= 1) {
if (j > 0){
j--;
}
else {
continue;
}
}
}
}
puts("Matrix Generated.\n\n");
}
void zero_vector_init(int vect[]) {
for (int i = 0; i < COL*3;i++) {
vect[i] = 0;
}
}
//print matrix function
void print_matrix(int mat[][COL]) {
for (int i = 0; i < ROW; i++) {
for (int j = 0; j < COL; j++) {
printf("[ %2i ] ", mat[i][j]);
}
printf("\n");
}
}
/* void maxi_vect(int vect[]) {
int max_value = 0, second_max_value = 0;
for (int i = 2; i < COL*3; i=i+3) {
if (vect[i] > max_value) {
second_max_value = max_value;
max_value = vect[i];
}
}
printf("\n\nIl max_value tra i punti importants e':\t%i", max_value);
} */
//find the mean of a given row
int row_mean_value(int mat[][COL], int i, int j) {
int r_mean = 0, sum = 0;
for (int r = i, c = j; c < COL; c++){
sum += mat[r][c];
}
r_mean = sum / COL;
printf("\nrow mean = %i / %i >>> %i", sum, COL, r_mean);
return r_mean;
}
//find the mean value in a given column
int column_mean_value(int mat[][COL], int i, int j) {
int c_mean = 0, sum = 0, r = 0, c = j;
for (r = i; r < ROW; r++){
sum += mat[r][c];
}
c_mean = sum / ROW;
printf("\ncolumn mean = %i / %i >>> %i", sum, ROW, c_mean);
return c_mean;
}
int max_in_vector(int vect[]) {
int max_value = 0, second_max_value = 0;
for (int i = 0; i < ROW*COL; i++) {
if (vect[i] > max_value) {
second_max_value = max_value;
max_value = vect[i];
}
}
return max_value;
}
//search inside the matrix for a given value and communicate its coordinates by modifying pointers to variables
void search_in_matrix(int mat[][COL], int to_search, int *mi, int *mj) {
//row and col variables are used for completeness, else we could just work with pointers
int found = 0, found_row = 0, found_col = 0;
for (int i = 0; i < ROW; i++) {
for (int j = 0; j < COL; j++) {
if (mat[i][j] == to_search) {
found = mat[i][j];
found_col = j;
found_row = i;
}
}
}
*mi = found_row;
*mj = found_col;
return;
}
int Importants(int a[ROW][COL], int *mi, int *mj, int *max){
//init variables, including the ones to modify coordinate pointers
int n_importants = 0, i_coord = 0, j_coord = 0, max_p = 0;
//init mean value variables
int r_mean = 0, c_mean = 0;
//init counters
int i = 0, j = 0, k = 0;
//traversing the matrix
for (i ; i < ROW; i++) {
//calculate the mean of the row we're in
r_mean = row_mean_value(a, i, j);
for (j , k; j < COL; j++, k++) {
//calculating the mean of the column we're in
c_mean = column_mean_value(a, i, j);
//check for Important Point: a[i][j] MUST BE STRICTLY GREATER than r_mean and c_mean
if (a[i][j] > r_mean && a[i][j] > c_mean) {
//increment n_importants counter and fill the supplementary array with the value
n_importants++;
importants_vect[k] = a[i][j];
}
else continue;
}
//reinit j to 0. There are problems in print if not. Still don't know why
j = 0;
}
//search for the max in the supplementary array then search for its coordinates in the matrix
//and pass them back to the coordinate pointers
max_p = max_in_vector(importants_vect);
search_in_matrix(a, max_p, mi, mj);
return n_importants;
}
int main() {
srand(time(NULL));
int mat[ROW][COL];
int mi = 0, mj = 0, max = 0;
create_matrix(mat);
print_matrix(mat);
//zero_vector_init(posizioni);
zero_vector_init(importants_vect);
int n_importants = Importants(mat, &mi, &mj, &max);
//maxi_vect(posizioni);
int max_value = max_in_vector(importants_vect);
//int search = search_in_matrix(mat, max_value);
printf("\n\nThere are %i Important Points inside the matrix", n_importants);
printf("\n\nThe max among Important Points is\t%i\n", max_value);
printf("It's found on the row n°\t%i\n", mi);
printf("And on column n°\t%i\n\n", mj);
//printf("media: %.2f", med);
return 0;
}

Function to print Matrix in abstract data type

In the matrix. c I have
struct matrix{
int row;
int col;
int *a;
};
Matrix* allocateMemory(int m, int n) {
Matrix* mat = (Matrix*) malloc(sizeof(Matrix));
if (mat == NULL) {
return NULL;
}
mat->row = m;
mat->col = n;
mat->a = (int*)calloc(m*n, sizeof(int));
return m;
}
While in the matrix.h I have
#ifndef MATRIX_H_INCLUDED
#define MATRIX_H_INCLUDED
typedef struct matrix Matrix;
Matrix* allocateMemory(int m, int n);
//...
int printMatrix(Matrix* mat);
int transpose(Matrix* mat);
#endif // MATRIX_H_INCLUDED
I am working in an ADT for matrices but I stucked in the print function. I would like to create a function
int printMatrix(Matrix* mat)
So in the main.c I would have something like
int i, j;
for (i = 0; i < row; i++){
for(j = 0; j < col; j++){
printf("%d ", printMatrix(mat));
}
printf("\n");
}
It means I want the printf in the main, not in the function, but I just could do this
void printMatrix(Matrix* mat){
int i, j, k;
for (i = 0; i < mat->row; i++){
for(j = 0; j < mat->col; j++){
k = i*mat->col + j;
printf("%d ", mat->a[k]);
}
printf("\n");
}
}
It does print the matrix, but it doesn't seem to be right. It is the same for the transpose matrix function, it does print the transpose matrix correctly, but I would like an
int transpose(Matrix* mat)
So I would use the function printMatrix in the main to print the transpose, but I just could do
void transpose(Matrix* mat){
int i, j, k;
for (i = 0; i < mat->col; i++){
for (j = 0; j < mat->row; j++){
k = j*mat->row + i;
printf("%f ", mat->a[k]);
}
printf("\n");
}
}
How can I create the int function to print the matrix?
I am still studying ADT, but what would be my lack of understanding so I couldn't do the function?
This is prefaced by my top comments.
A few more style tips ...
Do not cast the return of malloc [et. al.]
A bit more idiomatic is (e.g.):
Matrix *mat = malloc(sizeof(*mat));
I realize that in school, they teach the use of (e.g.) i, j, k, but try to use more descriptive names (e.g) row, col, off.
And, make the arguments descriptive as well:
Matrix *allocateMemory(int row,int col)
Here's a refactored version [with some style cleanups]:
#include <stdio.h>
#include <stdlib.h>
typedef struct matrix {
int row;
int col;
int *a;
} Matrix;
Matrix *
allocateMemory(int row, int col)
{
Matrix *mat = malloc(sizeof(*mat));
if (mat == NULL) {
perror("malloc");
exit(1);
}
mat->row = row;
mat->col = col;
mat->a = calloc(row * col, sizeof(*mat->a));
if (mat->a == NULL) {
perror("calloc");
exit(1);
}
return mat;
}
void
printMatrix(Matrix *mat)
{
int row, col, off;
for (row = 0; row < mat->row; row++) {
for (col = 0; col < mat->col; col++) {
off = (row * mat->col) + col;
printf("%d ", mat->a[off]);
}
printf("\n");
}
}
void
matrix_fill(Matrix * mat)
{
int row, col, off;
int val = 1;
for (row = 0; row < mat->row; row++) {
for (col = 0; col < mat->col; col++) {
off = (row * mat->col) + col;
mat->a[off] = val++;
}
}
}
void
transpose_copy(Matrix *matout,Matrix *matin)
{
int row, col;
int inoff, outoff;
for (row = 0; row < matin->row; row++) {
for (col = 0; col < matin->col; col++) {
inoff = (row * matin->col) + col;
outoff = (col * matout->col) + row;
matout->a[outoff] = matin->a[inoff];
}
printf("\n");
}
}
Matrix *
transpose_new(Matrix *matin)
{
Matrix *matout = allocateMemory(matin->col,matin->row);
transpose_copy(matout,matin);
return matout;
}
int
main(void)
{
Matrix *matin = allocateMemory(2,3);
matrix_fill(matin);
printf("Original:\n");
printMatrix(matin);
Matrix *matout = transpose_new(matin);
printf("Transposed:\n");
printMatrix(matout);
return 0;
}
Here's the program output:
Original:
1 2 3
4 5 6
Transposed:
1 4
2 5
3 6

Abort Trap Error: 6 - where is it coming from? - Sudoku solver

Have a sudoku solver method that check row/col location for solution and backtracks after testing if a number is not correct. It is printing out No Solution followed by Abort Trap Error: 6. I am using a test case that should return TRUE. Row and Col are initially being passed in parameter as 0
What might be the issue? I'm thinking it could be how I am incrementing row and col. It reads in a single line file and translates to 2D grid
Here is test input: 4.....8.5.3..........7......2.....6.....8.4......1.......6.3.7.5..2.....1.4......
#include <stdio.h>
#include <stdlib.h>
#define BLANK '.'
#define TRUE 1
#define FALSE 0
#define BLANK_SPACE '.'
int findBlankSpace(int grid2D[9][9]);
int valid(int grid2D[9][9], int rowIndex, int colIndex, int num);
void prettyPrint(int grid2D[9][9]);
int readLine(int grid2D[9][9]);
int findSolution(int grid2D[9][9],int row, int col);
int UsedInRow(int grid2D[9][9], int row, int num);
int UsedInCol(int grid2D[9][9], int col, int num);
int UsedInBox(int grid2D[9][9], int boxStartRow, int boxStartCol, int num);
int findSolution(int grid2D[9][9], int row, int col)
{
row = 0;
if (findBlankSpace(grid2D) == FALSE)
return TRUE;
if (row == 9) {
row = 0;
}
for (int num = 1; num <= 9; num++)
{
if (valid(grid2D, row, col, num))
{
grid2D[row][col] = num;
if (findSolution(grid2D, row, ++col))
{
return TRUE;
}
}
grid2D[row][col] = 0;
row++;
}
return FALSE;
}
int findBlankSpace(int grid2D[9][9])
{
int row;
int col;
for (row = 0; row < 9; row++)
for (col = 0; col < 9; col++)
if (grid2D[row][col] == 0)
return TRUE;
return FALSE;
}
int UsedInRow(int grid2D[9][9], int row, int num)
{
for (int col = 0; col < 9; col++)
if (grid2D[row][col] == num)
return TRUE;
return FALSE;
}
int UsedInCol(int grid2D[9][9], int col, int num)
{
for (int row = 0; row < 9; row++)
if (grid2D[row][col] == num)
return TRUE;
return FALSE;
}
int UsedInBox(int grid2D[9][9], int row1, int col1, int num)
{
for (int row = 0; row < 3; row++)
for (int col = 0; col < 3; col++)
if (grid2D[row+row1][col+col1] == num)
return TRUE;
return FALSE;
}
int valid(int grid2D[9][9], int row, int col, int num)
{
return !UsedInRow(grid2D, row, num) &&
!UsedInCol(grid2D, col, num) &&
!UsedInBox(grid2D, row - row % 3, col - col % 3, num);
}
int readLine(int grid2D[9][9])
{
int c;
int row = 0;
int col = 0;
while((c = getchar()) != EOF)
{
if(c == '.')
{
grid2D[row][col] = 0;
}
else
{
grid2D[row][col] = c - '0';
col++;
}
if(col%9 == 0)
{
row++;
col = 0;
}
}
return 0;
}
void prettyPrint(int grid2D[9][9])
{
int count = 0;
int row;
int col;
printf("solution:\n");
/* Use nested for-loops to iterate through 2-D array */
for(row = 1; row <= 9; row++)
{
for(col = 1; col<=9; col++)
{
/* After every 3rd character, print out "|", forming the board */
if((col%3==0)&&(col%9!=0))
{
printf("%d| ", grid2D[row - 1][col - 1]);
}
else
printf("%d ", grid2D[row - 1][col - 1]);
count++;
}
/* After every 3rd row, print out horizontal separations */
if((row%3==0)&&(row!=9))
{
/* Advance to the next line prior to printing separation to give space */
printf("\n");
printf("------+-------+------");
}
printf("\n");
}
}
int main()
{
int grid2D[9][9];
readLine(grid2D);
if(findSolution(grid2D, 0, 0)==TRUE)
{
prettyPrint(grid2D);
}
else
{
printf("No Solution Found!\n");
}
return 0;
}
in the recursive function: findSolution(), eventually the 'col' parameter will be 9 (or greater)! When that happens, the code will be accessing outside the bounds of the current row in the array. This results in undefined behavior and can lead to a seg fault event.

concatenate 2 matrices

I have a matrix dynamically allocated and I want to create another one which is the first matrix but with another copy beside. for example,I have the matrix:
11
22
My new matrix will be:
1 1 1 1
2 2 2 2
How can I concatenate them? This is my code in C:
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
int **create_matrix(int row, int col)
{
int **matrix = malloc(sizeof (int*)*row);
int i;
for (i = 0; i < row; i++)
{
matrix[i] = malloc(sizeof (int)*col);
}
return matrix;
}
void matrix_input(int **matrix, int row, int col)
{
int i, j;
printf("enter the elements of the matrix:\n");
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
scanf("%d", &matrix[i][j]);
}
}
}
int **extend_matrix(int **matrix, int row, int col)
{
int k, j;
int i;
int **extend_matrix = malloc(sizeof (int*)*row);
for (k = 0; k < row + row; k++)
{
extend_matrix[k] = malloc(sizeof (int)*col);
}
extend_matrix = matrix;
extend_matrix = (int**) realloc(extend_matrix, (row + row) * sizeof (int*));
extend_matrix[j] = matrix[j];
for (i = 0; i < row; i++)
{
extend_matrix[k] = matrix[i];
}
}
void print_matrix(int **matrix, int row, int col)
{
int i, j;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
printf(" %d ", matrix[i][j]);
}
printf("\n");
}
}
void print_extend_matrix(int **extend_matrix, int row, int col)
{
int k, j;
for (k = 0; k < row + row; k++)
{
for (j = 0; j < col; j++)
{
printf("%d", extend_matrix[k][j]);
}
printf("\n");
}
}
int main(void)
{
int **matrix;
int **extend_matrix;
int row, col;
printf("enter the number of rows of cols:");
scanf("%i%i", &row, &col);
matrix = create_matrix(row, col);
matrix_input(matrix, row, col);
print_matrix(matrix, row, col);
print_extend_matrix(extend_matrix, row, col);
getch();
return 0;
}
Although #NPE suggested to you a better way. If you want to allocate memory in extend_matrix()
error in your code (read comments)
int **extend_matrix = malloc(sizeof (int*)*row);
^ on row
for (k = 0; k < row + row; k++)
^ where as loop is for row + row
{
extend_matrix[k] = malloc(sizeof (int)*col); // So this cause an error,
// segment-fault
}
second, your concept is wrong to copy memory:
extend_matrix = matrix;
at this line you are assigning matrix to extend_matrix its wrong. you need loop here to copy each elements from matrix[][] to extend_matrix[][]. (but rectify your memory allocation code first)
I think extend_matrix() should just call create_matrix() to create a new matrix of double the width, and then use two simple nested loops to populate it.
If this is what you are looking for :
int concat(void * oldM, int row, int col,void& *newM) {
newM = malloc(sizeof(int)*row*col*2);
for(int i = 0;i<2;++i)
for(int j=0;j<2;++j)
newM[i][j+col] = newM[i][j] = oldM[i][j];
for(int i = 0;i<2;++i) {
for(int j=0;j<4;++j) {
cout<<"\t"<<newM[i][j];
}
cout<<"\n";
}
}

Resources