ruby even Fibonacci numbers - arrays

I am a extreme newbie to coding, I am trying to find anything I can to practice on. This is one of the questions on the Euler test. This is what I came up with to get the answer, but I know it can be shortened. I am working with ruby. I have 2 questions.
1) what should I do to clean this up?
2) At the end I just had it pull the evens out and sum them. What I wanted to do was make an array of the numbers then search the array for the even answers then sum them. How can I make the result populate an array?
I know this is a simple thing that I am missing and I am sorry to bug you guys with such a newby thing.
1 bob=0
2 x = 0
3 y = 1
4 index = 0
5 while index < 4000000
6 z = (x+y)
7 x = y
8 y = z
9
10 index = y
11
12 if z.even?
13 bob = bob+z
14 end
15 end
16 p bob

Create an array
array = []
Append elements to it
array << element
Filter it using select
array = array.select { |each| each.even? }
Sum all elements using inject
sum = array.inject { |a, b| a + b }
Best read the documentation of Enumerable module to learn about all of Ruby's array methods.
Some of the most useful functions are
all?
any?
collect
each_cons
each_slice
detect
inject
none?
select
take
Have fun with Euler project!

BTW, you can use methods chaining to simplify the code. Like this:
(1..10).select(&:even?).inject(:+)
(1..10) represents numbers range.
Take a look also at:
Select method
Inject method

This is probably best handled by an Enumerator Docs. I would proceed as follows:
fib_only_evens = Enumerator.new do |y|
a,b =0,1
loop do
y << a if a.even?
a, b = b, a + b
end
end
Then you can retrieve the number of even Fibonacci numbers that you want by using Enumberable#first or #take
fib_only_evens.first(10)
#=> [0, 2, 8, 34, 144, 610, 2584, 10946, 46368, 196418]
fib_only_evens.take(20)
#=> [0, 2, 8, 34, 144, 610, 2584, 10946, 46368, 196418, 832040, 3524578,
14930352, 63245986, 267914296, 1134903170, 4807526976, 20365011074,
86267571272, 365435296162]
Then using Enumerable#reduce to sum them
fib_only_evens.first(10).reduce(:+)
#=> 257114

Related

How do you iterate over this array? I know this is very basic

import numpy as np
a=np.arange(6)
for i in a:
b[i]=a[i] + 1
print(b)
this is the error
IndexError: list assignment index out of range
I want b to read [1 2 3 4 5 6]
for i in array returns the values, not the indices. To iterate over the indices, use range(len(a)) instead of just a.
The corrected code:
for i in range(len(a)):
b[i] = a[i] + 1
The better solution, if you're just looking for 1 to 6, is to do np.arange(1, 7)
Edit: As Paul points out, numpy has a much better solution than I knew. All you have to do is b = a + 1

Can't understand some array syntax

I found a MATLAB code like this one:
x = [1, ([1:(m-1)].^a)];
where a and m are scalar.
Could somebody explain that? I'm not so familiar with the MATLAB programming language.
1:(m-1) creates and array from 1 to m-1 in steps of 1.
.^a raises each element in the previous array to the power a (^ is a regular power and tries to compute the matrix power, the . makes operations element-wise, i.e. raise each element to power a instead of the whole matrix)
[1, y] is simply the array y with a 1 prepended as first element.
Putting this all together we find that x is an array which starts with 1, followed by an integer array 1:(m-1) with each element raised to the power a.
m=5;a=3;
x = [1, ([1:(m-1)].^a)]
x =
1 1 8 27 64
Broken down in steps:
tmp = 1:(m-1)
tmp =
1 2 3 4
tmp2 = tmp.^a
ans =
1 8 27 64
x = [1 tmp2]
x =
1 1 8 27 64

Trying to compare elements of on array with every element of another array in matlab

I'm using Matlab, and I'm trying to come up with a vectorized solution for comparing the elements of one array to every element of another array. Specifically I want to find the difference and see if this difference is below a certain threshold.
Ex: a = [1 5 10 15] and b=[12 13 14 15], threshold = 6
so the elements in a that would satisfy the threshold would be 10 and 15 since each value comes within 6 of any of the values in b while 1 and 5 do not. Currently I have a for loop going through the elements of a and subtracting an equivalently sized matrix from b (for 5 it would be a = [5 5 5 5]). This obviously takes a long time so I'm trying to find a vectorized solution. Additionally, the current format I have my data in is actually cells where each cell element has size [1 2], and I have been using the cellfun function to perform my subtraction. I'm not sure if this complicates the solution of each [1 2] block with the [1 2] block of the second cell. A vectorized solution response is fine, there is no need to do the threshold analysis. I just added it in for a little more background.
Thanks in advance,
Manwei Chan
Use bsxfun:
>> ind = any(abs(bsxfun(#minus,a(:).',b(:)))<threshold)
ind =
0 0 1 1
>> a(ind)
ans =
10 15

Vectorizing the subtraction of multiple vectors from one individual vector

I am trying to vectorize, or make the following code more efficient:
[Y,k] = min(abs(dxcp-X));
X = dxcp(k);
The objective of the code is to compare a value X to an array of accepted values for x (dxcp) and assign X to the closest value in the array dxcp. For example:
X is equal to 9 and the dxcp array is: [ 1, 2, 3, 6, 10, 20]. The second line would change X to be equal to 10.
I am trying to change my script so that X can be inputted as an array of numbers and was wondering what would be the most efficient way to go about making the above code work for this case. Of course I could use:
for i = 1:numel(X)
[Y,k] = min(abs(dxcp-X(i)));
X(i) = dxcp(k);
end
But I have the feeling that there must be a way to accomplish this more efficiently. Cheers, nzbru.
You need to use bsxfun to extend your case to a vector case.
Code
dxcp = [1 2 3 6 10 20];
X = [2 5 9 18]
abs_diff_vals = abs(bsxfun(#minus,dxcp,X')); %%//'
[~,k] = min(abs_diff_vals,[],2);
X = dxcp(k)
Output
X =
2 5 9 18
X =
2 6 10 20

How would I go about this task- Matlab [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to store value generated from nested for loop in an array, in Matlab?
I have an array of digits. e.g. x = [4,9,8]. I use find(x) to obtain [1,2,3], then find(x)+length(x) to obtain [4,5,6].
I want this(in this case, adding 3 to the array, to make a sequence of 1,2,3 4,5,6 7,8,9...) to go on n number of times, so I require a loop.
Now with the array x, I want to add [4,9,8] to [1,2,3] , which gives [5,11,11].
I have [1,2,3]...[10,11,12]...[n,n+1,n+2] from find(x)+length(x) looped, I want to add elements in x to the elements in corresponding positions, in the array that is going up in three.
So, for example, [4,5,6] 5 is in position 2. x=[4,9,8]. 9 is in position 2 within x. Therefore, I want to add 9 to 5. I want to do this for each element (in this case, each of the three elements). I would add 9 to 11, and 9 to 11 as both numbers are in position '2' in their respective arrays.
I was thinking of using a nested for loop, to take care of the find(x)+length(x). I am just unsure of how to make the 'location additions' happen.
I would then like to store the results of the additions in a separate array.
Thanks in advance for your time and help!
So, we start with
x = [4,9,8]
Let's add [1, 2, 3]
x + [1, 2, 3]
ans =
5 11 11
A more flexible way
x + (1 : length(x))
ans =
5 11 11
If you do not want to start at 1 but at b (say, we add [5, 6, 7] to x):
b = 5;
x + b + (0 : length(x) - 1)
ans =
9 15 15
I think this should get you going and you can add your loop now.
Warning: You have a very strange way of using find(). Just to make sure: find(x) returns the indices of the non-zero entries in x. If all elements of the vector x are non-zero, you have the equality
find(x) == 1 : length(x)
If any element in x is zero, you run into problems, when adding it to find(x):
x = [4, 9, 0, 8];
find(x)
ans =
1 2 4
x + find(x)
Error using +
Matrix dimensions must agree.

Resources