could someone tell me what is wrong with this? - c

Question: wow, you are given two things:
The calling order in which all the processes are called.
The ideal order in which all the processes should have been executed.
Now, let us demonstrate this by an example. Let's say that there are 3 processes, the calling order of the processes is: 3 - 2 - 1. The ideal order is: 1 - 3 - 2, i.e., process number 3 will only be executed after process number 1 has been completed; process number 2 will only be executed after process number 3 has been executed.
Iteration #1:
Since the ideal order has process #1 to be executed firstly, the calling ordered is changed, i.e., the first element has to be pushed to the last place. Changing the position of the element takes 1 unit of time. The new calling order is: 2 - 1 - 3. Time taken in step #1: 1.
Iteration #2: Since the ideal order has process #1 to be executed firstly, the calling ordered has to be changed again, i.e., the first element has to be pushed to the last place. The new calling order is: 1 - 3 - 2. Time taken in step #2: 1.
Iteration #3: Since the first element of the calling order is same as the ideal order, that process will be executed. And it will be thus popped out. Time taken in step #3: 1.
Iteration #4: Since the new first element of the calling order is same as the ideal order, that process will be executed. Time taken in step #4: 1.
Iteration #5: Since the last element of the calling order is same as the ideal order, that process will be executed. Time taken in step #5: 1.
Total time taken: 5 units.
S: Executing a process takes 1 unit of time. Changing the position takes 1 unit of time.
Input format:
The first line a number N, denoting the number of processes. The second line contains the calling order of the processes. The third line contains the ideal order of the processes.
Output format:
Print the total time taken for the entire queue of processes to be executed.
Constraints: 1<=N<=100
SAMPLE INPUT
3
3 2 1
1 3 2
SAMPLE OUTPUT
5
The first method that came to me was to declare a variable and increase it by one after every swap plus 2, but then if we take an array of size 3, there are only two possibilities. Hence I printed those out, and yes guys this is a problem from an online judge, there was no syntax error, but in the site it tells that there was some problem in declaration, I have no clue what to do I am new to programming and can someone suggest a new method which is applicable for arrays of bigger sizes.
#include <stdio.h>
swap(a,b);
long long int a,b;
int main(void) {
long long int n,i;
long long int a[3],b[3];
scanf("%d",&n);
for(i=0;i<=2;i++)
{
scanf("%d",a[i]);
}
for(i=0;i<=2;i++)
{
scanf("%d",&b[i]);
}
if(a[i]=b[i])
{
printf("2");
}
while(a[i]!=b[i])
{
swap(b[0],b[2]);
swap(b[0],b[1]);
{
if(a[i]=b[i])
printf("5");
}
}
return 0;
}
swap(a,b){
long long int temp;
a=temp;
b=a;
temp=b;
return swap(a,b);
}

Your swap() function has multiple issues:
1: It calls itself with return swap(a,b); in the last line of the function. This will result in infinite recursion and a stack overflow.
2: You need to declare the return type of the function. If it takes two long long parameters and returns nothing, then it should be declared as follows:
void swap(long long a, long long b);
3: As written, the function will have no effect anyway. You need to pass pointers to these variables if you want to change their values:
long long swap(long long *a, long long *b);
4: To pass pointers to this function, prefix the parameters with & as follows:
swap(&b[0],&b[2]); /* NOT: swap(b[0],b[2]); */
5: The order of operations in the swap() function is also wrong. You start by irretrievably losing the value of a instead of storing it so that it can be assigned to b. Try this instead:
void swap(long long *a, long long *b) {
long long temp;
temp = *a;
*a = *b;
*b = temp;
}
NOTE: Please learn how to format your code properly. Also, always compile your development code with warnings enabled (e.g., add -Wall -pedantic to the command line). Doing so would have drawn your attention to most if not all of these problems without having to ask here.

Related

Multiple return statements inside recursive function

I'm currently reading "Practical C Programming 3rd Edition" by Steve Oualline.
Currently I'm on the Chapter 2 reading about Recursion, in this chapter the author proposes an exercise where the reader must try to write a recursive function that counts the number of times a number appears in an array.
Please consider the following code:
#include <stdio.h>
size_t count(const int [], size_t, int);
enum {ARRAY_LEN = 11};
int main()
{
const int num_array[ARRAY_LEN] = {1, 2, 3, 4, 5, 5, 6, 7, 3, 9, 0};
int number = 0;
puts("Type a number: (0-9)");
scanf("%d", &number);
printf("Number of appearances: %lu\n", count(num_array, ARRAY_LEN, number));
return 0;
}
size_t count(const int n_array[], size_t arr_len, int num)
{
return arr_len == 0 ? 0 : ( n_array[arr_len - 1] == num ) + count( n_array, arr_len - 1, num );
}
My questions are:
How does C know which return to take back to the main function? Because, in this example we have 3 returns, and all of them in a certain time their conditions become true, so, how does C know that with a return 0; it must exit the recursive function and not continue in search for another return inside the count() function?
Thanks.
When you have recursive function calls, you have multiple "instances" of a function active, calling and returning to each other. To visualize this, I find it useful to imagine that, instead of a C program running on a computer, you have a bunch of people in a room, and you all give them an identical set of instructions, and then you ask them to start solving a problem for you. For the code in your question it would go something like this.
You pick a person and say, "Hey, John, here's an array of size 3: [1, 2, 3]. Can you tell me how many times the number 2 appears in it?"
John takes the array from you, and he looks at his instructions. The array is not of size 0, so he doesn't tell you 0. The last element of his array is not 2, so he doesn't do the second thing, either. But to do the third thing, he needs to make a recursive call, so he picks someone else in the room and he says, "Hey, Mary, here's an array of size 2: [1, 2]. Can you tell me how many times the number 2 appears in it?"
Mary takes the array from John, and she looks at her instructions. The array is not of size 0, so she doesn't tell John 0. But the last element of her array is 2, so she does do the second thing. But to do the second thing, she also needs to make a recursive call, so she picks someone else in the room and she says, "Hey, Fred, here's an array of size 1: [1]. Can you tell me how many times the number 2 appears in it?"
Fred looks at his instructions. The array is not of size 0, so he doesn't tell Mary 0. The last element of his array is not 2, so he doesn't do the second thing. He, too, needs to make a recursive call to do the third thing, so he picks someone else in the room and says, "Hey, Jane, here's an array of size 0: []. Can you tell me how many times the number 2 appears in it?"
Jane looks at her array, and the size is 0. So she says, "Fred, the number of times that 2 appears in that array is: 0".
That's what Fred was waiting for. Fred was working on the third return statement, so whatever he hears from Jane is his answer, too. He says, "Mary, the number of times that 2 appears in that array is: 0".
That's what Mary was waiting for. But she was working on the second return statement, so she adds 1 to whatever she hears from Fred. She says, "John, the number of times that 2 appears in that array is: 1".
That's what John was waiting for. John was working on the third return statement, so whatever he hears from Mary is his answer, too. He says to you, "The number of times that 2 appears in that array is: 1".
And now you have your answer!
I used to teach a C programming class, and one day I gave everyone in the class a handout which was some human-readable instructions on how to do a recursive, in-order traversal of a binary tree. Then I handed a "binary tree" -- a piece of cardboard with a bunch of yellow stickies arranged on it in a tree-like structure -- to a random student in the front row, to start traversing. It was absolute pandemonium, but also great fun. (I think. I thought it was fun, anyway!)
CPUs have a stack. This is a very important data structure, which describes execution context. A stack may look like this:
count(4, {10, 20, 30}, 3)
count(4, {10, 99, 33, 22}, 4)
count(4, {10, 99, 33, 22, 44}, 5)
main(1)
When a CPU calls a function, it adds another stack frame on top (actually, some people or debuggers visualize it upside-down, so it may be at the bottom).
When a CPU returns from a function, it removes a stack frame from the top, and continues from an execution point which is now at the top.
If you visualize this stack, you will see that each return statement doesn't have any definite destination - it's the stack which tells CPU where to continue execution. If main calls count, it returns to main, but if count calls count, it returns to count. But not only that - it remembers which invocation to return to.
A stack frame contains a copy of all the parameters with which a function was called, and a copy of the function's local variables (it's not always a copy, but the simplest and most important case is when it's really a copy).
For starters the function definition with multiple return statements is bad.
Moreover the function should be declared like
size_t count( const int [], size_t, int );
The function can be defined the following way
size_t count( const int a[], size_t n, int num )
{
return n == 0 ? 0 : ( a[n-1] == num ) + count( a, n - 1, num );
}
That is the return type of the function shall be size_t. The first parameter of the function shall have the qualifier const because the array passed to the function is not changed within the function.
And in main you should write
printf( "Number of appearances: %zu\n", count( num_array, ARRAY_LEN, number ) );
As for your question then it is clear that the control within the function will be passed to a return statement dependent on used conditions in the if statements.
if the value of arr_len is equal to 0 then the control will be passed to the return statement inside this if statement.
if(arr_len == 0)
return 0;
Pay attention to that in each recursive call of the function the value of the parameter arr_len is decremented.
So it is the base case of the function when arr_len is equal to 0. In this case the function stops its execution.
Otherwise if arr_len is not equal to 0 then if the last element of the array is equal to num then 1 is added the value returned by the next recursive call and the sum is returned. Otherwise if the last element of the array is not equal to num then the value returned by the next recursive call of the function is returned.
if(n_array[arr_len - 1] == num)
return (1 + count(num, n_array, arr_len - 1));
else
return count(num, n_array, arr_len -1);
This is what recursive programming is all about.
The code uses the first return it encounters in the if chain. If that return recursively calls "count" then that return is put on hold until the nested "count" call returns. This continues until everything has returned on arr_len == 0.

In a C program for adding up to a number then subtracting back to 0 using two parallel threads, I get a non-zero answer. This seems impossible

The program in question is this one:
#include <pthread.h>
#include <stdio.h>
#define NUM_LOOPS 500000000
long long sum = 0;
/* Add or subtract the offset specified in arg from the sum NUM_LOOPS times */
void* counting_function(void* arg) {
int offset = *(int*)arg;
for (int i = 0; i < NUM_LOOPS; i++) {
sum += offset;
}
pthread_exit(NULL);
}
int main(void) {
// Spawn the threads
pthread_t id1;
int offset1 = 1;
pthread_create(&id1, NULL, counting_function, &offset1);
pthread_t id2;
int offset2 = -1;
pthread_create(&id2, NULL, counting_function, &offset2);
// Wait for threads to finish
pthread_join(id1, NULL);
pthread_join(id2, NULL);
printf("Sum = %lld\n", sum);
return 0;
}
I have a global variable long long sum = 0
and a macro for NUM_LOOPS 500000000 that specifies the number to add up to.
The function void* counting_function(void* arg) just adds the offset to sum NUM_LOOPS times.
If I were to run this without threads but calling the functions one after another like this
// sum is 0
counting_function(1);
// sum is now equal to 500000000
countnig_function(-1);
// sum is now equal to 0
I would get the correct answer, 0.
But when using threads, I get a non-zero answer, different every time.
gcc -Wall -Wextra -Werror -std=c99 -pthread count.c && ./a.out
Sum = 40098157
./a.out
Sum = 303575386
It seems to me that in whatever order you add or subtract 1 from a number, if the total amount of summations and subtractions is the same, then the answer should always be 0.
For example, let's say that NUM_LOOPS = 10. The first thread adds 1 three times in a row, then the second thread subtracts 1 two times in a row.
The sum is now going to be equal to 1. Then the first thread does the remaining seven additions, so sum is equal to 8 and then the second thread subtracts the final eight times. The sum is 0.
How can you possibly get an answer that is different than 0? Having an answer different than 0 would mean that one of the two threads added or subtracted more than the specified amount in NUM_LOOPS.
The problem can be solved by adding mutual exclusion to the critical section sum += offset;
inside the counting function, but I can't seem to figure out why it wouldn't work without mutex.
What am I missing?
When a thread adds to sum, it does it in multiple steps: Load sum into a register. Add a value to the register. Store the value from the register into sum. (This might be two steps, such as load-and-add in one step and store in another step.) If a thread switch occurs during this, you can get an interleaving: Thread 1 loads sum, say with value 400 into a register and adds 1 to the register, getting 401. There is a switch, and thread 2 loads sum, still with value 400, into a register and adds −1, getting 399. Then it stores it, so sum is 399. Later, thread 1 stores 401.
Thus, the decrement to 399 is lost; it was overridden by the delayed store of 401.
And of course, thread 2 might run for a while before there is a switch back to thread 1, so there might be quite a number of decrements by thread 2 that are erased by the delayed store from thread 1.
What is likely to happen is a random selection of this interleaving effectively erasing various numbers of adds from one thread or another. Many of them will cancel—some erases of adds will cancel some erases of subtracts, and the results over a number of runs will show a distribution of sums centered on zero (or perhaps near it if the fact that one thread is started before the other skews the distribution).
That is only one problem that can happen with multithreading. Particularly since sum is long long it may be implemented in some target architectures using multiple machine words, so it has to be loaded in multiple steps and stored in multiple steps. Then multithreading can result in one thread storing part of a new value, another thread coming in and modifying sum, and the first thread finishing its storing of the other part. This can produce results more catastrophic than mere missing increments or decrements; it can corrupt the value of sum more profoundly. To avoid this, you want to use an atomic object.
The pthreads library shoehorns parallelism into a language that was designed for single-threaded operation. I recommend studying memory models and how they apply to multi-threaded programming.
Have a look at the Threads and data races section here. There is an example relevant to your problem here.
This wikipedia article has a good section covering race conditions.
It's interesting to note that this problem predates pthreads. You can observe the same behaviour in a 'single-threaded' C program with a signal handler, where both the main program and the signal handler are updating the same variable.
Congratulations on trying it out! You’ve discovered that trying to update the same variable from two threads is buggy.
Some solutions you can try. The ones higher up the list are what you should use if possible.
Give each thread a separate counter, and add the counts together when the threads have returned.
Make the count an atomic variable. Increment and decrement it with atomic_fetch_add_explicit(). In this case, you can use memory_order_relaxed, since the order of updates doesn’t matter. On most processors today, that compiles to a single, lock-free instruction. If it’s important to guarantee that all writes complete before reads, you should use acquire-release memory order instead.
Use the receive-copy-update pattern, in which they try to update the last value of the shared date they saw, and if another thread changes it in between, they retry. (Very inappropriate here, but works well for many other situations).
Have each thread insert its changes into a wait-free list, and the reader thread reconstructs the state from those. (Again, kind of ridiculous here, but worth considering in general.)
Wrap the data to be updated with a lock, or even a reader-writer lock. (Unnecessary here, but some resources require it.)
What am I missing?
The first thing that you are missing is that "yeah yeah I know" is embarrassing when you obviously don't.
Your threads have interleaved execution.
Thread one might load the value of sum (say 0), and before storing a result to it, the thread two might iterate the loop say 1000000 times ( so sum is now 1000000).
Then thread one stores back its copy of sum (0+1), so sum is now 1.
And so on. About the only thing you can predict from your program is than sum will have a value somewhere between -NUM_LOOPS and +NUM_LOOPS.

How does this Decimal to Binary conversion program work?

I was looking for an easy program for the decimal to binary conversion and then, came across the following program using recursion.
void bin(unsigned n)
{
/* step 1 */
if (n > 1)
bin(n/2);
/* step 2 */
printf("%d", n % 2);
}
int main(void)
{
bin(4);
return 0;
}
The output of this program was 100 as expected. But, I'm unable to understand how does it show the output 100 because according to me, the output should be 1 (incorrect) instead of 100.
Here is my interpretation of steps of the bin function.
We will put 4 as an argument of bin first.
4 > 1, therefore, it will again call the bin function with the argument 2.
Now, 2 > 1, therefore, it will again call the bin function with the argument 1.
Since 1 is not greater than 1, we will go to step 2 and the compiler will print 1 (since 1%2=1) and hence, this program should print 1 only and not 100.
Can anyone please explain and guide me where I am wrong?
Perhaps the illustrated sequence will make it easier for you to understand:
bin(4)
bin(2)
bin(1)
printf("%d",1%2); // 1
printf("%d",2%2); // 0
printf("%d",4%2); // 0
You are on the right track,
We will put 4 as an argument of bin first.
bin(4): 4 > 1, therefore, it will again call the bin function with the argument 2. Function execution is not complete yet. Program will return here once the called function is executed
bin(2): Now, 2 > 1, therefore, it will again call the bin function with the argument 1. Function execution is not complete yet. Program will return here once the called function is executed
bin(1): Since 1 is not greater than 1, we will go to step 2 and the compiler will print 1 (since 1%2=1) and hence, this program should print "1". Fcuntion execution complete
bin(2): program now returns to the caller function and prints 0(since 2%2=0). function execution complete
bin(4): program now returns to the caller function and prints 0(since 2%2=0). function execution complete
Hence the ouput is '100'
Dividing an integer by 2 is the same as shifting it right one bit. So using recursion, it shifts the bits to the right until only 1 bit is left (the leftmost bit)
Then it prints this leftmost bit and returns. Upon return, there are still two bits, the leftmost and one-before-leftmost. With the % 2 it discards all leftmost bits and prints this one-before-leftmost. Now it returns and... etc.
This effectively prints the bits left-to-right.
With your logic:
somefunc();
someotherfunc();
When somefunc() is finished doing it's thing, someotherfunc() will not be executed since somefunc() was done.
What happens is that step 2 is done when the call to bin is done or not run at all and then step 2 is always done. Thus Every iteration of bin prints something and since it's after the recursion it does it from the deepest and and up making the printing in reverse order from the actual recursive path.
Every call to binhas it's own local variables so they don't interfere with each other. Thus when the call to bin from bin is done n is the same as before but the returning bin had a n that was half of the caller's n.

Using It's Own Call as One The Parameters in a Function call statement

Here Is my code:
#include <stdio.h>
int mul(int,int);
int main()
{
int sum,m,n;
scanf("%d%d",&m,&n);
sum=mul(10,mul(m,n));
printf("%d",sum);
}
int mul(int x,int y)
{
int sum;
sum=x+y;
return(sum);
}
Input
10
5
Output
25
Can someone tell me why I get 25 as output? Was the function called 2 times?
One during parameters and other time during sum?
It's perfectly simple:
sum=mul(10,mul(m,n));
You're calling mul() with 10 as the first argument, and the return value of mul(m, n) as the second argument.
m and n are 10 and 5, so mul(10, 5) returns 15. The statement in your main function then evaluates to this:
sum = mul(10, 15);
Which is 25.
TL;DR: yes, mul() is called twice. Once with m and n as arguments. The second time with the sum of m and n, adding 10
Using a debugger, or even looking at the assembler output generated by the compiler would've told you there were 2 successive calls to mul.
And yes, as others have rightfully pointed out: reading the help section (in particular how to ask) would be a good idea. It explains that you're expected to do the sensible debugging/diagnostic steps yourself. Only if that didn't solve the problem should you post a question here:
Explain how you encountered the problem you're trying to solve, and any difficulties that have prevented you from solving it yourself.
You merely state that, given input X, you get output Y, and you don't know why.

difficulty in understanding successive recursive calls

I am trying to understand the following program in which successive recursion function calls are present, but getting confused while tracing how the tack gets loaded.
void func(char*); // function prototype
int main(){
func("123");
return 0;
}
void func(char a[]){
if(a[1]=='\0')
return;
func(a+1);
func(a+1);
printf("%c",a[1]);
}
the output for this is 3 3 2
would appreciate if someone could advise on this one...
does this kind of multiple recursive calls beneficial in any way or find application in specific problem areas..?
Just put yourself in the position of the CPU and step through line-by-line (or use a debugger to help with that task).
The first call is to
func("123")
this call does not satisfy the termination condition a[1] == '\0', so it calls
func("23");
The call to func("23") in turn calls
func("3")
which DOES satisfy the return condition. So, that call returns to the previous caller, func("23").
func("23") proceeds to make another call to func("3") due to the lines
func(a+1);
func(a+1);
Continue this process of executing the program in your mind, and write down what would be in each call to printf. That will explain your output.
UPDATE
Note that the call to printf() happens after the recursive calls, so e.g. a call to
func("123")
would proceed like
Enter func("123")
Termination condition not met
Call func("23")
Call func("23") again
Printf("3") (which is a[1])
Return
Debugging with breakpoints is one way to understand recursion. Another way is to draw the tree of recursive calls.
From the figure, In every level after level0, the printf statement occurs after every two nodes owing to these two lines of code:
func(a+1);
func(a+1);
In general, this becomes a perfect binary tree for any input string of length greater than 0. The total number of nodes is given by this formula:
2^(k+1) - 1 // k is the depth; here k = 2
Total number of printf statements executed can be obtained by this formula:
2^k - 1 // For k=2, there will be 3 printf statements each printing 3,3,2 respectively
the posted code is a rather poorly designed instance of recursion.
The following code has the correct 'tail' form of recursion.
It could be made even better by passing the reversed string back to main and let main print it.
It reverses the order of the string passed to func() by main()
Please, when asking about a runtime problem, post code the compiles, including the necessary #includes for header files so we are not guessing about which headers to include
#include <stdio.h>
void func(char*); // function prototype
int main(){
func("123");
return 0;
}
void func(char a[])
{
if(a[1]=='\0') // check for end of recursive sequence
{
printf( "%c", a[0] ); // last tail action
return;
}
func(a+1); // step+next recursion
printf( "%c", a[0] ); // tail action
return;
}
The recursion can be simply understood as follows.
For example:
Func(int a){
while(a>1)
return a * func(a-1);
}
Suppose a = 5.
What happens is that it returns 5 * func(4).
Now func(4) returns 4 * func(3) and it goes on like this.
Check out this example for use of recursion in fibonacci series.

Resources