I would appreciate if someone could explain why the output of this code:
*a, b = [1, 2, 3, 4]
a[b-2] + b
is 7. Could anyone please break it down line by line so I understand what's going on here? How does this become 7?
To break anything down line by line one could use REPL:
*a, b = [1, 2, 3, 4]
#⇒ [1, 2, 3, 4]
a
#⇒ [1, 2, 3]
b
#⇒ 4
Using splat operator, we have decomposed the original array to new array and the single value. Now everything is crystal clear: a[b-2] which is a[2], which is in turn 3 (check a array.) and b is still 4.
3 + 4
#⇒ 7
when you assign array like this,
*a, b = [1, 2, 3, 4]
then it will assign
a = [1,2,3]
and b = 4
Now when you tried to print a[b-2] + b
a[b - 2] = 3
b = 4
3 + 4 = 7
for more understanding use rails console and run line by line.
*a, b = [1, 2, 3, 4]
a
=> [1, 2, 3]
b
=> 4
a[b-2] // b-2 = 2 find value at index of 2 in a, like a[2] is 3
=> 3
a[b-2]+b
=> 7
*a, b = [1, 2, 3, 4] it means a = [1,2,3] and b = 4 when you do a[b-2] + b it will be
+-----------------------+
a[b-2] + b | a[2] |
a[4-2] + 4 | | |
a[2] + 4 | a[1, 2, 3] |
3 + 4 | 0 1 2 -> index |
= 7 +-----------------------+
By using the splat operator on a we are basically letting a to scoop up all the other numbers that b does not need. So b takes one number from the array and a takes everything that is left.
b = 4
a = [1,2,3]
Now when we do this:
a[b-2] + b
It translates into:
a[4-2] + 4
a[2] + 4
Now we check what number is in position 2 in array a.
3 + 4 = 7
Related
I need to draw an n sample from the uniform distribution on the interval [a,b] such that no two numbers are closer than d > 0. I can draw a sample and check this property and then throw it away and try again if not, but if n is large relative to b-a that could take a looong time. Is there a simple and nice algorithm to solve this problem? The numbers got to be uniformly distributed on [a,b], no deterministic setup.
This problem is equivalent to choosing n numbers greater than or equal to d and whose sum is equal to b - a.
There will be some solution provided that n * d <= b - a. We can write a recursive algorithm that looks for one:
b - a - X < (n - 1) * D
X > b - a - (n - 1) * d
FindSpacedSample(n, d, a, b)
1. if n * d > b - a then return "no solution"
2. avail = [d, b - a - (n - 1) * d]
3. guess = random(avail)
4. print(guess)
5. FindSpacedSample(n - 1, d, a + guess, b)
Example: n = 5, a = 0, b = 10, d = 1, assuming real numbers
FindSpacedSample(5, 1, 0, 10)
5 * 1 >? b - a? no
avail = [1, 10 - 0 - 4 * 1] = [1, 6]
guess = random(avail) = 2 (for the sake of argument)
print(2)
FindSpacedSample(4, 1, 2, 10)
4 * 1 >? 10 - 2? no
avail = [1, 10 - 2 - 3 * 1] = [1, 5]
guess = random(avail) = 4 (for the sake of argument)
print(4)
FindSpacedSample(3, 1, 6, 10)
3 * 1 >? 10 - 6? no
avail = [1, 10 - 6 - 2 * 1] = [1, 2]
guess = random(avail) = 1 (for the sake of argument)
print(1)
FindSpacedSample(2, 1, 7, 10)
2 * 1 >? 10 - 7? no
avail = [1, 10 - 7 - 1 * 1] = [1, 2]
guess = random(avail) = 2 (for the sake of argument)
print(2)
FindSpacedSample(1, 1, 9, 10)
1 * 1 >? 10 - 9? no
avail = [1, 10 - 9 - 0 * 1] = [1, 1]
guess = 1
print(1)
We should also have stopping condition n = 0. Then we get the sequence of spaces 2, 4, 1, 2, 1; we see these sum to ten; and we can get the values as follows:
point1 = 2 = 2
point2 = 2 + 4 = 6
point3 = 2 + 4 + 1 = 7
point4 = 2 + 4 + 1 + 2 = 9
point5 = 2 + 4 + 1 + 2 + 1 = 10
Now, there are a couple of ways in which this result is less than totally uniform:
the first number will never be less than d
earlier numbers tend to be spaced further apart
We can fix these by:
shuffling the spacings before converting to points
subtracting from each point some random value from [0, point1 - a].
So, if we shuffled 2, 4, 1, 2, 1 to 4, 1, 1, 2, 2 we'd get points 4, 5, 6, 8, 10; and if we subtracted 3 from each one (taken randomly between 0 and 4) we'd get 1, 2, 3, 5, 7.
Does this give you a uniform distribution over the set of all possible solutions? I'd be surprised if it did, but I'd also be surprised if what this does give you differs from that truly uniform distribution to an appreciable degree.
Can someone explain this behavior:
a = b = c = 1, 2, 3
a # => [1, 2, 3]
b # => 1
c # => 1
In the assignment a = b = c = 1, 2, 3, the variables a, b, and c should be assigned [1, 2, 3]. Any idea?
Can someone explain why is this happening
#shivam already answered the question, but adding some parentheses might clarify things even more.
a = b = c = 1, 2, 3
is interpreted as:
a = [(b = (c = 1)), 2, 3]
The expression is evaluated in this order:
c = 1
b = ( )
a = [( ), 2, 3]
the variables a, b, and c should be assigned [1, 2, 3]
To get the expected result, you could write:
a = b = c = [1, 2, 3]
which is interpreted as:
a = (b = (c = [1, 2, 3]))
and evaluated in this order:
c = [1, 2, 3]
b = ( )
a = ( )
You are being confused
a=b=c=1,2,3
is actually:
a = (b = c = 1), 2, 3
that leaves
c = 1 # => 1
b = c # => 1
a = 1,2,3 # => [1, 2, 3]
To do what you are talking about you should do as follow:
a,b,c = 1,2,3
p a #=> 1
p b #=> 2
p c #=> 3
I know that, for a k-permutation p of size k, built from n elements, there are:
P(n, k) = n! / (n - k)!
possible k-permutations. For example:
k = 2
n = 4
l = [1, 2, 3, 4]
P(n, k) = 4! / (4 - 2)! = 12
1 2 | 2 1 | 3 1 | 4 1
1 3 | 2 3 | 3 2 | 4 2
1 4 | 2 4 | 3 4 | 4 3
And yet another example:
k = 3
n = 4
l = [1, 2, 3, 4]
P(n, k) = 4! / (4 - 3)! = 24
1 2 3 | 2 1 3 | 3 1 2 | 4 1 2
1 2 4 | 2 1 4 | 3 1 4 | 4 1 3
1 3 2 | 2 3 1 | 3 2 1 | 4 2 1
1 3 4 | 2 3 4 | 3 2 4 | 4 2 3
1 4 2 | 2 4 1 | 3 4 1 | 4 3 1
1 4 3 | 2 4 3 | 3 4 2 | 4 3 2
So, how do I find the index of the k-permutation p? Consider the permutations
to be generated lexicographically.
Edit:
I could start by finding in which "block" p is, addressing the block by the first element of p. For example, for p = [3, 2, 4], the index for p should be at least 12 (counting from 0 to P(n, k) - 1).
But then, to find the second element inside that "block", I'd have to see what are the remaining items to be found, and in which position they will be. I mean, I'd be eventually addressing the list [1, 4], and 4 would be at position 2, so simply using the element as key would require some extra manipulation.
I could use a hash to look up the elements and update their positions, but it'd give me a O(n^2) time complexity. Is it possible to do any better?
The number of permutations for a given digit in a given position is given by a formula
(n-digit position)! / (n-k)! where digit position starts on the left with 1.
To get the number of preceding permutations for a given permutation (that is, its index), multiply the formula for each digit by the number of preceding digits not already used, and add them up.
Example 1, k = 2, n = 4, p = [3,4]
First digit, 3:
(4-1)! / (4-2)! * (number of unused preceding digits, 2) = 6
There are six permutations preceding the first that has 3 in position 1.
Second digit, 4:
(4-2)! / (4-2)! * (number of unused preceding digits, 2) = 2
There are two permutations preceding the first that has 4 in position 2.
Zero based index: 6 + 2 = 8.
Example 2, k = 3, n = 4, p = [3,2,4]
First digit, 3:
(4-1)! / (4-3)! * (number of unused preceding digits, 2) = 12
There are 12 permutations preceding the first that has 3 in position 1.
Second digit, 2:
(4-2)! / (4-3)! * (number of unused preceding digits, 1) = 2
There are two permutations preceding the first that has 2 in position 2.
Third digit, 4:
(4-3)! / (4-3)! * (number of unused preceding digits, 1) = 1
There is one permutation preceding the first that has 4 in position 3.
Zero based index: 12 + 2 + 1 = 15.
TXR language:
$ txr -p "(pos '(1 4 3) (perm '(1 2 3 4) 3))"
5
It is brute force, however; of course pos knows nothing about the structure of permutations.
Use binary search tree (BST). Store all you numbers in it before you start and delete them after you use one. To find x-th element maintain .subtreeSize for every vertex and just descend the tree to find the number you need. Pseudocode:
def findXth(x):
curVertex = BST.root
while:
curPosition = curVertex.leftChild.subtreeSize
if curPosition == x: return curVertex.value
elif curPosition > x: curVertex = curVertex.leftChild
elif curPosition < x: curVertex = curVertex.rightChild
Don't forget to check for vertices existence and to delete the vertex you find.
Overall complexity is going to be O(n log n).
you can reference below function
/**
* list all k or <=k size permutation of a given list with n unique elements.
* n can be bigger than 64. this function will take O(K^N) time, Bad.
*
* #param uniqueList
* #param permutationSize
* #param permutation
* #param only Only show the permutation of permutationSize,
* else show all permutation of less than or equal to permutationSize.
*/
public static void my_permutationOf(List<Integer> uniqueList, int permutationSize, List<Integer> permutation, boolean only) {
if (permutation == null) {
assert 0 < permutationSize && permutationSize <= uniqueList.size();
permutation = new ArrayList<>(permutationSize);
if (!only) {
System.out.println(Arrays.toString(permutation.toArray()));
}
}
for (int i : uniqueList) {
if (permutation.contains(i)) {
continue;
}
permutation.add(i);
if (!only) {
System.out.println(Arrays.toString(permutation.toArray()));
} else if (permutation.size() == permutationSize) {
System.out.println(Arrays.toString(permutation.toArray()));
}
if (permutation.size() < permutationSize) {
my_permutationOf(uniqueList, permutationSize, permutation, only);
}
permutation.remove(permutation.size() - 1);
}
}
E.g. you can think the element is the index
public static void main(String[] args) throws Exception {
my_permutationOf(new ArrayList<Integer>() {
{
add(0);
add(1);
add(2);
add(3);
}
}, 3, null, true);
}
the result is
[0, 1, 2]
[0, 1, 3]
[0, 2, 1]
[0, 2, 3]
[0, 3, 1]
[0, 3, 2]
[1, 0, 2]
[1, 0, 3]
[1, 2, 0]
[1, 2, 3]
[1, 3, 0]
[1, 3, 2]
[2, 0, 1]
[2, 0, 3]
[2, 1, 0]
[2, 1, 3]
[2, 3, 0]
[2, 3, 1]
[3, 0, 1]
[3, 0, 2]
[3, 1, 0]
[3, 1, 2]
[3, 2, 0]
[3, 2, 1]
this is my code to return the elements that are present
exactly once in the array
a = [1,2,2,3,3,4,5]
p a.select{|i| a.count(i) == 1}
# >> [1, 4, 5]
can anyone please suggest how to take the array as keyboard input from user??
print "Enter an array: "
STDOUT.flush
arr = STDIN.gets.chomp.split(/,/).map(&:to_i)
# Enter an array: 1,2,2,3,3,4,5 <ENTER>
arr # => [1, 2, 2, 3, 3, 4, 5]
Here's a pretty concise way of collecting a set amount of input into an array:
n = 7
a = n.times.collect { gets.chomp.to_i }
Then you can use your existing code on a.
irb(main):022:0> a = n.times.collect{gets.chomp.to_i}
1
2
2
3
3
4
5
=> [1, 2, 2, 3, 3, 4, 5]
irb(main):023:0> a.select{|i| a.count(i) == 1}
=> [1, 4, 5]
Below way:
s=gets.chomp
a = s.split("")
Use the gets method to get a string from standard input. (It's short for "get string"!)
chomp removes trailing whitespace, i.e. the newline character that results from pressing enter at the end of your input.
So, calling str = gets.chomp and entering 1 2 2 3 3 4 5 at the prompt will set str to "1 2 2 3 3 4 5". Then, just use str.split to convert it to an array.
I think I can illustrate this best with an example:
Suppose I have A = [ 1, 4, 2, 3;
0,-1, 2, -1]
I want to turn it into
[1, 2, 3, 4;
0, 2, -1, -1]
i.e. keep columns intact, sort by entries in first row. How do I do this?
The sortrows command does what you want:
>> A = [ 1, 4, 2, 3; 0,-1, 2, -1];
>> sortrows(A.').'
ans =
1 2 3 4
0 2 -1 -1
You can also use the second return value from sort to get the column permutation necessary to turn your matrix into the one you want:
>> [~,ii] = sort(A(1,:))
ii =
1 3 4 2
>> A(:,ii)
ans =
1 2 3 4
0 2 -1 -1