Overwrite first n elements of an array? - ruby

Here's my scenario:
a = ["","","","","","","","","",""] #10 elements. Need not always be blank.
b = ["a","b","c","d"]
I want to modify a such that the first n elements of a are replaced with the elements of b where n = b.size():
a = ["a","b","c","d","","","","","",""]
So, is there something simple like a.replace(b) minus the truncation?
An alternative would be a way to append a.size() - b.size() number of elements to b.

You can use slicing:
a[0, 4] = b
or with a dynamic length:
a[0, b.length] = b

Related

special pythagorean triplets

def pythagorean(n):
aAndB = []
for a in range(150, n-1):
for b in range(150, n):
for c in range(150,n+1):
if (c * c) == a *a + b*b and a + b + c == 1000:
aAndB.append(a)
return aAndB
print(pythagorean(500))
So I made this function to find pythagorean triplets that meets criteria a+b+c=1000. When I run this, I get [200,375]. Question is why do I receive two numbers in my list aAndB when I specifically asked to append an item for a?
If I try it with aAndB.append(c), the result shows [425, 425]. How do I fix it only to show exactly one element in the list?
Thank you for your help!
That's because there are 2 values, that satisfy your condition:
if (c * c) == a *a + b*b and a + b + c == 1000:
You can debug the code or just add more information in array, like that:
def pythagorean(n):
aAndB = []
for a in range(150, n-1):
for b in range(150, n):
for c in range(150,n+1):
if (c * c) == a * a + b * b and a + b + c == 1000:
aAndB.append({'a': a, 'b': b, 'c': c})
return aAndB
result = pythagorean(500)
for v in result:
print(v)
So if you want just one element - choose which one from 'result' array.
For example, if you want only first:
first_element = None
if len(result) > 0:
first_element = result[0]
print('First element:', first_element)
You can use euclid’s proof of pythagoreas triplets. You can choose any arbitrary numbers greater than zero say m,n. According to euclid the triplet will be a(m∗m−n∗n),b(2∗m∗n),c(m∗m+n∗n). Now apply this formula to find out the triplets , say our one value of triplet is 6 then, other two.
a(m∗m−n∗n),b(2∗m∗n),c(m∗m+n∗n)
It is sure that b(2∗m∗n) is obviously even. So now
(2∗m∗n)=6 =>(m∗n)=3 =>m∗n=3∗1 =>m=3,n=1
You can take any other value rather than 3 and 1 but those two values should hold the product of two numbers is 3 (m∗n=3).
Now , when m equals 3 and n equals 1 then
a(m∗m−n∗n)=(3∗3−1∗1)=8 , c(m∗m−n∗n)=(3∗3+1∗1)=10
6,8,10 is our triplet for value this our visualization of how generating triplets .
If given number is odd like (9) then slightly modified here, because b(2∗m∗n) never be odd. So, here we have to take
a(m∗m−n∗n)=7 , (m+n)∗(m−n)=7∗1 , So,(m+n)=7,(m−n)=1
Now find m and n from here then find other two values.
Do code according this , it will generate distinct triplets and efficiently

find all indices of multiple value pairs in a matrix

Suppose I have a matrix A, containing possible value pairs and a matrix B, containing all value pairs:
A = [1,1;2,2;3,3];
B = [1,1;3,4;2,2;1,1];
I would like to create a matrix C that contains all pairs that are allowed by A (i.e. C = [1,1;2,2;1,1]).
Using C = ismember(A,B,'rows') will only show the first occurence of 1,1, but I need both.
Currently I use a for-loop to create C, which looks like:
TFtot = false(size(B(:,1,1),1);
for i = 1:size(a(:,1),1)
TF1 = A(i,1) == B(:,1) & A(i,2) = B(:,2);
TFtot = TF1 | TFtot;
end
C = B(TFtot,:);
I would like to create a faster approach, because this loop currently greatly slows down the algorithm.
You're pretty close. You just need to swap B and A, then use this output to index into B:
L = ismember(B, A, 'rows');
C = B(L,:);
How ismember works in this particular case is that it outputs a logical vector that has the same number of rows as B where the ith value in B tells you whether we have found this ith row somewhere in A (logical 1) or if we haven't found this row (logical 0).
You want to select out those entries in B that are seen in A, and so you simply use the output of ismember to slice into B to extract out the affected rows, and grab all of the columns.
We get for C:
>> C
C =
1 1
2 2
1 1
Here's an alternative using bsxfun:
C = B(all(any(bsxfun(#eq, B, permute(A, [3 2 1])),3),2),:);
Or you could use pdist2 (Statistics Toolbox):
B(any(~pdist2(A,B),1),:);
Using matrix-multiplication based euclidean distance calculations -
Bt = B.'; %//'
[m,n] = size(A);
dists = [A.^2 ones(size(A)) -2*A ]*[ones(size(Bt)) ; Bt.^2 ; Bt];
C = B(any(dists==0,1),:);

Counting bits in an array

Given that we know how many bits are set in N elements that is if say we have array A and array of array B .
A store element
B[i] store positions of bits set corresponding to A[i].
Then question is can we find how many bits are set in sum of all A[i] for 1<=i<=N using this B array.
Like say we have A=[700,40]
As 700 is 1010111100 so we have [2 3 4 5 7 9]
As 40 is 101000 so we have [3 5]
B is [[2,3,4,5,7,9],[3,5]]
And we want count of bits set in 740.
How this can be done in efficient way ? Please help
This is about binary addition. In your example
A[0] = 1010111100 B[0] = [2,3,4,5,7,9]
A[1] = 0000101000 B[1] = [3,5]
A[0]+A[1] = 1011100100
So the sum is represented as [2,5,6,7,9]. Can you see how to get to this array given B[0] and B[1]?
Here's how you can proceed with just two arrays:
set B = B[0]
while B[1] not empty:
for each b in B[1]:
if b not in B:
append b to B
remove b from B[1]
else:
remove b from B
increment each of the remaining elements in B[1] by 1
return length(B)
You have to mimic binary addition via the elements of the B arrays.
To get the number of bits set, you just return the number of elements in B.
So given the array B, you want to calculate the sum of the elements of A, 740 in this example?
Easy:
int sum = 0;
foreach( var bSubArray in B)
foreach( var b in bSubArray)
sum += Power( 2, b);

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

Write an algorithm that finds the second smallest value among a, b, and c

How do I find the second smallest value among a,b and c in Java?
Find-2nd-Smallest (n: array)
smallest : infinity
2nd-smallest : infinity
for each i in n
if i < smallest
2nd-smallest = smallest
smallest = i
else if i < 2nd-smallest
2nd-smallest = i
return 2nd-smallest
How would I make it work for (a,b,c)? I am very confused on how to get a value with only 3 letters.
The function in this pseudo-code you gave finds the smallest and second smallest values in an array.
Run it on the array {a,b,c}.
If there's only three values, you can get away with a very simple function (pseudo-code below):
def second_smallest (a,b,c):
if a < b:
if b < c:
return b
return c
if a < c:
return a
return c
Obviously that will become massively unwieldy if there are more than three numbers but, at that point (see YAGNI), you would convert it to a more generalised solution.
That would be along the lines of:
def second_smallest (list):
if list.size < 2:
throw error "not enough numbers"
if list[0] < list[1]:
first = list[0]
second = list[1]
else:
first = list[1]
second = list[0]
for each index 2 through list.size - 1 inclusive:
if list[index] < first:
second = first
first = list[index]
next for
if list[index] < second:
second = list[index]
return second
That's basically the same sort of logic in your question but with some pre-checks to avoid having to represent infinity (that would be okay if your types were floating point but not so useful for integers).
You should be aware that the generalised solution also solves the more specific problem, assuming your three integers are actually in a list structure of some sort. If you just have the three "naked" values and you're not specifically tasked with coping with the generalised case, I'd use the first block of pseudo-code above.

Resources