Multiple components in an array slice - equivalent to perl5: #a[0..1,3] - slice

Very basic question but I can't seem to find anything about multiple ranges in the docs.
How do you select multiple ranges from a perl6 array?
my #a = "a","b","c","d";
#a[0..1,3] # expecting array with a, b & d as p5
This seems to return a sort of nested list, what's the Perl 6 syntax to acheive the result this would yeild in Perl 5 (i.e an array with a, b & d)?

Your question is a little confusing, but assuming you've just got typos or whatever, I'll try to guess what you are asking.
This makes a simple array:
> my #a = "a", "b', "c", "d";
[a b c d]
This makes an anonymous array of a Range from 0..1 and a 3:
> #[0..1,3];
[0..1 3]
If you want it to pull values out of the #a array, you have to refer to it:
> #a[0..1,3];
((a b) d)
pulls the bits you asked for from #a -- The first element is the 0..1 parts of #a, (a,b) -- (Not sure why you want to see c in here..)
That's the nested list -- the two bits you asked for include the list in the first field, and the value d you asked for in the second field.
If you want it flattened instead of nested, you can use .flat:
> #a[0..1,3].flat;
(a b d)

In Raku (formerly known as Perl 6), 0..1 results in a single item, which is a range. In Perl 5, 0..1 immediately expands into two numbers.
One of my most common mistakes in Raku is forgetting to flatten things. The upside is that in Raku, we basically get the equivalent of Perl 5 references for free, which eliminates a lot of messy referencing and dereferencing.

Related

Generating chains from an order of lists

I am searching for how to accomplish something I've somewhat a grasp on, but do not:
I have n number of lists of varying size:
{A, B, C, D}
{1,2}
{X, Y, Z}
...to the nth potentially
How do I generate all possible chains of 1 item from each level A1X, A1Y, A1Z, etc. Its an algotrithmic and mathematic task, no its not homework(I know school is starting), its part of something I'm working on, I have no code --- I just need to be pointed in the right direction to formulate my terms.
(You didn't ask for code, but I tend to use Python for executable pseudo-code. You still need to translate the core algorithm to the language of your choice).
In effect, you are talking about forming the Cartesian Product of the lists. It can be done in various ways. If the number of lists isn't known ahead of time, a recursive approach is the most natural.
Let L1*L2* ... *Ln denote the list of all strings which are of the form
s1+s2+...+sn where si in Li and + is the concatenation operator. For a basis you could either take n ==1, a single List, or n == 0, no lists at all. In many ways the latter is more elegant, in which case it is natural to define the product of an empty list of strings to be the list whose sole element is the empty string.
Then:
Return [''] if n == 0
Otherwise return
[a+b | a ranges over L1 and b ranges over (L2 * L3 * ... * Ln)]
where (L2 * L3 * ... *Ln) was alread computed recursively (which will just be the empty string if n is 1).
The last list can easily be built up in a nested loop, or expressed more directly in any language which supports list comprehensions.
Here is a Python implementation which returns the list of all products given a list of lists of strings (abbreviated as lls in the code):
def product(lls):
if len(lls) == 0:
return ['']
else:
return [a+b for a in lls[0] for b in product(lls[1:])]
Tested like thus:
lists_of_strings = [['A','B','C','D'],['1','2','3'],['X','Y','Z']]
print(product(lists_of_strings))
With output:
['A1X', 'A1Y', 'A1Z', 'A2X', 'A2Y', 'A2Z', 'A3X', 'A3Y', 'A3Z', 'B1X', 'B1Y', 'B1Z', 'B2X', 'B2Y', 'B2Z', 'B3X', 'B3Y', 'B3Z', 'C1X', 'C1Y', 'C1Z', 'C2X', 'C2Y', 'C2Z', 'C3X', 'C3Y', 'C3Z', 'D1X', 'D1Y', 'D1Z', 'D2X', 'D2Y', 'D2Z', 'D3X', 'D3Y', 'D3Z']
In Python itself there isn't much motivation to do this since the itertools module has a nice product and the same product can be expressed as:
[''.join(p) for p in itertools.product(*lists_of_strings)]

Given 2 arrays, returns elements that are not included in both arrays

I had an interview, and did one of the questions described below:
Given two arrays, please calculate the result: get the union and then remove the intersection from the union. e.g.
int a[] = {1, 3, 4, 5, 7};
int b[] = {5, 3, 8, 10}; // didn't mention if has the same value.
result = {1,4,7,8,10}
This is my idea:
Sort a, b.
Check each item of b using 'dichotomy search' in a. If not found, pass. Otherwise, remove this item from both a, b
result = elements left in a + elements left in b
I know it is a lousy algorithm, but nonetheless it's better than nothing. Is there a better approach than this one?
There are many approaches to this problem. one approach is:
1. construct hash-map using distinct array elements of array a with elements as keys and 1 is a value.
2. for every element,e in array b
if e in hash-map
set value of that key to 0
else
add e to result array.
3.add all keys from hash-map whose values 1 to result array.
another approach may be:
join both lists
sort the joined list
walk through the joined list and completely remove any elements that occurs multiple times
this have one drawback: it does not work if input lists already have doublets. But since we are talking about sets and set theory i would also expect the inputs to be sets in the mathematical sense.
Another (in my opinion the best) approach:
you do not need a search through your both lists. you can just sequentially iterate through them:
sort a and b
declare an empty result set
take iterators to both lists and repeat the following steps:
if the iterators values are unequal: add the smaller number to the result set and increment the belonging iterator
if the iterators values are equal: increment both iterators without adding something to the result set
if one iterator reaches end: add all remaining elements of the other set to the result

What does the Ruby sort function do, exactly?

Let me preface this by saying I'm a newbie to Ruby (pretty obvious). I'm learning Ruby on Codecademy and I'm confused by the sort function. To use as an example:
list = [3,2,1,4]
list.sort { |a,b| b <=> a }
I know that this will return the array in descending order - [4, 3, 2, 1]. What I don't understand is why, exactly. I know that when the sort function is called, the numbers from the array are passed into the function and compared, which then returns either -1, 0, or 1 - but then what? For instance, I'm guessing this is what would be compared first:
[3 <=> 2] = 1
But what does it do with the 1 that is returned? And what would the array look like after it gets the 1?
I'm confused because I don't understand how reversing the comparison (a <=> b vs. b <=> a) changes the direction in which the array is sorted. Unless I'm mistaken, doesn't "1 <=> 2" essentially return "1 comes before 2", whereas "2 <=> 1" returns "2 comes after 1"? Which is more or less the same thing, yet the results are obviously different.
The "spaceship" operator, <=> doesn't return something so English as "a comes before b". It returns what sort needs to know: where two elements are in relation to each other. Specifically, it returns the -1, 0, or 1 value you mentioned.
In a <=> b, if a is less than b (via whatever comparison method is used for the class of which a is an instance), the return is -1. If they're equal, return is 0; and if a is greater than b, the return is 1.
When you do b <=> a, the returned value is based on b rather than a, so if a is smaller, you'll get 1, whereas you got -1 when doing a <=> b.
So while the English meaning is the same, the devil is in the details: that -1, 0, or 1 return value. That value tells Ruby precisely how two elements fit into a sorted array.
The magic with those three numbers is in the quicksort algorithm used by Ruby. It's out of scope to try and explain precisely how that algorithm works, but you can basically look at it as a simple comparison on many values. For each item in an array, <=> is called with another item in the array in order to determine where the two items fall relative to each other. Once enough comparisons have been made, the positions of all those individual items is known and the sorting is done.
As a simple (and not really technically accurate, but close enough) example, consider the array [3, 2, 7, 1]. You can grab a value to compare others to in order to start the sorting. We'll pick 3. Running a comparison of 3 with all other numbers gives us:
3 <=> 2 == 1: 3 is greater than 2, so 2 must be to the left of 3. Our array might look like this now: [2, 3, 7, 1]
3 <=> 7 == -1: 3 is less than 7, so 7 must be the the right of 3. Our array continues to look as it did before, as the 7 was already on the right.
3 <=> 1 == 1: 3 is greater than 1, so the 1 must be on the left of 3. Our array looks like this now: [2, 1, 3, 7]
We know the 7 must be correct since it's the only element on the "greater than 3" side. So we just need to figure out the sort order for everything before the 3: 1 and 2. Running a similar comparison as above, we obviously swap the 1 and 2 to get [1, 2, 3, 7].
I hope this helps!
The comparison gets two arguments and returns -1 if the first argument is less than the second argument, 0 if the two arguments are equal, and 1 if the second argument is greater than the first argument. When you swap the two, it inverts the result. <=> doesn’t care about where its operands came from, so although the change doesn’t add any extra information about the relationship between a and b, it does invert the result of <=>, and that inverts the sorting order.
(1 <=> 2) == -1
(2 <=> 1) == 1
As the sorting function, you don’t get 1 <=> 2 or 2 <=> 1; you get -1 or 1. From whichever number, you decide which argument you passed to the comparison should come later in the result.
Unless I'm mistaken, doesn't "1 <=> 2" essentially return "1 comes before 2", whereas "2 <=> 1" returns "2 comes after 1"? Which is more or less the same thing, yet the results are obviously different.
No and yes. The question that is asked of the block is: "does the left element come before or after the right?" And by swapping left and right, you swap the order.
So, the answer is: you aren't reversing the comparison per se, but you are reversing the sort method's idea of which is left and which is right.
The return value of the block is interpreted by sort like this:
0: order doesn't matter
1: the elements are already in the right order
-1: the elements are in the wrong order
By swapping left and right, you swap whether the block tells sort that the elements are in the right or wrong order.
Note that Quicksort is completely irrelevant here. What matters is the contract of the comparator block. Whether that block is then used by Quicksort, Shellsort, Insertion Sort, Bubblesort, Bogosort, Timsort or whatever other comparison-based sort doesn't really matter.

Trying to understand how array.sort works with custom comparer block

I am new to ruby and doing a RubyMonk tutorial. One of the problems is the following. Can someone please enlighten me because I am not understanding the suggested solution?
Problem Statement
Create a method named 'sort_string' which accepts a String and rearranges all the words in ascending order, by length. Let's not treat the punctuation marks any different than other characters and assume that we will always have single space to separate the words.
Example: Given a string "Sort words in a sentence", it should return "a in Sort words sentence".
Suggested Solution:
def sort_string(string)
string.split(' ').sort{|x, y| x.length <=> y.length}.join(' ')
end
My questions are;
1) Why are there two block variables being passed through? Should there only be one, because you are going through every element of the sentence one at a time?
2) I looked up the <=> operator and it states,"Combined comparison operator. Returns 0 if first operand equals second, 1 if first operand is greater than the second and -1 if first operand is less than the second." So aren't we essentially sorting by -1, 0, and 1 then, not the words?
Thank you very much in advance for your help!
1) Why are there two block variables being passed through? Should there only be one, because you are going through every element of the sentence one at a time?
Because that's how the sort method works. It compares two elements at a time, and the block tells it how to compare the two elements. There is a single-element method called sort_by which will only require one which could be used in this case:
def sort_string(string)
string.split(' ').sort_by{|x| x.length}.join(' ')
end
Or even shorter:
def sort_string(string)
string.split(' ').sort_by(&:length).join(' ')
end
2) I looked up the <=> operator and it states,"Combined comparison operator. Returns 0 if first operand equals second, 1 if first operand is greater than the second and -1 if first operand is less than the second." So aren't we essentially sorting by -1, 0, and 1 then, not the words?
Again, this is how sorting works. Sort looks at the result and, depending upon the value -1, 0, or 1 will order the original data accordingly. It's not ordering the results of <=> directly. If you've done any C programming and used strcmp, think about how you would use that function. It's based upon the same concept.
For the first question, if you look at the documentation for the sort method its block form takes two variables
http://www.ruby-doc.org/core-2.0.0/Array.html#method-i-sort
For the second question, the spaceship operator does a comparison between the two operands and then returns -1, 0, or 1, and then you're sorting on the results. Yes, you're sorting on -1, 0, and 1, but those values are obtained from the comparison.
There are two block variables because to sort you need two items - you can't compare one item against nothing or itself.
You are sorting by -1, 0 and 1 - through the words.
Both of these questions are related to the sort method - here's an example which might make it clearer:
(1..10).sort { |a, b| b <=> a } #=> [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
for each number 1 -10, sort looks at 'a' and 'b' - the block arguments. then in the block, the code says to order b higher than a - and this is what it does
The sort function by default sorts the items in some order.
However, if it is passed a block, it uses that block to compare the elements of the array, so that you can define a different, custom order of the elements.
That is, the block has to compare the elements. A minimalistic working version of such comparison is to compare two elements, just to know which one is "greater-or-equal".
This is why the custom block takes two parameters: those are the elements to compare. You don't actually know which one. The sort will perform some sorting algorithm and depending on the internals, it will pick some pairs of elements, compare them using your block, and then, well, it will use that knowledge to reorder the elements in order.
As you provide a block that 'compares', it'd be not very efficient to just return BOOL that says "greater or not". A better and often a bit faster way is to determine if the elements are equal, less, or greater. At once.
arr.sort {|item1, item2}
if item1 < item2 return :lesser
if item1 == item2 return :equal
if item1 < item2 return :greater
}
This is just pseudocode.
With numbers, it is very easy: just subtract them. If you get less-than-zero, you know that the first was lesser. If you get more-than-zero, the first was bigger. If you got zero, they were equal. So, over the time it was 'standarized' way of describing the three-way comparison result to some sorting algorithms.
arr.sort {|item1, item2}
if item1 < item2 return -1
if item1 == item2 return 0
if item1 > item2 return 1
}
or just
arr.sort {|item1, item2}
return item1 - item2
}
Not all types can be subtracted though. Ruby went somewhat further and defined "comparison operator". Instead of just separate </>/==/<=/>=, it provides you with <=> that returns numeric values. -1 meaning that left was lesser and so on.
arr.sort {|item1, item2}
return item1 <=> item2
}
Now, if you provide <=> operator to MyClass, you will be able to sort them easily, even if plain item1-item2 cannot work on non-numeric 'MyClass'..

How do I apply the CYK algorithm to this CFG?

Let CFG G be:
S −→ AB|BA|AC|BD|EE
A −→ a
B −→ b
C −→ EB
D −→ EA
E −→ AB|BA|AC|BD|EE
How do I use the CYK algorithm to determine if the string aabbab is part of the language?
This is the pseudo code I have in my notes:
for i in 1 .. n
V[i,1] = { A | A -> x[i] }
for j in 2..n
for i in 1 .. n-j+1
{
V[i,j] = phi
for k in 1 .. j-1
V[i,j] = V[i,j] union { A | A -> BC where B in V[i,k]
and C in V[i+k,j-k]}
}
But I am not understanding how the answer got to be in an upside down triangular shape.
For example,
V[i,j] i
1(b) 2(a) 3(a) 4(b) 5(a)
1 B A,C A,C B A,C
2 S,A B S,C S,A
j
3 phi B B
4 phi S,A,C
5 S,A,C
^
|_ accept
The pseudocode[*] describes how to apply the algorithm to create the chart.
The [i, j] pair refers to a substring of the input that starts at the ith symbol and extends for j symbols. So [2, 3] refers to a 3-symbol substring, starting at symbol 2. If your input is baaba, then [2, 3] refers to the aab in the middle. (The indexes are 1-based, not 0-based.)
The chart forms a triangle because you can't have a substring that's longer than the input. If the input is 5 symbols long, then you can have a value in [1, 5], but you can't have [2, 5] because that wouldn't refer to a substring anymore. So each row is one box shorter than the row before it, forming the triangle.
V[i, j] refers to a box in the chart. Each box is the set of non-terminals that may have produced the substring described by [i, j].
The algorithm relies on the grammar being in Chomsky Normal Form. In CNF, the right side of each production is either one terminal symbol or two non-terminal symbols. (There's another algorithm that can transform a context-free grammar into CNF.)
Basically, you start with all the 1-symbol substrings of the input. The first loop in your pseudocode fills out the top row (j == 1) of your chart. It looks at all the productions in the grammar, and, if the right side of a production corresponds to that symbol, then the non-terminal on the left side of that production is added to the set V[i, 1]. (Your example seems to have some bogus entries in the first row. The {A, C} sets should be just {A}.)
The algorithm then proceeds through the rest of the rows, looking for all the possible productions that can produce the corresponding substring. For each possible way to split the current substring into two, it looks for a corresponding production. This involves combining pairs of non-terminals from certain boxes on previous rows and checking if there are any productions that produce that pair, thus building a set of non-terminals for that box.
If the box in the last row ends up with a set that contains the start symbol, then the input is valid according to the grammar. Intuitively, it says that the start symbol is a valid production for making the substring that starts at the first symbol and proceeds for the entire length.
[*] It looks like the pseudocode shown in the question contains some transcription errors. You'll want to consult an authoritative source to get the details right.

Resources