Finding largest 2x2 "square" of values in array C - c

For my assignment I have to take in an array of values, save them to a second array and print out a "square" of the 4 highest values. This means the "square" for which the sum of its elements is the greatest in the array.
Example: Given the array 1 2 3 4
5 6 7 8
9 10 11 12
the output should be 7 8
11 12
I was originally trying to use sets of nested for loops to find and store each of the subsequent largest values into the second array, but can't seem to figure out the proper algorithm. What I have so far just gives me the same value (in this example's case, 12). Also, I have come to realize that this way won't allow me to keep the formatting the same in the second array.
What I mean is that if I'm saving the largest number found into array b[0][0], it will be in the wrong spot, and my square would be off, looking something like:
12 11
10 9
Here's what I have so far:
int main(){
int og[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}}, new[2][2]={}, rows;
int columns, i, high,j,high2,high3,high4;
high = new[i][0];
high2= high - 1;
high3= high2 - 1;
high4= high3 - 1;
rows = 3;
columns = 4;
for (i=0; i<=rows; i++){
for(j=0; j<=columns; j++){
if (high < og[j][i])
high = og[j][i];
}
}
for(i=1;i<=rows;i++){
for(j=1;j<=columns;j++){
if(high2 < og[j][i])
high2= og[j][i];
}
}
printf("max = %d, %d\n", high, high2);
//return high;
system("pause");
return 0;

The logic should go roughly as follows (I dont have a compiler atm to test it, so let me know in the comments if i made a derpy error):
int i = 0;
int j = 0;
int max = 0;
int sum = 0;
int i_saved = 0;
int j_saved = 0;
for(i = 0; i < rows - 1; i++){
for(j =0; j < columns -1; j++){
sum = og[i][j] + og[i][j+1] + og[i+1][j] + og[i+1][j+1]; //sum the square
if (sum > max){
max = sum;
i_saved = i;
j_saved = j;
}
}
}
Since OP is asking for the values used in order to save to another array, all you have to do is retrieve the values again! We have the indices saved already, so this should be relatively trivial.
int [][] arr = [2][2];
arr[0][0] = og[i_saved][j_saved];
arr[0][1] = og[i_saved][j_saved+1];
arr[1][0] = og[i_saved+1][j_saved];
arr[1][1] = og[i_saved+1][j_saved+1];
The same way we summed them, we can also use that logic pattern to extract them!

I created this solution:
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int Mat[3][4]={{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}};
int maximum = 0;
int Max_2x2[2][2] = {{1, 2},
{5, 6}};
for(int i = 0; i < 2; i++) {
for(int j = 0; j < 3; j++) {
maximum = max(Mat[i][j]+Mat[i][j+1]+Mat[i+1][j]+Mat[i+1][j+1], maximum);
if(maximum == Mat[i][j]+Mat[i][j+1]+Mat[i+1][j]+Mat[i+1][j+1]) {
Max_2x2[0][0] = Mat[i][j];
Max_2x2[0][1] = Mat[i][j+1];
Max_2x2[1][0] = Mat[i+1][j];
Max_2x2[1][1] = Mat[i+1][j+1];
}
}
}
cout << maximum << endl;
for(int i = 0; i < 2; i++) {
for(int j = 0; j < 2; j++) {
cout << Max_2x2[i][j] << " ";
}
cout << endl;
}
return 0;
}
which gives the following output:
38 // maximum solution
7 8 // output array
11 12
This is obviously not a general solution, but it works for your example.

int new[2][2]={}
I'm not sure this is valid. You might need to specify a 0 value for each cell. Even it it's not required, it's good practice.
high = new[i][0];
I don't see where i has been initialized.

Related

Counting sort does not order the last element C

I have written this code in order to implement the Counting Sort in C. However it does not seem working properly.
I create an array of 10 elements and then I apply the steps of counting sort. Basically it orders the first elements, and then as last elements it uses the last elements of the original array. I am not understanding where is the problem.
The code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
// create an array of 100 random elements
// int my_array[10];
int my_array[] = { 10, 10, 9, 9, 6, 5, 4, 3, 2, 1 };
srand(time(NULL));
int i;
int N = 10;
/* for (i = 0; i < 10; i++) {
my_array[i] = rand() % 100 + 1;
} */
// print the array
for (i = 0; i < 10; i++) {
printf("%d\n", my_array[i]);
}
// define the minimum and the maximum as the first element of the array
int min_array = my_array[0];
int max_array = my_array[0];
printf("--------------\n");
// find the minimum and the maximum of the array
for (i = 0; i < N; i++) {
if (my_array[i] < min_array) {
min_array = my_array[i];
}
else if (my_array[i] > max_array) {
max_array = my_array[i];
}
}
// check if it worked
printf("max_array %d\n", max_array);
printf("min_array %d\n", min_array);
//
int range_array;
range_array = max_array - min_array + 1;
int count_array[range_array + 1];
for (i = 0; i < range_array; i++)
count_array[i] = 0;
int j = 0;
for (int i = 0; i < 10; i++) {
count_array[my_array[i] - min_array] = count_array[my_array[i] - min_array] + 1;
}
int z = 0;
for (i = min_array; i < max_array; i++) {
for (j = 0; j < count_array[i - min_array]; j++)
my_array[z++] = i;
// z = z + 1;
}
for (i = 0; i < N; i++) {
printf("%d\n", my_array[i]);
}
}
And one possible output:
10 10 9 9 6 5 4 3 2 1
--------------
max_array 10
min_array 1
--------------
1 2 3 4 5 6 9 9 2 1
So as you can see the numbers from 1 to 9 are ordered, while the last one, 10, is not ordered, and it uses the first numbers, so 1 and 2.
When rebuilding the array, you want to include the elements with a value of max_array.
i<max_array
should be
i<=max_array
As a side note, you never use the last element of count_array, so it should be one element smaller.
int count_array[range_array + 1];
should be
int count_array[range_array];
(Spotted by #user3386109)

Storing arrays into new arrays

I am not very good with words so I included a visual sample of my code. I would appreciate the help. Thank you (To add I am also a fresh programmer trying to learn algorithms but im struggling on this one)
Is there a working way to store a 2d array into a 1D array?? I have tried to do it in this way but I'm getting garbage values instead when I print it out.
#include <stdio.h>
int main() {
int disp[4][4] = {{12, 14, 32, 9},
{19, 24, 3, 4},
{11, 26, 3, 8},
{13, 24, 7, 5}
};
int quadrant_size = 2;
int k = 0;
int flat[4] = {0};
int N = 4;
int x, y, i, j;
for (x = 0 ; x < N ; x += quadrant_size) {
for (y = 0 ; y < N ; y += quadrant_size) {
int mx = disp[x][y];
for (i = x ; i < x + quadrant_size ; i++) {
for (j = y ; j < y + quadrant_size ; j++) {
if (disp[i][j] > mx) {
mx = disp[i][j];
flat[k] = disp[i][j];
k++;
}
}
}
printf("%d ", mx);
}
printf("\n");
}
for (i = 0; i < 4; i++) {
printf("%d", flat[i]);
}
return 0;
}
Basically, the output of this program will give you a result of
24 32
26 8
I am trying to print this in a 1D array using flat[k] running through a for loop will generate (Code sample included) without the pattern shown above. However, I am getting random values instead of getting a result of (When converting 2D Arrays to a 1D array)
Should be: 24 32 26 8
Instead, I am getting: 141924268
Is there an efficient way of executing this?
I made a few changes to the code and marked them with comments.
The essential problem was that writing the maximum to the array (and incrementing its write index) was inside the loop for determining the max element.
In your code you added each 'increment' to the array and not the final value as intended.
Also note, that there is no bounds check on k. So it might overflow the flat-array. It might be a good idea to add that if you use this code on other matrix sizes as well.
#include <stdio.h>
int main() {
int disp[4][4] = {
{12, 14, 32, 9},
{19, 24, 3, 4},
{11, 26, 3, 8},
{13, 24, 7, 5}
};
int quadrant_size = 2;
int k = 0;
int flat[4] = {0};
int N = 4;
int x, y, i, j;
for (x = 0 ; x < N ; x += quadrant_size) {
for (y = 0 ; y < N ; y += quadrant_size) {
int mx = disp[x][y];
for (i = x ; i < N && i < x + quadrant_size ; i++) {
// ~~~~~~~~ additional bounds check
for (j = y ; j < N && j < y + quadrant_size ; j++) {
// ~~~~~~~~ additional bounds check
if (disp[i][j] > mx) {
mx = disp[i][j];
// removed code here
}
}
}
// move code here
// only accept the maximum
flat[k] = mx;
k++;
printf("%d ", mx);
}
printf("\n");
}
for (i = 0; i < k; i++) {
// ~ use k as bound, k knows how many elements where inserted
printf("%d ", flat[i]);
// ~ space for readability
}
return 0;
}

smallest number in array [C]

I am trying to find the smallest element of an array, I think I am doing it correctly however I am receiving 0 as my smallest element, however, I am not entering 0 for any elements of my array.
I understand some things in here are done poorly but this is my whole code in order to be reproducible and fixed.
#include<stdio.h>
#include<string.h>
#include <stdlib.h>
int main(){
char input[500];
printf("Enter a list of whitespace-separated real numbers terminated by EOF or 'end'.");
puts("");
printf("-----------------------------------------------------------------------------");
puts("");
gets(input);
int size = strlen(input);
int elements[size];
int i = 0;
char *p = strtok(input," ");
while( p != NULL)
{
elements[i++] = strtol(p, NULL, 10);
p = strtok(NULL," ");
}
//NUM OF ELEMENTS
int numOfElements = 0;
for(int j = 0; j < i; j++){
elements[j] = numOfElements++;
}
//MIN ELEMENT
int min = INT_MAX;
for(int k = 0; k < i; k++){
if(elements[k] < min){
min = elements[k];
}
}
printf("-----------------------------------------------------------------------------\n");
printf("# of Elements: %d\n", numOfElements);
printf("Minimum: %d\n", min);
return 0;
}
RESULT:
Enter a list of whitespace-separated numbers.
-----------------------------------------------------------------------------
1 2 3 4 5
-----------------------------------------------------------------------------
# of Elements: 5
Minimum: 0
EXPECTED:
Enter a list of whitespace-separated numbers.
-----------------------------------------------------------------------------
1 2 3 4 5
-----------------------------------------------------------------------------
# of Elements: 5
Minimum: 1
The problem in the original posted excerpt was the else in this loop:
int min = INT_MAX; //I tried int min = elements[0] also
for(int k = 0; k < i; k++){
if(elements[k] < min){
min = elements[k];
}else{
min = elements[0];
}
}
Consider what happens if you're partway through the array, and you've updated min multiple times, but now you encounter an element that's >= min. The else will reset min to elements[0]. Just delete it:
int min = INT_MAX; //I tried int min = elements[0] also
for(int k = 0; k < i; k++){
if(elements[k] < min){
min = elements[k];
}
}
As an aside, either initialization of min will work. If you initialize it to elements[0], then you can start the loop at k = 1.
Update: The above answer was based on the originally posted code excerpt. Now that more code has been posted (and the fix I showed above has been applied), there are additional problems.
The main problem is the numOfElements loop. This loop completely erases the values in elements, replacing them with 0, 1, 2, etc. So the minimum value really is 0. It's not clear what the point of this loop is. I suggest deleting it entirely. The number of values in elements is just i, so there's nothing to compute. You could rename i to numOfElements if you like.
Other problems: (1) The code needs to include <limits.h> for the definition of INT_MAX, and (2) It should not be using gets. Change it to use fgets or something similar.
//NUM OF ELEMENTS
int numOfElements = 0;
for(int j = 0; j < i; j++){
elements[j] = numOfElements++;
}
problem in here, you reset the elements array when you get count of this array
here is gdb mess when pass here
(gdb) p min
$3 = 0
(gdb) p elem
elem-hash.h elements
(gdb) p elements
$4 = {0, 1, 2, 3, 4, 5, -8096, 32767, 1431652112, 21845, 1431652512}
here is the right
//NUM OF ELEMENTS
int numOfElements = 0;
for(int j = 0; j < i; j++){
numOfElements++;
}

Can't seem to sum multiple array lines to multiple int variables in c language

I'm a first grade student atm. and I'm struggling to finish my "homework" with c language.
Right now I'm trying to apply 4 array lines sum to 4 int variables and here's what I've achieved so far:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int dvimatisMas[4][4] = { {1,2,3,4}, {5,6,7,8}, {9,10,11,12}, {13, 14, 15, 16} };
int eiluciuSum[4];
for(int i = 0; i < 4; i++){
for(int x = 0; x < 4; x++){
for(int j = 0; j < 4; j++){
eiluciuSum[i] += dvimatisMas[x][j];
}
}
}
printf("suma 1 eil: %d\n", eiluciuSum[1]);
printf("suma 2 eil: %d\n", eiluciuSum[2]);
printf("suma 3 eil: %d\n", eiluciuSum[3]);
printf("suma 4 eil: %d\n", eiluciuSum[4]);
int min = 0;
int max = 0;
}
it simply gives out a bunch of answers even though there should be just 4. As you can see in the code I've tried to correct this by writing 4 separate prints and specifying each bracket for them so yeah I obviously get 4 answers like I should but they aren't correct and still I shouldn't be specifying all of that anyway.
If I write something more "simple" I get the desired result:
int dvimatisMas[4][4] = { {1,2,3,4}, {5,6,7,8}, {9,10,11,12}, {13, 14, 15, 16} };
int eilute1 = 0;
int eilute2 = 0;
int eilute3 = 0;
int eilute4 = 0;
for(int i = 0; i < 4; i++){
eilute1 += dvimatisMas[0][i];
eilute2 += dvimatisMas[1][i];
eilute3 += dvimatisMas[2][i];
eilute4 += dvimatisMas[3][i];
}
printf("suma 1 eil: %d\n", eilute1);
printf("suma 2 eil: %d\n", eilute2);
printf("suma 3 eil: %d\n", eilute3);
printf("suma 4 eil: %d\n", eilute4);
But the problem is that I also have to print out the smallest number out of 'eilute' as well as the biggest. But I can't get to that point since I need 'eilute[]' (I called it 'eiluciuSum[]' in the first code) to be expanded by the code and to use it in an 'if' statement like "if(eilute[i] < 0){ min += eilute[i]; printf("smallest: %d", min)" etc. and thats how I'm supposed to do it (well at the very least something like that instead of bunch of complicated equations and I mean it is more short and 'professional' am I right?).
If I managed to explain my situation understandably could someone help and explain on what I'm doing wrong in the first provided code?
Thank you in advance.
The final version of your code is at the bottom.
Firstly, you don't need the variable x. Cut out the second for loop.
for(int i = 0; i < 4; i++) {
for(int j = 0; j < 4; j++) {
eiluciuSum[i] += dvimatisMas[i][j];
}
}
Secondly, the problem is that the eiluciuSum array is not initialized to zero. It already contains a garbage value in it from whatever was stored in that memory address before. You should replace its definition with this:
int eiluciuSum[4] = { 0 };
Then just put the printf statement after the inner loop like this:
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
eiluciuSum[i] += dvimatisMas[i][j];
}
printf("%d\n", eiluciuSum[i]);
}
And it should work fine without the 4 printf statements below.
Thirdly, in regards to finding the maximum/minimum values, all you need to do is set the max/min variables to the first element in the array and then loop through the array, looking for values larger/smaller than whatever is the current largest/smallest, and switch those values.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int dvimatisMas[4][4] = { {1,2,3,4}, {5,6,7,8}, {9,10,11,12}, {13, 14, 15, 16} };
int eiluciuSum[4] = { 0 }; // initialize all elements of array to 0
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
eiluciuSum[i] += dvimatisMas[i][j];
}
printf("%d\n", eiluciuSum[i]);
}
int min = eiluciuSum[0]; // assume the first sum is the smallest
int max = eiluciuSum[0]; // assume the first sum is the largest
// loop through all elements of array and if you encounter one bigger/smaller
// than the current max/min, then make those the current max/min values
for (int i = 0; i < 4; i++) {
if (eiluciuSum[i] < min)
min = eiluciuSum[i];
if (eiluciuSum[i] > max)
max = eiluciuSum[i];
}
printf("The smallest sum is %d\n", min);
printf("The largest sum is %d\n", max);
}

Transferring sorting loop results to another array

Here's a loop to sort an array from min to max, I need the result of this loop to be put into another array so I can filter and remove the numbers that occur only once and find the last member of what's left.
Here's the code I have so far:
#include<stdio.h>
#include<conio.h>
#define buffas 1024
void main() {
int arr[buffas],i,j,element,no,temp;
printf("\nEnter the no of Elements: ");
scanf("%d", &no);
for(i=0; i<no; i++) {
printf("\n Enter Element %d: ", i+1);
scanf("%d",&arr[i]);
}
for(i=0; i<no; i++) {
for(j=i; j<no; j++) {
if(arr[i] > arr[j]) {
temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
}
}
printf("\nSorted array:");
for(i=0; i<no; i++) {
printf("\t%d",arr[i]);
}
getch();
}
How do I change the
printf("\t%d",arr[i]);
To fill another array and then sort that to remove single entries and leave ony those that repeat at least once.
eg. the first aray is
2 2 1 6 9 9
and after the second sorting the result should be
2 2 9 9
#include <stdio.h>
#define buffas 16
int main(void)
{
/* Instead of original input and sorting code */
int arr[] = { 1, 2, 2, 6, 9, 9, 10, 10, 10, 11, 12, 13, 14 };
int no = sizeof(arr) / sizeof(arr[0]);
/* Code to copy only duplicated elements in arr */
int copy[buffas];
int n = 0;
for (int i = 0; i < no; i++)
{
int j;
for (j = i + 1; j < no; j++)
{
if (arr[i] != arr[j])
break;
}
if (j - i > 1)
{
for (int k = i; k < j; k++)
copy[n++] = arr[k];
i = j - 1;
}
}
/* Print results for verification */
for (int i = 0; i < n; i++)
printf("c[%d] = %d\n", i, copy[i]);
return 0;
}
The code has been run with various lengths of sorted array and different data in the array; it seems to be correct. The code above produces the output:
c[0] = 2
c[1] = 2
c[2] = 9
c[3] = 9
c[4] = 10
c[5] = 10
c[6] = 10
Note that the code uses the C99 feature of declaring variables in a for loop control statement; if you're on Windows and without C99 support, you'll need to declare i and k outside the loops. If you're using GCC, you need to add -std=c99 or a similar option.

Resources