Maximum hourglass sum possible in a 6*6 array - c

There is a question on 2D array which says
Given a 6*6 matrix we have to print the largest (maximum) hourglass sum found in the matrix.
An hourglass is described as:
a b c
d
e f g
Sample Input
1 1 1 0 0 0
0 1 0 0 0 0
1 1 1 0 0 0
0 0 2 4 4 0
0 0 0 2 0 0
0 0 1 2 4 0
Sample Output
19
Explanation
The sample matrix contains the following hourglasses:
1 1 1 1 1 0 1 0 0 0 0 0
1 0 0 0
1 1 1 1 1 0 1 0 0 0 0 0
0 1 0 1 0 0 0 0 0 0 0 0
1 1 0 0
0 0 2 0 2 4 2 4 4 4 4 0
1 1 1 1 1 0 1 0 0 0 0 0
0 2 4 4
0 0 0 0 0 2 0 2 0 2 0 0
0 0 2 0 2 4 2 4 4 4 4 0
0 0 2 0
0 0 1 0 1 2 1 2 4 2 4 0
The hourglass with maximum sum (19) is
2 4 4
2
1 2 4
I have written a program where I have made a function for calculating the sum of hourglass. Now I have made a loop that calls this function for every four hourglass possible for a row. And for every four rows that can make a hourglass.
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <limits.h>
#include <stdbool.h>
int sum(int a[6][6],int i,int j)
{
int n=i+3;
int m=j+3;
int sum=0;
for(i;i<n;i++)
{
for(j;j<m;j++)
{
if(i==n-2)
{
sum += a[i][j+1];
break;
}
else
sum += a[i][j];
}
}
// printf("%d\t",sum);
return sum;
}
int main(){
int arr[6][6];
int i,j,n,k;
int max=0;
for(int arr_i = 0; arr_i < 6; arr_i++){
for(int arr_j = 0; arr_j < 6; arr_j++){
scanf("%d",&arr[arr_i][arr_j]);
}
}
for(int i=0;i<4;i++)
{
k=0;
while(k<4)
{
n=sum(arr,i,k);
// printf("%d\t",n);
k++;
if(n>max)
max=n;
}
}
printf("%d",max);
return 0;
}
Can anyone tell me where I am going wrong, or is this method not correct for doing this problem?
My program prints 10 as output.

The error is probably in your sum function. The way you did it is a bit of an overkill, it'd be much simpler (and readable!) for you to do sth like this:
#define GRID_SIZE (6)
int sum(int a[GRID_SIZE][GRID_SIZE], int i, int j)
{ // Define an hourglass by the index i,j of its central element
int sum = a[j-1][i-1] + a[j-1][i] + a[j-1][i+1] +
a[j][i] +
a[j+1][i-1] + a[j+1][i] + a[j+1][i+1];
return sum;
}
Then just be sure you iterate with sane values (in [1, len-2]):
for (int i = 1; i < (GRID_SIZE-1); i++)
{
for (int j = 1; j < (GRID_SIZE-1); j++)
{
n = sum(arr, i, j);
if (n > max)
max = n;
}
}
Edit: Check that it works here: http://www.cpp.sh/46jhy
Thanks, that was light fun :-).
PS: Make sure you check some coding standards document, it'll make your life a lot easier in the long run, just search for "C code format standard" and get used to trying to work with one you like. Unless you do something new and on your own, you will probably have to follow a standard and maybe not even have a say in which one, so get familiar with general rules and used to following one, whichever you like.

Here's some overkill — four different ways to write the 'hourglass sum' function. For reasons outlined in user3629249's comment, I've renamed the functions to hourglass_N (for N in 1..4). Of these variants, hourglass_1() is pretty neat for this particular shape, but hourglass_2() is more readily adaptable to other shapes.
The test code correctly handles matrices with negative maximum sums.
#include <assert.h>
#include <stdio.h>
enum { ARR_SIZE = 6 };
static int hourglass_1(int a[ARR_SIZE][ARR_SIZE], int i, int j)
{
assert(i >= 0 && i < ARR_SIZE - 2 && j >= 0 && j < ARR_SIZE - 2);
int sum = a[i+0][j+0] + a[i+0][j+1] + a[i+0][j+2]
+ a[i+1][j+1] +
a[i+2][j+0] + a[i+2][j+1] + a[i+2][j+2];
return sum;
}
static int hourglass_2(int a[ARR_SIZE][ARR_SIZE], int i, int j)
{
assert(i >= 0 && i < ARR_SIZE - 2 && j >= 0 && j < ARR_SIZE - 2);
static const int rows[] = { 0, 0, 0, 1, 2, 2, 2 };
static const int cols[] = { 0, 1, 2, 1, 0, 1, 2 };
enum { HG_SIZE = sizeof(rows) / sizeof(rows[0]) };
int sum = 0;
for (int k = 0; k < HG_SIZE; k++)
sum += a[rows[k]+i][cols[k]+j];
return sum;
}
static int hourglass_3(int a[ARR_SIZE][ARR_SIZE], int i, int j)
{
assert(i >= 0 && i < ARR_SIZE - 2 && j >= 0 && j < ARR_SIZE - 2);
int sum = 0;
for (int i1 = 0; i1 < 3; i1++)
{
for (int j1 = 0; j1 < 3; j1++)
{
if (i1 == 1)
{
sum += a[i + i1][j + j1 + 1];
break;
}
else
sum += a[i + i1][j + j1];
}
}
return sum;
}
static int hourglass_4(int a[ARR_SIZE][ARR_SIZE], int i, int j)
{
assert(i >= 0 && i < ARR_SIZE - 2 && j >= 0 && j < ARR_SIZE - 2);
int n = i + 3;
int m = j + 3;
int sum = 0;
for (int i1 = i; i1 < n; i1++)
{
for (int j1 = j; j1 < m; j1++)
{
if (i1 == n - 2)
{
sum += a[i1][j1 + 1];
break;
}
else
sum += a[i1][j1];
}
}
return sum;
}
typedef int (*HourGlass)(int arr[ARR_SIZE][ARR_SIZE], int i, int j);
static void test_function(int arr[ARR_SIZE][ARR_SIZE], const char *tag, HourGlass function)
{
int max_sum = 0;
int max_row = 0;
int max_col = 0;
for (int i = 0; i < (ARR_SIZE-2); i++)
{
for (int j = 0; j < (ARR_SIZE-2); j++)
{
int n = (*function)(arr, i, j);
if (n > max_sum || (i == 0 && j == 0))
{
max_sum = n;
max_row = i;
max_col = j;
}
}
}
printf("%s: %3d at (r=%d,c=%d)\n", tag, max_sum, max_row, max_col);
}
int main(void)
{
int arr[ARR_SIZE][ARR_SIZE];
for (int i = 0; i < ARR_SIZE; i++)
{
for (int j = 0; j < ARR_SIZE; j++)
{
if (scanf("%d", &arr[i][j]) != 1)
{
fprintf(stderr, "Failed to read integer (for row %d, col %d)\n", i, j);
return 1;
}
}
}
test_function(arr, "hourglass_1", hourglass_1);
test_function(arr, "hourglass_2", hourglass_2);
test_function(arr, "hourglass_3", hourglass_3);
test_function(arr, "hourglass_4", hourglass_4);
return 0;
}
For various different data sets, the code produces the correct answer.
Set 1:
1 1 1 0 0 0
0 1 0 0 0 0
1 1 1 0 0 0
0 0 2 4 4 0
0 0 0 2 0 0
0 0 1 2 4 0
hourglass_1: 19 at (r=3,c=2)
hourglass_2: 19 at (r=3,c=2)
hourglass_3: 19 at (r=3,c=2)
hourglass_4: 19 at (r=3,c=2)
Set 2:
-1 -1 -1 +0 +0 +0
+0 -1 +0 +0 +0 +0
+1 -1 +1 +0 +0 +0
+0 +0 -2 +4 -4 +0
+0 +0 +0 +2 +0 +0
+0 +0 +1 +2 -4 +0
hourglass_1: 7 at (r=2,c=2)
hourglass_2: 7 at (r=2,c=2)
hourglass_3: 7 at (r=2,c=2)
hourglass_4: 7 at (r=2,c=2)
Set 3:
-7 -2 -9 -7 -4 -4
-6 0 -7 -5 -8 -1
-9 -1 -2 -1 -3 -3
-9 -1 -3 -6 -2 -9
-8 -1 -3 -7 -7 -9
0 -3 -5 -2 -2 -5
hourglass_1: -18 at (r=2,c=1)
hourglass_2: -18 at (r=2,c=1)
hourglass_3: -18 at (r=2,c=1)
hourglass_4: -18 at (r=2,c=1)
Set 4:
-7 -7 0 -7 -8 -7
-9 -1 -5 -6 -7 -8
-2 0 -7 -7 -6 -3
-5 -3 -1 -6 -3 -1
-3 -5 0 -5 0 -7
-1 -2 -8 -8 -9 -9
hourglass_1: -20 at (r=2,c=0)
hourglass_2: -20 at (r=2,c=0)
hourglass_3: -20 at (r=2,c=0)
hourglass_4: -20 at (r=2,c=0)

#include <stdio.h>
int main() {
int numbers[6][6];
for (int i = 0; i < 6; i++){
for (int j = 0; j < 6; j++){
scanf("%d",&numbers[i][j]);
}
}
int currentHourGlass;
int largestSum = -999;
for (int i = 1; i < 5; i++){
for (int j = 1; j < 5; j++){
currentHourGlass = 0;
currentHourGlass += numbers[i-1][j-1];
currentHourGlass += numbers[i-1][j];
currentHourGlass += numbers[i-1][j+1];
currentHourGlass += numbers[i][j];
currentHourGlass += numbers[i+1][j-1];
currentHourGlass += numbers[i+1][j];
currentHourGlass += numbers[i+1][j+1];
if (currentHourGlass > largestSum)
{
largestSum = currentHourGlass;
}
}
}
printf("%d", largestSum);
}

Related

check column and row in sodoku- C programming

I'm trying to check if number (from 1 to n)
appears more than once in
row or column in sodoku board
I wrote a code that goes over each row and column and checks the numbers between 1 to n (every time checking number at a time after finishing with row 0 (for example) goes to the next one (if it wasn't true in the row before)
my code is working just if there is a number
appearing more than once
in row 0 (if there is in other rows it returns nothing!)
and for the column it doesn't return any thing
this is a matrix that I use for the test (matrix with solution and I change numbers in rows or columns):
7 1 0 0 0 0 6 0 9
2 0 0 0 0 3 0 0 0
0 0 0 1 5 0 0 0 8
0 0 7 0 0 0 0 9 0
0 0 6 0 0 0 7 0 0
0 2 0 0 0 0 4 0 0
1 0 0 0 2 9 0 0 0
0 0 0 3 0 0 0 0 4
9 0 5 0 0 0 0 8 6
and this is my code:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAX4USED 10
int n; //size of the sodoku board
bool CheckAppearingInRow(int matrix [n][n]) {
int used[MAX4USED] = {0};
int index = 1;
int row = 0;
while (index <= n) {
for(int j = 0; j < n; j++) {
if(matrix[row][j] == index ) {
used[index] +=1;
}
}
for(int i = 0; i <= n ; i++) {
if (used[i] > 1) {
return true;
}
used[i] = 0;
}
index += 1;
}
row += 1;
while (row < n) {
CheckAppearingInRow(matrix);
}
return false;
}
bool CheckAppearingInColumn(int matrix [n][n]) {
int used[MAX4USED] = {0};
int index = 1;
int col = 0;
while (index <= n) {
for(int i = 0; i < n; i++) {
if(matrix[i][col] == index ) {
used[index] +=1;
}
}
for(int i = 0; i <= n ; i++) {
if (used[i] > 1) {
return true;
}
used[i] = 0;
}
index += 1;
}
col += 1;
while(col < n){
CheckAppearingInColumn(matrix);
}
return false;
}
int main() {
printf("Please enter your sodoku dimension:");
scanf("%d", &n);
int a[n][n];
printf("\nInsert your sodoku board\n");
printf("Instruction: Enter 0 for blank\n");
for(int i=0; i<n; i++){
for(int j=0; j<n; j++) {
scanf("%d", &a[i][j]);
}
}
if (CheckAppearingInRow(a)== true || CheckAppearingInColumn(a) == true) {
printf("\nNo solution!\n");
}
return 0;
}

Unexpected output in 2D array [duplicate]

This question already has answers here:
Maximum hourglass sum possible in a 6*6 array
(3 answers)
Closed 3 years ago.
Given a 6x6 2D Array, :
1 1 1 0 0 0
0 1 0 0 0 0
1 1 1 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
We define an hourglass in to be a subset of values with indices falling in this pattern in this graphical representation:
a b c
d
e f g
There are 16 hourglasses in arr, and an hourglass sum is the sum of an hourglass' values. Calculate the hourglass sum for every hourglass in arr, then print the maximum hourglass sum.
For example, given the 2D array:
-9 -9 -9 1 1 1
0 -9 0 4 3 2
-9 -9 -9 1 2 3
0 0 8 6 6 0
0 0 0 -2 0 0
0 0 1 2 4 0
We calculate the following 16 hourglass values:
-63, -34, -9, 12,
-10, 0, 28, 23,
-27, -11, -2, 10,
9, 17, 25, 18
This is the code I have written
#include<stdio.h>
const int M=6;
const int N=6;
int hourglassSum(int arr_rows, int arr_columns, int arr[M][N]) {
int rows,columns;
rows=arr_rows-(arr_rows/3);
columns=arr_columns-(arr_columns/3);
int a[columns-1][rows-1];
int min_r,min_c,max_r,max_c,sum;
sum=0;
for(int k=0;k<columns;k++)
{
min_c=k;
max_c=k+2;
for(int l=0;l<rows;l++)
{
min_r=l;
max_r=l+2;
sum=0;
for(int i=min_c;i<=max_c;i++)
{
if(max_c>=arr_columns)
break;
for(int j=min_r;j<=max_r;j++)
{
if(max_r>=arr_rows)
break;
if(i!=min_c && i!=max_c)
{
int no=j+1;
sum +=arr[i][no];
break;
}
sum += arr[i][j];
}
}
a[min_c][min_r]=sum;
}
}
int max=-111;
for(int b=0;b<columns;b++)
{
for(int c=0;c<rows;c++)
{
if(max<a[b][c])
max=a[b][c];
}
}
for(int i=0;i<columns;i++)
{
for(int j=0;j<rows;j++)
printf("%d ",a[i][j]);
printf("\n");
}
return max;
}
int main()
{
int arr[6][6];
int arr_rows=6;
int arr_columns=6;
for(int i=0;i<arr_columns;i++)
for(int j=0;j<arr_rows;j++)
scanf("%d",&arr[i][j]);
int result=hourglassSum(arr_rows,arr_columns,arr);
printf("\n%d",result);
}
and I gave input as
-9 -9 -9 1 1 1
0 -9 0 4 3 2
-9 -9 -9 1 2 3
0 0 8 6 6 0
0 0 0 -2 0 0
0 0 1 2 4 0
and expected output is
-63 -34 -9 12
-10 0 28 23
-27 -11 -2 10
9 17 25 18
but my output is
-63 -34 -9 -10
-10 0 28 -27
-27 -11 -2 9
9 17 25 18
What's wrong?
Your calculations:
rows=arr_rows-(arr_rows/3);
columns=arr_columns-(arr_columns/3);
happen to produce the correct answer because 6 / 3 is 2, which is the correct value to subtract. If the matrix was 12x12, you'd be omitting rows and columns — you should be subtracting 2 because of the shape of the hourglass (or subtract hourglass_width - 1 and hourglass_height - 1 for the general case of a non-square hourglass).
Using int max=-111; is dangerous — again, it happens to work with the sample data, but it isn't a general solution. Use the value in a[0][0] as the initial maximum. It might be a lucky guess and actually the maximum, but it will be replaced by another larger value if there is one.
You should eliminate M and N and use:
int hourglassSum(int arr_rows, int arr_columns, int arr[arr_rows][arr_columns]) {
This would allow you to pass other sizes of array to the code.
However, the primary problem is that you make the a matrix too small.
You should be using int a[columns][rows]. (Arrays in C are normally a[rows][columns], but if you're consistent, you can reverse them and the difference doesn't matter when rows == columns anyway.) With the undersized matrix, I got the result you got; with the correctly sized matrix, I got the result expected.
#include <stdio.h>
static int hourglassSum(int arr_rows, int arr_columns, int arr[arr_rows][arr_columns])
{
int rows = arr_rows - 2;
int columns = arr_columns - 2;
int a[columns][rows];
for (int k = 0; k < columns; k++)
{
int min_c = k;
int max_c = k + 2;
for (int l = 0; l < rows; l++)
{
int min_r = l;
int max_r = l + 2;
int sum = 0;
for (int i = min_c; i <= max_c; i++)
{
if (max_c >= arr_columns)
break;
for (int j = min_r; j <= max_r; j++)
{
if (max_r >= arr_rows)
break;
if (i != min_c && i != max_c)
{
int no = j + 1;
sum += arr[i][no];
break;
}
sum += arr[i][j];
}
}
a[k][l] = sum;
}
}
int max = a[0][0];
for (int b = 0; b < columns; b++)
{
for (int c = 0; c < rows; c++)
{
if (max < a[b][c])
max = a[b][c];
}
}
for (int i = 0; i < columns; i++)
{
for (int j = 0; j < rows; j++)
printf(" %3d", a[i][j]);
printf("\n");
}
return max;
}
int main(void)
{
int arr[6][6];
int arr_rows = 6;
int arr_columns = 6;
for (int i = 0; i < arr_columns; i++)
{
for (int j = 0; j < arr_rows; j++)
{
if (scanf("%d", &arr[i][j]) != 1)
{
fprintf(stderr, "failed to read an integer\n");
return 1;
}
}
}
int result = hourglassSum(arr_rows, arr_columns, arr);
printf("\n%d\n", result);
return 0;
}
Output:
-63 -34 -9 12
-10 0 28 23
-27 -11 -2 10
9 17 25 18
28
Note that this is a more-or-less minimal fixup to the code in the question. My own code would look different in a number of respects (different variable names, more functions, etc.).
One other change (not made above): you don't actually need the array a; you can simply record the current maximum after you calculate the hourglass sum for each position.
For the alternative input:
-1 1 -1 0 0 0
0 -1 0 0 0 0
-1 -1 -1 0 0 0
0 -9 2 -4 -4 0
-7 0 0 -2 0 0
0 0 -1 -2 -4 0
I get the output:
-5 -2 -2 0
-9 -13 -6 -8
-19 -2 -7 -6
-8 -14 -15 -14
0
This produces the answer 0 which you say is expected (and I agree that 0 is what should be expected).
To output the maximum sum there is no need to create an auxiliary array. All you need is to calculate correctly the number of iterations for two nested loops.
In your function these calculations and the declaration of the array
rows=arr_rows-(arr_rows/3);
columns=arr_columns-(arr_columns/3);
int a[columns-1][rows-1];
are incorrect. For example it is unclear why the array has the number of rows equal to the value of columns - 1.
The function can be written simpler.
Here you are.
#include <stdio.h>
enum { M = 6, N = 6 };
long long int hourglassSum( int ( *a )[N], size_t m )
{
long long int max_sum = 0;
const size_t SIZE = 3;
if ( !( m < SIZE ) )
{
max_sum = ( long long int )
a[0][0] + a[0][1] + a[0][2] +
a[1][1] +
a[2][0] + a[2][1] + a[2][2];
for ( size_t i = 0; i + SIZE - 1 < m; i++ )
{
for ( size_t j = i == 0 ? 1 : 0; j + SIZE - 1 < N; j++ )
{
long long int sum = ( long long int )
a[i][j] + a[i][j+1] + a[i][j+2] +
a[i+1][j+1] +
a[i+2][j] + a[i+2][j+1] + a[i+2][j+2];
// printf( "%lld\n", sum );
if ( max_sum < sum ) max_sum = sum;
}
}
}
return max_sum;
}
int main(void)
{
int a[M][N] =
{
{ -9, -9, -9, 1, 1, 1 },
{ 0, -9, 0, 4, 3, 2 },
{ -9, -9, -9, 1, 2, 3 },
{ 0, 0, 8, 6, 6, 0 },
{ 0, 0, 0, -2, 0, 0 },
{ 0, 0, 1, 2, 4, 0 }
};
long long int sum = hourglassSum( a, M );
printf( "Hourglass Sum = %lld\n", sum );
return 0;
}
The program output is
Hourglass Sum = 28

Moving elements in 2d array

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;
}
How to change diagonals . For example :
1 0 0 0 2 2 0 0 0 1
0 3 0 4 0 0 4 0 3 0
0 0 5 0 0 to 0 0 5 0 0
0 6 0 7 0 0 7 0 6 0
8 0 0 0 9 9 0 0 0 8
Task is to print random matrix of d size then change diagonals placement using cycle and print it again.However i`m not getting how cycle should look like.
Appreciate any hints or examples.
Loop while j < d / 2 and then swap the values:
for (i = 0; i < d; i++) {
for (j = 0; j < d / 2; j++) {
int temp = a[i][j];
a[i][j] = a[i][d - j -1];
a[i][d - j -1] = temp;
}
}

Convert decimal values in 1D array to 2D array with bit values, transpose the 2D bit array and convert to 1D decimal array again

My problem is part of a larger communication algorithm I'm trying to implement. The point is to generate packets from messages, to send over the network. You fetch a batch of messages (decimal values), and form the packets from the bits from each message that are in the same column. The following figure illustrates this.
Packet formation from messages
My problem is the 'transpose' operation. How I'm trying to approach this is by transposing the bits of this 1D decimal value array of messages. Maximum decimal value of each message is 255, so 8 bits in length each.
I want to convert all decimal values to bits in a 2D array, where each column is a bit from the decimal value in that row. Finally I want to convert this 2D bit array to a 1D array with decimal values again.
Example:
Input is a decimal 1D array
decimal[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
Convert this 1D array to a 2D array representing the bits
bits[16][8] = { 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1
0 0 0 0 0 0 1 0
0 0 0 0 0 0 1 1
....
0 0 0 0 1 1 1 1 };
Transpose this bit array
bits2[8][16] = {
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1
0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1
0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1
0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 };
Convert it back to a decimal value 1D array
result[8] = { 0, 0, 0, 0, 255, 3855, 13107, 21845}
The code I have so far:
#define n 8 // COLUMNS
#define m 16 // ROWS
int data[m];
int result[n];
int i,j;
int counter = 0;
memset(data, 0, sizeof(data));
memset(result, 0, sizeof(result));
for ( i = 0; i < m; ++i) {
data[i] = counter;
++counter;
}
int a[m][n], b[n][m], x;
// Convert decimal array to 2D bit array
for(i=0; i<m; i++)
{
x = data[i];
for(j=0; j<n; j++)
{
a[i][j] = (x & 0x8000) >> 8;
x <<= 1;
}
}
// Transpose bit array
for(i=0; i<m; i++)
{
for(j=0; j<n; j++)
{
b[j][i] = a[i][j];
}
}
// Convert back to decimal
for(i=0; i<n; i++)
{
for(j=0; j<m; j++)
{
if (b[i][j] == 1) result[i] = result[i] * 2 + 1;
else if (b[i][j] == 0) result[i] *= 2;
}
}
I hope my explanation is clear! If not, I'll gladly explain some more. I've searched endlessly for ways to do this but I'm still not getting up with a solid solution.
PS: Apologies for the bad code formatting of the arrays, didn't find a proper way to visualize it without linking an image.
This should provide the desired output.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define n 8 // COLUMNS
#define m 16 // ROWS
int main(void)
{
int data[m];
int result[n];
int i, j;
int counter = 0;
memset(data, 0, sizeof(data));
memset(result, 0, sizeof(result));
for (i = 0; i < m; ++i) // print initial data
{
data[i] = counter;
printf("%d ", data[i]);
++counter;
}
putchar('\n');
char a[m][n], b[n][m];
int x;
// Convert decimal array to 2D bit array
for (i = 0; i < m; i++)
{
x = data[i];
for (j = n - 1; j >= 0; j--)
{
a[i][j] = x & 1;
x >>= 1;
}
}
// Transpose bit array
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
b[j][i] = a[i][j];
}
}
// Convert back to decimal
for (i = 0; i < n; i++)
{
for (j = 0; j < m; j++)
{
if (b[i][j] == 1)
result[i] = result[i] * 2 + 1;
else if (b[i][j] == 0)
result[i] *= 2;
}
}
for (i = 0; i < n; ++i) // print result
{
printf("%d ", result[i]);
}
putchar('\n');
return 0;
}
What you were doing wrong was the conversion to the 2d bit array , it was all filled with 0's.
You were doing (x&0x8000) >> 8;
0x8000 = 1000 0000 0000 0000 (grouped in nibbles to see clearly)
so (x&0x8000) will always be 0 considering that x will in your case take values <=255 .
I also changed the int arrays which were using way too much space than needed to char arrays.

Median windows in C

I wrote a code to find median filtering (median window). But, I can't make scannig to every number. What can I use instead of size in the for loops. When I use size it ensures just 5 Also, what about boundries ? What can I do for boundries ? Thank you for all appreciated answers. (I've opened new topic because users said that every topic is based on one question.If I did mistake,please delete the question, I will suffix the current question)
<size of array>
<size filter>
<data>
8
3
0 0 0 0 0 0 0 0
0 5 0 0 6 0 0 0
0 0 0 0 0 7 0 0
0 0 0 0 5 0 0 0
0 0 0 5 6 0 0 0
0 0 8 5 5 0 0 0
0 0 0 7 0 0 9 0
0 0 0 0 0 0 0 0
Output:
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 5 5 0 0 0
0 0 0 5 5 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
#include <stdio.h>
int median(int a[100],int n);
int main()
{
int a[100][100];
int temp[100];
int i,j,k,count=0;
int sizefilter;
int sizearray;
scanf("%d", &sizearray);
scanf("%d", &sizefilter);
for(i = 0; i < sizearray; i++)
for(j = 0; j < sizearray; j++)
scanf("%d", &a[i][j]);
for(k = 0; k < sizearray; k++)
for(i = 0; i < sizefilter; i++)
for(j = 0; j < sizefilter; j++)
{
temp[count] = a[i][j];
count++;
a[i][j] = median(temp, count);
}
printf("\n");
printf("\n");
for(i = 0; i < sizearray; i++)
for(j = 0; j < sizearray; j++)
{
printf("%d ", a[i][j]);
if(j == sizearray-1)
printf("\n");
}
return 0;
}
int median(int a[100],int n)
{
int i,j,t;
int result;
/* Sorting begins */
for (i = 1 ; i <= n-1 ; i++)
{ /* Trip-i begins */
for (j = 1 ; j <= n-i ; j++)
{
if (a[j] <= a[j+1])
{ /* Interchanging values */
t = a[j];
a[j] = a[j+1];
a[j+1] = t;
}
else continue ;
}
} /* sorting ends */
/* calculation of median */
if ( n % 2 == 0)
return result = (a[n/2] + a[n/2+1])/2 ;
else
return result = a[n/2 + 1];
}
There are some logical errors in your code:
When you filter, you need four nested loops: The outer two iterate over columns and rows of the matrix, the inner two iterate over columns and rows of the filter area. (That shouldn't be news to you; you have already been told that in an answer to your previous question.)
The constraints of the filter area are simple: The left and top indices must not fall below zero and the right and bottom indicies must be smaller than sizearray. If they are not, adjust them.
You need two arrays, the original array a and a second array that contains the filtered values. You cannot filter in-place, because if you look upwards and to the left, you'll see only filtered values, whereas your filter should always look at the original values.
Your wrong filtering loops apart: You never reset count, which you should reset, of course, for every median value you calculate. You also calculate the median in the inner loop, which is too often. A solution to this is to make count local to the loop that accumulates filter values and determines the median.
Your sorting has index errors. Instead of comparing i with i + 1, compare with ´i - 1. Your indices start from 1, soi - 1` will always yield a valid index.
You buble-sort the array, which is fine for small arrays, but slow in general. The <stdlib.h> has qsort, which may be useful to you for general sorting.
Your median indices are also off by one towards the right.
There are also some stylistic issues:
Please make a habit of using braces for code blocks for for, while and if. Only very trivial code blocks in the innermost scope can be written without braces. In your case, a lot has to be done "between" the loops, and having braces there makes it easy to add stuff.
Yor variable result in median is superfluous. You assign it and then immediately lose the variable itself, because you return. Just returning is enough.
Below is a version of your code that gives the desired output:
#include <stdint.h>
#include <stdio.h>
int min(int a, int b)
{
return a < b ? a : b;
}
int max(int a, int b)
{
return a > b ? a : b;
}
int median(int a[], int n)
{
int i, j;
for (i = 1 ; i < n ; i++) {
for (j = 1 ; j < n ; j++) {
if (a[j] < a[j - 1]) {
int t = a[j];
a[j] = a[j - 1];
a[j - 1] = t;
}
}
}
if (n % 2) return a[n / 2];
return (a[n / 2 - 1] + a[n / 2]) / 2 ;
}
int main()
{
int a[100][100];
int b[100][100];
int temp[100];
int i, j, ii, jj;
int sizefilter;
int sizearray;
scanf("%d", &sizearray);
scanf("%d", &sizefilter);
for(i = 0; i < sizearray; i++) {
for(j = 0; j < sizearray; j++) {
scanf("%d", &a[i][j]);
}
}
for(i = 0; i < sizearray; i++) {
for(j = 0; j < sizearray; j++) {
int imin = max(0, i - sizefilter / 2);
int imax = min(sizearray, i + sizefilter / 2 + 1);
int jmin = max(0, j - sizefilter / 2);
int jmax = min(sizearray, j + sizefilter / 2 + 1);
int count = 0;
for (ii = imin; ii < imax; ii++) {
for (jj = jmin; jj < jmax; jj++) {
temp[count] = a[ii][jj];
count++;
}
}
b[i][j] = median(temp, count);
}
}
for(i = 0; i < sizearray; i++) {
for(j = 0; j < sizearray; j++) {
printf("%3d", b[i][j]);
}
printf("\n");
}
return 0;
}

Resources