Finding minimum difference between a pair of integers - c

Given the set of unsorted integers, how to find every pair of integers which have minimum difference. There are 3 samples as described below:
a = random.sample (range(-200,200), 5)
b = random.sample (range(-1000, 1000), 25)
c = random.sample (range(-2000, 2000), 50)
The expected output should be something like:
List A = [-85, -154, -33, 192, -160]
Minimum pairs for list A:
(-160, -154)

Catch! :)
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
struct Pair
{
size_t first;
size_t second;
};
struct Pair minimum_difference( const int a[], size_t n )
{
struct Pair p = { 0 };
if ( 1 < n )
{
p.first = 0;
p.second = 1;
for ( size_t i = 0; i < n - 1; i++ )
{
for ( size_t j = i + 1; j < n; j++ )
{
// printf( "%d %d %llu\n", a[i], a[j],
// ( unsigned long long )abs( a[i] - a[j] ) );
if ( ( unsigned long long )abs( a[i] - a[j] ) <
( unsigned long long )abs( a[p.first] - a[p.second] ) )
{
p.first = i;
p.second = j;
}
}
}
}
return p;
}
int main(void)
{
const size_t N = 5;
const int UPPER_BOUND = 40 * N;
int a[N];
srand( ( unsigned int )time( NULL ) );
for ( size_t i = 0; i < N; i++ )
{
a[i] = rand() % ( 2 * UPPER_BOUND ) - UPPER_BOUND;
}
for ( size_t i = 0; i < N; i++ ) printf( "%d ", a[i] );
printf( "\n" );
struct Pair p = minimum_difference( a, N );
printf( "(%d, %d)\n", a[p.first], a[p.second] );
return 0;
}
The program output might look loke
119 9 -193 21 -43
(9, 21)
This prpgram finds only the first pair with the minimum difference. If there are several pairs with the minimum difference when you have to allocate dynamically an array of pairs. Of course the function will be changed.
The other approach is to use a sort-copy algorithm by using an additional array. And then traverse this array calculating the difference.

Related

I want to insert in a vector multiple values in a location

When I create a vector , let's say size of 5 , elements are 1,2,3,4,5 and I want to add at the location( for example index 2) the numbers 200 and 300 , the vector should look like 1 ,2 ,200,300,3,4,5.
#include <stdio.h>
#include <stdlib.h>
int main(){
int v[] ={1,2,3,4,5,6,7};
int n = sizeof(v)/sizeof(int);
int location,element;
printf("Enter location:");
scanf("%d",&location);
printf("Enter element:");
scanf("%d",&element);
for(int i = n - 1; i >= location;i--){
v[i + 1] = v[i];
}
v[location] = element;
for(int i = 0; i <= n;i++){
printf("%d ",v[i]);
}
}
You need to loop like this
for(;;){
int location,element;
printf("Enter location:");
scanf("%d",&location);
if(location == -1)
break;
printf("Enter element:");
scanf("%d",&element);
for(int i = n - 1; i >= location;i--){
v[i + 1] = v[i];
}
v[location] = element;
}
BUT you code is severely broken, you are adding to a vector thats of fixed size. you cannot do that
In this code
for (int i = n - 1; i >= location; i--) {
v[i + 1] = v[i];
}
n is the count of number of elements, so on the first loop you do
v[n] = v[n-1]
ie
v[7] = v[6]
well v[7] is off the end of the array (array indexes are 0 to 6) Thats very bad
You declared a fixed size array
int v[] ={1,2,3,4,5,6,7};
You can not enlarge it.
Thus this loop
for(int i = 0; i <= n;i++){
printf("%d ",v[i]);
}
invokes undefined behavior due to using the index with the value n that is outside the valid range of indices [0, n) for the source array.
You need to allocate the array dynamically and when you are going to add one more element you will need to reallocate the array.
Here is a demonstration program.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main( void )
{
size_t n = 7;
int *v = malloc( n * sizeof( int ) );
memcpy( v, ( int [7] ){ 1, 2, 3, 4, 5, 6, 7 }, n * sizeof( int ) );
for ( size_t i = 0; i < n; i++ )
{
printf( "%d ", v[i] );
}
putchar( '\n' );
size_t location = 0;
printf( "Enter location: " );
scanf( "%zu", &location );
if ( n < location ) location = n;
int element = 0;
printf( "Enter element: " );
scanf( "%d",&element );
int *tmp = realloc( v, ( n + 1 ) * sizeof( int ) );
if ( tmp != NULL )
{
v = tmp;
memmove( v + location + 1, v + location, ( n - location ) * sizeof( int ) );
v[location] = element;
++n;
}
for ( size_t i = 0; i < n; i++ )
{
printf( "%d ", v[i] );
}
putchar( '\n' );
free( v );
}
The program output might look like
1 2 3 4 5 6 7
Enter location: 2
Enter element: 200
1 2 200 3 4 5 6 7

Bigger number in array than the sum of the numbers to the right of it

I'm trying to create a program in C. I'm trying to find "special numbers" in a array. A special number is a number that is bigger than the sum of the numbers to the right of it.
I have this array
int input[] = {20,5,16,17,4,3,5,2,1};
Special numbers in this array are 17, 5, 2, 1... because 17 > 4+3+5+2; ...
I have function int special_numbers(). This function should find this special numbers and store them into array called result() and return it.
I have been trying for a very long time but I can't find a solution.
My code:
#include <stdio.h>
#include <math.h>
int special_numbers();
int main(){
int input[] = {20,5,16,17,4,3,5,2,1};
int result[9];
for(int i = 0; i < count; i++){
printf("%d ", result[i]);
}
printf("%d", special_numbers(input, 9));
return 0;
}
int special_numbers(const int input[], const int array_size, int result[]){
int result = 0;
for (int i = 0; i < array_size; i++){
if(input[i] > input[i+1]){
}
}
return result;
}
There are more efficient ways, but the simple way is to use a nested loop that gets the sum of all the elements after i.
int special_numbers(const int input_array[], const int array_size, int result_array[]){
int result = 0;
for (int i = 0; i < array_size; i++){
int sum = 0;
for (int j = i+1; j < array_size; j++) {
sum += input_array[j];
}
if (array[i] > sum) {
result_array[result++] = array[i];
}
}
return result;
}
You are calling the function twice
int count = special_numbers(input_array, 6, result_array);
//...
printf("%d", special_numbers(input_array, 6));
where the second call is redundant because you already have the variable count and is invalid because you forgot to specify the third argument.
Also it is a bad idea to use magic numbers as 6.
Within the function you need to calculate the sum of elements that follow the current element. It is better to declare the variable that will store the sum as having the type long long int to avoid an overflow.
The function can be defined the following way as it is shown in the demonstration program below.
#include <stdio.h>
size_t special_numbers( const int input_array[], size_t array_size, int result_array[] )
{
size_t result = 0;
long long int sum = 0;
for ( size_t i = array_size; i != 0; --i )
{
if ( i == array_size || sum < input_array[i - 1] ) ++result;
sum += input_array[i-1];
}
sum = 0;
for ( size_t i = array_size, j = result; i != 0; --i )
{
if ( i == array_size || sum < input_array[i - 1] )
{
result_array[--j] = input_array[i-1];
}
sum += input_array[i-1];
}
return result;
}
int main( void )
{
int input_array[] = { 16, 17, 4, 3, 5, 2 };
int result_array[sizeof( input_array ) / sizeof( *input_array )];
const size_t N = sizeof( input_array ) / sizeof( *input_array );
size_t count = special_numbers( input_array, N, result_array );
printf( "%zu: ", count );
for ( size_t i = 0; i < count; i++ )
{
printf( "%d ", result_array[i] );
}
putchar( '\n' );
return 0;
}
The program output is
3: 17 5 2
If the last element of the input array shall be greater than 0 then change the function the following way
size_t special_numbers( const int input_array[], size_t array_size, int result_array[] )
{
size_t result = 0;
long long int sum = 0;
for ( size_t i = array_size; i != 0; --i )
{
if ( sum < input_array[i - 1] ) ++result;
sum += input_array[i-1];
}
sum = 0;
for ( size_t i = array_size, j = result; i != 0; --i )
{
if ( sum < input_array[i - 1] )
{
result_array[--j] = input_array[i-1];
}
sum += input_array[i-1];
}
return result;
}

Loop and sum giving unexpexted result

This is my code
with the help of pointers i try to find and compare the sum of the main and second diagonal of a 5x5 matrix.The numbers are randomly generated
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main {
int i, s1, s2, j, a[5][5];
srand (time (NULL));
printf ("The matrix is:\n");
for (i = 0; i < 5; i++) {
printf ("\n\n");
for (j = 0; j < 5; j++) {
*(*(a + i) + j) = rand ();
printf ("%d ", *(*(a + i) + j));
}
}
for (i = 0; i < 5; i++) {
s1 += a[i][i]; // main diagonal
s2 += a[i][4 - i]; // second diagonal
}
printf ("\n\nThe sum 1:%d\nThe sum 2:%d", s1, s2);
if (s1 == s2) {
printf ("They are the same");
}
return 0;
}
The problem is that the sum of the main diagonal is bigger by 51 than it should be
s1 and s2 both are uninitialised. You need to initialize them with 0 before using in statements s1+=a[i][i]; and s2+=a[i][4-i];.
int i, s1 = 0, s2 = 0, j, a[5][5];
I would also suggest to use
a[i][j] = rand();
instead of
*(*(a+i)+j)=rand();
to access array members.
You have not initialised s1,s2 to zero
s1+=a[i][i]; // main diagonal
s2+=a[i][4-i]; // second diagonal
Prior to these statements
You could do as follow:
*(*(a+i)+j)=rand(); ----> a[i][j]=rand()%100;
printf("%d ",*(*(a+i)+j)); -----> printf("%d ", a[i][j]);
add s1 = s2 = 0;
Then the following could work.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
int i,s1,s2,j,a[5][5];
srand(time(NULL));
printf("The matrix is:\n");
for(i=0;i<5;i++)
{
printf("\n\n");
for(j=0;j<5;j++)
{
a[i][j]=rand()%100;
printf("%d ", a[i][j]);
}
}
s1 = s2 = 0;
for(i=0;i<5;i++)
{
s1+=a[i][i]; // main diagonal
s2+=a[i][4-i]; // second diagonal
}
printf("\n\nThe sum 1:%d\nThe sum 2:%d\n",s1,s2);
if (s1==s2)
{
printf("They are the same\n");
}
return 0;
}
For starters according to the C Standard function main without parameters shall be declared like
int main( void )
Secondly it is better to use a named constant instead of magic numbers. So you could define for example named constant N for the magic number 5. In this case your program will be more flexible and can be modified easy.
For the sums it is better to use a more larger integer type as long long int. Otherwise an overflow can occur.
You should initialize variables near the point in the program where the variables are used. If your compiler supports C99 then you may declare and initialize variables where they are used.
You could limit the maximum value that elements of the matrix can have.
The program can look the following way.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define N 5
#define VALUE_MAX 100
int main(void)
{
int a[N][N];
size_t i, j;
long long int s1, s2;
srand( ( unsigned int )time( NULL ) );
printf( "The matrix is:\n" );
for ( i = 0; i < N; i++ )
{
printf ( "\n\n" );
for ( j = 0; j < N; j++ )
{
*( *( a + i ) + j ) = rand() % VALUE_MAX;
printf ( "%d ", *( *( a + i ) + j ) );
}
}
s1 = 0ll;
s2 = 0ll;
for ( i = 0; i < N; i++ )
{
s1 += a[i][i]; // main diagonal
s2 += a[i][N - i - 1]; // second diagonal
}
printf( "\n\nThe sum 1: %lld\nThe sum 2: %lld\n", s1, s2 );
if ( s1 == s2 )
{
puts( "They are the same" );
}
return 0;
}
Its output might look like
The matrix is:
55 81 79 14 75
89 70 41 27 73
94 14 79 85 45
66 92 27 90 67
14 85 79 53 83
The sum 1: 377
The sum 2: 287
Or if your compiler supports C99 then the program can look like
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define N 5
#define VALUE_MAX 100
int main(void)
{
int a[N][N];
srand( ( unsigned int )time( NULL ) );
printf( "The matrix is:\n" );
for ( size_t i = 0; i < N; i++ )
{
printf ( "\n\n" );
for ( size_t j = 0; j < N; j++ )
{
*( *( a + i ) + j ) = rand() % VALUE_MAX;
printf ( "%d ", *( *( a + i ) + j ) );
}
}
long long int s1 = 0ll;
long long int s2 = 0ll;
for ( size_t i = 0; i < N; i++ )
{
s1 += a[i][i]; // main diagonal
s2 += a[i][N - i - 1]; // second diagonal
}
printf( "\n\nThe sum 1: %lld\nThe sum 2: %lld\n", s1, s2 );
if ( s1 == s2 )
{
puts( "They are the same" );
}
return 0;
}

Sorting array only with while and if

I get a message when I try to run the program. Why?
Segmentation fault
my code:
#include <stdio.h>
void sort_array(int *arr, int s);
int main() {
int arrx[] = { 6, 3, 6, 8, 4, 2, 5, 7 };
sort_array(arrx, 8);
for (int r = 0; r < 8; r++) {
printf("index[%d] = %d\n", r, arrx[r]);
}
return(0);
}
sort_array(int *arr, int s) {
int i, x, temp_x, temp;
x = 0;
i = s-1;
while (x < s) {
temp_x = x;
while (i >= 0) {
if (arr[x] > arr[i]) {
temp = arr[x];
arr[x] = arr[i];
arr[i] = temp;
x++;
}
i++;
}
x = temp_x + 1;
i = x;
}
}
I think that the problem is in the if statement.
What do you think? Why does it happen? I think that I use in positive way with the pointer to the array.
Thank you!
This loop in your program
while (i >= 0) {
//...
i++;
}
does not make sense because i is increased unconditionly.
The program can look the following way
#include <stdio.h>
void bubble_sort( int a[], size_t n )
{
while ( !( n < 2 ) )
{
size_t i = 0, last = 1;
while ( ++i < n )
{
if ( a[i] < a[i-1] )
{
int tmp = a[i];
a[i] = a[i-1];
a[i-1] = tmp;
last = i;
}
}
n = last;
}
}
int main( void )
{
int a[] = { 6, 3, 6, 8, 4, 2, 5, 7 };
const size_t N = sizeof( a ) / sizeof( *a );
for ( size_t i = 0; i < N; i++ ) printf( "%d ", a[i] );
printf( "\n" );
bubble_sort( a, N );
for ( size_t i = 0; i < N; i++ ) printf( "%d ", a[i] );
printf( "\n" );
return 0;
}
The program output is
6 3 6 8 4 2 5 7
2 3 4 5 6 6 7 8
If you want that the sorting function had only one while loop then you can implement it the following way
void bubble_sort( int a[], size_t n )
{
size_t i = 0;
while ( ++i < n )
{
if ( a[i] < a[i-1] )
{
int tmp = a[i];
a[i] = a[i-1];
a[i-1] = tmp;
i = 0;
}
}
}
In your inner loop, you increment i beyond the size of the array. Your algorithm should require you to decrement i instead, but I am not sure this would be enough to fix the sorting algorithm.
You should first try to implement Bubble sort with a single while loop where you compare adjacent items and step back whenever you swap them.

Find element in array with lowest difference from average in C

I need to set the size of array. After that I start to input numbers to dill this array. During that procedure I count sum for calculating average later.
Now I have an array and average and I need to find the element with lowest difference from average.
Like:
array size = 3
input = 1
input = 2
input = 3
average = 2
Counting
abs( 1 - 2 ) = 1
abs( 2 - 2 ) = 0
abs( 3 - 2 ) = 1
So the lowest difference have the element with value 2. And in the end of the program I need to out put that element from array and its index.
So far I came up with:
#include <stdio.h>
#include <stdlib.h>
int main( int argc, char **argv )
{
int n = 0, i = 0;
double average = 0;
int sum = 0;
double tmp = 0;
double min = 0;
int index = 0;
int *a;
double *b;
printf("Amount of elements = ");
scanf("%d", &n);
if( 0 == n )
{
return 0;
}
if( n < 1 || n > 10 )
{
return 0;
}
a = ( int* )malloc( sizeof( *a ) * n );
b = ( double* )malloc( sizeof( *b ) * n );
while( i < n )
{
printf("Input number: ");
scanf("%d", &a[i]);
sum += a[i];
i++;
}
average = ( double )( sum / n );
printf("Average = %.3lf\n", average);
for( i = 0; i < n; i++ )
{
tmp = abs( ( double )( a[ i ] ) - average );
b[ i ] = tmp;
}
/* for( i = 0; i < n; i++ )
{
} */
free( a );
free( b );
return 0;
}
Update: My apologies. The question is how to achive the last part without macking this simple program even more complicated.
Thank you all for help.
You need to use the 2 variables defined to hold the lowest difference and index of the lowest difference in something like
min = b[0]; /* initialize min with b[0] */
index = 0; /* and index with 0 */
for( i = 1; i < n; i++ ) /* loop from 1 onwards ... index 0 was used for initialization */
{
/* maybe change min to b[i] */
/* and index to i */
}
free(a);
free(b);

Resources