Inscrutable Ruby: Vector Assignment Example - ruby

Consider the following:
a=[0,1] #our starting value
a=[a,1] #=> [[0,1],1] as expected
I would anticipate the following to have the same result:
a=[0,1] #same starting place
a[0]=a #should make a the same thing as it was above, right?
a #=> [[...],1] !!!
In the first example, the second assignment refers to the value of a before the assignment was made. In the second example, the second assignment performs a recursive assignment. This feels like different behavior to me. Is this behavior in fact consistent? If so can someone please explain why?

In the first example you are creating a new array with the value [[0,1], 1]. Then you are reassigning a to refer to this array.
In the second example you are not creating a new array, nor are you changing what a refers to. You are changing the existing array to contain a reference to itself. That's very different.
More details
The first example is roughly equivalent to this code:
a = [0, 1] # Step 1
b = [a, 1] # Step 2
a = b # Step 3
In pictures it looks like this:
Step 1 - create an array:
---
|a|
---
|
v
[0, 1]
Step 2 - create another array which includes a reference to the first:
--- ---
|a| |b|
--- ---
| |
| v
| [ref, 1]
| |
+------------+
v
[0, 1]
Step 3 - change a to point to the array created in step 2:
--- ---
|a| |b|
--- ---
| |
+----------+
v
[ref, 1]
|
+-------------+
v
[0, 1]
On the other hand, the code in the second example gives you this:
---
|a|
---
|
+---+
| v
| [ref, 1]
| |
+-----+
Here there is still only one array, and a still points to it. But now the first element in the array refers to the array itself.

In ruby all variables (without exceptions) are references.
In this case a is a reference to Array. Kinda like a in int *a in C.
By doing a[0] = a you make a an array where the first element is reference to a.

Related

Solve under given group

I've created the group (its GF4 algebra) that has 4 elements:
OrderMat = {0, 1, lambda, lambda + 1}
And definition of operation (.) with this Matrix realized by function:
| 0 | 1 | lambda | lambda+1 |
______________________________________________
0|| 0 | 0 | 0 | 0 |
1|| 0 | 1 | lambda | lambda+1 |
lambda|| 0 | lambda | lambda+1 | 1 |
lambda+1|| 0 |lambda+1| 1 | lambda |
OPMatrix = {{0, 0, 0, 0},
{0, 1, lambda, lambda + 1},
{0, lambda, lambda + 1, 1},
{0, lambda + 1, 1, lambda}}
GF4Mult[x_, y_] := OPMatrix[[Position[OrderMat, x][[1]][[1]]]][[Position[OrderMat, y][[1]][[1]]]]
Now I would like to Solve equations in this group.
for example:
Solve[x.lambda == 1,x] ... x=>lambda+1
or like this:
Solve[GF4Mult[x,lambda]== 1,x] ... x=>lambda+1
Is this possible ? do i have to use some other structure to define group ?
I don't know if this is a good way of doing this, but it seems closer to what you are asking for than the last couple of things I tried. And it uses the notation that you chose, except for Mathematica reordering lambda+1 to be 1+lambda on output.
First let's define your multiplication operator
times={{0,0,0},{0,1,0},{0,lambda,0},{0,lambda+1,0},
{1,0,0},{1,1,1},{1,lambda,lambda},{1,lambda+1,lambda+1},
{lambda,0,0},{lambda,1,lambda},{lambda,lambda,lambda+1},{lambda,lambda+1,1},
{lambda+1,0,0},{lambda+1,1,lambda+1},{lambda+1,lambda,1},{lambda+1,lambda+1,lambda}};
That is exactly what you had except for my flattening that into a vector.
Now lets show a method somewhat similar to Solve that might work for you.
Suppose as a first example you wonder is there a lambda+1*something=lambda+1
Cases[times,{lambda+1,x_,lambda+1}]
and that shows you there is only one value which satisfies that, the identity.
{{1+lambda,1,1+lambda}}
Another example
Cases[times,{lambda+1,x_,lambda}]
gives you
{{1+lambda,1+lambda,lambda}}
Another example, is there lambda+1*anythingBUTlambda+1=lambda
Cases[times,{lambda+1,Except[lambda+1],lambda}]
gives you
{}
which shows there is no such value.
Another example
Cases[times,{lambda+1,x_,Except[x_]}]
gives you
{{1+lambda,1,1+lambda},{1+lambda,lambda,1},{1+lambda,1+lambda,lambda}}
That has a lot of flexibility because you can have unknowns in any position. But because of that flexibility it doesn't just return a single value to you. Perhaps you can use this for what you are thinking of or perhaps you can think of ways to adapt this to what you are trying to do.
If you want to extract one value of a result then you can do things like this:
Cases[times,{lambda+1,x_,lambda}:>x]
which will return
{1+lambda}
which is the value, or values, of x which satisfied that.
Check this carefully to see if you can find any mistakes before you depend on it.

Confusing matrix generation example in Lua

If you want to create NxM matrix in Lua you basically do the following:
function get_zero_matrix(rows, cols)
matrix = {}
for i=1, rows do
matrix[i] = {}
for j=1, cols do
matrix[i][j] = 0
end
end
return matrix
end
However, on the official Lua website I've seen the second variant:
function get_zero_matrix2(rows, cols)
mt = {}
for i=1, rows do
for j=1, cols do
mt[i*cols + j] = 0
end
end
return mt
end
First, I don't understand how it works. How [i*M + j] index is supposed to create rows and columns?
Second, I tried this variant, it works but what it returns is actually an array, not NxM matrix:
M = function get_zero_matrix2(10, 20)
print(#M, #M[1])
> attempt to get length of a nil value (field '?')
Can you please explain how the second variant works?
Maybe I am misinterpreting it.
I don't understand how it works.
For a 2D array of dimension N (rows) x M (cols), the total number of required elements = N * M. Now creating N * M elements in one shot as a single array, we will essentially have a 1D array (flattened 2D array) in memory. Since the formula assumes array index start as 0 and not 1 (the usual Lua's convention), we'll follow 0: the first M items with indices [0, M - 1] form row 0, next M items with indices [M, 2M - 1] form row 1, and so on.
Memory layout for a 5 x 2 array; index 4 in this 1D array is (2, 0) in the 2D array.
--+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+--
... | 0,0 | 0,1 | 1,0 | 1,1 | 2,0 | 2,1 | 3,0 | 3,1 | 4,0 | 4,1 | ...
--+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+--
|-- row 0 --|-- row 1 --|-- row 2 --|-- row 3 --|-- row 4 --|
To access element (i, j), one would get past i - 1 rows and then access the jth item on the ith row. But the index is already one lesser, since the index starts at 0, so i can be used as-is. Thus i * rows + j gives the right index.
How [i*M + j] index is supposed to create rows and columns?
It doesn't. It's an abstraction over a 1D array of numbers, giving the interface of a matrix. In languages like C, declaring a 2D array, most implementations do something similar. int a[2][3] would create an array of 6 integers and do the indexing with the formula above, so this is not an uncommon pattern.
The variant available on Lua PiL is actually representation/mapping of a 2D array as a 1D array.
Basically, consider the following 2x3 array/matrix:
{
{11, 12, 13},
{21, 22, 23}
}
The variant, instead creates it as:
{
[4] = 11,
[5] = 12,
.
.
.
[9] = 23
}
Now, when you want to, let's say, get matrix[1][x], you'll instead fetch:
matrix[1 * rows + x]
It does not, in any way create rows and columns. It is just data stored in a single row of numbers. You will have to implement your own logic; which here, essentially; is i * M + j.
The i*M + j is usually seen in languages with 0-indexing array, like C, where the matrix would be:
{
[0] = 11,
[1] = 12,
[2] = 13,
.
.
.
[5] = 23
}

how to make a sorting method in smalltalk

I am trying to make a new sorting method in smalltalk. Anyone know how to change this sorting java code to squeak?
public static void SelectionSort ( int [ ] num )
{
int i, j, first, temp;
for ( i = num.length - 1; i > 0; i - - )
{
first = 0; //initialize to subscript of first element
for(j = 1; j <= i; j ++) //locate smallest element between positions 1 and i.
{
if( num[j] < num[first] )
first = j;
}
temp = num[first]; //swap smallest found with element in position i.
num[first] = num[ i ];
num[i] = temp;
}
}
Short answer:
You don't have to.
To sort an array, just send it the message #asSortedCollection. For instance, inspect this in a workspace:
#(7 2 8 5) asSortedCollection
Long answer:
Since I assume you want to see how you would implement the equivalent of your Java code in Smalltalk if you really had to, here's a relatively "literal translation" you can test in a workspace (tested in Pharo, should work in Squeak as well):
| someNumbers |
someNumbers := #(7 2 8 5) copy. "See comments below for an explanation."
someNumbers size to: 1 by: -1 do: [:eachOuterIndex |
| indexOfSmallest swapValue |
indexOfSmallest := 1.
1 to: eachOuterIndex do: [:eachInnerIndex |
(someNumbers at: eachInnerIndex) < (someNumbers at: indexOfSmallest)
ifTrue: [ indexOfSmallest := eachInnerIndex ]
].
swapValue := someNumbers at: indexOfSmallest.
someNumbers at: indexOfSmallest put: (someNumbers at: eachOuterIndex).
someNumbers at: eachOuterIndex put: swapValue.
].
^someNumbers
Clearly, there are a few changes from your version, such as using explicit naming, which is one of Smalltalk's hallmark conventions (in particular, indexOfSmallest should be clearer than first, which is misleading since it's not necessarily the first index), and decreasing the scope of the variables you called first and temp). See #Leandro's answer for a version that uses your own variable names if you have trouble with the "translation".
If the code were to live in a method, I would probably put it in the SequenceableCollection hierarchy (or maybe you'd want to add yours as a subclass in there if you want to override other behaviour), and the start of it could look something like this:
copySortedDescending
"Answer a copy of the receiver, sorted in descending order."
| copy |
copy := self copy.
copy size to: 1 by: -1 do: [:eachOuterIndex |
"... and so on..."
].
^copy
Again, note that I'm deliberately changing the name, because I don't think selectionSort is a descriptive name of what the method does, and I wouldn't use a collection as an argument to a method living somewhere else - the knowledge of how to do the sorting belongs on the collection itself.
I'm sure you could come up with a better roll-your-own-answer very easily, though. For instance, you could try sending a SequenceableCollection instance the message sort: and pass a sort block as an argument, in which you could specify how you want your elements to be sorted.
Here is a line by line translation. Row numbers are not part of the code.
1. selectionSort: num
2. | first temp |
3. num size to: 1 by: -1 do: [:i |
4. first := 1. "initialize to subscript of first element"
5. 1 to: i do: [:j |
6. "locate smallest element between positions 1 and i"
7. (num at: j) < (num at: first) ifTrue: [first := j]].
8. temp := num at: first. "swap smallest with element in position i"
9. num at: first put: (num at: i).
10. num at: i put: temp]
Remarks:
No argument type declaration. No answer type.
Block temporaries i and j declared inside blocks (lines 3 and 5). In Smalltalk, indexed collections are 1 based.
num.length() -> num size. Decreasing for loop translates into to:by:do: message.
Assignment = becomes := and 0 becomes 1 (see line remark 2 above.)
Increasing for loop translates into to:do: message.
Comments are enclosed between double quotes.
[j] translates into the at: j message. if translates into an ifTrue: message.
temp could have been declared in the first block: do: [:i | | temp |....
num[j] = temp also becomes a message sending at:put:.
Idem 9. Note also that you could have used the cascade syntax for lines 9 and 10:
num
at: first put: (num at: i);
at: i put: temp
No need to answer num because it's been modified by the method. See, however, the interesting discussion originated in Amos' answer: Why shouldn't I store into literal arrays in Smalltalk?.

Ruby - Find element not in common for two arrays

I've been thinking about a following problem - there are two arrays, and I need to find elements not common for them both, for example:
a = [1,2,3,4]
b = [1,2,4]
And the expected answer is [3].
So far I've been doing it like this:
a.select { |elem| !b.include?(elem) }
But it gives me O(N ** 2) time complexity. I'm sure it can be done faster ;)
Also, I've been thinking about getting it somehow like this (using some method opposite to & which gives common elements of 2 arrays):
a !& b #=> doesn't work of course
Another way might be to add two arrays and find the unique element with some method similar to uniq, so that:
[1,1,2,2,3,4,4].some_method #=> would return 3
The simplest (in terms of using only the arrays already in place and stock array methods, anyway) solution is the union of the differences:
a = [1,2,3,4]
b = [1,2,4]
(a-b) | (b-a)
=> [3]
This may or may not be better than O(n**2). There are other options which are likely to give better peformance (see other answers/comments).
Edit: Here's a quick-ish implementation of the sort-and-iterate approach (this assumes no array has repeated elements; otherwise it will need to be modified depending on what behavior is wanted in that case). If anyone can come up with a shorter way to do it, I'd be interested. The limiting factor is the sort used. I assume Ruby uses some sort of Quicksort, so complexity averages O(n log n) with possible worst-case of O(n**2); if the arrays are already sorted, then of course the two calls to sort can be removed and it will run in O(n).
def diff a, b
a = a.sort
b = b.sort
result = []
bi = 0
ai = 0
while (ai < a.size && bi < b.size)
if a[ai] == b[bi]
ai += 1
bi += 1
elsif a[ai]<b[bi]
result << a[ai]
ai += 1
else
result << b[bi]
bi += 1
end
end
result += a[ai, a.size-ai] if ai<a.size
result += b[bi, b.size-bi] if bi<b.size
result
end
As #iamnotmaynard noted in the comments, this is traditionally a set operation (called the symmetric difference). Ruby's Set class includes this operation, so the most idiomatic way to express it would be with a Set:
Set.new(a) ^ b
That should give O(n) performance (since a set membership test is constant-time).
a = [1, 2, 3]
b = [2, 3, 4]
a + b - (a & b)
# => [1, 4]
The solution for Array divergences is like:
a = [1, 2, 3]
b = [2, 3, 4]
(a - b) | (b - a)
# => [1, 4]
You can also read my blog post about Array coherences

Remove value from Variable

This is probably a very trivial question, but..
Assuming we have a variable 'a' that has a value of 10
Then we have a variable 'b' that has a value of 5
Can I remove the value of 'b' from 'a' (leaving 5) and change the value of a each time?
In my head I think of it as:
a - b = 5
a - b = 0
a - b = -5
etc etc..
Thanks!
Consider this:
a = 10
b = 5
a = a - b
Now the value of a is 5. This is because Ruby evaluates what is on the right side of the assignment operator = first and then assigns that value to whatever is on the left side.
#Another way to put it
a = (a - b)
There is also a shortcut since this type of math is very common
a = a - b
a -= b
# These are both the same
If you want to do this a certain number of times, try a loop.
a = 10
b = 5
3.times do {a -= b}
# a is now -5
For further basic Ruby learning, I would suggest Try Ruby to get you started on concepts as I mentioned above. (Type "next" there to get started)

Resources