Task with matrix and diagonals in c - c

I have a matrix with n*n dimensions. For given integer k I have to print elements from diagonals.
From picture: for k=0, it has to print a vector: 1,12,23,34.
How do i do this?

A straightforward approach can look the following way
#include <stdio.h>
#define N 4
int main(void)
{
int a[N][N] =
{
{ 1, 2, 3, 4 },
{ 11, 12, 13, 14 },
{ 21, 22, 23, 24 },
{ 31, 32, 33, 34 }
};
int k;
printf( "Select a diagonal (%d, %d): ", -N, N );
scanf( "%d", &k );
if ( k < 0 )
{
for ( int i = -k, j = 0; i < N; i++, j++ )
{
printf( "%d ", a[i][j] );
}
}
else
{
for ( int i = 0, j = k; j < N; i++, j++ )
{
printf( "%d ", a[i][j] );
}
}
putchar( '\n' );
return 0;
}
The program output might look like
Select a diagonal (-4, 4): 2
3 14
or
Select a diagonal (-4, 4): -2
21 32
Or instead of the if-else statement with separate loops you can use one loop as for example
int i = k < 0 ? -k : 0;
int j = k > 0 ? k : 0;
for ( ; i < N && j < N; i++, j++ )
{
printf( "%d ", a[i][j] );
}
putchar( '\n' );

pseudo code:
function(martrix, k){
rowmax = matrix.length;
colmax = matrix[0].length;
output = []
for i = 0 to max(rowmax, colmax):
if k > 0 : x = i + k
if k < 0 : y = i + k
if(x < rowmax and y < colmax):
output.append(matrix[x][y])
}

Related

reverse array in range in C

I have to solve it in C language. I have arrays with n integers. L and U are lower and upper bound. I have to reverse numbers in array which is in [L,U]. I tried it by this way, but in some cases the answer is wrong. What mist be changed in the code? Or is there any other logic to complete the task?
#include <stdio.h>
int main() {
int x, arr[100], n, l, u, a, temp, temp1;
scanf("%d%d%d", &n, &l, &u);
for (int i = 0; i < n; i++) {
scanf("%d", &x); // read elements of an array
arr[i] = x;
}
a = n / 2;
for (int i = 0; i < a; i++) {
for (int j = a; j < n; j++) {
if (arr[i] >= l && arr[i] <= u) {
if (arr[j] >=l && arr[j] < u) {
temp = arr[j];
temp1 = arr[i];
arr[i] = temp;
arr[j] = temp1;
}
}
}
}
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
}
sample input:
10(number of integers) -7(lower bound) 5(upper bound)
-10 -9 5 -2 -3 7 10 6 -8 -5
sample output:
-10 -9 -5 -3 -2 7 10 6 -8 5
my output:
-10 -9 -5 -2 -3 7 10 6 -8 5
There is an O(N) solution that does not require nesting of loops.
First, with the code as you as you have it, declare an additional array and some other helper variables that keeps track of what indices need to be swapped.
int left, right;
int swaplist[100] = {0};
int swapcount = 0;
Your can keep your initial intake loop exactly as you have it, but amended to append the index of the newly scanned value to the swaplist array if the value is between the lower and upper bounds.
for (int i = 0; i < n; i++) {
scanf("%d", &x); // read elements of an array
arr[i] = x;
if ((x >= l) && (x <= u)) {
swaplist[swapcount++] = i;
}
}
Then a single loop to iterate over "swaplist" and do the swaps against the original array.
left = 0;
right = swapcount-1;
while (left < right) {
int leftindex = table[left];
int rightindex = table[right];
int tmp = arr[leftindex];
arr[leftindex] = arr[rightindex];
arr[rightindex] = tmp;
left++; right--;
}
You made a valiant attempt. Your nested for() loops are appropriate for some kinds of sorting algorithms, but not for what seems to be the purpose of this task.
From the sample input and desired output, you really want to establish a 'bracket' at either end of the array, then shift both toward the centre, swapping elements whose value happens to satisfy low <= n <= high value. (In this case, -7 <= n <= 5).
Here's a solution:
#include <stdio.h>
int swap( int arr[], size_t l, size_t r ) { // conventional swap algorithm
int t = arr[l];
arr[l] = arr[r];
arr[r] = t;
return 1;
}
int main() {
int arr[] = { -10, -9, 5, -2, -3, 7, 10, 6, -8, -5, }; // your data
size_t i, sz = sizeof arr/sizeof arr[0];
for( i = 0; i < sz; i++ ) // showing original version
printf( "%d ", arr[i] );
putchar( '\n' );
#define inRange( x ) ( -7 <= arr[x] && arr[x] <= 5 ) // a good time for a macro
size_t L = 0, R = sz - 1; // 'L'eft and 'R'ight "brackets"
do {
while( L < R && !inRange( L ) ) L++; // scan from left to find a target
while( L < R && !inRange( R ) ) R--; // scan from right to find a target
} while( L < R && swap( arr, L, R ) && (L+=1) > 0 && (R-=1) > 0 );
for( i = 0; i < sz; i++ ) // showing results
printf( "%d ", arr[i] );
putchar( '\n' );
return 0;
}
-10 -9 5 -2 -3 7 10 6 -8 -5
-10 -9 -5 -3 -2 7 10 6 -8 5
If I have understood the assignment correctly you need to reverse elements of an array that satisfy some condition.
If so then these nested for loops
for (int i = 0; i < a; i++) {
for (int j = a; j < n; j++) {
if (arr[i] >= l && arr[i] <= u) {
if (arr[j] >=l && arr[j] < u) {
temp = arr[j];
temp1 = arr[i];
arr[i] = temp;
arr[j] = temp1;
}
}
}
}
do not make sense.
It is enough to use only one for loop as shown in the demonstration program below.
#include <stdio.h>
int main( void )
{
int a[] = { 1, 10, 2, 3, 20, 4, 30, 5, 40, 6, 7, 50, 9 };
const size_t N = sizeof( a ) / sizeof( *a );
for (size_t i = 0; i < N; i++)
{
printf( "%d ", a[i] );
}
putchar( '\n' );
int l = 10, u = 50;
for (size_t i = 0, j = N; i < j; i++ )
{
while (i < j && !( l <= a[i] && a[i] <= u )) ++i;
if (i < j)
{
while (i < --j && !( l <= a[j] && a[j] <= u ));
if (i < j)
{
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
}
}
for (size_t i = 0; i < N; i++)
{
printf( "%d ", a[i] );
}
putchar( '\n' );
}
The program output is
1 10 2 3 20 4 30 5 40 6 7 50 9
1 50 2 3 40 4 30 5 20 6 7 10 9
You could write a separate function as for example
#include <stdio.h>
void reverse_in_range( int a[], size_t n, int low, int upper )
{
for (size_t i = 0, j = n; i < j; )
{
while (i < j && !( low <= a[i] && a[i] <= upper )) ++i;
if (i < j)
{
while (i < --j && !( low <= a[j] && a[j] <= upper ));
if (i < j)
{
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
++i;
}
}
}
}
int main( void )
{
int a[] = { 1, 10, 2, 3, 20, 4, 30, 5, 40, 6, 7, 50, 9 };
const size_t N = sizeof( a ) / sizeof( *a );
for (size_t i = 0; i < N; i++)
{
printf( "%d ", a[i] );
}
putchar( '\n' );
reverse_in_range( a, N, 10,50 );
for (size_t i = 0; i < N; i++)
{
printf( "%d ", a[i] );
}
putchar( '\n' );
}
Thanks for everyone help. I read all of them, but I found another way to solve this problem. I will write it just in case. (some variable names are random, so in case of questions, comment).
#include <stdio.h>
int main() {
int x, main[100], n, l, u, a = 0, arr[100], temp, m = 0,f=0,c,d;
scanf("%d%d%d", &n, &l, &u);
for (int i = 0; i < n; i++) {
scanf("%d", &x); // read elements of an array
main[i] = x;
if (x >= l && x <= u) {
a++; //check if element is in range [l,u] and increasing a. later "a" will be used a length of the array "arr". this array cootains elements, which in in [u,l].
}
}
//add [u,l] elements in new array "arr"
for (int i = 0; i < n; i++) {
if (main[i] >= l && main[i] <= u) {
arr[m] = main[i];
m++; //index counter of "arr",
}
}
d=0;
for(int i=0;i<n;i++){
if(main[i]==arr[d]){
c=arr[a-d-1];
main[i]=c;
d++;
}
}
for(int i=0;i<n;i++){
printf("%d ",main[i]);
}
}
My best guess is that scanf is very annoying, on top of that, your format is ambiguous.
How will %d%d%d read 1234? Will it give you 12 3 and 4? 1 23 and 4? ...
try to do
scanf("%d %d %d" ...); // or
scanf("%d, %d, %d" ...);
something like that. Note that scanf is not recommended to be used, getc is a neat alternative, though also annoying when you want to read numbers with more than one digit, but you could create a function read_number, which, based on getc, will read a number as a string and return the int value with stoi.

How to format a matrix in c with specific additional symbols?

I want to make a function that formats a matrix that's passed like this:
1 2 3 6
4 5 6 15
7 8 9 24
12 15 18 45
Into a matrix like this:
1 2 3 | 6
4 5 6 | 15
7 8 9 | 24
=============
12 15 18 | 45
I somewhat got the part with vertical bars, but I have no idea how to do the equals part, here's my take on vertical bar:
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
if (j == n - 2)
printf("%d | ", mat[i][j]);
else if (j == n - 1)
printf("%d\n", mat[i][j]);
else if (i == n - 1)
printf("%d ", mat[i][j]);
else printf("%d ", mat[i][j]);
Printing === before the last row just ends up like this:
1 2 3 | 6
4 5 6 | 15
7 8 9 | 24
===
12 ===
15 18 | 45
I tried everything, but it failed miserably, any suggestions?
Here is demonstrated a straightforward approach to output your array.
#include <stdio.h>
int main( void )
{
enum { N = 4 };
int a[N][N];
for ( int i = 0; i < N; i++ )
{
a[i][N-1] = 0;
for ( int j = 0; j < N - 1; j++ )
{
a[i][N-1] += a[i][j] = i * N + j + 1;
}
}
for ( int i = 0; i < N; i++ )
{
if ( i == N - 1 )
{
for ( int j = 0; j < 3 * N + 1; j++ )
{
putchar( '=' );
}
putchar( '\n' );
}
for ( int j = 0; j < N; j++ )
{
if ( j != N - 1 )
{
printf( "%-3d", a[i][j] );
}
else
{
printf( "| %-2d", a[i][j] );
}
}
putchar( '\n' );
}
}
The program output is
1 2 3 | 6
5 6 7 | 18
9 10 11 | 30
=============
13 14 15 | 42
You can write a more general function that outputs such an array by using the approach. What you need to do so is to calculate the length of the last element of the array (in the array above the length of the last element 45 is equal to 2) and instead of such a call of printf
printf( "%-3d", a[i][j] );
to use
printf( "%-*d", len + 1, a[i][j] );
so I did a little of modifications on your code like , you outer for loop must loop extra one time to print that = symbol , that's why I used that flag called printedHorizontalLineFlag so that not to go out of array boundaries.
and here is the full edited code :
#include <stdio.h>
void func(int column, int rows, int mat[rows][column])
{
int printedHorizontalLineFlag = 0;
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < column; j++) {
if (j == column - 2) {
printf("%d\t| ", mat[i][j]);
}
else if (j == column - 1) {
printf("%d\n", mat[i][j]);
}
else if (printedHorizontalLineFlag == 1 && i == rows - 1) {
printf("%d\t", mat[i][j]);
}
else if (printedHorizontalLineFlag == 0 && i == rows - 1) {
printf("============================\n");
i--;
printedHorizontalLineFlag = 1;
break;
}
else {
printf("%d\t", mat[i][j]);
}
}
}
}
int main()
{
int mat[][4] = {{1, 2, 3, 6},
{4, 5, 6, 15},
{7, 8, 9, 24},
{12, 15, 18, 45}};
func(4, 4, mat);
return 0;
}
and here is image of the output :

New to GCC - running a array insertion gives me different output locally than on online compiler

I am going through a TuturialsPoint algorithm and trying to run the C code with GCC. Would anyone know why my local output would be different that what is produced by an online C compiler?
#include <stdio.h>
main()
{
int LA[] = {1, 3, 5, 7, 8};
int item = 10, k = 3, n = 5;
int i = 0, j = n;
printf("The original array elements are :\n");
for (i = 0; i < n; i++)
{
printf("LA[%d] = %d \n", i, LA[i]);
}
n = n + 1;
while (j >= k)
{
LA[j + 1] = LA[j];
j = j - 1;
}
LA[k] = item;
printf("The array elements after insertion :\n");
for (i = 0; i < n; i++)
{
printf("LA[%d] = %d \n", i, LA[i]);
}
}
Expected output (from online gcc compiler)
The original array elements are :
LA[0] = 1
LA[1] = 3
LA[2] = 5
LA[3] = 7
LA[4] = 8
The array elements after insertion :
LA[0] = 1
LA[1] = 3
LA[2] = 5
LA[3] = 10
LA[4] = 7
LA[5] = 8
My local output:
The original array elements are :
LA[0] = 1
LA[1] = 3
LA[2] = 5
LA[3] = 7
LA[4] = 8
The array elements after insertion :
LA[0] = 1
LA[1] = 3
LA[2] = 5
LA[3] = 7
LA[4] = 8
LA[5] = 6
I am using gcc version 8.2.0 (MinGW.org GCC-8.2.0-5)
You defined an array of exactly 5 elements.
int LA[] = {1, 3, 5, 7, 8};
So the valid range of indices to access elements of the array is [0, 5).
This array may not be enlarged. So using an index equal to or greater than 5 results in access and overwriting the memory beyond the array.
You need initially to define the array with the number of elements that allows to insert new elements apart from the 5 explicitly initialized elements.
What you mean is something like the following
#include <stdio.h>
int main(void)
{
enum { N = 10 };
int a[N] = { 1, 3, 5, 7, 8 };
size_t n = 0;
while ( a[n] != 0 ) ++n;
printf( "The original array elements are :" );
for ( size_t i = 0; i < n; i++ ) printf( "%d ", a[i] );
putchar( '\n' );
int item = 10;
size_t pos = 3;
size_t j = n;
if ( pos < j )
{
for ( ; j != pos; j-- )
{
a[j] = a[j-1];
}
}
a[j] = item;
++n;
printf( "The array elements after insertion : " );
for ( size_t i = 0; i < n; i++ ) printf( "%d ", a[i] );
putchar( '\n' );
return 0;
}
The program output is
The original array elements are :1 3 5 7 8
The array elements after insertion : 1 3 5 10 7 8
Note: This code snippet
if ( pos < j )
{
for ( ; j != pos; j-- )
{
a[j] = a[j-1];
}
}
can be substituted for this loop
for ( ; pos < j; j-- )
{
a[j] = a[j-1];
}

Moving elements in 2d array for c

So I have 2d array filled with random numbers .For example:
#define d 4
int main(void)
{
int a[d][d];
int primary[d], secondary[d];
size_t i, j;
srand(time(NULL));
/* fill array with random numbers */
for (i = 0; i < d; i++)
for (j = 0; j < d; j++)
a[i][j] = rand() % 100;
/* save diagonals */
for (i = 0; i < d; i++)
{
primary[i] = a[i][i];
secondary[i] = a[d - (i + 1)][i];
How to mirror horizontally diagonals?
For example:
1 0 0 2
0 3 4 0
0 5 6 0
7 0 0 8
8 0 0 7
0 6 5 0
0 4 3 0
2 0 0 1
Task is to print main matrix and then print matrix with mirrored diagonals however i got no ideas how cycle for this should look like.
I thought about cycle for rotating matrix for 180 degrees however I will loose the positions of elements that are not included to the diagonals.
Or can i save diagonal and then reverse it somehow.
Here is code for matrix and diagonal what should i do now.
Hope for your help.
One of approaches is the following
#include <stdio.h>
#define N 4
int main(void)
{
int a[N][N] =
{
{ 1, 0, 0, 2 },
{ 0, 3, 4, 0 },
{ 0, 5, 6, 0 },
{ 7, 0, 0, 8 }
};
for ( size_t i = 0; i < N; i++ )
{
for ( size_t j = 0; j < N; j++ ) printf( "%d ", a[i][j] );
printf( "\n" );
}
printf( "\n" );
for ( size_t i = 0; i < N * N / 2; i++ )
{
int tmp = a[i / N][i % N];
a[i / N][i % N] = a[(N * N - i - 1) / N][(N * N - i - 1) % N];
a[(N * N - i - 1) / N][(N * N - i - 1) % N] = tmp;
}
for ( size_t i = 0; i < N; i++ )
{
for ( size_t j = 0; j < N; j++ ) printf( "%d ", a[i][j] );
printf( "\n" );
}
printf( "\n" );
return 0;
}
The program output is
1 0 0 2
0 3 4 0
0 5 6 0
7 0 0 8
8 0 0 7
0 6 5 0
0 4 3 0
2 0 0 1
The same can be written using pointers. For example
#include <stdio.h>
#define N 4
int main(void)
{
int a[N][N] =
{
{ 1, 0, 0, 2 },
{ 0, 3, 4, 0 },
{ 0, 5, 6, 0 },
{ 7, 0, 0, 8 }
};
for ( size_t i = 0; i < N; i++ )
{
for ( size_t j = 0; j < N; j++ ) printf( "%d ", a[i][j] );
printf( "\n" );
}
printf( "\n" );
for ( int *first = ( int * )a, *last = ( int * )a + N * N;
first < last;
++first, --last )
{
int tmp = first[0];
first[0] = last[-1];
last[-1] = tmp;
}
for ( size_t i = 0; i < N; i++ )
{
for ( size_t j = 0; j < N; j++ ) printf( "%d ", a[i][j] );
printf( "\n" );
}
printf( "\n" );
return 0;
}

Printing consecutive entries as pairs from an array

I have an array 'a' inserted by the user as:
printf("insert N");
scanf ("%d", &n);
printf ("insert group of numbers");
for(i=0; i<n; i++){
scanf("%d", &a[i]);
}
Then, from the original array, I have to make a sequence which will have all the entries of the original array but if an entry is coming multiple times consecutively, then instead of writing that number multiple times, only two numbers should be added to the sequence: first denoting the repeated number and the second denoting its frequency. Example:
Array : 1,3,4,1,1,1,1,6,7,1,1,1,1,1,1,9,3,2,5,6,1,2,1,1,1,1,1.
Sequence: 1,3,4,1,4,6,7,1,6,9,3,2,5,6,1,2,1,5
The first 3 numbers are written down as they are. Then '1' comes consecutively 4 times so we append 1,4 to the sequence and so on.
Actually i m confused how i can make i and j are on the same steps,
as far as i know i and j start from 0 then 1,2,3,4
but how can I make them start each in the same step so if a[i(that is 3 in the step)] = 10
so a[j( on step 3) is 10 too?
Thanks for the time! I appreciate!
Following code will do the job.
#include<stdio.h>
#include<stdlib.h>
void main()
{
int i,x,j=0,n,*a,*b;
printf("insert N");
scanf ("%d", &n);
a=(int *)malloc(n*sizeof(int));
b=(int *)malloc(n*sizeof(int));
printf ("insert group of numbers");
for(i=0; i<n; i++)
scanf("%d", &a[i]);
for( i=0;i<n;++i)
{
x=0;
while((i+1)<n&&a[i]==a[i+1])
{
++x;
++i;
}
if(x>1)
{
b[j++]=a[i];
b[j++]=x+1;
}
else b[j++]=a[i];
}
for(i=0;i<j;++i)
printf("%d ",b[i]);
}
Please check whether this code will help or not, insted of arr_1 elemets you could use the scanf and load the variables
#include<stdio.h> int main() {
int arr_1[]={1,3,4,1,1,1,1,6,7,1,1,1,1,1,1,9,3,2,5,6,1,2,1,1,1,1,1};
int arr_2[27];
int arr_len;
int i,j,cntr=0;
int flag = 0;
arr_len=sizeof(arr_1)/sizeof(int);
for(i=0,j=0;i<arr_len;i++)
{
if(arr_1[i] == arr_1[i+1])
{
if(flag == 0)
{
arr_2[j] = arr_1[i];
j++;
}
flag = 1;
cntr++;
}
else
{
if(cntr > 0)
{
arr_2[j] = cntr+1;
cntr=0;
flag = 0;
}
else
{
arr_2[j]=arr_1[i];
}
j++;
}
}
for(i=0;i<arr_len;i++)
printf("%d ",arr_1[i]);
printf("\n");
for(i=0;i<j;i++)
printf("%d ",arr_2[i]);
getch(); }
int count=0, last=0, j=0, n, i;
printf("insert N");
scanf ("%d", &n);
int b[n];
printf ("insert group of numbers");
for(i=0; i<n; i++){
scanf("%d", &a[i]);
if(a[i] == last){
count++;
}
else {
b[j] = last;
j++;
if(count != 0){
b[j] = count + 1;
j++;
count = 0;
}
last = a[i];
}
}
Rather than doing post processing as a few others have suggested you can process the input as it is received.
The if statement increments the count when a duplicate is encountered.
The else statement sets the second array to the last value (not current value) when the current value is different. If the last value was a duplicate, it adds the number of duplicates in the next if statement. After that, it updates the last variable.
Here is a demonstrative program that is based on using Variable Length Arrays (VLA). If you want you can change it such a way that instead of VLA(s) it used either arrays of fixed sizes or dynamically allocated arrays.
#include <stdio.h>
int main( void )
{
while ( 1 )
{
printf( "\nEnter array size: " );
size_t n = 0;
scanf( "%zu", &n );
if ( !n ) break;
int a[n];
printf( "Enter %zu elements of the array: ", n );
for ( size_t i = 0; i < n; i++ ) scanf( "%d", &a[i] );
printf( "\na[%zu] = { ", n );
for ( size_t i = 0; i < n; i++ ) printf( "%d, ", a[i] );
printf( "}\n" );
size_t m = 0;
size_t count;
for ( size_t i = 0; i < n; i += count )
{
count = 0;
while ( ++count + i < n && a[count + i] == a[i] );
m += count > 1 ? 2 : 1;
}
int b[m];
for ( size_t i = 0, j = 0; i < n; i += count )
{
count = 0;
while ( ++count + i < n && a[count + i] == a[i] );
b[j++] = a[i];
if ( count > 1 ) b[j++] = count;
}
printf( "b[%zu] = { ", m );
for ( size_t i = 0; i < m; i++ ) printf( "%d, ", b[i] );
printf( "}\n" );
}
}
The program might have the following output
Enter array size: 27
Enter 27 elements of the array: 1 3 4 1 1 1 1 6 7 1 1 1 1 1 1 9 3 2 5 6 1 2 1 1 1 1 1
a[27] = { 1, 3, 4, 1, 1, 1, 1, 6, 7, 1, 1, 1, 1, 1, 1, 9, 3, 2, 5, 6, 1, 2, 1, 1, 1, 1, 1, }
b[18] = { 1, 3, 4, 1, 4, 6, 7, 1, 6, 9, 3, 2, 5, 6, 1, 2, 1, 5, }
Enter array size: 6
Enter 6 elements of the array: 1 1 1 1 1 2
a[6] = { 1, 1, 1, 1, 1, 2, }
b[3] = { 1, 5, 2, }
Enter array size: 0

Resources