This program (in C) doesn't output what I'd expect:
int main()
{
int i, j ;
for ( i = 1 ; i <= 2 ; i++ )
{
for ( j = 1 ; j <= 2 ; j++ )
{
if ( i == j )
continue ;
printf ( "\n%d %d\n", i, j ) ;
}
}
}
I think it should be
1 2
1 3
2 1
2 3
But the program outputs
1 2
2 1
Why is this?
Number 3 cannot be ever reached by the loops' indices.
The values of i and j go through this sequence:
i j
---
1 1
1 2
2 1
2 2
Note that the i++ and j++ increments happen after each iteration of the loop body.
The only cases where your printf is called are where i and j are different. That means you get:
1 2
2 1
Related
I have to print this pattern in c
4 4 4 4 4 4 4
4 3 3 3 3 3 4
4 3 2 2 2 3 4
4 3 2 1 2 3 4
4 3 2 2 2 3 4
4 3 3 3 3 3 4
4 4 4 4 4 4 4
And I found this code associated with it
#include <stdio.h>
#include <limits.h>
#include <stdlib.h>
int main()
{
while ( 1 )
{
printf( "Enter a non-negative number (0 - exit): " );
int n;
if ( ( scanf( "%d", &n ) != 1 ) || ( n <= 0 ) ) break;
if ( INT_MAX / 2 < n )
{
n = INT_MAX / 2;
}
int width = 1;
for ( int tmp = n; tmp /= 10; ) ++width;
putchar( '\n' );
int m = 2 * n - 1;
for ( int i = 0; i < m; i++ )
{
for ( int j = 0; j < m; j++ )
{
int value1 = abs( n - i - 1 ) + 1;
int value2 = abs( n - j - 1 ) + 1;
printf( "%*d ", width, value1 < value2 ? value2 : value1 );
}
putchar( '\n' );
}
putchar( '\n' );
}
return 0;
}
I want to know why in this statementscanf( "%d", &n ) != 1 is used
if (( scanf( "%d", &n ) != 1 ) || ( n <= 0 ));
and also how single format specifier is accepting two values here
printf( "%*d ", width, value1 < value2 ? value2 : value1 );
Why % and * are used together"%*d"??
The expression scanf("%d", &n) will attempt to read in an integer into n and, if successful, will return the value 1 (actually, it will return the number of things successfully read but, since you're only asking for one thing, that's the most you'll get back). If it fails, you'll get something else.
Hence the comparison with 1 is to ensure it worked. If you don't get 1, something went wrong.
The statement printf( "%*d ", width, something) is actually closely related to printf("%5d", something) (which would print a field at least five characters wide) but, rather than the fixed 5, the variable width is used instead.
Hence the two printf calls below are equivalent:
int val = 42;
int wid = 5;
printf("%5d", val);
printf("%*d", wid, val);
Since width always appears to be 1 in the code you've given, I'm not sure why it was done that way. It seems to me it would be easier to just use %d as the format specifier.
If you're interested in a more concise and structured solution, you may find this helpful. Don't use this if it's educational work since the intent there is to learn to do it yourself, but it's helpful to see another approach.
This code factors out the logic for doing a single line, printing enough elements to go from the maximum down to one then back up again (but setting a minimum value to print based on the line).
The main code then just prints out enough lines so that the middle value of each line goes from the maximum down to one than back up again (basically the same logic used for each line).
#include <stdio.h>
// Code to print out a single line, values going from max down to min then back up.
static void outLine(int max, int min) {
for (int i = max; i > 0; i--) printf("%d ", i < min ? min : i);
for (int i = 2; i <= max; i++) printf("%d ", i < min ? min : i);
putchar('\n');
}
int main() {
while ( 1 ) {
// Get the value, <1 means stop.
int n;
printf( "\nEnter a non-negative number (< 1 = exit): " );
if ((scanf("%d", &n) != 1) || (n <= 0)) break;
// Do each line, max down to 1 then back up.
for (int i = n; i > 0; i--) outLine(n, i);
for (int i = 2; i <= n; i++) outLine(n, i);
}
return 0;
}
Transcript is, as requested:
pax> ./testProg
Enter a non-negative number (< 1 = exit): 2
2 2 2
2 1 2
2 2 2
Enter a non-negative number (< 1 = exit): 3
3 3 3 3 3
3 2 2 2 3
3 2 1 2 3
3 2 2 2 3
3 3 3 3 3
Enter a non-negative number (< 1 = exit): 4
4 4 4 4 4 4 4
4 3 3 3 3 3 4
4 3 2 2 2 3 4
4 3 2 1 2 3 4
4 3 2 2 2 3 4
4 3 3 3 3 3 4
4 4 4 4 4 4 4
Enter a non-negative number (< 1 = exit): -42
From the C Standard (7.21.6.4 The scanf function)
Returns
3 The scanf function returns the value of the macro EOF if an input
failure occurs before the first conversion (if any) has completed.
Otherwise, the scanf function returns the number of input items assigned, which can be fewer than provided for, or even zero, in the
event of an early matching failure.
In this if statement
if (( scanf( "%d", &n ) != 1 ) || ( n <= 0 ));
the sub-expression ( scanf( "%d", &n ) != 1 ) whether the call of scanf was successful that is whether the variable n got a value from the user. If so (that is in the case of success) then the second sub-expression ( n <= 0 ) checks whether the inputted value is non-positive.
That is if either the call of scanf was not successful or the user eetered a non-positive value the control is passed outside the while loop due to the break statement. As a result the program finishes its execution.
In this call of printf
printf( "%*d ", width, value1 < value2 ? value2 : value1 );
the format conversion specifier %*d specifies that the width of the outputted field (*) will be set as an argument of the call (width) and the expression value1 < value2 ? value2 : value1 selects the maximum value between these two value value1 and value2.
You could rewrite this call pf printf the following way
if ( value1 < value2 )
{
printf( "%*d ", width, value2 );
}
else
{
printf( "%*d ", width, value1 );
}
I have an array called int arr[10] = {1,2,3,4,5}
From my understanding the rest of the array is filled with 0's.
My questions is if its a fixed array length how can I put the first index behind the last index that is not a 0. For example
I believe the 0 is not shown in real printf but I am including it for illustration purposes
for (int i = 0 ; i < 10 ; i++)
{
print("%i" , arr[i]);
}
The output
1 2 3 4 5 0 0 0 0 0
If i move the first index to the back of the 5 like so
for (int i = -1 ; i < 10 ; i++)
{
arr[i] = arr[i + 1];
print("%i" , arr[i]);
}
Will the output put the 1 behind the 5 or at the back of the whole array?
2 3 4 5 1 0 0 0 0 0
or because there is 0s then
2 3 4 5 0 0 0 0 0 1
If my question is unclear please tell me and I will try explain it.
The output
1 2 3 4 5 0 0 0 0 0
No, the actual output is
1234500000
Your code has undefined behavior. The first iteration of the loop (with i = -1) tries to assign to arr[-1], which does not exist:
arr[i] = arr[i + 1];
Similarly, the last iteration (with i = 9) tries to read from arr[10], which also does not exist.
I'm not sure why you think your code will move the first element back.
From my understanding the rest of the array is filled with 0's
You are right.:)
If i move the first index to the back of the 5 like so
for (int i = -1 ; i < 10 ; i++)
{
arr[i] = arr[i + 1];
print("%i" , arr[i]);
}
then you will get undefined behavior because the indices -1 and 10 are not valid indices.
It seems what you are trying to do is the following
#include <stdio.h>
#include <string.h>
int main(void)
{
enum { N = 10 };
int a[N] = { 1, 2, 3, 4, 5 };
size_t pos = 0;
while ( pos < N && a[pos] != 0 ) ++pos;
if ( pos != N && !( pos < 3 ) )
{
int tmp = a[0];
pos -= 2;
memmove( a, a + 1, pos * sizeof( int ) );
a[pos] = tmp;
}
for ( size_t i = 0; i < N; i++ ) printf( "%d ", a[i] );
putchar( '\n' );
return 0;
}
The program output is
2 3 4 1 5 0 0 0 0 0
Link to CodeChef problem MAXSC
Attempted solution:
#include<stdio.h>
int main()
{
long long int n, t, k, i, j, max[701], a[701][701], sum, flag;
scanf( "%lld", &t );
for( k = 0 ; k < t ; k++ )
{
scanf( "%lld", &n );
for( i = 1 ; i <= n ; i++ )
{
for( j = 1 ; j <= n ; j++ )
{
scanf( "%lld", &a[i][j] );
if( j == 1)
max[i] = a[i][1];
if( a[i][j] > max[i] )
max[i] = a[i][j];
}
}
sum = 0, flag = 0;
for( i = 1 ; i <= n-1 ; i++ )
{
if( max[i] < max[i+1])
sum = sum + max[i];
else
{
flag = 1;
break;
}
}
if(flag == 1)
printf("-1\n");
else
{
sum = sum + max[n-1];
printf("%lld\n", sum );
}
}
}
Compute the maximum possible value of E1 + E2 + ... + EN. If it's impossible to pick the elements E1, E2, ..., EN, print -1 instead.
Constraint:
Code should pick N elements, one from each sequence; let's denote the element picked from sequence Ai by Ei. For each i (2 ≤ i ≤ N), Ei should be strictly greater than Ei-1.
Does this constraint mean we have to choose max element from each line?
If you look at example given:
Example Input:
1
3
1 2 3
4 5 6
7 8 9
Output:
18
Explanation
Example case 1: To maximize the score, pick 3 from the first row, 6 from the second row and 9 from the third row. The resulting sum is E1+E2+E3 = 3+6+9 = 18.
If you notice they have mentioned "maximize".
Though my code finds the max, it isn't being accepted.
why is this code not being accepted?
Code's logic is flawed. When max[i] < max[i+1] is false, it sets flag = 1; instead of considering other elements from a[i].
Does this constraint mean we have to choose max element from each line?
No. The goal is a maximal sum, not a sum of maximums.
// if( max[i] < max[i+1])
if(max[i] < max[i+1])
sum = sum + max[i];
else {
flag = 1;
break;
}
The solution lies in tying other elements. Even if that fails, perhaps a prior selection should be changed. Recursion may be employed or other analysis. I think it would make sense to first sort each row of data to avoid this code taking n*n run-time. It should be trivial to code a n*n solution (trying every combination).
As this is homework, leave to OP to develop the solution.
1
3
6 10 12
4 5 7
8 9 10
-1
but output should be 6+7+10=23.
question is given Ei should be strictly greater than Ei-1
1
3
1 2 3
4 5 6
7 8 9
Output is 3+6+9=18 means 3<6 and 6<9 which satisfy the above problem
3
6 10 12
4 5 7
8 9 10
Output is 6+7+10=23 means 12<7 which is false and 6<7 which is true and 7<10 also true so sum=23.
3
8 9 10
11 12 13
10 5 9
Output is -1 because 10<13 is true but 13 is not less than 10 or 5 or 9 which is false hence output is -1.
I want to generate all possible increasing subsequences of numbers (repetition allowed) from 1 to n, but of length k.
Ex. n=3, k=2
Output:
1 1
1 2
1 3
2 2
2 3
3 3
This is my code:
#include <stdio.h>
int s[100];
int n=6;
int k=4;
void subk(int prev,int index)
{
int i;
if (index==k)
{
for(int i=0; i<k; i++)
printf("%d ",s[i]);
printf("\n");
return;
}
s[index]=prev;
for (i=prev; i<=n; ++i)
{
subk(i,index+1);//,s,n,k);
}
}
int main()
{
int j;
for (j = 1; j<=n ; ++j)
{
subk(j,0);
}
return 0;
}
But this generates some unwanted repetitions. How do I eliminate those?
I have tested your code with n = 3 and k = 2 and got the following result:
1 1
1 1
1 1
1 2
1 2
1 3
2 2
2 2
2 3
3 3
This is obviously incorrect, as there are several identical numbers like 1 1 or 1 2.
But what exactly went wrong?
Let's write down the right results if n = 3 and k = 3. Now compare those to the result we got from the program when n = 3 and k = 2.
correct program (incorrect)
k = 3 k = 2
1 1 1 1 1
1 1 2 1 1
1 1 3 1 1
1 2 2 1 2
1 2 3 1 2
1 3 3 1 3
2 2 2 2 2
2 2 3 2 2
2 3 3 2 3
3 3 3 3 3
Now we can see that the incorrect output of the program is the same as the first two columns of the correct answer when we set k = 3. This means that the program solves the problem for 3 columns if we set k = 2, but only displays the first two columns.
You need to stop the program from writing the same number several times.
Solution 1
One way to do this is to execute the for-loop in the subk-function only once when it writes the last number (index == (k - 1)) into the buffer s.
In order to achieve this, you need to add the following two lines to the end of your for-loop.
if (index == (k - 1))
break;
(Instead of the break you could also use return)
After you added these two lines the function should look like this:
void subk(int prev, int index)
{
int i;
if (index == k)
{
for (int i = 0; i<k; i++)
printf("%d ", s[i]);
printf("\n");
return;
}
s[index] = prev;
for (i = prev; i <= n; ++i)
{
subk(i, index + 1);//,s,n,k);
if (index + 1 == k)
break;
}
}
Solution 2
Another way to solve the problem is to move the line s[index] = prev; to the beginning of the function and change the k in the if-statement to k - 1.
Now the function should look like this:
void subk(int prev, int index)
{
int i;
s[index] = prev;
if (index == k - 1)
{
for (int i = 0; i<k; i++)
printf("%d ", s[i]);
printf("\n");
return;
}
for (i = prev; i <= n; ++i)
{
subk(i, index + 1);//,s,n,k);
}
}
With this solution, the for-loop is never executed when the index shows that the program is at the last 'sub-number'. It just displays the number and exits the function because of the return.
You get the right result with both solutions, but I personally like the second solution better, because there is no additional if-statement that is executed every iteration of the for-loop and the program is (slightly) faster.
I would like to loop through two arrays in a semi-zipped fashion, such that for as many entries as possible, the following pattern is observed:
arr1[i] arr2[j]
arr1[i] arr2[j+1]
arr1[i+1] arr2[j+2]
arr1[i+1] arr2[j+3]
....
For example, if len arr1 is 96 and len arr2 is 3, I would like to see
0 0
0 1
1 2
1 0
2 1
2 2
3 0
3 1
4 2
4 0
5 1
5 2
I'm having a little trouble getting the logic exactly right; any help would be greatly appreciated
Pseudocode:
i = 0;
for (x = 0; i < arr1.len; ++x) {
i = x / 2; // integer division
j = x % arr2.len;
// use arr1[i] and arr2[j]
}
Use integer division to repeat a value multiple times before moving on to the next value (e.g. 0 0 1 1 2 2 3 3 ...), where the number of times you want to repeat a value is equal to the denominator.
Use modulo division to repeat a sequence of values indefinitely (e.g. 0 1 2 0 1 2 0 1 2 ...), where the number of items in the sequence is equal to the denominator.
If I have understood you correctly you need a loop like the one shown in the demonstrative program below.
#include <stdio.h>
#define N 10
#define M 3
int main( void )
{
int a[N];
int b[N];
for ( int i = 0; i < N; i++ ) a[i] = i;
for ( int i = 0; i < M; i++ ) b[i] = i;
for (int i = 0, j = 0, k = 1; i < N; i += k ^= 1, j = ( j + 1 ) % M)
{
printf( "%d %d\n", a[i] , b[j] );
}
}
The program output is
0 0
0 1
1 2
1 0
2 1
2 2
3 0
3 1
4 2
4 0
5 1
5 2
6 0
6 1
7 2
7 0
8 1
8 2
9 0
9 1