Nested if loop in Smallest positive number 2D Array in C - c

I have this weird problem, When I run following code snippet, it gives me wrong answer. I am trying to find smallest positive number from 2D array.
I tried combining two if conditions in one if, placing brackets, interchanging if conditions. But while I debug I see, control never goes inside if greater than 0 condition.
float smallest(float b[3][4]);
int main()
{
float a[3][4],result;
int i, j;
printf("\nEnter 12 numbers into the array:\n");
for (i = 0; i < 3; i++)
{
for (j = 0; j < 4; j++)
{
scanf("%f", &a[i][j]);
}
printf("\n");
}
result=smallest(a);
printf("\nSamllest positive number is %.1f", result);
system("pause");
return 0;
}
float smallest(float b[3][4])
{
int i, j;
float min = b[0][0];
for (i = 0; i < 3; i++)
{
for (j = 0; j < 4; j++)
{
if (b[i][j]<min)
if (b[i][j]>0)
min = b[i][j];
}
}
return min;
}
Enter 12 numbers into the array:
-5
4
9
7
6
2
3
1
-7
5
4
7
Samllest positive number is -5.0

It is becuse you set min to b[0][0] which is -5 in your example, so the only number where if (b[i][j]<min) is true is -7. But your second if only true if the number is greater than 0. Which is false for -7, therefore min = b[i][j]; this code never executes.
Initialize min to FLT_MAX and it should be fine. (Although this could be problematic if the array only contains negative numbers.)

assign first positive value of array to your min and then use your code.
int check = 0;
int i, j;
float min=-2;//this is for case when all elements are negative
for (i = 0; i < 3; i++)
{
for (j = 0; j < 4; j++)
{
if (b[i][j] > 0)
{
min = b[i][j];
check = 1;
break;
}
}
if (check == 1)
break;
}
so your smallest function:
float smallest(float b[3][4])
{
int check = 0;
int i, j;
float min=-1;
for (i = 0; i < 3; i++)
{
for (j = 0; j < 4; j++)
{
if (b[i][j] > 0)
{
min = b[i][j];
check = 1;
break;
}
}
if (check == 1)
break;
}
if(min<0)
printf("no positive number");
else
{
for (i = 0; i < 3; i++)
{
for (j = 0; j < 4; j++)
{
if (b[i][j]<min)
if (b[i][j]>0)
min = b[i][j];
}
}
}
return min;
}
you also should check if returned min is navigate or positive in main.
if it was negative no positive value were found.

The function initially is defined incorrectly.
For starters the function shall have a second parameter that specifies the number of "rows" in the array. This function declaration
float smallest(float b[3][4]);
is equivalent to the following function declaration
float smallest(float b[][4]);
and the both declarations declare the same one function the declaration of which is adjusted by the compiler to the fol;lowing
float smallest(float ( *b )[4]);
Secondly the array can have no positive element. SO in this case the function will return an incorrect value.
Th function should return either an index or a pointer to the minimum positive elements. And if the index or the pointer is outside the array then it means that the array does not have a positive element.
Here is a demonstrative program that shows how the function can be defined and how in the caller there can be determine whether the array has a minimum positive element.
#include <stdio.h>
#define N 4
size_t smallest( float a[][N], size_t size )
{
size_t i = 0;
float *p = ( float * )a;
while ( i < size * N && !( 0 < p[i]) ) ++i;
size_t min = i;
for ( ++i; i < size * N; i++ )
{
if ( 0 < p[i] && p[i] < p[min] ) min = i;
}
return min;
}
int main(void)
{
float a[][N] =
{
{ -5, 4, 9, 7 },
{ 6, 2, 3, 1 },
{ -7, 5, 4, 7 }
};
const size_t M = sizeof( a ) / sizeof( *a );
size_t min = smallest( a, M );
if ( min < M * N )
{
printf( "The smallest positive element is %.1f\n", a[min / N][min % N] );
}
else
{
puts( "There ia no minimal positive element in the array" );
}
return 0;
}
The program output is
The smallest positive element is 1.0

Related

How to make competitive coding solutions more efficient (BIT wise operations)?

How do I make my code more efficient (in time) pertaining to a competitive coding question (source: codechef starters 73 div 4):
(Problem) Chef has an array A of length N. Chef wants to append a non-negative integer X to the array A such that the bitwise OR of the entire array becomes = Y .
Determine the minimum possible value of X. If no possible value of X exists, output -1.
Input Format
The first line contains a single integer T — the number of test cases. Then the test cases follow.
The first line of each test case contains two integers N and Y — the size of the array A and final bitwise OR of the array A.
The second line of each test case contains N space-separated integers A_1, A_2, ..., A_N denoting the array A.
Please don't judge me for my choice of language .
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int* binary_number(int n) // returns pointer to a array of length 20(based on given constrains) representing binary
{
int* ptc;
ptc = (int*) malloc(20*sizeof(int));
for(int i = 0; i < 20; i++)
{
if((n / (int) pow(2,19-i)) > 0){*(ptc + i) = 1;}
else {*(ptc + i) = 0;}
n = n % (int) pow(2,19-i) ;
}
return ptc;
}
int or_value(int* ptc, int n) // Takes in pointers containing 1 or zero and gives the logical OR
{
for(int k = 0; k < n; n++)
{
if(*ptc == *(ptc + 20*k)){continue;} // pointers are 20 units apart
else{return 1;break;}
}
return *ptc;
}
int main(void) {
int t; scanf("%d", &t);
for (int i = 0; i < t; i++)
{
int n, y;
scanf("%d %d", &n, &y);
int a[n];
for(int j = 0; j < n ; j++)
{
scanf("%d", &a[j]);
}
int b[20*n];
for (int j = 0; j < n; j++)
{
for (int k = 0; k < 20; k++)
{
b[20*j + k] = *(binary_number(a[n])+k);
}
}
int c = 0;
int p = 0;
for (int j = 0; j < 20; j++)
{
if ((*(binary_number(y) + j) == 1) && (or_value((&b[0] + j),n) == 0)){c = c + pow(2,19 - j);}
else if ((*(binary_number(y) + j) == 0) && (or_value((&b[0] + j),n) == 1)){p = 1; break;}
}
if (p==1){printf("-1");}
else {printf("%d\n", c);}
}
return 0;
}

Sorting integers by sum of their digits

I'm trying to write a program that will sort an array of 20 random numbers by the sums of their digits.
For example:
"5 > 11" because 5 > 1+1 (5 > 2).
I managed to sort the sums but is it possible to return to the original numbers or do it other way?
#include <stdio.h>
void sortujTab(int tab[], int size){
int sum,i;
for(int i=0;i<size;i++)
{
while(tab[i]>0){//sum as added digits of an integer
int p=tab[i]%10;
sum=sum+p;
tab[i]/=10;
}
tab[i]=sum;
sum=0;
}
for(int i=0;i<size;i++)//print of unsorted sums
{
printf("%d,",tab[i]);
}
printf("\n");
for(int i=0;i<size;i++)//sorting sums
for(int j=i+1;j<=size;j++)
{
if(tab[i]>tab[j]){
int temp=tab[j];
tab[j]=tab[i];
tab[i]=temp;
}
}
for(int i=0;i<20;i++)//print of sorted sums
{
printf("%d,",tab[i]);
}
}
int main()
{
int tab[20];
int size=sizeof(tab)/sizeof(*tab);
for(int i=0;i<=20;i++)
{
tab[i]=rand()%1000;// assamble the value
}
for(int i=0;i<20;i++)
{
printf("%d,",tab[i]);//print unsorted
}
printf("\n");
sortujTab(tab,size);
return 0;
}
There are two basic approach :
Create a function that return the sum for an integer, say sum(int a), then call it on comparison, so instead of tab[i] > tab [j] it becomes sum(tab[i]) > sum (tab[j])
Store the sum into a different array, compare with the new array, and on swapping, swap both the original and the new array
The first solution works well enough if the array is small and takes no extra memory, while the second solution didn't need to repeatedly calculate the sum. A caching approach is also possible with map but it's only worth it if there are enough identical numbers in the array.
Since your numbers are non-negative and less than 1000, you can encode the sum of the digits in the numbers itself. So, this formula will be true: encoded_number = original_number + 1000 * sum_of_the_digits. encoded_number/1000 will decode the sum of the digits, and encoded_number%1000 will decode the original number. Follow the modified code below. The numbers enclosed by parentheses in the output are original numbers. I've tried to modify minimally your code.
#include <stdio.h>
#include <stdlib.h>
void sortujTab(int tab[], int size)
{
for (int i = 0; i < size; i++) {
int sum = 0, n = tab[i];
while (n > 0) { //sum as added digits of an integer
int p = n % 10;
sum = sum + p;
n /= 10;
}
tab[i] += sum * 1000;
}
for (int i = 0; i < size; i++) { //print of unsorted sums
printf("%d%c", tab[i] / 1000, i < size - 1 ? ',' : '\n');
}
for (int i = 0; i < size; i++) { //sorting sums
for (int j = i + 1; j < size; j++) {
if (tab[i] / 1000 > tab[j] / 1000) {
int temp = tab[j];
tab[j] = tab[i];
tab[i] = temp;
}
}
}
for (int i = 0; i < size; i++) { //print of sorted sums
printf("%d(%d)%c", tab[i] / 1000, tab[i] % 1000, i < size - 1 ? ',' : '\n');
}
}
int main(void)
{
int tab[20];
int size = sizeof(tab) / sizeof(*tab);
for (int i = 0; i < size; i++) {
tab[i] = rand() % 1000; // assamble the value
}
for (int i = 0; i < size; i++) {
printf("%d%c", tab[i], i < size - 1 ? ',' : '\n'); //print unsorted
}
sortujTab(tab, size);
return 0;
}
If the range of numbers doesn't allow such an encoding, then you can declare a structure with two integer elements (one for the original number and one for the sum of its digits), allocate an array for size elements of this structure, and initialize and sort the array using the digit sums as the keys.
You can sort an array of indexes rather than the array with data.
#include <stdio.h>
//poor man's interpretation of sumofdigits() :-)
int sod(int n) {
switch (n) {
default: return 0;
case 5: return 5;
case 11: return 2;
case 1000: return 1;
case 9: return 9;
}
}
void sortbyindex(int *data, int *ndx, int size) {
//setup default indexes
for (int k = 0; k < size; k++) ndx[k] = k;
//sort the indexes
for (int lo = 0; lo < size; lo++) {
for (int hi = lo + 1; hi < size; hi++) {
if (sod(data[ndx[lo]]) > sod(data[ndx[hi]])) {
//swap indexes
int tmp = ndx[lo];
ndx[lo] = ndx[hi];
ndx[hi] = tmp;
}
}
}
}
int main(void) {
int data[4] = {5, 11, 1000, 9};
int ndx[sizeof data / sizeof *data];
sortbyindex(data, ndx, 4);
for (int k = 0; k < sizeof data / sizeof *data; k++) {
printf("%d\n", data[ndx[k]]);
}
return 0;
}

Majority element in an array.It

#include <stdio.h>
void main()
{
int maj, count, n = 6;
int arr[] = {1, 2, 2, 2, 2, 3, 4};
for (int i = 0; i < n; i++) {
maj = arr[i];
count = 0;
for (int j = 9; j < n; j++) {
if (arr[j] == maj) count++;
}
if (count > n / 2) {
break; /* I think some problem is here ,if majority element not found then it takes last element as the majority element */
}
}
printf("%d", maj);
}
It is giving correct output if majority ellement is there but incorrect output if no majority element is there for example if array is {1,2,3,4} it is giving output as 4. please help!!
#include <stdio.h>
int main() {
int maj, count, n = 7; //n is size of arr
int arr[] = {1, 2, 2, 2, 2, 3, 4};
int isFound = 0; //0 -> false, 1 -> true
for (int i = 0; i < n; i++) {
maj = arr[i];
count = 1; //first elements is itself
isFound = 0; //by default we assume that no major elements is found
for (int j = i+1; j < n; j++) { //iterate from next elements onwards to right in array
if (arr[j] == maj) count++;
}
if (count > n / 2) {
isFound = 1;
break; //major elements found; no need to iterator further; just break the loop now
}
}
if(isFound) printf("%d ", maj);
else printf("no major element");
return 0;
}
For starters according to the C Standard function main without parameters shall be declared like
int main( void )
Try not to use magic numbers. Usually as in your program they are a reason for program bugs. For example you declared the array arr as having 7 elements however the variable n that should keep the number of elements in the array is initialized with the value 6. Another magic number 9 is used in the loop
for (int j = 9; j < n; j++) {
^^^
There is no need to write the outer loop that travers the whole array. Also the program does not report the case when the majority number does not exist in the array.
Using your approach with two loops the program can look the following way
#include <stdio.h>
int main( void )
{
int a[] = { 1, 2, 2, 2, 2, 3, 4 };
const size_t N = sizeof( a ) / sizeof( *a );
size_t i = 0;
for ( ; i < ( N + 1 ) / 2; i++ )
{
size_t count = 1;
for ( size_t j = i + 1; count < N / 2 + 1 && j < N; j++ )
{
if ( a[i] == a[j] ) ++count;
}
if ( !( count < N / 2 + 1) ) break;
}
if ( i != ( N + 1 ) / 2 )
{
printf( "The majority is %d\n", a[i] );
}
else
{
puts( "There is no majority element" );
}
return 0;
}
Its output is
The majority is 2

get max min element from array, delete them and sum rest of the array

I am trying to get 5 different grades from judges, and putting them in a array.
Then I try to find the max and the min element from the array.
example {2,3,4,5,6}
max= 6 , min = 2.
After that I have to delete 6 and 2, and then add 3+4+5 which gives me a sum of 12.
How do delete and then add the sum? Since it looks like I am getting errors while deleting from the array .Here is the code
#include <stdio.h>
int main()
{
int judge1, judge2,judge3,judge4, judge5,i,max,min;
int size = 4;
printf("Judge one grade");
scanf("%d", &judge1);
printf("Judge one grade");
scanf("%d", &judge2);
printf("Judge one grade");
scanf("%d", &judge3);
printf("Judge one grade");
scanf("%d", &judge4);
printf("Judge one grade");
scanf("%d", &judge5);
int a[] = {judge1, judge2, judge3, judge4, judge5};
max=a[0];
for(i=1;i<size;i++){
if(max<a[i])
max=a[i];
}
min=a[0];
for(i=1;i<size;i++){
if(min>a[i])
min=a[i];
}
for (i=0;i < size ;i++) {
if(a[i] == min || a[i] == max){
a[i] = a[i+1];
}
}
for (i=0;i < size ;i++) {
int sum = 0;
sum+= a[i];
printf("%d\n", sum);
}
return 0;
}
Logic you used in two for loops is wrong.
1st for loop -
for (i=0;i < size ;i++) {
if(a[i] == min || a[i] == max){
a[i] = a[i+1];
}
}
Here you are copying next element to previous. Thus for array [2, 3, 4, 5, 6], you'll be copying 3 to 2 so array will become [3, 3, 4, 5, 6] which will give wrong result on summing up.
2nd for loop -
for (i=0;i < size ;i++) {
int sum = 0;
sum+= a[i];
printf("%d\n", sum);
}
Here you are initializing sum to 0 in every iteration, thus a[i] always will get added to 0. Thus output will be last element value.
You should initialize sum before start of for loop.
Answer -
#include <stdio.h>
int main()
{
int judge1=2, judge2=3,judge3=4,judge4=5, judge5=6,i,max,min;
int size = 5;
int a[] = {judge1, judge2, judge3, judge4, judge5};
max=0;
for(i=1;i<size;i++){
if(a[max]<a[i])
max=i;
}
for (i=max;i<size;i++) {
a[i] = a[i+1];
}
size--;
min=0;
for(i=1;i<size;i++){
if(a[min]>a[i])
min=i;
}
for (i=min;i < size ;i++) {
a[i] = a[i+1];
}
size--;
int sum = 0;
for (i=0;i < size ;i++) {
sum+= a[i];
printf("%d\n", sum);
}
return 0;
}
Or if you just need the sum here's the easy solution
#include <stdio.h>
int main()
{
int judge1=2, judge2 = 3,judge3 = 4,judge4 = 5, judge5 = 6, i;
int size = 5, sum = 0, max, min;
int a[] = {judge1, judge2, judge3, judge4, judge5};
max = a[0];
min = a[0];
for (i=0;i < size ;i++) {
if(max<a[i])
max=a[i];
if(min>a[i])
min=a[i];
sum+= a[i];
}
sum = sum - (max + min);
printf("%d\n", sum);
return 0;
}
Here's your deleting code. The basic idea is if it's the min or max to replace it with the one after it.
for (i=0;i < size ;i++) {
if(a[i] == min || a[i] == max){
a[i] = a[i+1];
}
}
Ok, let's try it. {4, 3, 6, 5}. 3 is min, 6 is max.
i == 0
a[0] == 4
a[1] == 3
No change: {4, 3, 6, 5}
i == 1
a[1] == 3 (the min)
a[2] == 6 (the max)
a[1] = a[2]: {4, 6, 6, 5} /* whoops, you replaced the min with the max */
i = 2
a[2] == 6 (the max)
a[3] == 5
a[2] = a[3]: {4, 6, 5, 5}
i == 3
a[3] == 5
a[4] == garbage /* whoops, you walked off the array */
No change
So there's two problems. When you do the replacement you have to recheck the new value. This will be a problem if the min and max or next to each other, or if there's two max values.
Second is you're walking off the array. i + 1 is a red flag. If the min or max was the last value, you'd replace it with garbage. A memory checker such as Valgrind will find these sorts of very, very common problems. I highly recommend you always run a memory checker and fix everything it complains about.
Rather than altering the array, which gets tricky, it's much easier to do this in two passes. It's also non-destructive, you don't have to alter or copy the data.
Find the min and the max.
Take the average by ignoring the min and the max.
You can find the min and max in one loop.
int min = a[0];
int max = a[0];
for( i = 1; i < size; i++ ) {
if( a[i] < min ) {
min = a[i];
}
if( a[i] > max ) {
max = a[i];
}
}
Then take the average and ignore the min and max.
int sum = 0;
int count = 0;
for( i = 0; i < size; i++ ) {
if( a[i] != min && a[i] != max ) {
sum += a[i];
count++;
}
}
int avg = sum / count;
This reveals another problem. What if there are multiple mins and maxes? What if the scores are {3, 3, 3, 5, 5, 5}? Do you want to throw them all out and get an average of 0? Probably not. You probably only want to throw out the highest and lowest single scores.
You could make seen_min and seen_max boolean variables to only skip min and max once, but this gets complicated. #MikeNakis solution is better, store the index of the min and max and use that to do the skipping.
int min_idx = 0;
int max_idx = 0;
for( i = 1; i < size; i++ ) {
if( a[i] < a[min_idx] ) {
min_idx = i;
}
if( a[i] > a[max_idx] ) {
max_idx = i;
}
}
int sum = 0;
int count = 0;
for( i = 0; i < size; i++ ) {
/* Skip the min and max score */
if( i == min_idx || i == max_idx ) {
continue;
}
sum += a[i];
/* You could replace count with size - 2, but this way
there's one less assumption */
count++;
}
double avg = (double)sum / count;
Instead of looping through the array again, use the index. Note that in your code, you reset sum inside the loop so it will only show the last value and is not in scope when the loop is finished (so it will disappear). You also print inside the loop instead of after the full sum has been calculated.
int imin = 0, imax = 0;
max=a[0];
for(i=1; i<size; i++){
if(max<a[i]) {
imax = i;
max=a[i];
}
}
min=a[0];
for(i=1; i<size; i++){
if(min>a[i]) {
min=a[i];
imin = i;
}
}
a[imin] = 0; // Does not contribute to the sum
a[imax] = 0; // Does not contribute to the sum
int sum = 0;
for (i=0; i<size; i++) {
sum += a[i];
}
printf("sum = %d\n", sum);
No need to even have an array. Calculate the min, max and sum as you go:
unsigned min = -1u; // min is set to the greatest unsigned value
unsigned max = 0; // max is set to the least unsigned value
unsigned sum = 0;
for (int i=0; i<5; i++) {
unsigned judge;
printf("Judge one grade ");
if (scanf("%u", &judge) != 1) break; // validate input
if (judge > max) max = judge;
if (judge < min) min = judge;
sum += judge;
}
if (min > max) {
printf("No valid input\n");
return -1;
}
// print sum less the min and max, which is OP's goal
unsigned sum_less_min_max = sum - min - max;
printf("sum = %u\n", sum_less_min_max);

Add the digits of each element in an multidimensional array

I have a 2 dimensional array. I'm trying to add the digits of each element in the array and find the sum.
For example :
consider my array is: a[2][2] = { {15,11}, {13,21} }.
Now for the element 15 i need to add 1+5 and the result 6 placed in the same position.
and for element 11 1+1 and place the result 2 in the same position. And the same for all other elements.
Following is my code.
int main ()
{
int a[3][2] = { {19,11}, {13,21}, {12,14}};
int i, j;
int digit1,digit2,sum1=0,sum2=0,rem1,rem2;
for ( i = 0; i < 3; i++ )
{
for ( j = 0; j < 2; j++ )
{
digit1 = a[i];
rem1 = digit1%10;
sum1 = sum1 + rem1;
digit1 = digit1/10;
digit2 = a[j];
rem2 = digit2%10;
sum2 = sum2 + rem2;
digit2 = digit2/10;
printf("\nthe sum of i: ", sum1);
printf("\nthe sum of j: ", sum2);
}
}
return 0;
}
But from above code I'm not getting the sum.
I am kinda new to this and got stuck here. Here's the code in EDITOR.
Define a function to compute the sum of the digits of an integer.
int getSumOfDigits(int n)
{
int ret = 0;
while ( n > 0 )
{
ret += (n%10);
n /= 10;
}
return ret;
}
Use the function in the for loop.
for ( i = 0; i < 3; i++ )
{
for ( j = 0; j < 2; j++ )
{
a[i][j] = getSumOfDigits(a[i][j]);
}
}
Its simple. Do the following -
//Assuming the array is a[3][2]
for(int i=0;i<3;i++)
for(int j=0;j<2;j++)
{
int sum = 0;
while(a[i][j])
{
sum+=a[i][j]%10;
a[i][j]/=10;
}
a[i][j]=sum;
}
Inside for loop put this code instead of your code it will work
for ( j = 0; j < 2; j++ )
{
sum1=0;
while(a[i][j]){
sum1=sum1+(a[i][j]%10);
a[i][j]=a[i][j]/10;
}
a[i][j]=sum1;
printf("\nthe sum of [%d][%d]: %d", i,j,sum1);
}

Resources