I have a N*N matrix full of elements. With a function I can destroy some elements so that they leave an empty space that can be occupied by numbers falling from above. An example of the process:
[1][3][4][5] [1][ ][4][5] [ ][ ][ ][5]
[3][3][3][0]-->[ ][ ][ ][0]-->[ ][ ][4][0]
[3][0][2][1]-->[ ][0][2][1]-->[1][0][2][1]
[2][4][5][3] [2][4][5][3] [2][4][5][3]
In this example only the numbers 1 and 4 fell down. Also when a column is completely empty those filled on the left must move right.
I want to create a function void gravity (game_t * p).
game_t in defined:
typedef struct game{
int n; /*n*n matrix */
int h; /* numbers on matrix go from 0 to h-1*/
int ** board; /*the actual matrix*/
} game_t
I can't think of a good strategy to solve this problem, can you please help me?
edit: this is what I wrote so far:
void gravity(game_t *p) {
int i, j, k;
for (k = 0; k < p->n - 1; k++) {
for (i = p->n - 2; i = 0; i--) {
for (j = p->n - 1; i = 0; i--) {
if (p->board[i - 1][j] == EMPTY) {
p->board[i - 1][j] = p->board[i][j];
p->board[i][j] = EMPTY;
}
}
}
return;
}
This one I wrote doesn't seem very efficient, maybe it should be recursive. For each element of the matrix from the second to last row going right to left I check if the element below is empty and move it there. However I have to check the matrix multiple times (k) because some elements may have to move more than once. `
Ok, as expected: "I know you will not do it, but please provide a minimal reproducible example." Yet again people ask a question and are not even interested in letting others solve their problem. The function you provided doesn't even compile...
Anyway, a solution is provided here along with all the code required to test it. It would have taken much less effort if you just had written all of this in the question with the non working gravity() function.
For the future readers , check out how the allocation done with a single malloc() and some casting, which allows to free everything with a single call to free(). It would be even better to use a single pointer to the data instead of the double pointer, but I understand that teachers around the world still favor the double pointer version. Also the game_set() function is interesting because it's a variadic function.
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <stdarg.h>
const int EMPTY = INT_MIN;
typedef struct game {
int n; /*n*n matrix */
int h; /* numbers on matrix go from 0 to h-1*/
int **board; /*the actual matrix*/
} game_t;
game_t *game_construct(game_t *g, int n, int h)
{
assert(n > 0);
g->n = n;
g->h = h;
g->board = malloc(n * sizeof(int*) + n * n * sizeof(int));
g->board[0] = (int*)((char*)g->board + n * sizeof(int*));
for (int i = 1; i < n; ++i) {
g->board[i] = g->board[i - 1] + n;
}
return g;
}
game_t* game_destruct(game_t* g)
{
free(g->board);
return g;
}
void game_set(game_t* g, ...)
{
va_list argptr;
va_start(argptr, g);
for (int r = 0; r < g->n; ++r) {
for (int c = 0; c < g->n; ++c) {
g->board[r][c] = va_arg(argptr, int);
}
}
}
void game_print(game_t *g)
{
for (int r = 0; r < g->n; ++r) {
for (int c = 0; c < g->n; ++c) {
if (g->board[r][c] == EMPTY) {
printf("[ ]");
}
else {
printf("[%d]", g->board[r][c]);
}
}
printf("\n");
}
printf("\n");
}
void gravity(game_t *g)
{
for (int c = 0; c < g->n; ++c) {
int rf = g->n - 1;
for (int r = rf; r >= 0; --r) {
if (g->board[r][c] != EMPTY) {
g->board[rf--][c] = g->board[r][c];
}
}
while (rf >= 0) {
g->board[rf--][c] = EMPTY;
}
}
}
int main(void)
{
game_t g;
game_construct(&g, 4, 9);
game_set(&g,
1, 3, 4, 5,
3, 3, 3, 0,
3, 0, 2, 1,
2, 4, 5, 3);
game_print(&g);
game_set(&g,
1, EMPTY, 4, 5,
EMPTY, EMPTY, EMPTY, 0,
EMPTY, 0, 2, 1,
2, 4, 5, 3);
game_print(&g);
gravity(&g);
game_print(&g);
game_destruct(&g);
return 0;
}
Related
I have been working on this problem for a while now: basically I need to put the for loop in a function so I can call for it, but I don't how to to make a function return a 2D array, I want to solve this by creating a 1D array, but the problem is that my task is to compute the sum of numbers under the diagonal of a matrix, so I need it to be 2D first, then it can only become 1D. Does anyone have a solution?
Maybe my thought process is just wrong and somebody could just recommend how to put the for loops in functions? If it was without the if clause inside then I might have an idea, but now I really don't.
#include <math.h>
#include <stdio.h>
#include <stdlib.h> // libraries added from example
#include <time.h>
//(*) For a square matrix calculate the sum of elements under the main diagonal excluding it.
#define A -10
#define B 10
int main() {
void enter(int *x, int *y);
int get_random(int lbound, int ubound); // telling the programs that functions are declared
int r;
int c;
int row, col, sum = 0;
enter(&r, &c); // calling the function
srand48(time(NULL)); //Call srand48 with current time reported by `time` casted to a long integer.
// srand48 is used to reinitialize the most recent 48-bit value in this storage
int array[r][c]; // we decided its gonna be r rows and c columns
int line[r * c]; // turning 2d into 1d array
for (row = 0; row < r; ++row) // we cycle numeration of rows of matrix
{
for (col = 0; col < c; col++) // we cycle numeration of columns of matrix
{
array[row][col] = get_random(B, A);// filling array with random numbers, taken from example
printf("%d ", array[row][col]);
if (row > col) { //since we want the sum numbers below the diagonal row>col must be true
sum = sum + array[row][col];// if row>col then we add the number to our sum;
};
}
printf("\n"); // this is to break line after row 1,2 col 3, so it looks nicer
}
for (row = 0; row < r; ++row) // we cycle numeration of rows of matrix
{
for (col = 0; col < c; col++) // we cycle numeration of columns of matrix
{
line[row * r + col] = array[row][col];
}
}
printf("the array in 1D: ");
for (row = 0; row < r * c; row++) {
printf("%d ", line[row]);
}
printf("\n");
printf("sum of array below the diagonal: %d\n", sum);
return 0;
}
void enter(int *x, int *y) { // we have to use pointers if we want more then one return from a function
printf("How man rows in array? "); // just like the last lab we decide how big the matrix will be
scanf("%d", x); // we use x instead of &x because we need the address of the number not the value
printf("How man columns in array? ");
scanf("%d", y); // we use y instead of &y because we need the address of the number not the value
}
int get_random(int lbound, int ubound) {
return mrand48() % (ubound - lbound + 1) + lbound; // function for generating random numbers
}
Conditions have to be met:
the user decides size of square matrix
the matrix has to be filled with random numbers
the array is called by the function has to be 1D using i*N+j, 2D array can't be passed
Let's consider your assignment
Conditions have to be met:
the user decides size of square matrix
the matrix has to be filled with random numbers
the array is called by the function has to be 1D using i*N+j, 2D
array can't be passed
Firstly the matrix must be square.
So this your function
void enter(int *x, int *y) { // we have to use pointers if we want more then one return from a function
printf("How man rows in array? "); // just like the last lab we decide how big the matrix will be
scanf("%d", x); // we use x instead of &x because we need the address of the number not the value
printf("How man columns in array? ");
scanf("%d", y); // we use y instead of &y because we need the address of the number not the value
}
does not make sense. The user can enter different values for the numbers of rows and columns of the matrix. You need to enter only one positive value.
Secondly as we are speaking about a matrix then it means that you have to define a two-dimensional array.
Also you need to write a function that will calculate the sum of elements under the main diagonal of a matrix. The function is declared such a way that it can accept only a one-dimensional array. This means that you need to pass your matrix to the function casting it to a pointer of the type int *. There is no need to create an auxiliary one-dimensional array,
Here is a demonstration program that shows how the function can be declared and defined and how the matrix can be passed to the function.
#include <stdio.h>
long long int sum_under_dioganal( const int a[], size_t n )
{
long long int sum = 0;
for (size_t i = 1; i < n; i++)
{
for (size_t j = 0; j < i; j++)
{
sum += a[i * n + j];
}
}
return sum;
}
int main( void )
{
enum { N = 5 };
int a[N][N] =
{
{ 0, 0, 0, 0, 0 },
{ 1, 0, 0, 0, 0 },
{ 2, 3, 0, 0, 0 },
{ 4, 5, 6, 0, 0 },
{ 7, 8, 9, 10, 0 }
};
printf( "sum of elements under the main diagonal = %lld\n",
sum_under_dioganal( ( int * )a, N ) );
}
The program output is
sum of elements under the main diagonal = 55
Another approach to define the function and call it is the following
#include <stdio.h>
long long int sum_under_dioganal( const int a[], size_t n )
{
long long int sum = 0;
size_t m = 0;
while (m * m < n) ++m;
if (m * m == n)
{
for (size_t i = 1; i < m; i++)
{
for (size_t j = 0; j < i; j++)
{
sum += a[i * m + j];
}
}
}
return sum;
}
int main( void )
{
enum { N = 5 };
int a[N][N] =
{
{ 0, 0, 0, 0, 0 },
{ 1, 0, 0, 0, 0 },
{ 2, 3, 0, 0, 0 },
{ 4, 5, 6, 0, 0 },
{ 7, 8, 9, 10, 0 }
};
printf( "sum of elements under the main diagonal = %lld\n",
sum_under_dioganal( ( int * )a, N * N ) );
}
The program output is the same as shown above.
sum of elements under the main diagonal = 55
2d arrays don't really exist. The compiler just allows you to write a[i][j] so that you can believe in them. Here's some simple code to demonstrate a few methods:
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
void *
make_array(size_t size)
{
int *a = malloc(sizeof *a * size * size);
int *t = a;
if( a == NULL ){
perror("malloc");
exit(1);
}
for( int row = 0; row < size; row += 1 ){
for( int col = 0; col < size; col += 1 ){
*t++ = rand() % 32 - 16;
}
}
return a;
}
int
trace(void *v, size_t s)
{
int *a = v;
int sum = 0;
for( size_t i = 0; i < s; i += 1 ){
sum += *a;
a += s + 1;
}
return sum;
}
int
main(int argc, char **argv)
{
srand(time(NULL));
size_t s = argc > 1 ? strtol(argv[1], NULL, 0) : 5;
void *v = make_array(s);
/* a, b, c, and d will demonstrate different access techniques */
int *a = v; /* a is the conventional "1-d array" (1)*/
int (*b)[s] = v; /* b is a "two-d" array */
int *c = v; /* c iterates through each element */
int *d = v; /* d treats each row as a 1-d array */
for( int i = 0; i < s; i += 1 ){
for( int j = 0; j < s; j += 1 ){
printf("%3d ", b[i][j]);
assert( a[i * s + j] == b[i][j] );
assert( *c == b[i][j] );
assert( d[j] == b[i][j] );
c += 1;
}
d += s;
putchar('\n');
}
printf("trace: %d\n", trace(v, s));
}
/* (1) These comments are not strictly accurate. `a` is *not* an
* array, and `b` is *not* a 2-d array. `a` is a pointer, and `b` is
* an array of pointers. Arrays are not pointers, and pointers are
* not arrays.
*/
I want to make a program that finds the shortest path from 0x0 to the mxn point recursively and change the values of the path to '-'. '1' values in the matrix means path and '0' means wall, and I can go in all directions.
I'm very fresh, so please try to explain the details as much you can.
int startRow = 0, startColumn = 0;
char fun(char arr[][3]);
int main()
{
char matrix[3][3] = { {1,0,1},{1,1,0},{0,1,1} };
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
printf("%d\t", matrix[i][j]);
}
printf("\n");
}
fun(matrix);
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
printf("%d\t", matrix[i][j]);
}
printf("\n");
}
return 0;
}
char fun(char arr[][3])
{
if (arr[startColumn][startRow+1] != 0)
{
arr[startColumn][startRow + 1] = '-';
return fun(arr[startColumn][startRow + 1]);
}
else
{
startRow = 0;
return fun(arr[startColumn + 1][startRow]);
}
}
The output should be like this:
Shortest path in an unweighted graph like this is typically best done with a breadth-first search, which is implemented iteratively using a queue data structure to store search state, rather than a depth-first search using a stack (such as the call stack and recursion).
If you use a stack, a search that happens to hit the goal node isn't necessarily shortest, because the path isn't extended methodically one level at a time as in BFS. Rather, the DFS explores all the way to a terminal state as soon as possible, then begins to backtrack and explore other terminal paths. None of these paths have the shortness guarantee of BFS.
The consequence of this is that with a naive recursive implementation, you will need to explore all paths before you can claim you've found the shortest one. But if your grids are small or have few paths as appears to be the case here, this shouldn't be a problem.
If you do need to optimize yet maintain the recursion, see the canonical thread Performing Breadth First Search recursively. But going forward I'll assume we're doing DFS.
The other concern is that when the graph has cycles, you need to be able to keep track of visited nodes to avoid an infinite loop. Since you seem to not mind changing characters in your grid, it should suffice that you'll never try to re-visit a cell marked '-' and you'll undo any '-' mark at the end of a recursive call in case you find a faster path to that cell in the future.
As a C-specific aside, it's best not to write function headers like char fun(char arr[][3]). The name is unclear, as is the return value, and the parameter is hard-coded to be exactly 3 columns wide. It's unrealistic to expect a client calling the function from a library to go in and edit the source code every time they want to use a different grid. Even if they did, they'd be prohibited from calling this function on multiple grid sizes in the same program. That size should be dynamic. Also, the function relies on global state, int startRow = 0, startColumn = 0; which is not thread-safe and very prone to errors. Pass all state as parameters, or at least only read global constants.
Here's a proof of concept that could still use some clean-up (repeated code, hardcoded literals). Basically, run a standard DFS to get the length of the shortest path, then run it again to populate the first path that fulfills the minimum length requirement: very much a brute-force approach.
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void ensure(bool predicate, const char *msg, unsigned int line) {
if (!predicate) {
fprintf(stderr, "%s:%d: %s\n", __FILE__, line, msg);
exit(1);
}
}
void print_grid(size_t rows, size_t cols, char **grid) {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
printf("%c", grid[i][j]);
}
puts("");
}
}
void find_shortest_path_recursive(
int path_length,
int *shortest_path_length,
int y,
int x,
size_t rows,
size_t cols,
char **grid
) {
if (y < 0 || x < 0 || y >= rows ||
x >= cols || grid[y][x] != '1') {
return;
}
else if (y == rows - 1 && x == cols - 1 &&
(*shortest_path_length < 0 ||
path_length < *shortest_path_length)) {
*shortest_path_length = path_length + 1;
}
grid[y][x] = '-';
const static int dirs[][2] = {{-1, 0}, {0, -1}, {1, 0}, {0, 1}};
for (int i = 0; i < 4; i++) {
find_shortest_path_recursive(
path_length + 1,
shortest_path_length,
y + dirs[i][0],
x + dirs[i][1],
rows,
cols,
grid
);
}
grid[y][x] = '1';
}
bool set_shortest_path_recursive(
int path_length,
int shortest_path_length,
int y,
int x,
size_t rows,
size_t cols,
char **grid
) {
if (y < 0 || x < 0 || y >= rows ||
x >= cols || grid[y][x] != '1') {
return false;
}
grid[y][x] = '-';
if (y == rows - 1 && x == cols - 1 &&
path_length + 1 == shortest_path_length) {
return true;
}
const static int dirs[][2] = {{-1, 0}, {0, -1}, {1, 0}, {0, 1}};
for (int i = 0; i < 4; i++) {
if (set_shortest_path_recursive(
path_length + 1,
shortest_path_length,
y + dirs[i][0],
x + dirs[i][1],
rows,
cols,
grid
)) {
return true;
}
}
grid[y][x] = '1';
return false;
}
int set_shortest_path(size_t rows, size_t cols, char **grid) {
int shortest_path_length = -1;
find_shortest_path_recursive(
0, &shortest_path_length, 0, 0, rows, cols, grid
);
set_shortest_path_recursive(
0, shortest_path_length, 0, 0, rows, cols, grid
);
return shortest_path_length;
}
int main(void) {
size_t rows = 8;
size_t cols = 8;
char src_grid[8][8] = {
"10011110",
"10001011",
"11111010",
"00100010",
"00110110",
"11100010",
"10011110",
"11110011",
};
char **grid = malloc(sizeof(*grid) * rows);
ensure(grid, "malloc failed", __LINE__);
for (int i = 0; i < rows; i++) {
grid[i] = malloc(sizeof(grid[i]) * cols);
ensure(grid[i], "malloc failed", __LINE__);
memcpy(grid[i], src_grid[i], cols);
}
int shortest_path_length = set_shortest_path(rows, cols, grid);
print_grid(rows, cols, grid);
printf("shortest path length: %d\n", shortest_path_length);
return 0;
}
Output:
-001---0
-000-0-1
-----0-0
001000-0
001101-0
111000-0
100111-0
111100--
shortest path length: 19
How can one iterate through order of execution?
I am developing a piece of software that have several steps to compute over some data, and i was thinking in may changing the order of those steps pragmatically so i can check what would be the best order for some data.
Let me exemplify: I have let's say 3 steps (it's actually more):
stepA(data);
stepB(data);
stepC(data);
And I want a contraption that allow me to walk thought every permutation of those steps and then check results. Something like that:
data = originalData; i=0;
while (someMagic(&data,[stepA,stepB,stepC],i++)){
checkResults(data);
data = originalData;
}
then someMagic execute A,B then C on i==0. A, C then B on i==1. B, A then C on i==2 and so on.
You can use function pointers, maybe something like the following:
typedef void (*func)(void *data);
int someMagic(void *data, func *func_list, int i) {
switch (i) {
case 0:
func_list[0](data);
func_list[1](data);
func_list[2](data);
break;
case 1:
func_list[0](data);
func_list[2](data);
func_list[1](data);
break;
case 2:
func_list[1](data);
func_list[0](data);
func_list[2](data);
break;
default: return 0;
}
return 1;
}
func steps[3] = {
stepA,
stepB,
stepC
}
while (someMagic(&data, steps, i++)) {
....
}
The key is to find a way to iterate over the set of permutations of the [0, n[ integer interval.
A permutation (in the mathematical meaning) can be seen as a bijection of [0, n[ into itself and can be represented by the image of this permutation, applied to [0, n[.
for example, consider the permutation of [0, 3[:
0 -> 1
1 -> 2
2 -> 0
it can be seen as the tuple (1, 2, 0), which in C, translate naturally to the array of integers permutation = (int []){1, 2, 0};.
Suppose you have an array of function pointers steps, then for each permutation, you'll then want to call steps[permutation[i]], for each value of i in [0, n[.
The following code implements this algorithm:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
static void stepA(int data) { printf("%d: %s\n", data, __func__); }
static void stepB(int data) { printf("%d: %s\n", data, __func__); }
static void stepC(int data) { printf("%d: %s\n", data, __func__); }
static void (* const steps[])(int) = {stepA, stepB, stepC,};
static int fact(int n) { return n == 0 ? 1 : fact(n - 1) * n; }
static int compare_int(const void *pa, const void *pb)
{
return *(const int *)pa - *(const int *)pb;
}
static void get_next_permutation(int tab[], size_t n)
{
int tmp;
unsigned i;
unsigned j;
unsigned k;
/* to find the next permutation in the lexicographic order
* source: question 4 (in french, sorry ^^) of
* https://liris.cnrs.fr/~aparreau/Teaching/INF233/TP2-permutation.pdf
. */
/* 1. find the biggest index i for which tab[i] < tab[i+1] */
for (k = 0; k < n - 1; k++)
if (tab[k] < tab[k + 1])
i = k;
/* 2. Find the index j of the smallest element, bigger than tab[i],
* located after i */
j = i + 1;
for (k = i + 1; k < n; k++)
if (tab[k] > tab[i] && tab[k] < tab[j])
j = k;
/* 3. Swap the elements of index i and j */
tmp = tab[i];
tab[i] = tab[j];
tab[j] = tmp;
/* 4. Sort the array in ascending order, after index i */
qsort(tab + i + 1, n - (i + 1), sizeof(*tab), compare_int);
}
int main(void)
{
int n = sizeof(steps) / sizeof(*steps);
int j;
int i;
int permutation[n];
int f = fact(n);
/* first permutation is identity */
for (i = 0; i < n; i++)
permutation[i] = i;
for (j = 0; j < f; j++) {
for (i = 0; i < n; i++)
steps[permutation[i]](i);
if (j != f - 1)
get_next_permutation(permutation, n);
}
return EXIT_SUCCESS;
}
The outer loop in main, indexed by j, iterates over all the n! permutations, while the inner one, indexed by i, iterates overs the n steps.
The get_next_permutation modifies the permutation array in place, to obtain the next permutation in the lexicographical order.
Note that it doesn't work when the permutation in input is the last one (n - 1, ..., 1, 0), hence the if (j != f - 1) test.
One could enhance it to detect this case (i isn't set) and to put the first permutation (0, 1, ..., n - 1) into the permutation array.
The code can be compiled with:
gcc main.c -o main -Wall -Wextra -Werror -O0 -g3
And I strongly suggest using valgrind as a way to detect off-by-one errors.
EDIT: I just realized I didn't answer the OP's question precisely. The someMagic() function would allow a direct access to the i-th permutation, while my algorithm only allows to compute the successor in the lexicographic order. But if the aim is to iterate on all the permutations, it will work fine. Otherwise, maybe an answer like this one should match the requirement.
I've come to a solution that is simple enough:
void stepA(STRUCT_NAME *data);
void stepB(STRUCT_NAME *data);
void stepC(STRUCT_NAME *data);
typedef void (*check)(STRUCT_NAME *data);
void swap(check *x, check *y) {
check temp;
temp = *x;
*x = *y;
*y = temp;
}
void permute(check *a, int l, int r,STRUCT_NAME *data) {
int i, j = 0, score;
HAND_T *copy, *copy2, *best_order = NULL;
if (l == r) {
j = 0;
while (j <= r) a[j++](data);
} else {
for (i = l; i <= r; i++) {
swap((a + l), (a + i));
permute(a, l + 1, r, data);
swap((a + l), (a + i));
}
}
}
check checks[3] = {
stepA,
stepB,
stepC,
};
int main(void){
...
permute(checks,0,2,data)
}
i'm having problems writing this excercise.
this should evaluate if a given array contains a palindrome sequence of numbers, the program builds correctly but doesn't run (console remains black). where am i wrong on this? thanks for all help!
#include <stdio.h>
#include <stdlib.h>
#define SIZE 15
//i'm using const int as exercise demand for it
//should i declare size as int when giving it to function? also if it's been declared?
//i'm a bit confused about that
int palindrome(const int a[], int p, int size);
int main()
{
int a[SIZE] = {0, 1, 2, 3, 4, 5, 6, 7, 6, 5, 4, 3, 2, 1, 0};
int p = 1; //i'm not using boolean values, but i think should work anyway, right?
p = palindrome(a, p, SIZE);
if (p)
printf("\nseries is palindrome\n");
else
printf("\nseries isn't palindrome\n");
return 0;
}
int palindrome(const int a[], int p, int size)
{
int mid, j;
mid = size / 2;
while (p) {
for (j = 0; j < (SIZE / 2); j++){
if (a[mid + (j + 1)] != a[mid - (j + 1)]) //i think i might be wrong on this, but don't know where i'm in fault
p = 0;
}
}
return p;
}
p.s.
how can i activate debugger "watches" on Code Blocks to look at others function variables? (i put a stop on main function)
You don't need while (p) { loop. It is possible to have infinite loop here (and you have it!), because if you don't change p, this loop never stops.
You mix size and SIZE in the implementation of palindrome() (mid is half of size, but the whole loop is from 0 to SIZE-1).
Also it is better to move int p = 1; in the beginning of implementation of palindrome() (and to remove int p from list of it's parameters).
Just try this:
int palindrome(const int a[], int p, int size)
{
int mid, j;
mid = size / 2;
for (j = 0; j < (size / 2); j++){
if (a[mid + (j + 1)] != a[mid - (j + 1)]);
p = 0;
break;
}
}
return p;
}
here's an alternative without p where palindrome returns 0 or 1
int palindrome(const int a[], int size)
{
int j , k , ret;
for (j = 0 , k = size - 1 ; j < k; j++ , k--)
{
if (a[j)] != a[k])
{
ret = 0;
break;
}
}
if(j >= k)
ret = 1;
return ret;
}
you can call palindrome in the if statement in main like this :
if(palindrome(a , SIZE))
printf("\nseries is palindrome\n");
else
printf("\nseries isn't palindrome\n");
I'm currently working on a school (matrix multiplier) project and I have a problem.
I reprensent a matrix with a 2d array and I allocate it this way :
typedef struct matrix
{
int** matrix;
unsigned int l;
unsigned int c;
} matrix;
int matrix_alloc(matrix** matr, unsigned int l, unsigned int c)
{
unsigned int i, j;
*matr = malloc(sizeof(matrix)); /* Allocate memory for the structure */
if (*matr == NULL) /* Check if malloc succeeded */
{
fprintf(stderr, "malloc error"); /* If not print error */
return -1;
}
(*matr)->matrix = malloc(l*sizeof(int*)); /* Allocate memory for columns of the matrix*/
if ((*matr)->matrix == NULL)
{
fprintf(stderr, "malloc error");
free(*matr);
return -1;
}
for (i = 0; i < l; i++)
{
(*matr)->matrix[i] = malloc(c*sizeof(int));
if ((*matr)->matrix[i] == NULL)
{
fprintf(stderr, "malloc error");
for (j = 0; j < i; j++)
{
free((*matr)->matrix[j]);
}
free(*matr);
return -1;
}
for (j = 0; j < c; j++)
{
(*matr)->matrix[i][j] = 2; // Matrix should be filled with 2 for tests
printf("Element added : %d\n", (*matr)->matrix[i][j]);
}
}
(*matr)->l = l;
(*matr)->c = c;
printf("will print matrix----------------------\n");
matrix_print(*matr);
return 0;
}
And this is how I print the matrix
void matrix_print(matrix* m)
{
unsigned int i, j;
int v;
printf("********************************************************************************\n");
printf("Lines:\t %i\n", m->l);
printf("Cols:\t %i\n", m->c);
printf("Matrix::\n");
for (i = 0; i < m->l; i++)
{
for (j = 0; j < m->c; j++)
{
matrix_get_elem_at(v, i, j, m);
printf("\t%d", v);
/*printf("\t%ld", mpz_get_si(v)); */
}
printf("\n");
}
printf("********************************************************************************\n");
}
When I do
matrix* matr;
/* alloc matrix */
assert(matrix_alloc(&matr, 10, 10) == 0);
printf("----------------------------will print test matrix\n");
matrix_print(matr);
My matrix is filled with 32767 instead of 2
Can someone help me get rid of this bug?
Thank you
Ben
You should show us more code (for example, how did you declare typedef matrix?) But I bet that the problem is in matrix_get_elem_at - it should get int* for the first parameter. not int.
If I may give you an advice, it would be better to represent your matrix as one contiguous array.In this case rows are positionned one after another, like Row1| Row1| ... |Row(col). For example
[1, 2, 3]
[4, 5, 6]
will be
[1, 2, 3, 4, 5, 6]
To create the matrix you use
int** matrix = (int**)malloc(sizeof(rowCount*colCount))
To access element at [i][j] you use matrix[ i*colCount + j ].
Most of your functions will be much simpler to write.