I was trying Project Euler Challenge #2 on the HackerRank, and my Python code passed the sample test case but failed the hidden test cases, with the compiler displaying 'Wrong Answer' for all of them. Here is the link to the challenge-
https://www.hackerrank.com/contests/projecteuler/challenges/euler002/problem
What is the mistake I have committed?
I have tried various inputs (including huge values and many test cases). It had given me correct answers when I executed them in PyCharm editor. I think I have covered all range of inputs. If not, please let me know.
t=int(input().rstrip())
n=[]
for i in range(t):
n.append(int(input().rstrip()))
inp=sorted(n)
f1=1
f2=2
sf=2 #sum of fibonacci
it=iter(inp)
value=next(it)
out=[None]*len(n)
maxi=max(inp)
while f2<=maxi:
f1=f1+f2
f2=f1+f2
f1=f2-f1
f2=f2-f1
if f2>value:
out[n.index(value)]=sf
try:
value=next(it)
except StopIteration:
pass
if f2%2==0:
sf=sf+f2
print(*out,sep='\n')
I'm not sure this answer will help future readers, but let's go though your code quickly.
Let's try a different input:
3
10
11
12
For the new examples, the outputs should be 10 as well (the next number in the sequence after 8 is 13):
10
10
10
If we run your program with this input, we get:
10
None
None
Oops! That looks like a bug. Where is the None coming from? The list of outputs is filled with None when the program initializes: out=[None]*len(n) so it seems like the correct value is not put in the output list.
The line where the values are filled in: out[n.index(value)]=sf only runs once for each item in the input list. The problem seems to be that inputs that have the same output will only be computed once.
I'm guessing you were trying to reduce the runtime complexity by calculating all values in one iteration, instead of generating the Fibonacci sequence for each input. That's smart!
So, we noticed that inputs with the same output value only updates the first value in output. What if we do for all values smaller than f2 instead?
t=int(input().rstrip())
n=[]
for i in range(t):
n.append(int(input().rstrip()))
inp=sorted(n)
f1=1
f2=2
sf=2 #sum of fibonacci
it=iter(inp)
value=next(it)
out=[None]*len(n)
maxi=max(inp)
while f2<=maxi:
f1=f1+f2
f2=f1+f2
f1=f2-f1
f2=f2-f1
while f2>value:
out[n.index(value)]=sf
try:
value=next(it)
except StopIteration:
break
if f2%2==0:
sf=sf+f2
print(*out,sep='\n')
Only two things changed, the if f2>value: is now while f2 > value: and instead of pass when there are no more values, we break out of the while loop instead. That takes care of the first problem, it seems. The output is now what we expected:
10
10
10
Ok, let's try another input. Remember, it doesn't say anywhere that the inputs are unique. They might occur more than once - what will happen if they do? Let's try this input:
2
100
100
The output should just be 44 twice, right? With the new version above, we get:
44
None
Oh no, another bug. The problem seems to be on the line that updates the output, again: out[n.index(value)]=sf. It's clear that if the input is something like [100, 100], the output should be [44, 44] but n.index(100) will always be 0. The index method will only return the first index that matches a value. Now we have more than one and this will not work.
There are obviously many solutions to this, but let's put the answers in a dictionary called results instead and create out at the end once we know what all the outputs are supposed to be:
t=int(input().rstrip())
n=[]
for i in range(t):
n.append(int(input().rstrip()))
inp=sorted(n)
f1=1
f2=2
sf=2 #sum of fibonacci
it=iter(inp)
value=next(it)
results = {}
maxi=max(inp)
while f2<=maxi:
f1=f1+f2
f2=f1+f2
f1=f2-f1
f2=f2-f1
while f2>value:
results[value] = sf
try:
value=next(it)
except StopIteration:
break
if f2%2==0:
sf=sf+f2
out = [results[x] for x in n]
print(*out, sep='\n')
This one passes all the HackerRank test cases as well.
You were so close, nice!
The problem in your print(*out,sep='\n'). You should call print in loop
Try this. All tests passed
#!/bin/python3
import sys
t = int(input().strip())
for a0 in range(t):
n = int(input().strip())
if (n < 2) :
print(0)
continue
# Initialize first two even prime numbers and their sum
ef1, ef2 = 0, 2
sm = ef1 + ef2
# calculating sum of even Fibonacci value
while ef2 <= n:
# get next even value of Fibonacci sequence
ef3 = 4 * ef2 + ef1
# If we go beyond limit, we break loop
if ef3 > n:
break
# Move to next even number and update sum
ef1, ef2 = ef2, ef3
sm = sm + ef2
print(sm)
Related
I wrote a code to solve the following algorithm question:
Given a number of positive integers all larger than 1, find the maximum number of pairs whose sum is a prime number. The number of positive integers is always an even number.
For example, given 2 5 6 13 2 11, the answer is 3 since 2+5=7, 6+13=19, 2+11=13.
I wrote the following code to solve the problem. I know this is not the optimal algorithm, but I just cannot find the bug in it that results in my failure in test cases.
def _isPrime(num):
for i in range(2, int(num**0.5)+1):
if num % i==0:
return False
return True
def findPairs(odds, evens, pairDict):
if len(odds)==0 or len(evens)==0:
return 0
key=' '.join(list(map(str, odds+evens)))
if key in pairDict:
return pairDict[key]
n=0
for i in range(len(evens)):
newOdds=odds.copy()
newEvens=evens.copy()
del newOdds[0]
del newEvens[i]
if _isPrime(odds[0]+evens[i]):
n=max(n,findPairs(newOdds, newEvens, pairDict)+1)
else:
n=max(n,findPairs(newOdds, newEvens,pairDict))
pairDict[key]=n
return n
numbers=list(map(int,input().split()))
odds=[i for i in numbers if i%2==1]
evens=[j for j in numbers if j%2==0]
pairDict={}
print(findPairs(odds,evens,pairDict))
Can someone help me find where the problem is. Thanks a lot!
The problem is that the recursion always tries to match the first odd number with some even number. This can go wrong if there are fewer even numbers than odd numbers because it will use up an even number that could have been used for a later match.
For example, consider "13 2 3". This code will return 0, but 2+3 is a prime.
You could fix it by also allowing an extra recursion case where the first odd number is discarded without reducing the even list.
del newOdds[0]
n=max(n,findPairs(newOdds, newEvens, pairDict)) # added line
del newEvens[i]
My homework is simple, declare a function named printPrimeNumbersTo with a single argument named to
I created the skeleton of the code itself, however, I needed some help from the net.
GeeksforGeeks was the site where I "borrowed" a line of code, which I don't completely understand. (Site: https://www.geeksforgeeks.org/python-program-to-print-all-prime-numbers-in-an-interval/)
My code looks like this (I have comments on nearly every line, describing what I think that the line of code does):
def printPrimeNumbersTo(to):
x = 0
prime_list = [] # This was a string, however, I changed it to a list so I won't have to convert the numbers to a string every time I wanted to append it to the list
for i in range(x, to + 1): # Create a for loop, using the function range an starting the loop at number 0. Add 1 to 'to', because range excludes the end integer
if i == 0 or i == 1:
continue
else:
for j in range(2, i // 2 + 1): # <--
if i % j == 0: # If 'j' is divided by any number in the list and remainder is 0, then the number is not a prime number, which means I can break the loop
break
else:
prime_list.append(i) # Append the prime number to the list
return str(prime_list)[1:-1] # Returns '[2,3,5,7..]', I use the square brackets the get rid of the brackets themselves
print(printPrimeNumbersTo(7)) # >>> 2, 3, 5, 7
The one line I don't understand is marked with an arrow, it's the 8th line of the code.
Why am I dividing the number by 2? And then making it an integer? When I do the calculations, it works, but... where is the logic? Anybody help?
The biggest number which could possibly be an even factor of a number is the half of that number. The integer division operator // produces this number as an integer.
Because of how range works, the ending index needs to be the desired number plus one.
There are two points to note:
the code needs to be indented correctly, in Python indentation matters as it forms the code blocks.
aside from this and specifically adressing the question: the range function that you refer to requires integers otherwise it would throw an typeerror like this: 'float' object cannot be interpreted as an integer .
# this will throw an error
for i in range(1, 10.5):
print(i)
# this will work
for i in range(1, 10):
print(i)
So the reason why the line of code you queried was written like that was to ensure that the upper bound of the range was an integer.
You should also note that the // has a meaning, for example try this:
x = 5//2
print(x)
y = 5/2
print(y)
x is the integer part only (x=2)
y is the full number (y=2.5)
In terms of implementaiton, there are a number of methods that would be better (suggested here):
Print series of prime numbers in python
Dividing the number by 2 is done to reduce the number of iterations. For example, the number 12 you can divide it without a remainder by 1,2,3,4,6. Notice that there is no number bigger than (6) which is 12 / 2. And this goes on with all of the numbers.
16 ---> 1,2,8 no number bigger than its half (8)
I have used this code to determine the value of e^pi with a specified tolerance in spyder(Python 3.8).
from math import*
term=1
sum=0
n=1
while (abs(e**pi-term))>0.0001:
term=term*pi/n
sum+=term
n+=1
print(sum,e**pi)
I ran this code several times. But spyder is not showing anything when I run this code. I am new to python. So now I have no way to know whether this code is correct or not. It would be beneficial if you could verify whether this code is valid or not.
Okay, so the taylor series for e^x is sum n=0 to inf of x^n / n! which you seem to be doing correctly by multiplying by pi/n during each iteration.
One problem I noticed was with your while loop condition. To check the error of the function, you should be subtracting your current sum from the actual value. This is why you enter the infinite loop, because your term will approach 0, so the difference will approach the actual value, e^pi, which is always greater than .0001 or whatever your error is.
Additionally, since we start n at 1, we should also start sum at 1 because the 0th term of the taylor series is already 1. This is why you enter the infinite loop, because
Therefore, our code should look like this:
from math import*
term = 1
sum = 1
n = 1
while (abs(e ** pi - sum)) > 0.0001:
term = term * pi / n
sum += term
n += 1
print(sum,e**pi)
Output:
23.140665453179782 23.140692632779263
I hope this helped answer your question! Please let me know if you need any further clarification or details :)
The while loop does not end.
I have stuck in a condition to break out of the loop (at 10,000 cycles) to show this:
from math import*
term=1
sum=0
n=1
while (abs(e**pi-term))>0.0001:
term=term*pi/n
sum+=term
n+=1
if n > 10_000:
print('large n')
break
print(sum,e**pi)
If you replace the while loop with a for loop, then you can see each iteration as follows.
term=1
sum=0
for n in range(1, 101):
term=term*(math.pi)/n
sum+=term
print(n, sum, math.e**math.pi)
And this is the result for the first 10 items:
1 3.141592653589793 23.140692632779263
2 8.076394854134472 23.140692632779263
3 13.244107634184441 23.140692632779263
4 17.30281976060121 23.140692632779263
5 19.852983800478555 23.140692632779263
6 21.188246569333145 23.140692632779263
7 21.787511098653937 23.140692632779263
8 22.02284172901283 23.140692632779263
9 22.104987615623955 23.140692632779263
10 22.13079450701397 23.140692632779263
The numbers are getting larger, hence the while loop was never exited (and your laptop probably got quite hot in the process !!).
I'm new to Python, which is why I'm having trouble on a problem which others might find easy.
Background to this problem: Euler Project, question 2. The problem essentially asks us to add all the even terms in the Fibonacci sequence, so long that each term is under 4,000,000. I decided to do the problem a little differently than what many solutions online show, by calculating the nth Fibonacci term from a closed formula. For now, suppose this function is called Fibonacci(n).
What I'd essentially like to do is loop through an unknown amount of integers that represent the indexes of the Fibonacci set (i.e., 1, 2, 3, 4... etc) and plug each value into Fibonacci(n). If the result has no remainder when divided by 2, then add this Fibonacci number to some value initially set at 0.
Here's what I have so far:
def Fibonacci(n):
return (1/(5**0.5))*((((1+5**0.5)/2)**n)-(((1-5**0.5)/2)**n))
i=0
FibSum = 0
nFib = 0
while (nFib <= 10):
nFib = Fibonacci(i)
if(nFib%2==0):
FibSum += nFib
i += 1
print FibSum
(Yes, as you can see, I'm constraining the Fibonacci sequence to end at 10 as opposed to 4,000,000; this is done merely for testing's sake.)
Now, here's my problem: when I run this code, I get 2.0 instead of 10.0 (2 and 8 are the two Fibonacci numbers that should be added together).
How come? My guess is that the loop stops after it gets to the third Fibonacci number (2) and doesn't continue beyond that. Does anyone see something wrong with my code?
Please comment if you have any further questions. Thanks in advance.
Solution provided by Gal Dreiman is fine but, conversion with in function is more better, below is your revised code:
def Fibonacci(n):
return int((1/(5**0.5))*((((1+5**0.5)/2)**n)-(((1-5**0.5)/2)**n)))
You have a floating point problem (which you can read on here)- the returned value 'nFib' is not an integer and not a rounded value. I ran your code and added print for this value in every iteration and got:
0.0
1.0
1.0
2.0
3.0000000000000004
5.000000000000001
8.000000000000002
13.000000000000002
The solution for this is to modify your code as the following:
nFib = int(Fibonacci(i))
After that I got the output: 10
The problem is with nFib%2==0 comparison. Here you try to compare the float LHS with integer 0. So either modify the if loop as below or modify the return as return int((1/(5**0.5))*((((1+5**0.5)/2)**n)-(((1-5**0.5)/2)**n))).
>>> def Fibonacci(n):
... return (1/(5**0.5))*((((1+5**0.5)/2)**n)-(((1-5**0.5)/2)**n))
...
>>> i=0
>>> FibSum = 0
>>> nFib = 0
>>> while (nFib <= 10):
... nFib = Fibonacci(i)
... if(int(nFib%2)==0):
... FibSum += nFib
... i += 1
...
>>> print FibSum
10.0
After some trial and error I have found a solution which works very quickly for the Project Euler Problem 5. (I have found another way which correctly solved the example case (numbers 1-10) but took an eternity to solve the actual Problem.) Here it goes:
def test(n):
for x in range(2,21):
if n % x != 0:
return False
return True
def thwart(n):
for x in range(2,21):
if test(n/x):
n /= x
return n
raise TypeError
num = 1
for x in range(1,21):
num *= x
while True:
try:
num = thwart(num)
except TypeError:
break
print(num)
My main problem is understanding why calling thwart(num) repeatedly is enough to result in the correct solution. (I.e. why is it able to find the SMALLEST number and doesnt just spit out any number divisible by the numbers 1-20?)
I only had some vague thoughts when programming it and was surprised at how quickly it worked. But now I have trouble figuring out why exactly it even works... The optimized solutions of other people on SO Ive found so far were all talking about prime factors which I can't see how that would fit with my program...?
Any help is appreciated! Thanks!
Well this isn't really a coding issue but a mathematical issue. If you look at all the numbers from 1-20 as the prime sthat make them you'll get the following:
1, 2,3,2^2,5,2^3,7,2^3....2^2*5.
the interesting part here is that once you multiply by the highest exponent of every single factor in these numbers you will get a number that can be divided by each of the numbers between one and twenty.
Once you realize that the problem is a simple mathematical one and approach it as such you can use this basic code:
import math
primes = [2]
for n in range(3,21): #get primes between 1 and 20
for i in primes:
if n in primes:
break
if n%i == 0:
break
if i> math.sqrt(n):
primes.append(n)
break
s = 1
for i in primes:
for j in range(10): # no reason for 10, could as well be 5 because 2^5 >20
if i**j > 20:
s = s*(i**(j-1))
break
print s
Additionally, the hint that the number 2520 is the smallest number that can be divided by all numbers should make you understand how 2520 is chosen:
I have taken a photo for you:
As you can caculate, when you take the biggest exponents and multiply them you get the number 2520.
What your solution does
your solution basically takes the number which is 1*2*3*4..*20 and tries dividing it by every number between 2 to 20 in such a way that it will still remain relevant. By running it over and over you remove the un-needed numbers from it. early on it will remove all the unnecessary 2's by dividing by 2, returning the number and then being called again and divided by 2 again. Once all the two's have been eliminated it will eliminate all the threes, once all the unnecessary threes will be eliminated it will try dividing by 4 and it will se it wont work, continue to 5, 6, 7... and when it finishes the loop without being able to divide it will raise a TypeError and you will finish your program with the correct number. This is not an efficient way to solve this problem but it will work with small numbers.