The problem:
Given an array of integers nums containing n + 1 integers where each integer is in the range [1, n] inclusive.
There is only one repeated number in nums, return this repeated number.
You must solve the problem without modifying the array nums and uses only constant
extra space.
Here is one of the possible solution using binary search
class Solution(object):
def findDuplicate(self, nums):
beg, end = 1, len(nums)-1
while beg + 1 <= end:
mid, count = (beg + end)//2, 0
for num in nums:
if num <= mid: count += 1
if count <= mid:
beg = mid + 1
else:
end = mid
return end
Example 1:
Input: nums = [1,3,4,2,2]
Output: 2
Example 2:
Input: nums = [3,1,3,4,2]
Output: 3
Can someone please explain this solution for me? I understand the code but I don't understand the logic behind this. In particular, I do not understand how to construct the if statements (lines 7 - 13). Why and how do you know that when num <= mid then I need to do count += 1 and so on. Many thanks.
The solution keeps halving the range of numbers the answer can still be in.
For example, if the function starts with nums == [1, 3, 4, 2, 2], then the duplicate number must be between 1 and 4 inclusive by definition.
By counting how many of the numbers are smaller than or equal to the middle of that range (2), you can decide if the duplicate must be in the upper or lower half of that range. Since the actual number is greater (3 numbers are lesser than or equal to 2, and 3 > 2), the number must be in the lower half.
Repeating the process, knowing that the number must be between 1 and 2 inclusive, only 1 number is less than or equal to the middle of that range (1), which means the number must be in the upper half, and is 2.
Consider a slightly longer series: [1, 2, 5, 6, 3, 4, 3, 7]. Between 1 and 7 lies 3, 4 numbers are less than or equal to 3, so the number must be between 1 and 3. Between 1 and 3 lies 2, 2 numbers are less than or equal to 2, so the number must be over 2, which leaves 3.
The solution will iterate over all n elements of nums a limited number of times, since it keeps halving the search space. It's certainly more efficient than the naive:
def findDuplicate(self, nums):
for i, n in enumerate(nums):
for j, m in enumerate(nums):
if i != j and n == m:
return n
But as user #fas suggests in the comments, this is better:
def findDuplicate(nums):
p = 1
while p < len(nums):
p <<= 1
r = 0
for n in nums:
r ^= n
for n in range(len(nums), p):
r ^= n
return r
This is how given binary search works. Inside binary search you have implementation of isDuplicateLessOrEqualTo(x):
mid, count = (beg + end)//2, 0
for num in nums:
if num <= mid: count += 1
if count <= mid:
return False # In this case there are no duplicates less or equal than mid.
# Actually count == mid would be enough, count < mid is impossible.
else:
return True # In this case there is a duplicate less or equal than mid.
isDuplicateLessOrEqualTo(x) is a non-decreasing function (assume x has a duplicate, then for all i < x it's false and for all i >= x it's true), that's why you can run binary search over it.
Each iteration you run through the array, which gives you overall complexity O(n log n) (where n is size of array).
There's a faster solution. Note that xor(0..(2^n)-1) = 0 for n >= 2, because there are 2^(n-1) ones for each bit position and it's an even number, for example:
0_10 = 00_2
1_10 = 01_2
2_10 = 10_2
3_10 = 11_2
^
2 ones here, 2 is even
^
2 ones here, 2 is even
So by xor-ing all the numbers you'll receive exactly your duplicate number. Let's write it:
class Solution(object):
def nearestPowerOfTwo(number):
lowerBoundDegreeOfTwo = number.bit_length()
lowerBoundDegreeOfTwo = max(lowerBoundDegreeOfTwo, 2)
return 2 ** lowerBoundDegreeOfTwo
def findDuplicate(self, nums):
xorSum = 0
for i in nums:
xorSum = xorSum ^ i
for i in range(len(nums), nearestPowerOfTwo(len(nums) - 1)):
xorSum = xorSum ^ i
return xorSum
As you can see that gives us O(n) complexity.
If anyone is interested in a different approach (not binary search) to solve this problem:
Sum all elements of the array - we will call it sumArray - the time complexity is O(n).
Sum all numbers from 1 to n (inclusive) - we will call it sumGeneral - this is simply (n * (n+1) / 2) - the time complexity is O(1).
Return the result of sumArray - sumGeneral
In total, the time complexity is O(n) (you cannot do better since you have to look at all elements of the array, potentially the repeated one is at the end), and additional space complexity is O(1).
(If you could use O(n) additional space complexity you could use a hash table)
Related
I am taking a programming class in college and one of the exercises in the problem sheet was to write this code:
number = int(input())
x = 0
y = 0
for n in range(number):
if n % 2 == 0:
x += n
else:
y += n
print(x)
print(y)
using only one "for" loop, and no "while" or "if".
The purpose of the code is to find the sum of the even and the sum of
the odd numbers from zero to the number inputted and print it to the
screen.
Be reminded that at this time we aren't supposed to know about
functions.
I've been trying for a long time now and can't seem to find a way of doing it without using "if" statements to know if the loop variable is even or odd.
Purely for educational purposes (and a bit of fun), here is a solution that does not use any for loops at all. (Granted, in the underlying logic of the functions, there are at least five loops.)
num = list(range(int(input('Enter number: '))))
even = num[::2]
odd = num[1::2]
print('Even list:', even)
print('Odd list:', odd)
print('Even:', sum(even))
print('Odd:', sum(odd))
Output:
Enter number: 10
Even list: [0, 2, 4, 6, 8]
Odd list: [1, 3, 5, 7, 9]
Even: 20
Odd: 25
How does it work?
The input() function returns a str object, which is converted into an integer using the int() function.
The integer is wrapped in the range() and list() functions to convert the given number into a list of values within that range.
This is a convention you will use/see a lot through your Python career.
List slicing is used to get every second element in the list. Given the list is based at zero, these will be even numbers.
Slice the same list again, starting with the second element, and get every second element ... odd numbers.
Link to a nice SO answer regarding slicing in Python.
The simply use the sum() function to get the sums.
for n in range(number):
x += (1 - n % 2) * n
y += (n % 2) * n
You asked for a solution with one loop, but how about a solution with no loop?
It is well known that the sum of the numbers from 1 to n is (n+1)*n/2. Thus, the sum of even numbers is 2 * (m+1)*m/2 with m = n//2 (i.e. floor(n/2)). The sum of odd can then be calculated by the sum of all numbers minus the sum of even numbers.
n = 12345
m = n // 2
e = (m+1)*m
o = (n+1)*n//2 - e
Verification:
>>> e, e==sum(i for i in range(n+1) if i % 2 == 0)
38112102 True
>>> o, o==sum(i for i in range(n+1) if i % 2 == 1)
38105929 True
Note: This calculates the sums for number up to and including n.
for n in range(1,number,2):
x += n
y += n-1
print(y)
print(x)
This code has the same output with the example.
Ternary operator:
for n in range(number):
x += (n,0)[n%2]
y += (0,n)[n%2]
I think you are a beginner. I wouldn't like to confuse you with slicing operators complex implementation.
As you mentioned
The purpose of the code is to find the sum of the even and the sum of
the odd numbers from zero to the number inputted and print it to the
screen.
There is no need to find the initial number is odd/even
And your program is wrong if you want to include the input number in calculating the even/odd sum.
Example
Input
5
Expected Output
6
9
Explanation
Even Sum : 2+4 = 6
Odd Sum : 1+3+5 = 9
Your Output
6 4 (wrong output)
The range() function will exclude the number. It will only iterate from 0 to 4 while the input is 5. so if you want to include 5, you should add 1 to the number while passing it in the range() function.
number = int(input())
x = 0
y = 0
for n in range(number+1):
x += (1 - n % 2) * n #this will add 0 if not even
y += (n % 2) * n #this will add 0 if not odd
print(x)
print(y)
There is also mathematical way:
num = int(input("Enter number:"))
odd = ((num+1)/2)**2
even = num*(num+1)/2 - odd
The sum of the first n odd numbers is n^2. To get count of odd numbers we use (num+1)/2. To get sum of even numbers, we could use similar approach, but I preferred, subtracting odd from the sum of the first n numbers, which is n*(n+1)/2.
Here is my 2cents if we are allowed to use numpy.
import numpy as np
number = int(input())
l = np.array(range(number))
print('odd:',sum(l % 2 * l))
print('even:', sum((1- l % 2) * l))
If you're allowed to use a list
number = int( input() )
counts = [ 0, 0 ]
for n in range( number ):
counts[ n % 2 ] += n
print( counts[ 0 ] )
print( counts[ 1 ] )
There's another way which sums the odd and even indices together in the for loop based on the remainder modulo 2:
number = int(input())
odd = 0
even = 0
for i in range(len(number)):
odd += i * (i % 2)
even += i * ((i + 1) % 2)
print (odd, even)
number = 1000000
x = 0
y = 0
[(x:=x+n, y:=y+(n+1)) for n in range(0,number,2)]
print(f'{x}, {y}')
This uses a list comprehension and the new Python assignment operator.
Sum of first n numbers is n(n+1)/2 (Mathematically derived). So if we know the value of n then we can find the sum of all numbers from 1 to n.
If we find the sum of all odd numbers before n and subratract it from the sum of first n we get he sum of all even numbers before n.
Here's the code:
n = int(input("Enter a number: "))
odd = 0
for i in range(1,n+1,2):
odd += i
even = int(n*(n+1)/2) - odd
print("even:",even,"odd:",odd)
I'm trying to find the median in a list. The equation to find the median is N terms/2. The code i've tried is to find and index the number but when i index i get 0 or an error, why is this?
def Median():
#MedianList_Str = ""
MedianList = [2,4,6]
print("What number do you want to add to the array, enter 0 to exit")
try:
Int = int(input())
if Int == 0:
QuitApp()
else:
MedianList.append(Int)
except:
print("Please enter a number")
MedianT = math.floor(len(MedianList)/2) #finds the nth term
MedianList.sort #sorts the list so you can find the median term
MedianList_Str.join(MedianList)
this is what i've done. I've also tried index
def Median():
MedianList_Str = ""
MedianList = [2,4,6]
print("What number do you want to add to the array, enter 0 to exit")
try:
Int = int(input())
if Int == 0:
QuitApp()
else:
MedianList.append(Int)
except:
print("Please enter a number")
MedianT = math.floor(len(MedianList)/2) #finds the nth term
MedianList.sort #sorts the list so you can find the median term
print(MedianList.index(MedianT))
which gets me 0
what can i do to get me the median? I understand that there already exists such a question but i want to try a different way.
Here's a nice trick to avoid using if/else to handle the odd and even length cases separately: the indices in the middle are (len(nums) - 1) // 2 and len(nums) // 2. If the length is odd, then these indices are equal, so adding the values and dividing by 2 has no effect.
Note that you should do floor-division with the // operator to get an integer to use as an index.
def median(nums):
nums = sorted(nums)
middle1 = (len(nums) - 1) // 2
middle2 = len(nums) // 2
return (nums[middle1] + nums[middle2]) / 2
Examples:
>>> median([1, 2, 3, 4])
2.5
>>> median([1, 2, 3, 4, 5])
3.0
As others have mentioned, I would used sorted(MedianT) instead of MeadianT.sort().
In addition, use array based indexing instead of the .index() function.
For example, this:
print(MedianList[MedianT])
Instead of this:
print(MedianList.index(MedianT))
I have included below with comments the logic and thought process of finding median value of an array in Python.
def median(array):
length = len(array)
sorted_arr = sorted(array) # sorting in O(n) time or linear complexity
# we are subtracting 1 from overall
# length because indexing is 0-based
# essentially indexes of arrays start at 0
# while counting length starts at 1
# idx_norm = (length-1) / 2 # using only single division operator yields a float
idx = (length-1) // 2 # using floor division operator // yields an Int which can be used for index
# we run a simple condition to see
# whether if the overall length of array
# is even or odd.
# If odd then we can use index value (idx) to find median
# we use modulus operator to see if if there is any remainder
# for a division operation by 2. If remainder equals 0 then
# array is even. If not array is odd.
if length % 2 == 0:
return (sorted_arr[idx] + sorted_arr[idx + 1]) / 2.0 # if you need an Int returned, then wrap this operation in int() conversion method
else:
return sorted_arr[idx]
# If even we have to use index value (idx) and the next index value (idx + 1)
# to create total and then divide for average
a = [1, 2, 3, 4, 12, 1, 9] # 7 elements, odd length --> return 3
b = [2, 3, 7, 6, 8, 9] # 6 elements, even length --> return 6.5
median(a)
median(b)
Please let me know if you have any questions and hope this helps. Cheers!
The median is either the middle element by value, or the average of the middle two if the length of the array is even.
So first we must sort the array, and then apply our logic.
def median(l):
l = sorted(l)
middle = len(l) // 2
return l[middle] if len(l) % 2 == 1 else (l[middle - 1] + l[middle]) / 2
Note that there exist more efficient algorithms to find the median, that take O(n) instead of O(n log n) time, however they're not trivial to implement and are not available in Python's standard library.
I created a class. You can add elements to your list with the addNum method. The findMedian method will check if the length of the list is odd or even and will give you the median depending on the situation.
class MedianFinder:
def __init__(self):
num_list = []
self.num_list = num_list
def addNum(self, num):
self.num_list.append(num)
return self.num_list
def findMedian(self):
# Check len of list
if len(self.num_list) % 2 == 0:
l = int(len(self.num_list) / 2)
return (self.num_list[l - 1] + self.num_list[l]) / 2
else:
l = math.floor(len(li) / 2)
return self.num_list[l]
Example usage;
s.addNum(2)
s.addNum(4)
s.addNum(6)
s.addNum(8)
print(s.findMedian())
Output: 5.0
A Python coding exercise asks to make a function f such that f(k) is the k-th number such that its k-th digit from the left and from the right sums to 10 for all k. For example 5, 19, 28, 37 are the first few numbers in the sequence.
I use this function that explicitly checks if the number 'n' satisfies the property:
def check(n):
#even digit length
if len(str(n)) % 2 == 0:
#looping over positions and checking if sum is 10
for i in range(1,int(len(str(n))/2) + 1):
if int(str(n)[i-1]) + int(str(n)[-i]) != 10:
return False
#odd digit length
else:
#checking middle digit first
if int(str(n)[int(len(str(n))/2)])*2 != 10:
return False
else:
#looping over posotions and checking if sum is 10
for i in range(1,int(len(str(n))/2) + 1):
if int(str(n)[i-1]) + int(str(n)[-i]) != 10:
return False
return True
and then I loop over all numbers to generate the sequence:
for i in range(1, 10**9):
if check(i):
print(i)
However the exercise wants a function f(i) that returns the i-th such number in under 10 seconds. Clearly, mine takes a lot longer because it generates the entire sequence prior to number 'i' to calculate it. Is it possible to make a function that doesn't have to calculate all the prior numbers?
Testing every natural number is a bad method. Only a small fraction of the natural numbers have this property, and the fraction decreases quickly as we get into larger numbers. On my machine, the simple Python program below took over 3 seconds to find the 1,000th number (2,195,198), and over 26 seconds to find the 2,000th number (15,519,559).
# Slow algorithm, only shown for illustration purposes
# '1': '9', '2': '8', etc.
compl = {str(i): str(10-i) for i in range(1, 10)}
def is_good(n):
# Does n have the property
s = str(n)
for i in range((len(s)+1)//2):
if s[i] != compl.get(s[-i-1]):
return False
return True
# How many numbers to find before stopping
ct = 2 * 10**3
n = 5
while True:
if is_good(n):
ct -= 1
if not ct:
print(n)
break
n += 1
Clearly, a much more efficient algorithm is needed.
We can loop over the length of the digit string, and within that, generate numbers with the property in numeric order. Sketch of algorithm in pseudocode:
for length in [1 to open-ended]:
if length is even, middle is '', else '5'
half-len = floor(length / 2)
for left in (all 1) to (all 9), half-len, without any 0 digits:
right = 10's complement of left, reversed
whole-number = left + middle + right
Now, note that the count of numbers for each length is easily computed:
Length First Last Count
1 5 5 1
2 19 91 9
3 159 951 9
4 1199 9911 81
5 11599 99511 81
In general, if left-half has n digits, the count is 9**n.
Thus, we can simply iterate through the digit counts, counting how many solutions exist without having to compute them, until we reach the cohort that contains the desired answer. It should then be relatively simple to compute which number we want, again, without having to iterate through every possibility.
The above sketch should generate some ideas. Code to follow once I’ve written it.
Code:
def find_nth_number(n):
# First, skip cohorts until we reach the one with the answer
digits = 1
while True:
half_len = digits // 2
cohort_size = 9 ** half_len
if cohort_size >= n:
break
n -= cohort_size
digits += 1
# Next, find correct number within cohort
# Convert n to base 9, reversed
base9 = []
# Adjust n so first number is zero
n -= 1
while n:
n, r = divmod(n, 9)
base9.append(r)
# Add zeros to get correct length
base9.extend([0] * (half_len - len(base9)))
# Construct number
left = [i+1 for i in base9[::-1]]
mid = [5] * (digits % 2)
right = [9-i for i in base9]
return ''.join(str(n) for n in left + mid + right)
n = 2 * 10**3
print(find_nth_number(n))
This is a function that exploits the pattern where the number of "valid" numbers between adjacent powers of 10 is a power of 9. This allows us to skip over very many numbers.
def get_starting_point(k):
i = 0
while True:
power = (i + 1) // 2
start = 10 ** i
subtract = 9 ** power
if k >= subtract:
k -= subtract
else:
break
i += 1
return k, start
I combined this with the method you've defined. Supposing we are interested in the 45th number,
this illustrates the search starts at 1000, and we only have to find the 26th "valid" number occurring after 1000. It is guaranteed to be less than 10000. Of course, this bound gets worse and worse at scale, and you would want to employ the techniques suggested by the other community members on this post.
k = 45
new_k, start = get_starting_point(k)
print('new_k: {}'.format(new_k))
print('start at: {}'.format(start))
ctr = 0
for i in range(start, 10**9):
if check(i):
ctr += 1
if ctr == new_k:
break
print(i)
Output:
new_k: 26
start at: 1000
3827
It seems the 45th number is 3827.
I'm tryin to design a function that, given an array A of N integers, returns the smallest positive integer (greater than 0) that does not occur in A.
This code works fine yet has a high order of complexity, is there another solution that reduces the order of complexity?
Note: The 10000000 number is the range of integers in array A, I tried the sort function but does it reduces the complexity?
def solution(A):
for i in range(10000000):
if(A.count(i)) <= 0:
return(i)
The following is O(n logn):
a = [2, 1, 10, 3, 2, 15]
a.sort()
if a[0] > 1:
print(1)
else:
for i in range(1, len(a)):
if a[i] > a[i - 1] + 1:
print(a[i - 1] + 1)
break
If you don't like the special handling of 1, you could just append zero to the array and have the same logic handle both cases:
a = sorted(a + [0])
for i in range(1, len(a)):
if a[i] > a[i - 1] + 1:
print(a[i - 1] + 1)
break
Caveats (both trivial to fix and both left as an exercise for the reader):
Neither version handles empty input.
The code assumes there no negative numbers in the input.
O(n) time and O(n) space:
def solution(A):
count = [0] * len(A)
for x in A:
if 0 < x <= len(A):
count[x-1] = 1 # count[0] is to count 1
for i in range(len(count)):
if count[i] == 0:
return i+1
return len(A)+1 # only if A = [1, 2, ..., len(A)]
This should be O(n). Utilizes a temporary set to speed things along.
a = [2, 1, 10, 3, 2, 15]
#use a set of only the positive numbers for lookup
temp_set = set()
for i in a:
if i > 0:
temp_set.add(i)
#iterate from 1 upto length of set +1 (to ensure edge case is handled)
for i in range(1, len(temp_set) + 2):
if i not in temp_set:
print(i)
break
My proposal is a recursive function inspired by quicksort.
Each step divides the input sequence into two sublists (lt = less than pivot; ge = greater or equal than pivot) and decides, which of the sublists is to be processed in the next step. Note that there is no sorting.
The idea is that a set of integers such that lo <= n < hi contains "gaps" only if it has less than (hi - lo) elements.
The input sequence must not contain dups. A set can be passed directly.
# all cseq items > 0 assumed, no duplicates!
def find(cseq, cmin=1):
# cmin = possible minimum not ruled out yet
size = len(cseq)
if size <= 1:
return cmin+1 if cmin in cseq else cmin
lt = []
ge = []
pivot = cmin + size // 2
for n in cseq:
(lt if n < pivot else ge).append(n)
return find(lt, cmin) if cmin + len(lt) < pivot else find(ge, pivot)
test = set(range(1,100))
print(find(test)) # 100
test.remove(42)
print(find(test)) # 42
test.remove(1)
print(find(test)) # 1
Inspired by various solutions and comments above, about 20%-50% faster in my (simplistic) tests than the fastest of them (though I'm sure it could be made faster), and handling all the corner cases mentioned (non-positive numbers, duplicates, and empty list):
import numpy
def firstNotPresent(l):
positive = numpy.fromiter(set(l), dtype=int) # deduplicate
positive = positive[positive > 0] # only keep positive numbers
positive.sort()
top = positive.size + 1
if top == 1: # empty list
return 1
sequence = numpy.arange(1, top)
try:
return numpy.where(sequence < positive)[0][0]
except IndexError: # no numbers are missing, top is next
return top
The idea is: if you enumerate the positive, deduplicated, sorted list starting from one, the first time the index is less than the list value, the index value is missing from the list, and hence is the lowest positive number missing from the list.
This and the other solutions I tested against (those from adrtam, Paritosh Singh, and VPfB) all appear to be roughly O(n), as expected. (It is, I think, fairly obvious that this is a lower bound, since every element in the list must be examined to find the answer.) Edit: looking at this again, of course the big-O for this approach is at least O(n log(n)), because of the sort. It's just that the sort is so fast comparitively speaking that it looked linear overall.
I'm new to programming and I'm trying to write a program in Python that will find the sum of the even numbers of the numbers below 4,000,000 in the Fibonacci sequence. I'm not sure what I'm doing wrong but nothing will print. Thanks for any help.
def fib():
listx = []
for x in range(4000000):
if x == 0:
return 1
elif x == 1:
return 1
else:
listx.append(fib(x - 1) + fib(x - 2))
return listx
def evens(fib):
y = 0
for x in fib():
if x % 2 == 0:
y += x
else:
continue
print (y)
Here's an approach that uses a generator to keep memory usage to a minimum:
def fib_gen(up_to):
n, m = 0, 1
while n <= up_to:
yield n
n, m = m, n + m
total = 0
for f in fib_gen(4000000):
if f % 2 == 0:
total += f
Another option:
def fib_gen(up_to, filter):
n, m = 0, 1
while n <= up_to:
if filter(n):
yield n
n, m = m, n + m
sum(fib_gen(4000000, lambda f: f % 2 == 0)) # sum of evens
sum(fib_gen(4000000, lambda f: f % 2)) # sum of odds
First things first, there appears to be some contention between your requirements and the code you've delivered :-) The text of your question (presumably taken from an assignment, or Euler #2) requests the ...
sum of the even numbers of the numbers below 4,000,000 in the Fibonacci sequence.
Your code is summing the even numbers from the first four million Fibonacci numbers which is vastly different. The four millionth Fibonacci number has, according to Binet's formula, north of 800,000 digits in it (as opposed to the seven digits in the highest one below four million).
So, assuming the text to be more correct than the code, you don't actually need to construct a list and then evaluate every item in it, that's rather wasteful on memory.
The Fibonacci numbers can be generated on the fly and then simply accumulated if they're even. It's also far more useful to be able to use an arbitrary method to accumulate the numbers, something like the following:
def sumFibWithCond(limit, callback):
# Set up initial conditions.
grandparent, parent, child = 0, 0, 1
accum = 0
# Loop until number is at or beyond limit.
while child < limit:
# Add any suitable number to the accumulator.
accum = accum + callback(child)
# Set up next Fibonacci cycle.
grandparent, parent = parent, child
child = grandparent + child
# Return accumulator when done.
return accum
def accumulateEvens(num):
# Return even numbers as-is, zero for odd numbers.
if num % 2 == 0:
return num
return 0
sumEvensBelowFourMillion = sumFibWithCond(4000000, accumulateEvens)
Of special note is the initial conditions. The numbers are initialised to 0, 0, 1 since we want to ensure we check every Fibonacci number (in child) for the accumulating condition. This means the initial value of child should be one assuming, as per the question, that's the first number you want.
This doesn't make any difference in the current scenario since one is not even but, were you to change the accumulating condition to "odd numbers" (or any other condition that allowed for one), it would make a difference.
And, if you'd prefer to subscribe to the Fibonacci sequence starting with zero, the starting values should be 0, 1, 0 instead.
Maybe this will help you.
def sumOfEvenFibs():
# a,b,c in the Fibonacci sequence
a = 1
b = 1
result = 0
while b < 4000000:
if b % 2 == 0:
result += b
c = a + b
a = b
b = c
return result