'Concentric square matrix

I have coding problem to write concentric square matrix (biggest number is in the middle) For example user needs to write an matrix For example:

                 5 5 5 5 5 
                 5 6 6 6 5
                 5 6 7 6 5     
                 5 6 6 6 5 
                 5 5 5 5 5

My program has to output "Yes" because this is, by my program's rules, a concentric square matrix.

                 5 5 5 5 5 
                 5 6 6 6 5
                 5 6 7 8 5     
                 5 6 6 6 5 
                 5 5 5 5 5

This is not a concentric square matrix because 8 is in 4th column and 3rd row.

This is my code:

#include <stdio.h>

int main() {
    
    int mat[100][100];
    int i,j;
    int n;
    scanf("%d",&n);
    printf("Unesite matricu; ");
    for(i=0;i<n;i++)
    {
        for(j=0;j<n;j++)
        {
            scanf("%d",&mat[i][j]);
        }
    }    
}

I don't know how to do the rest of it so if someone can help me, I would be happy :))

Comment::

I forgot to say that only odd numbers can be the dimension of the matrix (1,3,11,27). The only final output of the program has to be "YES (if the matrix is a concentric square matrix) or "NO" (if it's not). I know how to make a concentric square matrix when the user inputs a number (for example, 4) and the matrix has 2*n-1 dimensions. And through the loops, the program automatically makes the matrix (if you know what I mean). But for my matrix, the user has to input all the elements of the matrix and the program has to check if the matrix is concentric or not.

c


Solution 1:[1]

I created an answer using more functions than just main(). It is more verbose than what is required for your homework — it prints out the matrix it reads and diagnoses the first problem it comes across. It works with both positive and negative numbers, and with matrices with odd or even numbers of elements.

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

enum { MAT_SIZE = 100 };

static int err_error(const char *fmt, ...)
{
    va_list args;
    va_start(args, fmt);
    vfprintf(stderr, fmt, args);
    va_end(args);
    exit(EXIT_FAILURE);
}

static int err_shell(int r, int c, int a_val, int e_val)
{
    printf("Element M[%d][%d] = %d vs expected value %d\n", r, c, a_val, e_val);
    return 0;
}

static int check_shell(int shell, int n, int matrix[MAT_SIZE][MAT_SIZE])
{
    int lb = shell;
    int ub = n - shell - 1;
    int val = matrix[lb][lb];

    /* Check the horizontals */
    for (int c = lb; c <= ub; c++)
    {
        if (matrix[lb][c] != val)
            return err_shell(lb, c, matrix[lb][c], val);
        if (matrix[ub][c] != val)
            return err_shell(ub, c, matrix[ub][c], val);
    }

    /* Check the verticals */
    for (int r = lb; r <= ub; r++)
    {
        if (matrix[r][lb] != val)
            return err_shell(r, lb, matrix[r][lb], val);
        if (matrix[r][ub] != val)
            return err_shell(r, ub, matrix[r][ub], val);
    }

    return 1;
}

static int check_matrix(int n, int matrix[MAT_SIZE][MAT_SIZE])
{
    for (int i = 0; i <= n / 2; i++)
    {
        if (check_shell(i, n, matrix) == 0)
            return 0;
    }

    for (int i = 0; i < (n - 1) / 2; i++)
    {
        if (matrix[i][i] >= matrix[i+1][i+1])
        {
            printf("Shell %d has value %d but inner shell %d has value %d\n",
                   i, matrix[i][i], i+1, matrix[i+1][i+1]);
            return 0;
        }
    }
    return 1;
}

static int read_size(void)
{
    int n;
    if (scanf("%d", &n) != 1)
        err_error("failed to read an integer\n");
    if (n <= 0 || n > MAT_SIZE)
        err_error("matrix size %d is not in the range 1..%d\n", n, MAT_SIZE);
    return n;
}

static void read_matrix(int n, int matrix[n][n])
{
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            if (scanf("%d", &matrix[i][j]) != 1)
                err_error("failed to read M[%d][%d]\n", i, j);
        }
    }
}

static int max_field_width(int n, int matrix[MAT_SIZE][MAT_SIZE])
{
    int min_val = matrix[0][0];
    int max_val = matrix[0][0];
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            if (matrix[i][j] < min_val)
                min_val = matrix[i][j];
            if (matrix[i][j] > max_val)
                max_val = matrix[i][j];
        }
    }
    int fld_width = snprintf(0, 0, "%d", max_val);
    if (min_val < 0)
    {
        int min_width = snprintf(0, 0, "%d", min_val);
        if (min_width > fld_width)
            fld_width = min_width;
    }
    return fld_width;
}

static void print_matrix(const char *tag, int n, int matrix[MAT_SIZE][MAT_SIZE])
{
    printf("%s (%d):\n", tag, n);
    int w = max_field_width(n, matrix) + 1;
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            printf("%*d", w, matrix[i][j]);
        }
        putchar('\n');
    }
}

int main(void)
{
    int matrix[MAT_SIZE][MAT_SIZE];
    int n = read_size();
    read_matrix(n, matrix);
    print_matrix("Input", n, matrix);
    if (check_matrix(n, matrix))
        printf("YES: Matrix is a valid concentric matrix\n");
    else
        printf("NO: Matrix is not a valid concentric matrix\n");
    return 0;
}

One detail is that this code can be made to use a VLA (variable-length array) by simply replacing MAT_SIZE by n in each function definition and modifying main() to read:

static int check_shell(int shell, int n, int matrix[n][n]) { … }
static int check_matrix(int n, int matrix[n][n]) { … }
static void read_matrix(int n, int matrix[n][n]) { … }
static int max_field_width(int n, int matrix[n][n]) { … }
static void print_matrix(const char *tag, int n, int matrix[n][n]) { … }

int main(void)
{
    int n = read_size();
    int matrix[n][n];
    read_matrix(n, matrix);
    print_matrix("Input", n, matrix);
    if (check_matrix(n, matrix))
        printf("YES: Matrix is a valid concentric matrix\n");
    else
        printf("NO: Matrix is not a valid concentric matrix\n");
    return 0;
}

This reads the matrix size before allocating the matrix, instead of allocating a fixed size matrix first. The read_size() function enables this change — that input must be done separately from the main matrix scanning code.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Jonathan Leffler