What the the variables in following program stores? - list

total_item([],0).
total_item([_|Rest],N) :- total_item(Rest,C), N is C+1.
This program takes an array as input and count the total number of item in that list. But I am not getting what exactly variable N and C stores. Any explanation would be appreciate. Thank you

Read it backwards:
total_item([], 0).
total_item maps 0 to [] (relates the two).
total_item([_ | Rest], N) :-
total_item( Rest, C ),
N is C + 1 .
with C mapped to Rest, C+1 is mapped to [_ | Rest] -- the list one element longer than the list Rest.
See this with the most general query working in the generative fashion:
2 ?- total_item(L, C).
L = [],
C = 0 ;
L = [_G1464],
C = 1 ;
L = [_G1464, _G1467],
C = 2 ;
L = [_G1464, _G1467, _G1470],
C = 3 ;
L = [_G1464, _G1467, _G1470, _G1473],
C = 4 .

Will Ness answer should have provided you with a clear understanding of that predicate definition. But there's more that you can learn from it. Let's do a trace of a simple call. Here I'm using GNU Prolog but most Prolog system provide the same trace functionality:
| ?- trace.
The debugger will first creep -- showing everything (trace)
yes
{trace}
| ?- total_item([1,2,3], N).
1 1 Call: total_item([1,2,3],_285) ?
2 2 Call: total_item([2,3],_354) ?
3 3 Call: total_item([3],_378) ?
4 4 Call: total_item([],_402) ?
4 4 Exit: total_item([],0) ?
5 4 Call: _430 is 0+1 ?
5 4 Exit: 1 is 0+1 ?
3 3 Exit: total_item([3],1) ?
6 3 Call: _459 is 1+1 ?
6 3 Exit: 2 is 1+1 ?
2 2 Exit: total_item([2,3],2) ?
7 2 Call: _285 is 2+1 ?
7 2 Exit: 3 is 2+1 ?
1 1 Exit: total_item([1,2,3],3) ?
N = 3
(1 ms) yes
You can see in the first four lines that the predicate results in walking the list until the end and only then we compute the pending N is C + 1 goals. Each element in the list results in one pending arithmetic evaluation goal. These pending goals must be stored in a stack until the recursive call to the total_item /2 predicate terminates. As a consequence, computing the length of a list of size N requires space (for the stack) proportional to N. I.e. this predicate definition is not tail-recursive.
But we can rewrite the predicate, making it tail-recursive to improve its space complexity by using an accumulator. An accumulator is an argument that stores intermediate results, in this case, the count so far of the number of elements in the list:
total_item(List, Total) :-
total_item(List, 0, Total).
total_item([], Total, Total).
total_item([_| Rest], Total0, Total) :-
Total1 is Total0 + 1,
total_item(Rest, Total1, Total).
Let's trace the same goal:
| ?- total_item([1,2,3], N).
1 1 Call: total_item([1,2,3],_285) ?
2 2 Call: total_item([1,2,3],0,_285) ?
3 3 Call: _382 is 0+1 ?
3 3 Exit: 1 is 0+1 ?
4 3 Call: total_item([2,3],1,_285) ?
5 4 Call: _435 is 1+1 ?
5 4 Exit: 2 is 1+1 ?
6 4 Call: total_item([3],2,_285) ?
7 5 Call: _488 is 2+1 ?
7 5 Exit: 3 is 2+1 ?
8 5 Call: total_item([],3,_285) ?
8 5 Exit: total_item([],3,3) ?
6 4 Exit: total_item([3],2,3) ?
4 3 Exit: total_item([2,3],1,3) ?
2 2 Exit: total_item([1,2,3],0,3) ?
1 1 Exit: total_item([1,2,3],3) ?
N = 3
(1 ms) yes
Notice that how the accumulator, the second argument in the auxiliary total_item/3 predicate is incremented as we walk thew list. With this definition, there are no pending goals, which means the space complexity is O(1) instead of O(N). Much better.

Related

How to write stack for a recursive function having two recursive functions?

I have been stuck on a problem having two recursive functions in it. I could not understand the mechanism of loop and stack behind it. This are the lines of code of my program.
#include<iostream>
using namespace std;
int test(int num)
{
if (num != 0)
{
num = num - 1;
test(num);
cout << num << " ";
test(num);
}
}
int main()
{
test(3);
}
This is the output of the program
0 1 0 2 0 1 0
Can someone explain me the output of this program using stack?
Unroll the recursion. The output in the rightmost column below matches what you are getting.
executed printed
-------- -------
test(3)
test(2)
test(1)
test(0)
cout << 0 0
test(0)
cout << 1 1
test(1)
test(0)
cout << 0 0
test(0)
cout << 2 2
test(2)
test(1)
test(0)
cout << 0 0
test(0)
cout << 1 1
test(1)
test(0)
cout << 0 0
test(0)
For brevity lets call this function f.
What does this function do? Well, it prints something if its argument is positive and calls itself recursively twice, with the argument decreased by 1. If the argument is zero, the function immediately returns, so the recursion starting from positive arguments will be stopped there. For negative arguments we have an error.
Now, What does it do? It decreases its argument, then calls itself on it, prints it, calls itself again. We can draw a diagram like this:
n: [f(n-1) n-1 f(n-1)]
which means that (neglecting the problem of the number of spaces) it prints whatever f(n-1) prints, then n-1 (and a space), then again f(n-1). The first conclusion: the printout will be symmetric about its central element. And it actually is. If you expand this formula a step further, you'll get this:
n-1: [f(n-2) n-2 f(n-2) n-1 f(n-2) n-2 f(n-2)]
So, in the central position there will always be n-1. Its left-hand and right-hand "neighbour substrings" will be identical. n-2 will be seen in this sequence twice. It's not difficult to see that n-3 will be seen 4 times, etc., till 0 will be seen 2^n times. One can even see that 0 will occupy every second position.
How many numbers will we see? 1 + 2 + ... + 2^n = 2^{n-1} -1. For n=2 this gives 2^3 - 1 = 8 - 1 = 7. That's correct.
What may be the "meaning" of this sequence?
Look (n = 5):
0 1 0 2 0 1 0 3 0 1 0 2 0 1 0 4 0 1 0 2 0 1 0 3 0 1 0 2 0 1 0
Now, take the consequtive integers
1 2 3 4 5 6 7 8 9 10 ... 31
and count the number of times each of them is divisible by 2. Can you see? 1 is not divisible by 2, hence 0 in your sequence. 2 is divisible once, hence 1. 3 is not divisible by 2 - hence 0. 4 is divisible twice, hence 2 on the fourth position. Etc., etc.

Can we really avoid extra space when all the values are non-negative?

This question is a follow-up of another one I had asked quite a while ago:
We have been given an array of integers and another number k and we need to find the total number of continuous subarrays whose sum equals to k. For e.g., for the input: [1,1,1] and k=2, the expected output is 2.
In the accepted answer, #talex says:
PS: BTW if all values are non-negative there is better algorithm. it doesn't require extra memory.
While I didn't think much about it then, I am curious about it now. IMHO, we will require extra memory. In the event that all the input values are non-negative, our running (prefix) sum will go on increasing, and as such, sure, we don't need an unordered_map to store the frequency of a particular sum. But, we will still need extra memory (perhaps an unordered_set) to store the running (prefix) sums that we get along the way. This obviously contradicts what #talex said.
Could someone please confirm if we absolutely do need extra memory or if it could be avoided?
Thanks!
Let's start with a slightly simpler problem: all values are positive (no zeros). In this case the sub arrays can overlap, but they cannot contain one another.
I.e.: arr = 2 1 5 1 1 5 1 2, Sum = 8
2 1 5 1 1 5 1 2
|---|
|-----|
|-----|
|---|
But this situation can never occur:
* * * * * * *
|-------|
|---|
With this in mind there is algorithm that doesn't require extra space (well.. O(1) space) and has O(n) time complexity. The ideea is to have left and right indexes indicating the current sequence and the sum of the current sequence.
if the sum is k increment the counter, advance left and right
if the sum is less than k then advance right
else advance left
Now if there are zeros the intervals can contain one another, but only if the zeros are on the margins of the interval.
To adapt to non-negative numbers:
Do as above, except:
skip zeros when advancing left
if sum is k:
count consecutive zeros to the right of right, lets say zeroes_right_count
count consecutive zeros to the left of left. lets say zeroes_left_count
instead of incrementing the count as before, increase the counter by: (zeroes_left_count + 1) * (zeroes_right_count + 1)
Example:
... 7 0 0 5 1 2 0 0 0 9 ...
^ ^
left right
Here we have 2 zeroes to the left and 3 zeros to the right. This makes (2 + 1) * (3 + 1) = 12 sequences with sum 8 here:
5 1 2
5 1 2 0
5 1 2 0 0
5 1 2 0 0 0
0 5 1 2
0 5 1 2 0
0 5 1 2 0 0
0 5 1 2 0 0 0
0 0 5 1 2
0 0 5 1 2 0
0 0 5 1 2 0 0
0 0 5 1 2 0 0 0
I think this algorithm would work, using O(1) space.
We maintain two pointers to the beginning and end of the current subsequence, as well as the sum of the current subsequence. Initially, both pointers point to array[0], and the sum is obviously set to array[0].
Advance the end pointer (thus extending the subsequence to the right), and increase the sum by the value it points to, until that sum exceeds k. Then advance the start pointer (thus shrinking the subsequence from the left), and decrease the sum, until that sum gets below k. Keep doing this until the end pointer reaches the end of the array. Keep track of the number of times the sum was exactly k.

What will be the output of the following pseudo code for input 7?

Please help me to understand the following code and what will be the possiable output.
What will be the output of the following pseudo code for input 7?
1.Input n
2.Set m = 1, T = 0
3.if (m > n)
Go to step 9
5.else
T = T + m
m = m + 1
8.Go to step 3
9.Print T
0
n is less than n so go to step 9 which is print T which is equal to 0 as set in step 2.
T should be 28. It will loop till m>7 (since n=7) and in each iteration T adds m to itself, since T is 0 initially it is only summing up m after incrementing it by 1 in each iteration.So if you add 1+2+3.....+7 you get 28 and that is when the loop breaks since m is now equal to 8.
for m = 1 2 3 4 5 6 7 and for 8 m>n will be true and it will go to step 9
T=(T+M)= 1 3 6 10 15 21 28 basically T is a series where next is added as 2,3,4,5,6,7 to prev number 2 3 4 5 6 7 if one look from other angle

Extract all possible ordered sub-sets

I have a set of elements from which I want to extract ordered subsets. What I mean by ordered subsets is that I cannot switch elements inside the set. I gave three examples to show how I am trying to solve the problem.
How can I extract these subsets recursively?
Do you have any pseudo-code in mind?
{ . } = subset
Example 1
Let S = {f1,f2,f3} be a set composed of 3 elements. I want to extract all the possible ordered sub-sets as follows:
-{f1},{f2},{f3} // {f1} is a subset, {f2} is a subset etc.
-{f1,f2},{f3} // {f1,f2} form a subset and {f3} is also a subset
-{f1},{f2,f3} // {f1} is a subset and {f2,f3} form a subset
Example 2
Let S = {f1,f2,f3,f4} be set a composed of 4 elements.
Possible ordered subsets:
-{f1},{f2},{f3},{f4}
-{f1,f2},{f3,f4}
-{f1},{f2,f3},{f4}
-{f1},{f2},{f3,f4}
-{f1,f2,f3}{f4}
-{f1},{f2,f3,f4}
-{f1,f2},{f3},{f4}
-{f1,f2,f3,f4}
Example 3
Let S = {f1,f2,f3,f4,f5} be set a composed of 5 elements.
Possible ordered subsets:
-{f1},{f2},{f3},{f4},{f5}
-{f1,f2},{f3},{f4},{f5}
-{f1},{f2,f3},{f4},{f5}
-{f1},{f2},{f3,f4},{f5}
-{f1},{f2},{f3},{f4,f5}
-{f1,f2},{f3,f4},{f5}
-{f1},{f2,f3},{f4,f5}
-{f1,f2,f3},{f4,f5}
-{f1,f2,f3},{f4},{f5}
-{f1},{f2,f3,f4},{f5}
-{f1},{f2},{f3,f4,f5}
-{f1,f2},{f3,f4,f5}
-{f1,f2,f3,f4}{f5}
-{f1},{f2,f3,f4,f5}
- etc...
If an array contains the set, modify the array such that there is one space between every element. This space is reserved for partitioning. Take any naming convention. 0 implies no partition whereas 1 implies partition. Now traverse through the array to recursively add 1 or 0 in the partition. All possible combinations can be generated.
Taking Example 1:
S = {f1,f2,f3}
S'= {f1,0,f2,0,f3}
So the subsets will be:
{f1,0,f2,0,f3}, {f1,0,f2,1,f3}, {f1,1,f2,0,f3}, {f1,1,f2,1,f3}
which is same as:
{f1,f2,f3}, {{f1,f2},{f3}}, {{f1},{f2,f3}}, {{f1},{f2},{f3}}
If you don't want the original set to appear in the set of all subsets, just don't consider the state where every partition contains 0.
Let's say set S = {a,b,c,d} contain 4 elements. All the subsets can be generated by writing 2 ^ n - 1 in binary and subsequent subtraction.
a b c d
1 1 1 1 => (a b c d)
1 1 1 0 => (a b c)(d)
1 1 0 1 => (a b d)(c) //The logic is to club all the 1's together
1 1 0 0 => (a b) now 0 0 can be further broken down into (1 1) => (c d) , (1 0) => (c)(d)
1 0 1 1 => (a c d)(b)
1 0 1 0 => (a c) now 0 0 can be further broken down into (1 1) => (b d ), (1 0 ) => (b)(d)
1 0 0 1 => (a d) same steps as above
1 0 0 0 => (a) now left with 3 zeros we have b c d as 3 sets now we can start afresh with 1 1 1 and then go to 1 1 0 and so on.
In this way we are able to generate all the subsets.

Function that given these 2 values produces this third value?

I'm trying to write a function that when given 2 arguments, the 2 leftmost columns, produces the third column as a result:
0 0 0
1 0 3
2 0 2
3 0 1
0 1 1
1 1 0
2 1 3
3 1 2
0 2 2
1 2 1
2 2 0
3 2 3
0 3 3
1 3 2
2 3 1
3 3 0
I know there will be a modulus involved but I can't quite figure it out.
I'm trying to figure out if 4 people are sitting at a table, given the person and target, from the person's perspective which seat is the target sitting in?
Thanks
If a and b are the positions of the two persons, their "distance" is:
(4+b-a) % 4
This also shows that the forth block in your example is wrong.
Assuming that last block of numbers is wrong, I think you're looking for (4 + b - a) % 4 gives c (for columns a b c).