Does Ruby already know the Fibonacci Sequence? - ruby

The following method is used to find the nth number in the Fibonacci Sequence:
def fibonacci(number)
if number < 2
number
else
fibonacci(number - 1) + fibonacci(number - 2)
end
end
puts fibonacci(6)
The answer is 8 (the sixth number in the sequence if you start counting from 1 and not 0 (0, 1, 1, 2, 3, 5, 8...)
The above code simply deals with the position of numbers in the sequence, right? So how does Ruby already know what the value of a number is at a given position? In the words, how does Ruby know that fibonacci(4) has the value 3 ? Is the Fibonacci sequence already built in to Ruby?

No, the sequence is not built in.
fibonacci is a recursive function. It will be called nine times (!) to compute fibonacci(4) to get 3. (By the way, this is a terrible approach to calculating Fibonacci numbers. 25 calls for fibonacci(6)! It should at least memoize previous calculations.)

So how does Ruby already know what the value of a number is at a given position?
It doesn't already know. It finds out, as part of this method. To find out the value at this position, it first calculates all the values of all the numbers at all the previous positions.
how does Ruby know that fibonacci(4) has the value 3
Because the first thing it does in order to calculate fibonacci(4) is to call fibonacci(3). The algorithm is recursive.

Related

How to use the Pisano Period to find the Last Digit of the Sum of Fibonacci Numbers?

I'm taking an online algorithms course, and I've come across a problem where I need to find the last digit of the sum of the Fibonacci numbers up the nth (current) number.
I need some help connecting the dots. As I understand it, the "Last Digit of the Sum of Fibonacci Numbers" problem has a solution that is somehow related to the Pisano Period.
But I don't really understand what that means.
The Pisano Period was used to calculate the remainder given some value of m for an extremely large Fibonacci Number, which was the focus of a prior problem (I.E., Solve Fn mod m = ???).
Forum posts (and the instruction set) seem to suggest that the length can somehow help us quickly zero in on the sum for the current Fibonacci without having to actually build up to it normally through a loop.
I would rather avoid just looking at someone else's solution if possible, so if anyone has any useful hints that can help me see the missing link, I would really appreciate it.
The last digit of a Fibonacci number is just that number reduced modulo 10. Pisaso periods are the periods of which the sequence of fibonacci numbers, modulo some base, repeat. So, if you're interested in F(x) mod 10, you'd interested in the Pisaso Period p(10).
If we have this period, say it was something like [1, 5, 2, 7, 0] (its not, but for sake of example), we'd know that the 3rd integer in the sequence ended with a "2". And because it repeats, we'd know the 8th integer also ends in a "2", and the 13th...
Generalizing this, we could say that the last digit of the number N could be found at the ith index in our list we just built, for i satisfying N = 5 * k + i, where k is just any integer, and 5 comes from the fact that our list has 5 elements (and thus repeats every 5 values). Rewriting this, we could say i = N mod 5.
Putting that all together (spoilers), we just need to find the actual values of the repeating sequence mod 10, and then take our input value N (for finding the Nth Fibonacci number mod 10), and index into said repeatingSequence at index N mod len(repeatingSequence) for our answer.
For reference, for base 10, the actual repeating sequence is:
011235831459437077415617853819099875279651673033695493257291

Calculate the number of distinct possible values of the array after the repeated process of absolute difference between any 2 elements

This was a question asked in a mock test. So, I could not find any online evaluator for this.
Basically, you are provided with an array of elements. You can take any 2 elements and add their absolute difference back to the array.
The solution should be the number of distinct values in the array after infinite number of above given step.
Example 1-
Input [2,3,4,5]
Output - 5
Explanation: Since 3-2=1, this can be added to the set. So the total number of distinct values will be 5.
Example 2-
Input [1,100]
Output - 100
Explanation - 100-1 = 99 -> add this back to the set
Then, 99-1 = 98 -> add this back to the set.
After repeating the process, all the numbers from 1 to 100 will be present in the set.
I used a hash set to store the distinct elements to store the initial array elements and used 2 for loops to subtract the store the distinct result to the same array-
But only after submitting my code, i realized, the distinct result should be again used for further subtraction.
Hence my answer was wrong.
Can anyone help me solve this ? Thanks in advance.
Edit : correcting the solution of first example to 5 instead of 6.
Adding explanation for maximum(array)/gcd(array) as pointed out in the comments.
gcd(array) - the greatest common divisor for all the numbers in the array is calculated i.e. the largest number that divides all the values in the array. It is known that division is nothing but repeated subtractions. So, no matter how many times we were to find absolute difference of the numbers in the array, GCD of the numbers is the maximum we can reduce the difference to. For an instance, let's say the array is [2, 10], the array can only be become [2, 4, 6, 8, 10]. Other numbers in this range will never get added, that is, an absolute difference of 1 never occurs.
maximum(array) - we are finding difference here, so at any point, the difference cannot exceed the maximum value.
Therefore, maximum(array)/gcd(array) formula gives the right output for the question.
Hope this helps!

What is general name of described math function

I need to know the name of this function, please help.
The idea of this function is that you have some number and you need to finding two biggest numbers from fibonacci sequence which you need to add to get this number. And method returns to you array of this fibonacci digits but the numbers in this array represented by 0 and 1 where two numbers 1 and all others 0. And the position of 1 in array is the same where the biggest numbers as in fibonacci seq.
For example i have fibonacci sequence {1,1,2,3,5,8,13}
Number = 11 so the two numbers from sequence will be 8 and 3
The output will be {0,0,0,1,0,1,0}
Its pretty famous as i remember and I'm not completeley sure but using of fibonacci is one of the solutions of it. Please help to get the name of it so i could find out more about it
This is not function, but numeral system: Fibonacci coding - representation of integer as sum of Fib. numbers

How to find subsequences?

I'm given a random sequence of numbers of random length, consisting of 0's, 1's, 2's:
201102220221
I'm also given a number: either 1 or 2. I can only loop through the sequence once, and I need to identify all the subsequences of the number I'm given, run that value through another function and add the value to a sum (initialized to 0).
Any 0's can be replaced with a 1 or a 2. Subsequences can therefore be "expanded", by replacing 0's beside it with the number. If a subsequence cannot be expanded to a minimum length of more than 4, I need to discard it.
For example, say I'm given the sequence:
11011002102
and the number 1. I identify the subsequence of length 2 at the beginning (See first element). It can be expanded to a subsequence of length 7, by replacing the first 0, third and fourth zero with 1's. Therefore I run its current length through a function and add it to the sum.
sum += function(2);
I then identify the next subsequence of 1's (See fourth element). It's currently of size 2 and can be expanded to a maximum size of 7, by replacing the zeros around it. So I pass its length to a function and add it to the sum.
sum += function (2);
I finally identify the last subsequence of 1's (See sixth element). It currently has a length of 1 and can be expanded to a maximum size of 2, by replacing the zero beside it with a 1, which is less than 4, so I discard it.
Could someone help me write a function that does what was described above by only looping through the sequence once. Please do not give me real code, just ideas, suggestions or pseudocode.
I don't have any work to share, I'm completely lost. I also know no algorithms, so please don't start talking about things like dynamic programming or linear programming, but instead explain possible ways to approach the problem.
Given the requirement that you can only loop through the sequence once, you know the basic structure of the code.
Given the parameters for discarding a subsequence (expanded length of 4 or more) and for processing a subsequence (unexpanded sequence length), you know what data you need to track along the way. Work out how to best store this data according to your environment and language conventions.
At each iteration of the loop, consider the current character of the input series and how it affects the data stored.
I've tried to clarify the question here without just handing you the solution. Feel free to ask more questions.
Edit:
Consider how you would break the problem down step by step. Here are the iterations of your for loop:
1----------
Okay, we're looking for 1s and we've found one straight up.
-1---------
Cool, another 1, now our subsequence length has increased to 2
--0--------
Right, so as this is not a 1, the length of this subsequence is now known to be 2 - it doesn't increase any more, but as this is a 0, it might still qualify if it can expand to at least 4. The expanded subsequence length is now 3.
---1-------
The expanded subsequence length is now 4! This means we can add the last sequence length to the total sum after passing it through function. This is also the start of another subsequence - so subsequence length is now reset to 1, but expanded subsequence length is still valid at 4. That means that this subsequence is already long enough not to be rejected, but we haven't finished counting it's length at this stage.
----1------
subsequence length = 2, and expanded subsequence length = 5
-----0-----
This marks the end of the 2nd subsequence, process it as before. Etc
------0----
-------2--- <- expanded subsequence length gets reset here
--------1-- <- start of another subsequence
---------0- <- expanded length is 2
----------2 <- expanded length is not long enough for this to qualify, discard it
So, fairly straight forward. There are two factors we need to keep track of: subsequence length and expanded subsequence length.
Once you've got that working, think about what happens for this input sequence "1010101".
Forget the computer for a bit; think of it as a faster version of using pencil and paper.
Try to imagine how you would solve this problem as you traverse each element of the sequence; what you might want to write down and/or edit on your piece of paper at each iteration (each element you reach in the sequence).
For example:
Sequence = 11011002102
Index 0:
Value is 1
Current is 1, Previous was null
Tracking a subsequence of 1's starting at 0 => [1,0] = 1
Index 1:
Value is 1
Current is 1, Previous was 1
Current == Previous so the subsequence length is increased by 1 => [1,0] = 2
...

From the given array of numbers find all the of numbers in group of 3 with sum value N

Given is a array of numbers:
1, 2, 8, 6, 9, 0, 4
We need to find all the numbers in group of three which sums to a value N ( say 11 in this example). Here, the possible numbers in group of three are:
{1,2,8}, {1,4,6}, {0,2,9}
The first solution I could think was of O(n^3). Later I could improve a little(n^2 log n) with the approach:
1. Sort the array.
2. Select any two number and perform binary search for the third element.
Can it be improved further with some other approaches?
You can certainly do it in O(n^2): for each i in the array, test whether two other values sum to N-i.
You can test in O(n) whether two values in a sorted array sum to k by sweeping from both ends at once. If the sum of the two elements you're on is too big, decrement the "right-to-left" index to make it smaller. If the sum is too small, increment the "left-to-right" index to make it bigger. If there's a pair that works, you'll find them, and you perform at most 2*n iterations before you run out of road at one end or the other. You might need code to ignore the value you're using as i, depends what the rules are.
You could instead use some kind of dynamic programming, working down from N, and you probably end up with time something like O(n*N) or so. Realistically I don't think that's any better: it looks like all your numbers are non-negative, so if n is much bigger than N then before you start you can quickly throw out any large values from the array, and also any duplicates beyond 3 copies of each value (or 2 copies, as long as you check whether 3*i == N before discarding the 3rd copy of i). After that step, n is O(N).

Resources