Find the maximum value in a 2D matrix (recursively) - c

I'm struggling to find the error in my code, I'm trying to find the maximum value in my 2D matrix, in a certain row. Can you help me locate where my logic fails?
int maxInRowmaxInRow(int mtx[][N], int row, int cols);
int main()
{
int mtx[][N] = { {8,1,2,6,7},{1,8,3,9,6},{4,5,-5,1,8},{1,2,3,4,5},{5,4,3,5,3} };
printf("%d", maxInRow(mtx, 1,N));
getch();
}
int maxInRow(int mtx[][N], int row, int cols)
{
int possibleMax = maxInRow(mtx, row, cols - 1);
if (cols == 0) return mtx[row][cols];
int max = mtx[row][cols - 1];
max = (max < maxInRow(mtx, row, cols - 1)) ? possibleMax : max;
return max;
}

You're doing the recursion termination case in the wrong order. You're also do two recursions instead of one. Simplifying your code:
int maxInRow(int mtx[][N], int row, int cols)
{
if (cols == 0) return mtx[row][cols];
int possibleMax = mtx[row][cols - 1];
int sublistMax = maxInRow(mtx, row, cols - 1);
int max = (sublistMax > possibleMax) ? sublistMax : possibleMax;
return max;
}
int main()
{
int mtx[][N] = {{8,1,2,6,7}, {1,8,3,9,6}, {4,5,-5,1,8}, {1,2,3,4,5}, {5,4,3,5,3}};
printf("%d\n", maxInRow(mtx, 1, N));
}

Related

Monte Carlo Simulation of Percolation is not Giving Expected Results

I've started working my way through the Princeton Algorithms course on Coursera. The course uses Java, but I decided to follow along with C as it is what I am most comfortable with. One of the assignments has you write a program to estimate the value of the percolation threshold via a Monte Carlo simulation (https://coursera.cs.princeton.edu/algs4/assignments/percolation/specification.php). I have written all the code, but my program's output is not the same as the one on the site (it is not completely off, but still incorrect.) e.g.
Their implementation:
~/Desktop/percolation> java-algs4 PercolationStats 200 100
mean = 0.5929934999999997
stddev = 0.00876990421552567
95% confidence interval = [0.5912745987737567, 0.5947124012262428]
~/Desktop/percolation> java-algs4 PercolationStats 2 100000
mean = 0.6669475
stddev = 0.11775205263262094
95% confidence interval = [0.666217665216461, 0.6676773347835391]
Mine:
~/percolation> ./percolation_stats 200 100
mean = 0.628564
stddev = 0.206286
95% confidence interval = [0.588132, 0.668996]
~/percolation> ./percolation_stats 2 100000
mean = 0.728548
stddev = 0.189745
95% confidence interval = [0.727371, 0.729724]
Here is my code:
percolation_stats.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include "percolation.h"
double mean(double *, int);
double stddev(double *, int);
double confidencelo(double *, int);
double confidencehi(double *, int);
int main(int argc, char **argv) {
int n, T, row, col;
percolation *p;
double *samp;
srand((unsigned) time(NULL));
sscanf(argv[1], "%d", &n);
sscanf(argv[2], "%d", &T);
samp = malloc(T * sizeof *samp);
for (int i = 0; i < T; ++i) {
p = creategrid(n);
while (!percolates(p)) {
do {
row = rand() % n + 1;
col = rand() % n + 1;
} while (is_open(p, row, col));
open(p, row, col);
}
samp[i] = (double) number_of_open_sites(p) / (n * n);
}
printf("mean = %g\n", mean(samp, T));
printf("stddev = %g\n", stddev(samp, T));
printf("95%% confidence interval = [%g, %g]\n", confidencelo(samp, T),
confidencehi(samp, T));
return 0;
}
// mean: sample mean of percolation threshold
double mean(double *a, int len) {
double sum = 0.0;
for (int i = 0; i < len; ++i) {
sum += a[i];
}
return sum / len;
}
// stddev: sample standard deviation of percolation threshold
double stddev(double *a, int len) {
double mean(double *, int);
double sum = 0.0;
double avg = mean(a, len);
for (int i = 0; i < len; ++i) {
sum += (a[i] - avg) * (a[i] - avg);
}
return sqrt(sum / (len - 1));
}
// confidencelo: low endpoint of 95% confidence interval
double confidencelo(double *a, int len) {
double mean(double *, int);
double stddev(double *, int);
return mean(a, len) - (1.96 * stddev(a, len)) / sqrt(len);
}
// confidencehi: high endpoint of 95% confidence interval
double confidencehi(double *a, int len) {
double mean(double *, int);
double stddev(double *, int);
return mean(a, len) + (1.96 * stddev(a, len)) / sqrt(len);
}
percolation.h
#include <stdbool.h>
typedef struct percolation percolation;
percolation *creategrid(int);
void open(percolation *, int, int);
bool is_open(percolation *, int, int);
bool is_full(percolation *, int, int);
int number_of_open_sites(percolation *);
bool percolates(percolation *);
percolation.c
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include "quick_union.h"
#define pos(p, x, y) (((x) - 1) * (p)->width + ((y) - 1))
typedef struct percolation {
int width;
int open_sites;
UF *uf;
bool *open;
} percolation;
// creategrid: creates n-by-n grid, with all sites initially blocked
percolation *creategrid(int n) {
if (n <= 0) {
fprintf(stderr, "open: illegal argument\n");
exit(1);
}
percolation *p;
p = malloc(sizeof *p);
p->width = n;
p->open_sites = 0;
p->uf = createuf(n * n + 2);
p->open = malloc(n * n * sizeof *p->open);
for (int i = 0; i < n * n; ++i) {
p->open[i] = false;
}
for (int i = 0; i < n; ++i) {
connect(p->uf, n * n, pos(p, 1, i));
connect(p->uf, n * n + 1, pos(p, n, i));
}
return p;
}
// open: opens the site (row, col) if it is not open already
void open(percolation *p, int row, int col) {
if (row < 1 || row > p->width || col < 1 || col > p->width) {
fprintf(stderr, "open: illegal argument\n");
exit(1);
}
if (p->open[pos(p, row, col)]) {
return;
}
p->open[pos(p, row, col)] = true;
++p->open_sites;
if (col > 1 && p->open[pos(p, row, col - 1)]) {
connect(p->uf, pos(p, row, col), pos(p, row, col - 1));
}
if (col < p->width && p->open[pos(p, row, col + 1)]) {
connect(p->uf, pos(p, row, col), pos(p, row, col + 1));
}
if (row > 1 && p->open[pos(p, row - 1, col)]) {
connect(p->uf, pos(p, row, col), pos(p, row - 1, col));
}
if (row < p->width && p->open[pos(p, row + 1, col)]) {
connect(p->uf, pos(p, row, col), pos(p, row + 1, col));
}
}
// is_open: is the site (row, col) open?
bool is_open(percolation *p, int row, int col) {
if (row < 1 || row > p->width || col < 1 || col > p->width) {
fprintf(stderr, "is_open: illegal argument\n");
exit(1);
}
return p->open[pos(p, row, col)];
}
// is_full: is the site (row, col) full?
bool is_full(percolation *p, int row, int col) {
if (row < 1 || row > p->width || col < 1 || col > p->width) {
fprintf(stderr, "is_full: illegal argument\n");
exit(1);
}
return !p->open[pos(p, row, col)];
}
// number_of_open_sites: returns the number of open sites
int number_of_open_sites(percolation *p) {
return p->open_sites;
}
// percolates: does the system percolate?
bool percolates(percolation *p) {
return connected(p->uf, p->width * p->width, p->width + p->width + 1);
}
quick_union.h
#include <stdbool.h>
typedef struct UF UF;
UF *createuf(int);
void connect(UF *, int, int);
bool connected(UF *, int, int);
int find(UF *, int);
quick_union.c
#include <stdlib.h>
#include <stdbool.h>
#define max(a, b) (((a) > (b)) ? (a) : (b))
typedef struct UF {
int count;
int *id;
int *sz;
int *largest;
} UF;
// createuf: return pointer to UF with n elements
UF *createuf(int n) {
UF *uf;
uf = malloc(sizeof *uf);
uf->count = n;
uf->id = malloc(n * sizeof *uf->id);
uf->sz = malloc(n * sizeof *uf->sz);
uf->largest = malloc(n * sizeof *uf->largest);
for (int i = 0; i < n; ++i) {
uf->id[i] = uf->largest[i] = i;
uf->sz[i] = 1;
}
return uf;
}
// connect: connect elements p and q
void connect(UF *uf, int p, int q) {
int root(UF *, int);
int i = root(uf, p);
int j = root(uf, q);
if (i == j) {
return;
}
if (uf->sz[i] <= uf->sz[j]) {
uf->id[i] = j;
uf->sz[j] += uf->sz[i];
uf->largest[j] = max(uf->largest[i], uf->largest[j]);
} else {
uf->id[j] = i;
uf->sz[i] += uf->sz[j];
uf->largest[i] = max(uf->largest[j], uf->largest[i]);
}
}
// connected: return true if elements p and q are connected
bool connected(UF *uf, int p, int q) {
int root(UF *, int);
return root(uf, p) == root(uf, q);
}
// find: return largest element in i's connected component
int find(UF *uf, int i) {
int root(UF *, int);
return uf->largest[root(uf, i)];
}
// root: return root element of i
int root(UF *uf, int i) {
while (i != uf->id[i]) {
uf->id[i] = uf->id[uf->id[i]];
i = uf->id[i];
}
return i;
}
Where did I go wrong?

Dynamically 2D array in C using the single pointer:

I'm trying to dynamically allocate memory to a 2d array using a single pointer. For that, I have 3 functions that allocate the respective memory newarray() and to store individual elements in it store(), to fetch elements from it fetch(). I don't know why I get execution errors while I test it, also I should allocate the the exact amount of memory for it, that might be the problem but I'm not sure how to do that. This probrams deals with a triangular matrix which should have the number of columns lower than the number of rows when It comes to adding elements, like I, have a 5x5 array where (4,2) and (4,4) its OK but (4,5) its NOT.
Here is the code
typedef int* triangular;
triangular newarray(int N){
triangular mat = NULL; //pointer to integer
//Allocate memory for row
mat = (int *)malloc(N * N * sizeof(int));
//Check memory validity
if(mat == NULL)
{
return 1;
}
return mat;
}
int store(triangular as, int N, int row, int col, int val){
if(row >= col){
as[row * N + col] = val;
return 1;
}else if(row < col){
return -1;
}else if((row > N) ||(col > N) || (row + col > N + N))
return -1;
}
int fetch(triangular as, int N, int row, int col){
int value;
value = as[row * N + col];
if((row > N) ||(col > N) || (row + col > N + N) )
return -1;
else if(row < col)
return -1;
return value;
}
nt main()
{
int iRow = 0; //Variable for looping Row
int iCol = 0; //Variable for looping column
int N;
triangular mat = newarray(5);
printf("\nEnter the number of rows and columns = ");
scanf("%d",&N); //Get input for number of Row
store(mat,N,3,2,10);
store(mat,N,3,3,10);
store(mat,N,4,2,111);
store(mat,N,3,5,11);
printf("the element at [3,5] is : %i", fetch(mat,N,3,5));
//Print the content of 2D array
for (iRow =0 ; iRow < N ; iRow++)
{
for (iCol =0 ; iCol < N ; iCol++)
{
printf("\nmat[%d][%d] = %d\n",iRow, iCol,mat[iRow * N + iCol]);
}
}
//free the allocated memory
free(mat);
return 0;
}
int store(triangular as, int N, int row, int col, int val){
if(row >= col){
as[row * N + col] = val;
return 1;
}else if(row < col){
return -1;
}else if((row > N) ||(col > N) || (row + col > N + N))
return -1;
}
in store function, first if condition is so weird. Why you dont set the value to the array when the parameters passed to function is 2(row), 3(column).
I changed your store in the following way. index and array size are different things because of that index is equal to N - 1. In your code, there are a lot of if checks I guess checking only row and col is enough to understand that they are inside boundaries.
int store(triangular as, int N, int row, int col, int val){
int index = N - 1;
if((row > N) ||(col > N))
return -1;
as[row * index + col] = val;
return 1;
}
I changed your fetch function like below because the reason I mentioned about your store function.
int fetch(triangular as, int N, int row, int col){
int value;
int index = N - 1;
if((row > index) ||(col > index))
return -1;
value = as[row * index + col];
return value;
}
You are making this needlessly complicated. All those functions and manual run-time calculations aren't really necessary.
Also, you have the following problems:
Don't hide pointers behind typedef, it just makes the code unreadable for no gain.
Initialize the data returned from malloc or instead use calloc which sets everything to zero, unlike malloc.
Arrays in C are zero-indexed so you can't access item [3][5] in an array of size 5x5. This is a common beginner problem since int array[5][5]; declares such an array but array[5][5] for index accessing goes out of bounds. The syntax for declaration and access isn't the same, access needs to start at 0.
You didn't include any headers, I'm assuming you left that part out.
Here's a simplified version with bug fixes that you can use:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int N=5;
int (*mat)[N] = calloc( 1, sizeof(int[N][N]) ); // allocate 2D array dynamically
if(mat == NULL)
return 0;
mat[3][2] = 10;
mat[3][3] = 10;
mat[4][2] = 111;
mat[3][4] = 11;
for(int i=0; i<N; i++)
{
for(int j=0; j<N; j++)
{
printf("[%d][%d] = %d\n", i, j, mat[i][j]);
}
}
free(mat);
return 0;
}
Further study: Correctly allocating multi-dimensional arrays

Find max value in multidimensional array recursively

I'm studying an algorithm to recursively find the highest value in a multidimensional array (of any size). But it is not working properly.
#include <stdio.h>
int N = 5;
int maxInRow(int matrix[][N], int row, int cols)
{
if (cols == 0){
return matrix[row][cols];
}
int maxCandidate = matrix[row][cols - 1];
int maxSublist = maxInRow(matrix, row, cols - 1);
int max = (maxSublist > maxCandidate) ? maxSublist : maxCandidate;
return max;
}
int main()
{
int mtx[5][5] = {{8,1,2,6,7}, {1,80,3,9,6}, {4,5,5,1,8}, {1,2,3,4,5}, {5,4,3,5,300}};
printf("%d\n", maxInRow(mtx, 1, N-1));
}
It should return 300, but it returns 80. Where am I going wrong?
What you have done is to find out maximum value of a particular row and NOT the max value of the multidimensional arrays. To get the maximum value of whole arrays , need to recursively compare all items of all the rows.
Here is one of the way to achieve this(code below)
#include <stdio.h>
int N = 5;
int maxInRow(int matrix[][N], int row, int cols)
{
if (cols == 0 ){
if(row==1) {
// the last element of the matrix
return matrix[0][0];
}
else{
// Comparing all items of row is done, begin next row
row--;
cols=N;
}
}
int maxCandidate = matrix[row-1][cols - 1];
int maxSublist = maxInRow(matrix, row, cols - 1);
int max = (maxSublist > maxCandidate) ? maxSublist : maxCandidate;
return max;
}
int main()
{
int mtx[5][5] = {{8,1,2,6,7}, {1,80,3,9,6}, {4,5,5,1,8}, {1,2,3,4,5}, {5,4,3,5,300}};
printf("%d\n", maxInRow(mtx, N, N));
}

recursive find number in between in C

I want to find the number within a range in an array and must be in a recursive way. The function variables couldn't be modified.
Let's say in the range of 2 and 3
The input is : int a[] = {4, 1, 3, 1, 3, 2};
and the output will be = {3,3,2} , 3 found
Not sure how to code the recursive function in this case. The below I have tried not working.
int within(int a[], int N, int lower, int upper, int result[])
{
if(N == 1 && N <= upper && N>= lower)
return a[0];
return within(&a[1], N-1, lower, upper, result);
}
int main()
{
int a[] = {4, 1, 3, 1, 3, 2};
int result[6] = {0};
int i, nResult;
nResult = within(a, 6, 2, 3, result);
printf("%d data passed the bounds\n", nResult);
for (i = 0; i < nResult; i++){
printf("%d ", result[i]);
}
printf("\n");
return 0;
}
I want to find the number within a range in an array
Let's say in the range of 2 and 3
Normally a for loop or similar would be so much easier here
If it has to be recursive....
// need to have another number - r - number in range
// r starts at zero
//
// normally lower case for variable and capitals for things you #define
// N starts at the number of elements of a less one
//
int within(int a[], int N, int lower, int upper, int r, int result[])
{
if(a[0] <= upper && a[0]>= lower) {
result[r]= a[0];
r++;
}
if(N==0) {
return r;
} else {
r = within(&a[1], N-1, lower, upper, r, result);
return r;
}
}
the function will give a return value of the number of values found within the range.
The code above is recursive, but so much more complicated and fragile than a simple loop... such as the fragment below
for (i=0;i<N;i++) {
if(a[i] <= upper && a[i]>= lower) {
result[r]= a[i];
r++;
}
}
If it has to be recursive wihtout r...
// need to have another number - result[0] - number in range
// result[0] starts at zero
//
// normally lower case for variable and capitals for things you #define
// N starts at the number of elements of a less one
//
int within(int a[], int N, int lower, int upper, int result[])
{
if(a[0] <= upper && a[0]>= lower) {
result[0]++;
result[result[0]]= a[0];
}
if(N==0) {
return result[0];
} else {
result[0] = within(&a[1], N-1, lower, upper, result);
return result[0];
}
}
now result conatins
{number in range, first number in range, second number in range....}
Something like this. If you want to implement a recursive function, try to do it in the way that the recursive call happens at the end.
#include <stdio.h>
int find_in_range(int* out, int const *in, int length, int from, int to)
{
if (length == 0)
{
return 0;
}
int addon;
if (*in >= from && *in <= to)
{
*out = *in;
++out;
addon = 1;
}
else
{
addon = 0;
}
return find_in_range(out, in + 1, length - 1, from, to) + addon;
}
#define N 6
int main()
{
int in[N] = {4, 1, 3, 1, 3, 2};
int out[N] = {0};
int num_found = find_in_range(out, in, N, 2, 3);
for (int i = 0; i < num_found; ++i)
{
printf("%d ", out[i]);
}
printf("\n");
return 0;
}
You can modify the following code as per your requirements. This is just a proof of concept code:
#include <stdio.h>
#include <stdlib.h>
static int result[4];
static int ctr1 = 0;
static int ctr2 = 0;
void recFind(int* arr, int* key){
if(ctr2 == 8)
return;
if(*arr >= key[0] && *arr <= key[1])
result[ctr1++] = *arr;
arr++;
ctr2++;
recFind(arr, key);
}
int main(){
int arr[] = {1,3,3,6,4,6,7,8};
int key[] = {1,4};
recFind(arr, key);
printf(" { ");
for(int i = 0; i < 4; i++){
printf("%d ", result[i]);
}
printf("}\n");
}
As it follows from the description of the assignment the function should provide two values: the number of elements that satisfy the condition and an array that contains the elements themselves.
It is evident that the array should be allocated dynamically. And it is logically consistent when the function itself returns the number of elements while the pointer to the generated array is passed by reference as an argument.
The recursive function can look the following way
#include <stdio.h>
#include <stdlib.h>
size_t get_range( const int a[], size_t n, int lower, int upper, int **out )
{
size_t m;
if ( n )
{
m = get_range( a, n - 1, lower, upper, out );
if ( lower <= a[n-1] && a[n-1] <= upper )
{
int *tmp = realloc( *out, ( m + 1 ) * sizeof( int ) );
if ( tmp )
{
tmp[m] = a[n-1];
*out = tmp;
++m;
}
}
}
else
{
*out = NULL;
m = 0;
}
return m;
}
int main(void)
{
int a[] = { 1, 2, 3, 4, 5, 4, 3, 2, 1 };
const size_t N = sizeof( a ) / sizeof( *a );
int lower = 2, high = 3;
int *out;
size_t n = get_range( a, N, lower, high, &out );
for ( size_t i = 0; i < n; i++ )
{
printf( "%d ", out[i] );
}
putchar( '\n' );
free( out );
return 0;
}
The program output is
2 3 3 2
Below codes will work for you in recursive way. If you don't want to print the numbers just comment out printf statement inside function printfRange. Hope you can understand the logic :-
int within(int *a, int rngH, int rngL, int length)
{
int len = length;
static int i = 0;
static int found = 0;
if(len <=0 )
{
return i;
}
if (*a == rngH)
{
printf("%d,",*a);
i++;
found = 1;
within(++a,rngH, rngL,--len);
}
else if(*a == rngL && found > 0)
{
printf("%d,",*a);
i++;
within(++a,rngH, rngL,--len);
}
else
{
within(++a,rngH, rngL,--len);
}
return i;
}
int main() {
int a[] = {4, 1, 3, 1, 3, 2};
int total = within(a,3,2,6);
printf("\n");
printf("Total :%d\n",total);
return 0;
}

Trying to compare chars from matrix C

I'm tryingto compare chars from a matrix, but it's not adding any values and i don't know why
so here's my code:
#include <stdio.h>
#include <math.h>
#include <assert.h>
#include <limits.h>
#include <string.h>
#include <stdlib.h>
#define MAX_LINES 1000
#define MAX_LINE_LENGTH 1000
//---------------------
//READING & WRITING
//---------------------
char *ints_new(int n)
{
return (char *) malloc(n * sizeof(char));
}
char **ints2_new(int rows, int cols)
{
char **result = (char **) malloc(rows * sizeof(char *));
char *p = ints_new(rows * cols);
for (int i = 0; i < rows; i++, p += cols)
result[i] = p;
return result;
}
int str_readline(FILE *f, char *s)
{
int result = EOF;
char *p = fgets(s, INT_MAX, f);
if (p != NULL)
{
result = (int) strlen(s);
if (result > 0 && s[result-1] == '\n')
s[--result] = '\0';
}
return result;
}
char *str_dup(const char *s)
{
char *result = (char *) malloc(strlen(s) + 1);
strcpy(result, s);
return result;
}
int strings_read(FILE *f, char **a)
{
int result = 0;
char line[MAX_LINE_LENGTH + 2];
while (str_readline(f, line) != EOF)
a[result++] = str_dup(line);
return result;
}
// --------------------
// Problema A
// --------------------
void values_to_m(char **m, int rows, int cols, char **readings)
{
int i;
int j;
int k = 0;
int l = 0;
for(i = 0; i < rows; i++)
{
for(j = 0; j < cols; j++)
{
m[i][j] = readings[k][l];
l++;
}
k++;
l = 0;
}
}
int count_points(char **m, int i, int j, int rows, int cols)
{
int result = 0;
if(i < rows-2)
{
if(m[i][j] == m[i+1][j] == m[i+2][j])
result++;
if(j < cols-2)
{
if(m[i][j] == m[i][j+1] == m[i][j+2])
result++;
if(m[i][j] == m[i+1][j+1] == m[i+2][j+2])
result++;
}
if(j > 1)
{
if(m[i][j] == m[i+1][j-1] == m[i+2][j-2])
result++;
}
}
else
{
if(j < cols-2)
{
if(m[i][j] == m[i][j+1] == m[i][j+2])
result++;
}
}
printf("%d\n", result);
return result;
}
void points(char **m, int rows, int cols)
{
int i;
int j;
int player1 = 0; //O's
int player2 = 0; //X's
for(i = 0; i < rows; i++)
{
for(j = 0; j < cols; j++)
{
int count;
count = count_points(m, i, j, rows, cols); //counts points
if (m[i][j] == 'X') //if values i'm couning are X, points go to player 2
player2 += count;
else if(m[i][j] == 'O') //if O go to player 1
player1 += count;
}
}
printf("%d %d\n", player1, player2);
}
// --------------------
// --------------------
void test_problem_A()
{
char **readings = malloc((MAX_LINES * MAX_LINE_LENGTH) * sizeof(char) + 1);
int rows = strings_read(stdin, readings); //to read from console
int cols = strlen(readings[0]);
printf("%d\n%d\n", rows, cols); //just to make sure nr of rows and cols is right
char **m = ints2_new(rows, cols); //create matrix
values_to_m(m, rows, cols, readings); //put the values to matrix
points(m, rows, cols); //calculate points
ints2_printf(m, rows, cols, "%c");
}
// --------------------
// --------------------
int main(int argc, char **argv)
{
test_problem_A();
return 0;
}
My programm has to read a bunch of 'X', 'O' and '.'.
If there are 3 'X' in a row(vertical, horizontal or diagonal) player 2 gets 1 point, if the same happens to 'O', player 1 gets 1 point. '.' don't count any points.
my matrix had to have minimum 3 rows and cols and maximum 1000 rows and cols.
example:
If i put in console
XXO
OXO
OXO
player 1 and 2 each get 1 point
if i put:
XXXXXO //(int this line Player 2 get 3 points because there are 3 times 3 X in a row)
OXOXOO
OXOOXO
OXOXOO
player 1 gets 5 points
and player 2 gets 6 points
So my problema is with function "count_points" it's not counting any points, when I print "result" it always gives me 0 points.
Can't I compare 2 chars if they belong in a matrix?
Thanks
In count_points, you try to compare three values with expressions like
if (a == b == c) ...
This doesn't do what you think it does. You treat it like a comparison in mathematical notation, but C interprets it as:
if ((a == b) == c) ...
The comparison a == b yields either 0 or 1. That result is then compared with c.
You could rewrite your desired expression as
if (a == b && b == c) ...
Given that your a, b and c are compound expressions, you could write a small function for that:
static int eq3(int a, int b, int c)
{
return (a == b && b == c);
}
int count_points(char **m, int i, int j, int rows, int cols)
{
int result = 0;
if (i < rows-2) {
if (eq3(m[i][j], m[i+1][j], m[i+2][j]))
result++;
if (j < cols - 2) {
if (eq3(m[i][j], m[i][j+1], m[i][j+2]))
result++;
if (eq3(m[i][j], m[i+1][j+1], m[i+2][j+2]))
result++;
}
if (j > 1) {
if (eq3(m[i][j], m[i+1][j-1], m[i+2][j-2]))
result++;
}
} else {
if (j < cols-2) {
if (eq3(m[i][j], m[i][j+1], m[i][j+2]))
result++;
}
}
return result;
}
As for the allocation of your matrix, see alk's answer. Your method of allocation - one char ** for the rows and then string duplication for the row data, could leave you with a ragged array and you may not safely access m[j + 1][i] for some cases where i is a valid index for row j, but not for row j + 1.
For starters, here you want to allocate pointers to char:
char **readings = malloc((MAX_LINES * MAX_LINE_LENGTH) * sizeof(char) + 1);
So do so:
char **readings = malloc((MAX_LINES * MAX_LINE_LENGTH) * sizeof(char*) + 1);
or even better:
char **readings = malloc((MAX_LINES * MAX_LINE_LENGTH) * sizeof *readings + 1);

Resources