I am currently learning the basics of C, and I came across this code. The main function calls Count() and passes 1. And in Count(), 1 is printed and since cnt is less than 5 it'll keep on calling itself and therefore continue to print out 1 2 3 4 5.
After, cnt is 5, then it'll print out 5 and then since cnt is = 5, so it'll print out 5 again (won't satisfy the if condition statement).
void Count(int cnt){
printf("%d\n", cnt);
if(cnt < 5){
Count(cnt + 1);
}
printf("%d\n", cnt);
}
int main(){
Count(1);
}
I thought the output would simply be 1 2 3 4 5 5, but I don't get why its 1 2 3 4 5 5 4 3 2 1.
An easy-to-understand explanation would be appreciated!
First thing to notice is that you have two printf statements in each count function. So you will print the passed number cnt two times in the function.
The second thing you need to know is how the functions are called.
count(1) -> count(2) -> count(3) -> count(4) -> count(5) At count(5) the function will not call any further counts.
Up to here you have printed 1 2 3 4 5
The return will be count(5) -> count (4) -> count (3) -> count(2) -> count (1)
Before each return you will print respectively 5 4 3 2 1
Finally you get
1 2 3 4 5 5 4 3 2 1
The first printf() prints all of the numbers counting up, as each new call to Count() adds another call frame to the stack. This prints
1
2
3
4
5
Once the if condition (which makes the recursion continue) is no longer met, no more recursive calls are made, which allows the recursion to end and the last printf() (located after the if condition) for the most recent stack frame now runs. This prints the 2nd 5. The stack frames on the stack now "unroll", from most recent to least recent, allowing each function call/stack frame to run to completion and thereby perform it's 2nd printf() statement, which now comes out in reverse order (including the 5 I just mentioned above) as:
5
4
3
2
1
Remember that recursion adds stack frames for a given function call, and only after recursion stops going deeper (the end condition is met) does the latter part of the function, after the recursive call to Count(), for each stack frame, now in reverse order on the stack, begin to get run to completion, releasing each stack frame from the stack as each recursive function call on the stack runs through to the end of the function.
Answered from my phone. Forgive the lack of formatting.
Fixed!
Related
I am new to python.
May I ask why the sixth outcome is 8 instead of 5? As I learnt from "scope" that the later statement should not be affected by whatever happened in another inner scope, so i+=3 should have no effect on what "i" is going to be printed? Thank you for the help.
for i in range (0,10):
if i==5:
i+=3
print i
outcome:
0
1
2
3
4
8
6
7
8
9
In the code you created a condition that if the i reaches number 5 it will add +3 giving an 8.
the += adds do not replace.
if you expect that change the number 5 with a 3 try:
for i in range (0,10):
if i==5:
i = 3
print i
This was an interview question.
I was given an array of n+1 integers from the range [1,n]. The property of the array is that it has k (k>=1) duplicates, and each duplicate can appear more than twice. The task was to find an element of the array that occurs more than once in the best possible time and space complexity.
After significant struggling, I proudly came up with O(nlogn) solution that takes O(1) space. My idea was to divide range [1,n-1] into two halves and determine which of two halves contains more elements from the input array (I was using Pigeonhole principle). The algorithm continues recursively until it reaches the interval [X,X] where X occurs twice and that is a duplicate.
The interviewer was satisfied, but then he told me that there exists O(n) solution with constant space. He generously offered few hints (something related to permutations?), but I had no idea how to come up with such solution. Assuming that he wasn't lying, can anyone offer guidelines? I have searched SO and found few (easier) variations of this problem, but not this specific one. Thank you.
EDIT: In order to make things even more complicated, interviewer mentioned that the input array should not be modified.
Take the very last element (x).
Save the element at position x (y).
If x == y you found a duplicate.
Overwrite position x with x.
Assign x = y and continue with step 2.
You are basically sorting the array, it is possible because you know where the element has to be inserted. O(1) extra space and O(n) time complexity. You just have to be careful with the indices, for simplicity I assumed first index is 1 here (not 0) so we don't have to do +1 or -1.
Edit: without modifying the input array
This algorithm is based on the idea that we have to find the entry point of the permutation cycle, then we also found a duplicate (again 1-based array for simplicity):
Example:
2 3 4 1 5 4 6 7 8
Entry: 8 7 6
Permutation cycle: 4 1 2 3
As we can see the duplicate (4) is the first number of the cycle.
Finding the permutation cycle
x = last element
x = element at position x
repeat step 2. n times (in total), this guarantees that we entered the cycle
Measuring the cycle length
a = last x from above, b = last x from above, counter c = 0
a = element at position a, b = elment at position b, b = element at position b, c++ (so we make 2 steps forward with b and 1 step forward in the cycle with a)
if a == b the cycle length is c, otherwise continue with step 2.
Finding the entry point to the cycle
x = last element
x = element at position x
repeat step 2. c times (in total)
y = last element
if x == y then x is a solution (x made one full cycle and y is just about to enter the cycle)
x = element at position x, y = element at position y
repeat steps 5. and 6. until a solution was found.
The 3 major steps are all O(n) and sequential therefore the overall complexity is also O(n) and the space complexity is O(1).
Example from above:
x takes the following values: 8 7 6 4 1 2 3 4 1 2
a takes the following values: 2 3 4 1 2
b takes the following values: 2 4 2 4 2
therefore c = 4 (yes there are 5 numbers but c is only increased when making steps, not initially)
x takes the following values: 8 7 6 4 | 1 2 3 4
y takes the following values: | 8 7 6 4
x == y == 4 in the end and this is a solution!
Example 2 as requested in the comments: 3 1 4 6 1 2 5
Entering cycle: 5 1 3 4 6 2 1 3
Measuring cycle length:
a: 3 4 6 2 1 3
b: 3 6 1 4 2 3
c = 5
Finding the entry point:
x: 5 1 3 4 6 | 2 1
y: | 5 1
x == y == 1 is a solution
Here is a possible implementation:
function checkDuplicate(arr) {
console.log(arr.join(", "));
let len = arr.length
,pos = 0
,done = 0
,cur = arr[0]
;
while (done < len) {
if (pos === cur) {
cur = arr[++pos];
} else {
pos = cur;
if (arr[pos] === cur) {
console.log(`> duplicate is ${cur}`);
return cur;
}
cur = arr[pos];
}
done++;
}
console.log("> no duplicate");
return -1;
}
for (t of [
[0, 1, 2, 3]
,[0, 1, 2, 1]
,[1, 0, 2, 3]
,[1, 1, 0, 2, 4]
]) checkDuplicate(t);
It is basically the solution proposed by #maraca (typed too slowly!) It has constant space requirements (for the local variables), but apart from that only uses the original array for its storage. It should be O(n) in the worst case, because as soon as a duplicate is found, the process terminates.
If you are allowed to non-destructively modify the input vector, then it is pretty easy. Suppose we can "flag" an element in the input by negating it (which is obviously reversible). In that case, we can proceed as follows:
Note: The following assume that the vector is indexed starting at 1. Since it is probably indexed starting at 0 (in most languages), you can implement "Flag item at index i" with "Negate the item at index i-1".
Set i to 0 and do the following loop:
Increment i until item i is unflagged.
Set j to i and do the following loop:
Set j to vector[j].
if the item at j is flagged, j is a duplicate. Terminate both loops.
Flag the item at j.
If j != i, continue the inner loop.
Traverse the vector setting each element to its absolute value (i.e. unflag everything to restore the vector).
It depends what tools are you(your app) can use. Currently a lot of frameworks/libraries exists. For exmaple in case of C++ standart you can use std::map<> ,as maraca mentioned.
Or if you have time you can made your own implementation of binary tree, but you need to keep in mind that insert of elements differs in comarison with usual array. In this case you can optimise search of duplicates as it possible in your particular case.
binary tree expl. ref:
https://www.wikiwand.com/en/Binary_tree
To be clear the following is not my original problem which has data that is much larger and this code is in the context of a larger application and code base. I have reduced my work to the simplest example that’s now at toy or didactic size for clarity and dev and unit testing because that helps a lot for these purposes as well as for sharing on stackexchange. I am experienced in R but not in octave (Matlab). This is code for octave version 4.0.0. I seem to be stuck on translating group computations such as R’s tapply() or by() as well as writing and calling user defined functions (plus a bit of additional processing than those built-ins), but now written in the octave language.
Starting state is an array a as shown:
a = [5 1 8 0; 2 1 9 0; 2 3 3 0; 5 3 9 0]
a =
5 1 8 0
2 1 9 0
2 3 3 0
5 3 9 0
The process I need to do is essentially just this: Group by column 1, find the min statistic in column 3, return the value stored in column 2 of the same row, and write the value to column 4. I want no optional packages to be used. The built-in accumarray and min functions together get me pretty close but I’ve not found the needed syntax. Matlab seems to have many versions of parameter passing syntaxes developed over different releases and please note my code needs to run in Octave 4.0.0.
Final state desired is same array a, but column 4 is updated as shown:
a =
5 1 8 1
2 1 9 3
2 3 3 3
5 3 9 1
My best few code snippets of near-misses and most interesting things among all my failed attempts (not shown, as there are many pages of attempts that do not work) are:
[x,y] = min(a(a(:,1)==5,3),[],1)
x = 8
y = 1
Notice that y is index of row within the group, but not row within the a array, which is fine and good as long as I later do a computation to translate indexes from group-relative to global-relative, and inside there read the value of a(y,2) which is the correct answer value for each row.
>> [x,y] = min(a(a(:,1)==2,3),[],1)
x = 3
y = 2
>> [~,y] = min(a(a(:,1)==2,3),[],1);
>> y
y = 2
Notice that y is all I need from min() since it’s the index of the row of interest.
>> accumarray(a(:,1), a(:,3), [], #([~,y]=min([],[],1)))
parse error:
syntax error
Notice that with some kind of syntax I need to pass to min() in its first parameter the group of values determined by parameters 1 and 2 of accumarray.
I ultimately need to have something like this happen within the group computations after min() returns row index y:
a(y,4) = a(y,2); % y is the desired row index found by min() within each group
So, I tried to write a function that’s named for possibly simpler syntax:
>> function idx = ccen(d)
[~,y]=min(d,[],1);
idx=a(y,2);
end
>> accumarray(a(:,1), a(:,3), [], #ccen)
error: 'a' undefined near line 3 column 5
error: called from
ccen at line 3 column 4
accumarray at line 345 column 14
Seems to me, that to my surprise, a is not accessible to function ccen. Now what can I do? Thank you for reading.
When declaring functions in MATLAB / Octave, any variables declared outside the scope (by default) are not accessible. This means that even though you have a declaration for a, when you create that function, a is not accessible within the scope of the function.
What you can do is modify ccen so that a is supplied to the function so it can access the variable when the function is being called. After, wrap an anonymous function around your call to ccen when calling accumarray. Anonymous functions however do have the luxury of capturing the scope of variables that aren't explicitly declared as input variables into the function:
So first:
function idx = ccen(a, d) %// Change
[~,y]=min(d,[],1);
idx=a(y,2);
end
And now...
out = accumarray(a(:,1), a(:,3), [], #(x) ccen(a,x)); %// Change last parameter
This call is acceptable because the anonymous function is capturing a at the time of creation. Notice how x in the anonymous function is what is piped in from the accumarray calls. You're simply forwarding that as the second parameter to ccen and keeping a constant. This doesn't change the way the function is being run.... it's just resolving a scope issue.
I get the following in Octave:
octave:10> a = [5 1 8 0; 2 1 9 0; 2 3 3 0; 5 3 9 0]
a =
5 1 8 0
2 1 9 0
2 3 3 0
5 3 9 0
octave:11> function idx = ccen(a,d)
> [~,y]=min(d,[],1);
> idx=a(y,2);
> end
octave:12> out = accumarray(a(:,1), a(:,3), [], #(x) ccen(a,x))
out =
0
1
0
0
1
Here is a seemingly simple function to generate prime numbers. However, it does not work as expected. I have trawled the online guides but I can't seem to get my head around it. Your help is much appreciated.
primes = function(limit)
local t = {2}
for i = 3, math.sqrt(limit) do
for k, v in ipairs(t) do
if i % v == 0 then -- check if "i" is evenly divisible by each table element
break
else table.insert(t, i) -- if it is not, it is a prime number
break
end
end
end
return t
end
When I do:
for k, v in ipairs(primes(15)) do print (k, v) end
I get:
1 2
2 3
3 5
4 7
5 9
6 11
7 13
8 15
9 and 15 are not prime numbers, and it looks like the second "for" loop is not going past the first element in the table(2). What is the correct way to use the "for" loop in this case?
Thanks, Vince
EDIT: limited the passed in argument to its square root as suggested.
You're inserting too soon, you have to finish the for loop before you do the insert. Here's one way:
primes = function(limit)
local t = {2}
local is_prime, i_rt
for i = 3, limit do
is_prime=true
i_rt=math.sqrt(i)
for k, v in ipairs(t) do
if i % v == 0 then -- evenly divisible, not prime
is_prime=false
break
end
if v > i_rt then -- break once you exceed square root of i for efficiency
break
end
end
if is_prime then
table.insert(t, i) -- insert if it is a prime
end
end
return t
end
And an example:
> for k, v in ipairs(primes(50)) do print (k, v) end
1 2
2 3
3 5
4 7
5 11
6 13
7 17
8 19
9 23
10 29
11 31
12 37
13 41
14 43
15 47
I think you just need to flip the order of your for loops. As it is, you're testing 3 against every number, then four against every number, then five against every number, and so on. If you switch your two "for" statements, you'll compare 3,4,5... against the first number, 3,4,5... against the second number, 3,4,5... against the third number and so on.
EDIT
Actually, you'll have to do a bit more. You have to make sure that none of 3,4,5... divide the number, and then after the inner for loop, insert the number if nothing has gone in. Furthermore, you should limit your inner loop to stop at sqrt(v), because if nothing under the sqrt(v) divides v, then nothing over sqrt(v) will either (besides v).
EDIT
Actually, I think I misinterpreted your code, and you should ignore what I said. Limit the inner loop to sqrt, but other than that, go with what BMitch said.
An implementation of a brute-force algorithm to solve Sudoku puzzles fails if a cell is discovered in which placing any of the digits 1-9 would be an illegal move.
The implementation is written in C, with the board represented by a 9x9 array. The solver counts down from 9 until a legal number's reached, and if none can be reached, it outputs a zero in its place.
A zero also represents a cell to be filled in. Here's the output (truncated) if a string of zeros (an empty board) is the input:
9 8 7 6 5 4 3 2 1
6 5 4 9 8 7 0 0 0
Those last three zeros are there because the values filled in previously aren't changing. How can I stop the solver from failing like this?
If you would currently put a zero in a spot, instead go back to the previous spot you put a number in and continue to count down till you find another value number for that spot.
For instance, in your example:
9 8 7 6 5 4 3 2 1
6 5 4 9 8 7 0 0 0
Instead of putting the zero in below the three, you would instead go back and try putting a 6 in below the 4.
don't treat every "move" like the right move. E.g. placing the last 7 seemed ok but makes it so that in the next cell no valid moves are left. So upon hitting the "no move possible" situation, go back, and try the next option. Iterate and you will have your solution.
A better way of course would be to start brute forcing for places with a small set of options left; run through all cells and start brute forcing with the cell with the least number of options left. When starting out with all-zero, you would then end up with
9 8 7 6 5 4 3 2 1
6 5 4 0 0 0 0 0 0
3 2 1 0 0 0 0 0 0
which is legal, without backtracking once.
You can do this by pushing your guesses onto a stack. Every time you end up wanting to output a zero, instead pop your last answer off the board and continue counting from it.
So if you guess 3 in (2,3) and next you're looking at (3,3) and get to zero, go back to (2,3) and try 2, then 1, then pop to before your (2,3) guess, etc.