PowerShell - Want to understand why $myarr[(-1)..0] gives 10 1 but $myarr[$myarr[-1]..0] gives expected 10 9 8 ... 0 - arrays

I want to better understand what is going on here with PowerShell's range operator.
$myArray = 1..10
so we have $myArray with 1 2 3 4 ... 10
Now I want to use -1 to get the last value in the array and show 1 - 10 in reverse, so I do
$myArray[(-1)..0] but this yields only 10 1 (those two values only, nothing in between).
But if I do $myArray[$myArray[-1]..0] this will yield all the values expected 10 9 8 ... 1
Can anyone give an explanation for this? I would think the (-1) being inside [] would evaluate to the last element or value 10 which it seems to be doing then the range would kick in as 10..0 but it seems like the range is being skipped and giving only the two listed values. This is an exercise just to learn PowerShell, there is no specific application of this I'm after. Btw, I get the same 10 1 only if I run the -1 without the ().
Thanks,
Jason

It is quite simple
Let's see what -1..0 returns:
-1
0
So $myArray[-1..0] is equivalent to the $myArray[-1, 0] hence the result.
But the 10..0 expression returns an entire range reversed. Hence the $myArray[$myArray[-1]..0] expression works as you would expected.

Related

Python scope and loop confusing

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

The meaning of target value of Leetcode Search in Rotated Sorted Array

The original problem is like this:
Suppose a sorted array is rotated at some pivot unknown to you beforehand.
(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).
You are given a target value to search. If found in the array return its index, otherwise return -1.
You may assume no duplicate exists in the array.
The link is here https://oj.leetcode.com/problems/search-in-rotated-sorted-array/
I don't know the meaning of the 'target value' here. Is it the value we want to find or something else? Why it is given to me?
Is it the value we want to find or something else?
Yes, for example, if you have rotated array:
4 5 6 7 0 1 2
and you are given number 6, you should return 2 - the index of 6 in the array (assuming indexes start from 0). If you are given number 8, which doesn't occur in the array - return -1.

Using bsxfun with an anonymous function

after trying to understand the bsxfun function I have tried to implement it in a script to avoid looping. I am trying to check if each individual element in an array is contained in one matrix, returning a matrix the same size as the initial array containing 1 and 0's respectively. The anonymous function I have created is:
myfunction = #(x,y) (sum(any(x == y)));
x is the matrix which will contain the 'accepted values' per say. y is the input array. So far I have tried using the bsxfun function in this way:
dummyvar = bsxfun(myfunction,dxcp,X)
I understand that myfunction is equal to the handle of the anonymous function and that bsxfun can be used to accomplish this I just do not understand the reason for the following error:
Non-singleton dimensions of the two input arrays must match each other.
I am using the following test data:
dxcp = [1 2 3 6 10 20];
X = [2 5 9 18];
and hope for the output to be:
dummyvar = [1,0,0,0]
Cheers, NZBRU.
EDIT: Reached 15 rep so I have updated the answer
Thanks again guys, I thought I would update this as I now understand how the solution provided from Divakar works. This might deter confusion from others who have read my initial question and are confused to how bsxfun() works, I think writing it out helps me understand it better too.
Note: The following may be incorrect, I have just tried to understand how the function operates by looking at this one case.
The input into the bsxfun function was dxcp and X transposed. The function handle used was #eq so each element was compared.
%%// Given data
dxcp = [1 2 3 6 10 20];
X = [2 5 9 18];
The following code:
bsxfun(#eq,dxcp,X')
compared every value of dxcp, the first input variable, to every row of X'. The following matrix is the output of this:
dummyvar =
0 1 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
The first element was found by comparing 1 and 2 dxcp = [1 2 3 6 10 20]; X' = [2;5;9;18];
The next along the first row was found by comparing 2 and 2 dxcp = [1 2 3 6 10 20]; X' = [2;5;9;18];
This was repeated until all of the values of dxcp where compared to the first row of X'. Following this logic, the first element in the second row was calculating using the comparison between: dxcp = [1 2 3 6 10 20]; X' = [2;5;9;18];
The final solution provided was any(bsxfun(#eq,dxcp,X'),2) which is equivalent to: any(dummyvar,2). http://nf.nci.org.au/facilities/software/Matlab/techdoc/ref/any.html seems to explain the any function in detail well. Basically, say:
A = [1,2;0,0;0,1]
If the following code is run:
result = any(A,2)
Then the function any will check if each row contains one or several non-zero elements and return 1 if so. The result of this example would be:
result = [1;0;1];
Because the second input parameter is equal to 2. If the above line was changed to result = any(A,1) then it would check for each column.
Using this logic,
result = any(A,2)
was used to obtain the final result.
1
0
0
0
which if needed could be transposed to equal
[1,0,0,0]
Performance- After running the following code:
tic
dummyvar = ~any(bsxfun(#eq,dxcp,X'),2)'
toc
It was found that the duration was:
Elapsed time is 0.000085 seconds.
The alternative below:
tic
arrayfun(#(el) any(el == dxcp),X)
toc
using the arrayfun() function (which applies a function to each element of an array) resulted in a runtime of:
Elapsed time is 0.000260 seconds.
^The above run times are averages over 5 runs of each meaning that in this case bsxfun() is faster (on average).
You don't want every combination of elements thrown into your any(x == y) test, you want each element from dxcp tested to see if it exists in X. So here is the short version, which also needs no transposes. Vectorization should also be a bit faster than bsxfun.
arrayfun(#(el) any(el == X), dxcp)
The result is
ans =
0 1 0 0 0 0

MATLAB: Return the largest number in an array?

I'm new to MATLAB (and this website!) and I needed some help with a problem I had been assigned for class. I searched this website for similar MATLAB problems, but I didn't come across any. The problem is asking the user to return the biggest number which is next to a zero. In other words, write a function which takes a list/array of numbers as input and returns the largest number which is adjacent to a zero. For instance, if
a=[1 -2 3 4 0 5 6 0 -7], Output: y=6.
I tried to solve the problem using a somewhat complex function I found online, and it seems to work on MATLAB. However, it won't work on our automated online MATLAB grading system as the command "imdilate" isn't recognized:
x=[1 2 0 4 5 -6 0 7 0 8]
zero_mask = (x == 0);
adjacent_to_zero_mask = imdilate(zero_mask, [1 0 1]);
max_value_adjacent_to_zero = max(x(adjacent_to_zero_mask));
y=max_value_adjacent_to_zero
I wanted to ask, is there is much simpler method of solving this problem not involving "imdilate" or other similar functions?
Thank you for your help, I really appreciate it!
I came up with a dirty solution:
a=[0 1 -2 3 4 0 5 6 0 -7];
I=find(a==0);
I=unique([I+1,I-1]);
I=I((I>0)&(I<=length(a)));
output = max(a(I));

How can I iterate subranges in a "cyclic array"?

I'm trying to write the following Perl subroutine. Given are an array a of length n, an index i in the array (0<=i<n an upstream window length u and a downstream window length d.
I want to iterate over the values in the upstream window and the downstream window to i. In the simplest case, this will iterating over the values in a[i-u..i-1] (upstream window) and a[i+1..i+d] (downstream window).
For example: if my array is 1 2 3 4 5 6 7 8 9 10, i=5 and both window sizes are 2, the upstream values are simply 6 7 and the downstream values are 9 10.
However, there are two complications:
I would like to consider my array is cyclic. If i is relatively small (close to
0) or large (close to n), then one
of the windows may not fit in the
array. In that case, I want to look
at the array as a cyclic one. for
example, if my array is 1 2 3 4 5 6 7 8 9 10, i=8 and both window sizes
are 4, the upstream values are
simply 4 5 6 7, but the downstream
values are 9 10 1 2.
I would prefer some way to iterate
over these values without explicitly
copying them into a new array, since
they might be very long.
You can just get a list of indices using the range operator (..) by subtracting the upstream window from $i and adding the downstream window to $i. You will need to remember to skip the iterator when the iterator is equal to $i if you don't want that $ith value.
You will need to use the modulo operator (%) to keep the index within the bounds of the array. Given an array of size 11, we can see that by modifying the index with 11 it will always point to the right place in the array:
#!/usr/bin/perl
use strict;
use warnings;
for my $i (-22 .. 22) {
print "$i => ", $i % 11, "\n";
}
You may run into problems with huge numbers (i.e., numbers larger than what your platform holds in an unsigned integer), because Perl 5 changes the algorithm the modulus uses around there. It becomes more like C's fmod (but there are some differences).
You may also want to not use the integer pragma. It makes % faster, but you get the behavior of the C modulo operator. Neither ANSI nor ISO define what C should do with negative numbers, so you may or may not get a valid index back. Of course, so long as the version of C spits back either
X -5 -4 -3 -2 -1 0 1
X%5 0 -4 -3 -2 -1 0 1
or
X -5 -4 -3 -2 -1 0 1
X%5 0 1 2 3 4 0 1
it should be fine (if not very portable).
It looks like C99 defines the modulo operator to return the second case, so long as perl gets compiled with a C99 compiler (with the C99 flag on) it should be safe to use the integer pragma.

Resources