My assignment is to create a function that produces 3 lists of the numbers in the fibonacci sequence starting at 0. Here is my code so far.
def fibList(n):
a = 0; b = 1; fibList = []
if n <= 0:
return
elif n == 1:
fibList = [a]
elif n == 2:
fibList = [a,b]
else:
for i in range(0,n):
a, b = b, a + b
fibList.append(b)
return fibList
def main():
print (fibList(4))
print (fibList(10))
print (fibList(-4))
what i want my output to look like is [0,1,1,2] for 4, [0,1,1,2,3,5,8,13,21,34,55] for 10, and [] for -4
My issue begins with fibList(4) currently giving an output of [1, 2, 3, 5] and fibList(10) gives an output of [1, 2, 3, 5, 8, 13, 21, 34, 55, 89] and for -4 I get "None" instead of a [].
If I type in fibList(1) I get [0] and for fibList(2) I get [0, 1], but when i test fibList(3) the first 0 and 1 are lost, giving me [1,2,3]
How would I go about making it so any number above 3 starts with [0, 1, 1, 2...]? My main issue is getting the 0 and 1 to be the first two numbers in the sequence and getting fibList(-4) to produce a [].
any help or tips would be greatly appreciated :-)
All that you are missing is to add an empty list in the case of less than or equal to zero, and recurse correctly over your range of Fibonacci numbers greater than 2. Making those small changes like so:
def fibList(n):
if n <= 0:
fibnums = []
elif n == 1:
fibnums = [0]
elif n >= 2:
fibnums = [0, 1]
for i in range(2,n):
fibnums.append(fibnums[i-1]+fibnums[i-2])
return fibnums
Note that this recursive method can get quite slow for large numbers, if that is of concern to you with your program. Best of luck!
With these changes,
print (fibList(4)) => [0, 1, 1, 2]
print (fibList(10)) => [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
print (fibList(-4)) => []
You did not quite define your function. Should the resulting list have n values [f(0), ..., f(n-1)] or n+1 values [f(0), ..., f(n)]? Your examples are contradictory: the 'expected' output for 4 has 4 values ending with f(3) while that for 10 has 11 values ending with f(10).
I am going to assume that the latter is correct. Here is a revised version of your fast iterative solution. (If my assumption is wrong, stop the range at n instead of n+1.)
def fibs(n):
"Return [fib(0), ..., fib(n)."
ret = [0, 1] # fib(0), fib(1)
a, b = ret
if n <= 1:
return ret[:n+1]
else:
for i in range(2, n+1):
a, b = b, a+b # b = f(i)
ret.append(b)
return ret
print(fibs(-4), fibs(0), fibs(2), fibs(4), fibs(10))
#
[] [0] [0, 1, 1] [0, 1, 1, 2, 3] [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
Related
I have written a function where the input is a list of numbers (items), where the length is a multiple of 3.
I want to this function to continue, until there is only 1 value left in items.
while len(items) > 1:
for x in range(0, len(items), 3):
if items[x] < items[x+1] < items[x+2] or items[x] > items[x+1] >items[x+2] :
result.append(items[x+1])
elif items[x+1] < items[x] < items[x+2] or items[x+1] > items[x] > items[x+2]:
result.append(items[x])
else:
result.append(items[x+2])
items = result
break
return items
Taking a guess at what you needed and how your code should appear...
items = [99, 42, 17, 7, 1, 9, 12, 77, 15]
while len(items) > 1:
result = []
for x in range(0, len(items), 3):
a, b, c = items[x], items[x+1], items[x+2]
if a < b < c or a > b >c :
result.append(b)
elif b < a < c or b > a > c:
result.append(a)
else:
result.append(c)
items = result
print(items)
Introducing the variables a, b, and c helped me better read the code.
The logic is not quite right. Imagine a simple input of [1, 1, 0]. By looking at this, the median should be 1 but the use of > and < instead of <= and >= end up with the code entering the final else block because 1<1 is False and 1>1 is also False. The final else block sets the result equal to the third element, which is 0.
Switch your operators to >= and <= to fix this. The break at the bottom of your for loop immediately breaks after one iteration, so that also needs to be removed.
If you have a list of one element (3**0 = 1), you will end up with an IndexError when you try to get the 2nd and 3rd elements in your loop.
So we need to
Switch operators to test for equality as well
Remove the erroneous break
Handle the base case
def median_split3(items):
if len(items) == 1: # Base Case
return items[0]
while len(items) > 1:
result = []
for x in range(0, len(items), 3):
a, b, c = items[x:x+3]
if a <= b <= c or a >= b >= c:
result.append(b)
elif b <= a <= c or b >= a >= c:
result.append(a)
else:
result.append(c)
items = result
return items[0]
test1 = [99, 42, 17, 7, 1, 9, 12, 77, 15]
print(test1, "-->", median_split3(test1))
test2 = [1, 1, 0]
print(test2, "-->", median_split3(test2))
test3 = [0, 0, 1]
print(test3, "-->", median_split3(test3))
test4 = [9]
print(test4, "-->", median_split3(test4))
Output:
[99, 42, 17, 7, 1, 9, 12, 77, 15] --> 15
[1, 1, 0] --> 1
[0, 0, 1] --> 0
[9] --> 9
So i'm writing a code, listing square numbers lower than n.
I want the output to be a list. like so: [1, 4, 9, 16] etc.
n=int(input("input number: "))
counter = 1
while counter * counter < n:
for counter in range(1,n):
a = counter*counter
print (a)
if a < n:
break
I would be very grateful if I can get some help.
you can remove the need for the while loop and utilise pythons range function to generate your numbers up to n and use a for loop to iterate over them. you also need to initalise a list to store them in before the loop starts. and then each iteration of the loop append the square number to the list.
n=int(input("input number: "))
squares = []
for num in range(1, n):
squares.append(num * num)
print(squares)
OUTPUT for n=10
[1, 4, 9, 16, 25, 36, 49, 64, 81]
Although this can be simpfied using pythons list comprehension style as
n=int(input("input number: "))
squares = [num * num for num in range(1, n)]
print(squares)
OUTPUT for n=10
[1, 4, 9, 16, 25, 36, 49, 64, 81]
UPDATE based on comment from B. Go
user B. Go pointed out that my answer is printing all the results of squaring number up to the value of N. But the question was actually print all the square numbers less than N. Below code to print squares less than N
n=int(input("input number: "))
squares = []
for num in range(1, n):
result = num * num
if result >= n:
break
squares.append(num * num)
print(squares)
OUTPUT N=50
[1, 4, 9, 16, 25, 36, 49]
I would like to count the number of instances of a given number N in an array using recursion. For example, given:
array = [1, 2, 3, 1, 1, 4, 5, 2, 1, 8, 1]
and N = 1, the function should return 5.
This problem can be solved using the .counter attribute as shown here. However, I am looking to not use any in-built functions or attributes.
Here's my attempt to solve this using recursion but I get a count of 1 and not 5. What am I doing wrong?
def count_val(array, n, count=0):
if len(array) == 0:
return None
# Base Case
if len(array) == 1:
if array[0] == n:
count += 1
else:
count_val(array[1:], n, count)
if array[0] == n:
count += 1
return count
print(count_val2(array, 1))
1
I think for an empty array, the value should be 0 (len == 0 should be the base case), and, you don't need to have a count parameter if you just return the count, your function could be reduced to this:
def count_val(array, n):
if len(array) == 0:
return 0
return (array[0] == n) + count_val(array[1:], n)
array = [1, 2, 3, 1, 1, 4, 5, 2, 1, 8, 1]
print(count_val(array, 1))
Output:
5
You can have it as a one-liner as well (as suggested by #blhsing):
def count_val(array, n):
return len(array) and (array[0] == n) + count_val(array[1:], n)
What am I doing wrong?
The function you wrote will always keep only the last few characters, so after a while it will be [1, 8, 1], after that [8, 1] and after that [1], which returns 1. The array never contains just any of the other 1s.
An easy way to do this is to loop over all elements in a list and test if they are equal to N.
array = [1, 2, 3, 1, 1, 4, 5, 2, 1, 8, 1]
def count_val(array, n):
if len(array) == 0:
return 0
count=0
for i in array:
if i==n:
count += 1
return count
print(count_val(array, 1))
This returns 5.
Given a list:
list1 = [1,2,3,4,5,6,1,2,3,4,1,2,3,4,5,6,7]
While iterating though list1, every time the integer 1 is hit, start the loop over but increment it by 1.
Tried the two examples below but it only returns a list of 1's for the length of list1.
digit = []
i = 0
for num in list1:
num = i
if num != 1:
i += 1
digit.append(i)
elif num == 1:
digit.append(num)
digit = []
i = 0
for num in list1:
num = i
if num == 1:
digit.append(num)
continue
elif num != 1:
i += 1
digit.append(i)
digit
Looking to get something like the list below
digit = [1,1,1,1,1,1,2,2,2,2,3,3,3,3,3,3,3]
You're overthinking this. Initialise a variable to zero. Append it to a list at each iteration. Increment if the corresponding list value is 1.
values = []
i = 0
for l in list1:
if l == 1: # The check must come before appending. Can you explain why?
i += 1
values.append(i)
values
# [1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3]
If you were to ask me for a pythonic solution to this problem, I'd suggest itertools.accumulate:
from itertools import accumulate
from operator import add
list(accumulate((int(x == 1) for x in list1), add))
# [1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3]
# Uses python3
# Compute the Last Digit of a Large Fibonacci Number
def Fib_Last_Digit(n):
if n == 0 : return 0
elif n == 1: return 1
else:
a,b = 0,1
for i in range(1,n):
c = a + b;
a = b;
b = c;
# Calculate the last digit of the final number
lastdigit = int(repr(c)[-1]);
print(lastdigit);
n = int(input(""));
Fib_Last_Digit(n);
This code works very well. However, I want to revise the algorithm to save more time and memory. By the way, the input and output should be kept the same with the previous version.
Only keeping the last digit during calculation saves a lot of time:
def fib_last_digit(n):
if n < 2: return n
else:
a, b = 0, 1
for i in range(1,n):
a, b = b, (a+b) % 10
print(b)
n = int(input())
fib_last_digit(n)
Handling numbers that fit in fewer bytes saves time.
When you're working with huge numbers, you can save a lot of time using the answer described here, slightly modified to only keep track of the last digit:
def fib_last_digit(n):
v1, v2, v3 = 1, 1, 0 # initialise a matrix [[1,1],[1,0]]
for rec in bin(n)[3:]: # perform fast exponentiation of the matrix (quickly raise it to the nth power)
calc = (v2*v2) % 10
v1, v2, v3 = (v1*v1+calc) % 10, ((v1+v3)*v2) % 10, (calc+v3*v3) % 10
if rec == '1': v1, v2, v3 = (v1+v2) % 10, v1, v2
return v2
And finally, based on the concept described in Eugene Yarmash's answer (the last digits repeat every 60 steps) we can make an even faster solution (O(1)):
def fib_last_digit(n):
return (
[1, 1, 2, 3, 5, 8, 3, 1, 4, 5, 9, 4, 3, 7, 0, 7, 7, 4, 1, 5, 6, 1, 7, 8, 5, 3, 8, 1, 9, 0, 9, 9, 8, 7, 5, 2, 7, 9, 6, 5, 1, 6, 7, 3, 0, 3, 3, 6, 9, 5, 4, 9, 3, 2, 5, 7, 2, 9, 1, 0]
[n % 60 - 1]
)
The series of final digits of Fibonacci numbers repeats with a cycle length of 60. Therefore, the Nth Fibonacci number has the same last digit as the (N % 60)th, which should be pretty fast to calculate. As an additional optimization, you can keep only the last digit of each term:
def fib_last_digit(n):
a, b = 0, 1
for i in range(n % 60):
a, b = b, (a + b) % 10
return a
print([fib_last_digit(n) for n in range(1, 11)])
Output:
[1, 1, 2, 3, 5, 8, 3, 1, 4, 5]
def fib(n):
phi = (1 + 5 ** 0.5) / 2
fib_n = round(((phi** n) - (phi**-n) )/(5 ** .5))
return fib_n % 10
Phi is your friend.
def fib_digit(n):
f=[1,1]
for i in range(2,n):
f.append((f[i-1]+f[i-2]) % 10 )
return f[-1]
n = int(input())
print(fib_digit(n))
This is one of the simplest answers,i'm sure, there is a faster algorithm.
Here is what I found:
f1, f2 = 0, 1
for i in range(int(input())-1):
f1, f2 = f2, (f1+f2)%10
print(f2)
It took only --- 0.002832174301147461 seconds --- to complete the code.
import time
n = 100000000000000000000000000000000000000000
def printfib(previous, latest, n):
if(latest > n):
return
print(', ', latest, end='')
printfib(latest, previous + latest, n)
start_time = time.time()
print(0, end='')
printfib(0, 1, n)
print(" ")
print("--- %s seconds ---" % (time.time() - start_time))