Solve Fibonacci Number using dynamic programming but get crazy slow running time - fibonacci

I am attempting to solve nth Fibonacci number using dynamic programming and here is my code:
class Solution:
def fib(self, n: int) -> int:
result = [0]*(n+1)
if n==0:
return 0
elif n==1:
return 1
else:
result[n] = self.fib(n-1) + self.fib(n-2)
return result[n]
I run on leetcode and it took more than 2000 ms to finish.
The solution on leetcode only takes 28 ms to finsih:
class Solution:
cache = {0: 0, 1: 1}
def fib(self, N: int) -> int:
if N in self.cache:
return self.cache[N]
self.cache[N] = self.fib(N - 1) + self.fib(N - 2)
return self.cache[N]
I compare my solution with leetcode solution and find that they are actually very similar. Leetcode use dictionary for storing, I use list. But the time complexity for getting item and inserting for both dictionary and list are O(1)? So I don't understand why there is a huge difference in runtime

Related

Is it atomic operation when exchange std::atomic with itself?

Will following code be executed atomically?
const int oldId = id.exchange((id.load()+1) % maxId);
Where id is std::atomic<int>, and maxId is some integer value.
I searched google and stackoverflow for std::atomic modulo increment. And I found some topics but I can't find clear answer how to do that properly.
In my case even better would be to use:
const int newId = id.exchange((++id) % maxId);
But I am still not sure if it will be executed atomically.
No, this is not atomic, because the load() and the exchange() are separate operations, and nothing is preventing id from getting updated after the load, but before the exchange. In that case your exchange would write a value that has been calculated based on a stale input, so you end up with a missed update.
You can implement a modulo increment using a simple compare_exchange loop:
int val = id.load();
int newVal = (val + 1) % maxId;
while (!id.compare_exchange_weak(val, newVal) {
newVal = (val + 1) % maxId;
}
If the compare_exchange fails it performs a reload and populates val with the updated value. So we can re-calculate newVal and try again.
Edit:
The whole point of the compare-exchange-loop is to handle the case that between the load and the compare-exchange somebody might change id. The idea is to:
load the current value of id
calculate the new value
update id with our own value if and only if the value currently stored in id is the same one as we read in 1. If this is the case we are done, otherwise we restart at 1.
compare_exchange is allows us to perform the comparison and the conditional update in one atomic operation. The first argument to compare_exchange is the expected value (the one we use in our comparison). This value is passed by reference. So when the comparison fails, compare_exchange automatically reloads the current value and updates the provided variable (in our case val).
And since Peter Cordes pointed out correctly that this can be done in a do-while loop to avoid the code duplication, here it is:
int val = id.load();
int newVal;
do {
newVal = (val + 1) % maxId;
} while (!id.compare_exchange_weak(val, newVal);

Problem of understading the programing syntax of DART recursion [duplicate]

I have trouble understanding the code of this recursive function. I am new to DART programming. I understand what a recursive function accomplishes, but I have a problem understanding the programming syntax.
int sum(List<int> numberList, int index) {
if (index < 0) {
return 0;
} else {
return numberList[index] + sum(numberList, index - 1);
}
}
main() {
// Driver Code
var result = sum([1, 2, 3, 4, 5], 4);
print(result);
}
Question: where is the value for each step stored- Does the result for the first pass at line 5 equals 9 taken the inputs from line 11. Where is the value of result 9 stored? How does the function know to add 9 + 3 in the second pass?
Does the recursive function have "internal memory" of the values generated by each pass?
My understanding of the programing language would be that var result passes the arguments to the sum function.
The sum function executes the if-else command until the index value is 0, which means it executes 4 times. With the first pass the return command creates a value of 9 (5 + 4 since value of index is 5 and value of index-1 is 4).
Here begins my confusion. The sum function would now do a second if-else pass and execute the return command again.
Now the initial value of numberList[index] would need to be 9 and the value of sum(numberList, index - 1); would need to be 3, to get 9 + 3 = 12. Additional 2 passes gets 12 + 2 = 14 and 14 + 1 = 15 the expected result.
My question here is how does (if it does) the index value in the "numberList[index]" changes. The index value is defined as 4. Is this an internal logic of the recursive function or am I completely misinterpreting the programming syntax? I would expect that we have a "temporary" variable for the result which increases with each pass.

What does this code mean (if v then return v end)?

So I have this piece of code and it is this:
do
local function index(n,m)
return n*(n+1)//2 + m
end
local binomtable = {}
function binom3(n,m)
if n<0 or m<0 or m>n then return 0 end
if n=0 or m=0 or m=n then return 1 end
local i = index(n,m)
local v = binomtable[i]
if v then return v end
v = binom3(n-1,m-1) + binom3(n-1,m)
binomtable[i] = v
return v
end
end
and I would like to know what
if v then return v end
means.
Thank you!
The short answer is that if v then return v end returns the value v if it is truthy, i.e., if it is neither false nor nil. Otherwise the function continues by calculating a value for v, storing that value in binomtable, and finally returning it. The more interesting question is, why is the function doing all of this?
In the posted code, binom3 is a recursive function. With the recursive calls v = binom3(n-1,m-1) + binom3(n-1,m) there will be a lot of duplication of effort, meaning a lot of wasted space and time. Consider:
binom3(4, 2)
--> binom3(3, 1) + binom3(3, 2)
--> binom3(2, 0) + binom3(2, 1) + binom3(2, 1) + binom3(2, 2)
--> 1 + binom3(1, 0) + binom3(1, 1) + binom3(1, 0) + binom3(1, 1) + 1
Note how in the second reduction there are two identical terms:
binom3(2, 1) + binom3(2, 1)
There is no reason to calculate the term binom3(2, 1) twice, and doing so means that the pair of terms:
binom3(1, 0) + binom3(1, 1)
also must be calculated twice, as seen in the third reduction. It would be smart to calculate binom3(2, 1) only once, and to save the result for later use in the larger calculation. When m and n are larger and the number of calculations explodes exponentially this becomes a very important issue for performance both in the amount of memory required and in the amount of time required.
The posted code is using memoization to improve performance. When a calculation is made, it is stored in the table binomtable. Before any calculation is made, binomtable is consulted. First, v is set to the value of binomtable[i]; if this value is any truthy value (any integer is a truthy in Lua), then that value is simply returned without the need for recursive calculation. Otherwise, if nil is returned (i.e., no value has yet been stored for the calculation), the function continues with a recursive calculation. After completing the calculation, the new value is stored in binomtable for use the next time it is needed. This strategy saves a lot of wasted computational effort, and can make a huge difference in the performance of such recursive algorithms.
For your specific question of what
if v then return v end
means, is that if v, a variable, is not nil or false it is to return the value of the v variable and stop executing that function.
--Similar
function myfunc(input)
local MyVar = "I am a string and am not nil!"
if MyVar then
return "hi"
else
return "hello"
end
print("I am not seen because I am unreachable code!")
end
if this function was called it would always return "hi" instead of "hello" because MyVar is true, because it has a value. Also the print function below that will never get called because it stops executing the function after a return is called.
Now for your codes case it is checking a table to see if it has an entry at a certain index and if it does it returns the value.

Find all occurences of exact string in range and list it

I want to create list of all occurences of "x" string in range. This is my sheet:
And I want to search all occurences and list them and give proper names:
For example for G2, I want "Beret Grey" string as result. I think that I need to use array formula or something like that.
Let me first preface this that vba would be much more robust, but this formula will get you there. It may be slow as it is an array type formula and is doing a lot of calculations. These calculations only expound exponentially as the number of cells with them in it increases:
=IFERROR(INDEX(A:A,AGGREGATE(15,6,ROW($B$2:$G$7)/($B$2:$G$7="x"),ROW(1:1))) & " " & INDEX($1:$1,AGGREGATE(15,6,COLUMN(INDEX(A:G,AGGREGATE(15,6,ROW($B$2:$G$7)/($B$2:$G$7="x"),ROW(1:1)),0))/(INDEX(A:G,AGGREGATE(15,6,ROW($B$2:$G$7)/($B$2:$G$7="x"),ROW(1:1)),0)="x"),ROW(1:1)-COUNTIF($B$1:INDEX(G:G,AGGREGATE(15,6,ROW($B$2:$G$7)/($B$2:$G$7="x"),ROW(1:1)) -1),"x"))),"")
You will need to expand the range to what you need. Change all the $B$2:$G$7 to $B$2:$N$29. Do not use full column references outside those that I have used. It will kill Excel.
Also note what is and what is not relative references, they need to remain the same or you will get errors as the formula is dragged/copied down.
As simple UDF to do what you want:
Function findMatch(rng As Range, crit As String, inst As Long) As String
Dim rngArr() As Variant
rngArr = rng.Value
Dim i&, j&, k&
k = 0
If k > Application.WorksheetFunction.CountIf(rng, crit) Then
findMatch = ""
Exit Function
End If
For i = LBound(rngArr, 1) + 1 To UBound(rngArr, 1)
For j = LBound(rngArr, 2) + 1 To UBound(rngArr, 2)
If rngArr(i, j) = crit Then
k = k + 1
If k = inst Then
findMatch = rngArr(i, 1) & " " & rngArr(1, j)
Exit Function
End If
End If
Next j
Next i
then you would call it like this:
=findMatch($A$1:$G$7,"x",ROW(1:1))
And drag/copy down.

Hash value of String that would be stable across iOS releases?

In documentation String.hash for iOS it says:
You should not rely on this property having the same hash value across
releases of OS X.
(strange why they speak of OS X in iOS documentation)
Well, I need a hasshing function that will not change with iOS releases. It can be simple I do not need anything like SHA. Is there some library for that?
There is another question about this here but the accepted (and only) answer there simply states that we should respect the note in documentation.
Here is a non-crypto hash, for Swift 3:
func strHash(_ str: String) -> UInt64 {
var result = UInt64 (5381)
let buf = [UInt8](str.utf8)
for b in buf {
result = 127 * (result & 0x00ffffffffffffff) + UInt64(b)
}
return result
}
It was derived somewhat from a C++11 constexpr
constexpr uint64_t str2int(char const *input) {
return *input // test for null terminator
? (static_cast<uint64_t>(*input) + // add char to end
127 * ((str2int(input + 1) // prime 127 shifts left almost 7 bits
& 0x00ffffffffffffff))) // mask right 56 bits
: 5381; // start with prime number 5381
}
Unfortunately, the two don't yield the same hash. To do that you'd need to reverse the iterator order in strHash:
for b in buf.reversed() {...}
But that will run 13x slower, somewhat comparable to the djb2hash String extension that I got from https://useyourloaf.com/blog/swift-hashable/
Here are some benchmarks, for a million iterations:
hashValue execution time: 0.147760987281799
strHash execution time: 1.45974600315094
strHashReversed time: 18.7755110263824
djb2hash execution time: 16.0091370344162
sdbmhash crashed
For C++, the str2Int is roughly as fast as Swift 3's hashValue:
str2int execution time: 0.136421

Resources