Understanding XQuery position(): inclusive or exclusive end position - xquery

I have read a lot of XQuery position, but all examples are about >, <, or =. But you can also use x - y and I am confused as to what is inclusive and what is not.
[position() = $startPosition to $endPosition]
Let's say $startPosition is 1 (as I have read that position does not start with 0 but with 1), what will return the first hit? $endPosition set to 1 as well, or to 2?
In other words, given an expected return of n, what would be the formula for both variables? To make things more clear, we can add an incrementing loop ($iteration). Basically we are generating a search that will find all subsequent hits with position. (As an example.)
$endPosition = 1 + ($iteration * n);
$startPosition = $endPosition - n;
This is what I came up with. This will result in the following outcome, for $iteration starting from 1 and incrementing, and n of 3.
1:
$endPosition = 1 + (1 * 3); // 4
$startPosition = 4 - 3; // 1
2:
$endPosition = 1 + (2 * 3); // 7
$startPosition = 7 - 3; // 4
3:
$endPosition = 1 + (3 * 3); // 10
$startPosition = 10 - 3; // 7
But, is this correct? I am not sure. Is the $endPosition included? If not, my code is correct, if not - it isn't, and then I am interested in the correct formula.

The expression $sequence[position() = $a to $b] is equivalent to the following FLWOR expression (where $position start at 1):
for $x at $position in $seq
where $position >= $a and $position <= $b
return $x
So to skip the first two items and then return the following five, you need $seq[position() = 3 to 7].
Here is how you can go from this to a subsequence function that uses a 0-based offset and the number of items to return:
declare function local:subsequence(
$seq as item()*,
$offset as xs:integer,
$length as xs:integer
) as item()* {
let $start := $offset + 1,
$end := $offset + $length
return $seq[position() = $start to $end]
};
local:subsequence(1 to 100, 0, 5), (: returns (1, 2, 3, 4, 5) :)
local:subsequence(1 to 100, 13, 3) (: returns (14, 15, 16) :)

It's unclear the specific problem you're trying to solve, so I don't know if this answers your question, but let's unpack that expression first:
[position() = $startPosition to $endPosition]
Say $startPosition is 1 and $endPosition is 3. That will evaluate to:
[position() = (1, 2, 3)]
That predicate will return true any time position() equals any of the values in the sequence on the right.

Related

Could someone explain why this function doesn't always return the first element of the list

I have been having a look at some simple recursive functions to wrap my head around the concept. However one example has me a little confused.
The function below uses recursion to obtain the largest integer from a list:
A = [-4, 2, 4]
n = len(A)
def findMaxRec(A, n):
if (n == 1):
return A[0]
else:
return max(A[n - 1], findMaxRec(A, n - 1))
As n will eventually equal 1 why does the function not always return the first element in the list?
In such cases it might be helpful to just write out what code will be executed. I've tried to do that with your function as pseudo-code, where n is replaced with its value:
findMaxRec(A, 3):
if (3 == 1):
return A[0]
else:
return max(A[3 - 1],
findMaxRec(A, 2):
if (2 == 1):
return A[0]
else:
return max(A[2 - 1],
findMaxRec(A, 1):
if (1 == 1):
return A[0]
)
)
Effectively, this results in:
max(A[2], max(A[1], A[0]))
Where the inner call max(A[1], A[0]) = max(2, -4) = 2
And the outer call max(A[2], ...) = max(4, 2) = 4

Pascal recursive summation function school practice problem

This function is a school practice problem (it is running but does not work properly).
My task is to call for a integer from the user.
When the number arrives, my task is to write out (with a recursive algorithm)
what is the sum of the number with the numbers before the given number.
For example if our number is 10 then the upshot is 55 because 1+2+3+4+5+6+7+8+9+10 = 55, etc.
I've already tried to write this code:
function egesszamosszeg(n:integer) : integer;
begin
egesszamosszeg:=0
if n=1 then
egesszamosszeg:=1
else
for n:=1 to egesszamosszeg do
begin
egesszamosszeg:=egesszamosszeg+1;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var egesszam:integer;
begin
egesszam:=strtoint(Inputbox('','Give an integer please!',''));
Showmessage(inttostr(Egesszamosszeg(egesszam)));
end;
My problem is that I do not know what is the main problem with this code.
I do not know what is the main problem with this code.
There are several problems with your code: it's iterative, not recursive; it's way too complicated; this loop:
for n:=1 to egesszamosszeg do
is effectively:
for n:=1 to 0 do
Consider this simple function which effectively implements the gist of your problem:
function egesszamosszeg(n:integer) : integer;
begin
egesszamosszeg := n;
if (n > 1) then
egesszamosszeg := egesszamosszeg + egesszamosszeg(n - 1);
end;
begin
writeln(egesszamosszeg(10));
end.
You are simply trying to increment egesszamosszeg (couldn't you use an easier name?), instead of adding the consecutive numbers to it. But your loop is wrong: eggesszamosszeg is 0, so you are in fact doing for n := 1 to 0 do. That loop will never run. Don't re-use n, use another variable for the loop index:
for i := 1 to n do
egesszamosszeg := egesszamosszeg + i;
But you say it must be recursive, so it must call itself with a different parameter value. Then do something like:
function egesszamosszeg(n: integer): integer;
begin
if n = 1 then // terminating condition
egesszamosszeg := 1
else
egesszamosszeg := n + egesszamosszeg(n - 1); // recursion
end;
In most Pascals, you can use the pseudo-variable Result instead of the function name. Often, that makes typing a little easier.
FWIW, did you know that you could make this a little simpler and do not need recursion or iteration at all? The result can be calculated directly:
function egesszamosszeg(n: Integer): Integer;
begin
result := n * (n + 1) div 2;
end;
For 1..10, that will give 10 * 11 div 2 = 55 too.
See: https://www.wikihow.com/Sum-the-Integers-from-1-to-N
In effect, you count (1+10) + (2+9) + (3+8) + (4+7) + (5+6) = 5 * 11 = 55. You can do the same for any positive number. Same with 1..6: (1+6) + (2+5) + (3+4) = 3 * 7 = 21.
That leads to the formula:
sum = n * (n + 1) div 2
(or actually:
n div 2 * (n+1) // mathematically: n/2 * (n+1)
which is the same).

Learning Binary Search in python 3.7

I found this code on https://www.geeksforgeeks.org/binary-search/
# Python Program for recursive binary search.
# Returns index of x in arr if present, else -1
def binarySearch (arr, l, r, x):
# Check base case
if r >= l:
mid = l + (r - l)/2;
# If element is present at the middle itself
if arr[mid] == x:
return mid
# If element is smaller than mid, then it
# can only be present in left subarray
elif arr[mid] > x:
return binarySearch(arr, l, mid-1, x)
# Else the element can only be present
# in right subarray
else:
return binarySearch(arr, mid+1, r, x)
else:
# Element is not present in the array
return -1
# Test array
arr = [ 2, 3, 4, 10, 40, 50, 80, 140, 200, 2000, 100]
x = 50
# Function call
result = binarySearch(arr, 0, len(arr)-1, int)
if result != -1:
print ("Element is present at index %d" % result)
else:
print ("Element is not present in array")
However, when I run it I get this problem: TypeError: list indices must be integers or slices, not float
I'm not sure how to convert do that. I attempted to set the entire array as an int but that didn't work or replace x with int and that didn't work either.
Any suggestion?
The issue is on this line:
mid = l + (r - l)/2;
In Python 3 / does floating point division and as mid is used as an array index it needs to be an int. To do integer division use //
mid = l + (r - l) // 2;
There is also another issue with the call to the function:
result = binarySearch(arr, 0, len(arr) - 1, int)
The last parameter should not be int but x (the variable you are searching for):
result = binarySearch(arr, 0, len(arr) - 1, x)
when you pass in int as the last parameter you'll get an error TypeError: unorderable types: int() > type()

Recursive approach for pow(x,n) for finding 2^(37) with less than 10 multiplications

The regular recursive approach for pow(x,n) is as follows:
pow (x,n):
= 1 ...n=0
= 0 ...x=0
= x ...n=1
= x * pow (x, n-1) ...n>0
With this approach 2^(37) will require 37 multiplications. How do I modify this to reduces the number of multiplications to less than 10? I think this could be done only if the function is not excessive.
With this approach you can compute 2^(37) with only 7 multiplications.
pow(x,n):
= 1 ... n=0
= 0 ... x=0
= x ... n=1
= pow(x,n/2) * pow (x,n/2) ... n = even
= x * pow(x,n/2) * pow(x,n.2) ... n = odd
Now lets calculate 2^(37) with this approach -
2^(37) =
= 2 * 2^(18) * 2^(18)
= 2^(9) * 2^(9)
= 2 * 2^(4) * 2^(4)
= 2^(2) * 2^(2)
= 2 * 2
This function is not excessive and hence it reuses the values once calculated. Thus only 7 multiplications are required to calculate 2^(37).
You can calculate the power of a number in logN time instead of linear time.
int cnt = 0;
// calculate a^b
int pow(int a, int b){
if(b==0) return 1;
if(b%2==0){
int v = pow(a, b/2);
cnt += 1;
return v*v;
}else{
int v = pow(a, b/2);
cnt += 2;
return v*v*a;
}
}
Number of multiplications will be 9 for the above code as verified by this program.
Doing it slightly differently than invin did, I come up with 8 multiplications. Here's a Ruby implementation. Be aware that Ruby methods return the result of the last expression evaluated. With that understanding, it reads pretty much like pseudo-code except you can actually run it:
$count = 0
def pow(a, b)
if b > 0
$count += 1 # note only one multiplication in both of the following cases
if b.even?
x = pow(a, b/2)
x * x
else
a * pow(a, b-1)
end
else # no multiplication for the base case
1
end
end
p pow(2, 37) # 137438953472
p $count # 8
Note that the sequence of powers with which the method gets invoked is
37 -> 36 -> 18 -> 9 -> 8 -> 4 -> 2 -> 1 -> 0
and that each arrow represents one multiplication. Calculating the zeroth power always yields 1, with no multiplication, and there are 8 arrows.
Since xn = (xn/2)2 = (x2)n/2 for even values of n, we can derive this subtly different implementation:
$count = 0
def pow(a, b)
if b > 1
if b.even?
$count += 1
pow(a * a, b/2)
else
$count += 2
a * pow(a * a, b/2)
end
elsif b > 0
a
else
1
end
end
p pow(2, 37) # 137438953472
p $count # 7
This version includes all of the base cases in the original question, it's easy to run and confirm that it calculates 2^37 in 7 multiplications, and doesn't require any allocation of local variables. For production use you would, of course, comment out or remove the references to $count.

How to find the range for a given number, interval and start value?

Provided the below values
start value = 1
End Value = 20
Interval = 5
I have been provided a number 6. I have to find the range of numbers in which the number 6 falls say now the answer is 6-10.
If the given number is greater than the end value then return the same number.
Is there any formula so that i can generate the range for the number?
UPDATE
I tried the below solution, But it is not working if the range interval is changed,
$end_value = $start_value + $range_interval;
// we blindly return the last term if value is greater than max value
if ($input_num > $end_value) {
return '>' . $end_value;
}
// we also find if its a first value
if ($input_num <= $end_value && $value >= $start_value) {
return $start_value . '-' . $end_value;
}
// logic to find the range for a given integer
$dived_value = $input_num/$end_value;
// round the value to get the exact match
$rounded_value = ceil($dived_value);
$upper_bound_range = $rounded_value*$end_value;
$lower_bound_range = $upper_bound_range - $end_value;
return $lower_bound_range . '-'. $upper_bound_range;
In (c-style) pseudocode:
// Integer division assumed
rangeNumber = (yourNumber - startValue) / rangeLength;
lower_bound_range = startValue + rangeNumber*rangeLength;
upper_bound_range = lower_bound_range + rangeLength-1;
For your input:
rangeNumber = (6-1)/5 = 1
lower_bound_range = 1 + 5*1 = 6
upper_bound_range = 10
and so range is [6, 10]
The answer depends on whether you talk about integers or floats. Since all your example numbers are integers, I assume you talk about those. I further assume that all your intervals contain the same number of integers, in your example 5, namely 1...5, 6...10, 11...15, and 16...20. Note that 0 is not contained in the 1st interval (otherwise the 1st interval had 6 numbers).
In this case the answer is easy.
Let be:
s the start value that is not contained in the 1st interval,
i the interval size, i.e. the number of integers that it contains,
p the provided number to which an interval should be assigned,
b the 1st integer in this interval, and
e the last integer in this interval.
Then:
b = s + (p-s-1)\i * i + 1 (here, "\" means integer division, i.e. without remainder)
e = b + i - 1
In your example:
s = 0, i = 5, p = 6, thus
b = 0 + (6-0-1)\5 * 5 + 1 = 6
e = 6 + 5 - 1 = 10

Resources