Project Euler #25 Python Why this wont work? - python

I'm trying to solve this problem:
The 12th term, F12, is the first term to contain three digits.
What is the first term in the Fibonacci sequence to contain 1000
digits?
check = True
mylst = [1,1]
i = 1
while check:
if len(str(mylst[i])) >= 1000:
check = False
else:
mylst.append(mylst[i-1] + mylst[i-2])
i=i+1
a =str((mylst[len(mylst)-1]))
print(len(a))
print(a)
I seem to get correct answer for test cases 2 and 3 but my answer is not being accepted. Please help me me I am not able to understand what went wrong.

I think you have an error in your code. If you look at the first iteration, you start with i=1 then call
mylst.append(mylst[i-1] + mylst[i-2])
Which will add mylst[0] + mylst[-1]. This also gives me incorrect answers (for finding the first index with 3 digits, F12. Your code gives me F18).
Obviously this is not what you want to do. You can fix it by changing the list indices you are adding together.
check = True
mylst = [1,1]
i = 1
while check:
if len(str(mylst[i])) >= 1000:
check = False
else:
mylst.append(mylst[i] + mylst[i-1])
i=i+1
Then, as others have mentioned, you want the index of the answer.
print len(mylst)

The answer is the index of the fibonacci number, not the number itself.
So, if Fn is the first term in the Fibonacci sequence to contain 1000 digits you need to enter the corresponding n.

Because the question is what term is the first to contain 1000 digits, not which number. So, if the question was
What is the first term in the Fibonacci sequence to contain 3 digits?
The answer would have been 12, not 144.
A general tip on Project Euler: Read the problem description carefully. And do it at least 3 times. If I had burned one calorie for each minute I've spent troubleshooting a PE problem due to a misread of the problem text, my body would probably be in a healthy shape.

Related

How to find the numbers that their sum equal to a given number?

This seems like a repost but it's not. Most people asked for the pair numbers. I need all numbers, not just two. Like n0+n1+n2+n3+n4+...+n100=x And also, each number must be lower than the number comes before him. For example for 8 output must be:
There are 5:
7+1
5+3
6+2
5+2+1
4+3+1
In here you can see 5>3 and 6>2 and vice versa.
I came so close with this code. I found this on stackoverflow, and then improved it to according to my needs. However I tested it on a super computer, that if you give 200 to this, it says it's wrong. I just don't get it how could this be wrong? Please can someone help me improve this? With my pc it takes a lot of time. Give this 50, and it will still take hours. Here is my code:
from itertools import combinations
def solution(N):
array=[]
counter=0
for i in range(N):
if(i==0):
continue
array.append(i)
for K in range(N):
for comb in combinations(array, K):
if sum(comb) == N:
counter+=1
#print(comb) uncomment this if you like, it prints pairs.
return counter
res=solution(50)
print(res)
By the way, can I do it without itertools at all? Maybe it causes problems.
I think I may have found a solution, I will share it and maybe you can check with me if it is correct :) I assumed that all numbers must be smaller than N.
To start, I am not so sure your code is necessarily wrong. I think it produces the right answers but maybe you should consider what is happening and why your code takes so long. Currently, you are checking for all combination of sums, but by iterating in another way you can exclude many possibilities. For example, suppose my goal is to find all sums that result in a total of 8.
Suppose I now have a sum of 6 + 5 = 11. Currently, you are still checking all other possibilities when adding other numbers (i.e. 6 + 5 + 4 and 6 + 5 + 3 etc etc), but we already know they all will be >8, hence we do not even have to compute them.
As a solution we can start with the highest number smaller than our goal, i.e. 7 in our example. Then we will try all combinations with numbers smaller than this. As soon as our sum gets bigger than 8, we do not follow the trail further. This sounds a lot like recursing, which is how I currently implemented it.
To get an idea (I hope it is correct, I haven't tested it extensively):
def solution(goal, total_solutions=0, current_sum=0.0, current_value=None):
if current_value is None:
current_value = goal
# Base condition
if current_sum >= goal:
if current_sum == goal:
return total_solutions + 1
return total_solutions
for new_value in range(current_value - 1, 0, -1):
total_solutions = solution(
goal, total_solutions, current_sum + new_value, new_value
)
return total_solutions
res = solution(8)
print(res) # prints 5
So as an answer to your question, yes you can do it with itertools, but it will take a long time because you will be checking a lot of sums of which you do not really need to check.
I compared this program with yours and it produces the same output up until N=30. But then your code really starts to blow up so I won't check further.
The Answer you're looking for is in the post : programming challenge: how does this algorithm (tied to Number Theory) work?
The classical method start taking some time at the 100th step but the use of memoization also called dynamic programming reduces the complexity drastically and allows your algorithm to compute at the 4000th step without taking any time at all.

Python input multiple lines and spaces

Im trying to solve one of the a2oj problems "given three numbers a , b and c. print the total sum of the three numbers added to itself."
I came with this
import sys
numbers = [int(x) for x in sys.stdin.read().split()]
print(numbers[0] + numbers[1] + numbers[2])
I saw many topics but I cant figure out how to read just 3 values from input. I know I can stop this procces by typing CTRL+D, but is there any possibility to make it automatic (after reaching third value)?
Thanks
// Thanks for very quick answers, I made mistake and posted only Problem Statement without Input Format: "three numbers separated by bunch of spaces and/or new lines"
So for example input should look like this:
2
1 4
// Ok thanks to you guys finally I made this:
n = []
while len(n) < 3:
s=input()
i = s.split()
[n.append(int(j)) for j in i]
print(2 * sum(n))
It's working but when I sent my results I got Runtime Error. I have no idea why:
Link: https://a2oj.com/p?ID=346
You could just use:
sys.argv
import sys
numbers = [int(x) for x in sys.argv[1:4]]
print(numbers)
print(sum(numbers))
When inputs are given line by line.
from sys import stdin
sum = 0
for num in stdin.readline(4):
sum = sum + int(num)
print(sum)
When inputs are given on CLI.
from sys import argv
sum = 0
for num in argv[1:4]:
sum = sum + int(num)
print(sum)
Use Python strip() and split() functions as per your usecases
I am not sure what you are looking for, but it seems that you are looking for is the input function, from python's builtins:
x=input()
This reads any input from the user, as a string. You have then to convert it to a number if needed.
You can read three values:
x=input("First value:")
y=input("Second value:")
z=input("Third value:")
As you have now specified more precisely the problem statement, I edit my answer:
In your case, this is not very complicated. I am not going to give you the answer straight away, as it would defeat the point, but the idea is to wrap the input inside a while loop. Something like:
numbers=[]
while (you have less than 3 numbers):
(input one line and add the numbers to your list)
(print the sum of your numbers)
That way you are waiting for as many inputs as you need until you reach 3 numbers. By the way, depending on your input, you might have to check whether you do not get more than 3 numbers.
After seeing the update from the question author and linked the online judge question description, the tweak to his code needed is below. It's worth noting that the expected output is in float and has precision set to 6 and the output is 2 * sum of all inputs, not just sum. There is no description on this in the online judge question and you've to understand from the input vs output.
n = []
while len(n) < 3:
s = input()
i = s.split()
n.extend(float(j) for j in i)
print(format(2 * sum(n), '.6f'))
Screenshot below
But the first version of this answer is still valid to the first version of this question. Keeping them if anyone else is looking for the following scenarios.
To separate inputs by enter aka New lines:
numbers_List = []
for i in range(3):
number = int(input())
numbers_List.append(number)
print("Sum of all numbers: ", sum(numbers_List))
Screenshot:
To separate inputs by space aka Bunch of spaces:
Use map before taking input. I'd suggest using input as well instead of sys.stdin.read() to get input from users, separated by space, and ended by pressing Enter key.
Very easy implementation below for any number of inputs and to add using sum function on a list:
numbers = list(map(int, input("Numbers: ").split()))
print("Sum of all numbers: ", sum(numbers))
The screenshot below and link to the program is here
Read Python's Built-in Functions documentation to know more about all the functions I used above.

Wrong Answer python3.6

You are given a set S and Q queries. Initially, S is empty. In each query:
You are given a positive integer X.
You should insert X into S.
For each y∈S before this query such that y≠X, you should also insert y⊕X into S (⊕ denotes the XOR operation).
Then, you should find two values E and O: the number of elements of S with an even number of 1's and with an odd number of 1's in the binary representation, respectively.
I have tried splitting the problem into smaller subproblems but it seems to exceed time because of large input size and large list size. Any suggestion into the code and further optimization will be very helpful.I have mow used set but the expected output is not as same as my output. Any suggestions as where I am going wrong in the solution code..?
s=set()
def fun(n,q):
c=0
cc=0
s.add(n)
for k in range(len(list(s))):
if list(s)[k]!=n:
s.add((list(s)[k])^n)
for k in s:
if bin(k)[2::].count('1')%2==0:
c+=1
else:
cc+=1
print(c,cc)
for _ in range(int(input())):
q=int(input())
for j in range(q):
n=int(input())
fun(n,q)
Example Input:
1
3
4
2
7
Example Output:
0 1
1 2
3 4
The first thing i see wrong on your code is that S should be a set of numbers. A list can have duplicates, so you need to work with sets
And to optimize your script, you can start by improving how you count the amount of enabled bits in your number expressed in binary. Such count is called the hamming weight of a string.
Search it on the web. For instance you have this article
I think you are inserting duplicate value in your List. fix it you will be good to go.
Solution And Reference :- https://whitefox-89ea6.firebaseapp.com/

Split day-of-month integers into digits, sum them repeatedly until get a single-digit integer

I am attempting to take two-digit integers representing day-of-month, split the digits into single digits by taking each character in the single digit and adding them together to form a new number.
e.g. If the value for day was an integer 29, then the program would turn that into strings and split them into '2' and '9'. The program would then turn 2 and 9 into integers and add them together to equal 11. Since this is still a double digit number, the program would loop and 1 and 1 would be added together and the final value that would print would be 2. According to the code below(mostly the last ~5 lines), if I enter day=29, then the final answer I keep getting is 4 which is incorrect. Can someone help me fix this:
Note someone mentioned that I didn't re-enter dayStringSum and I accidentally deleted their post am not sure what that means at all.
dayString = str(int(day))
# Turns value day into int
dayStringA = int(str(dayString[0]))
# If day=29 then this variable represents the 2...
dayStringB = int(str(dayString[1]))
# ...and this represents the 9
dayStringSum = (dayStringA + dayStringA)
while(dayStringSum >=10):
dayStringA = int(str(dayStringSum[0]))
# Since daystringsum is now 11, this code changes the value of daystringA into a new value of 1, likewise for below.
dayStringB = int(str(dayStringSum[1]))
print(dayStringSum)
dayStringSum is an integer, so dayStringSum[n] makes no sense. You'll want to turn it into a string first, and then look at its individual characters.
Also, you do not assign a new value to dayStringSum inside the while loop, so if it is >= 10 upon entering the loop, it will remain so, resulting in an infinite loop. You say that you got a final result of 4, but I fail to see how you would get a final result at all.
Try something like this:
daySum = int(day) # Ensure that day is an int before we start.
while(daySum >= 10):
newString = str(daySum)
dayIntA = int(newString[0])
dayIntB = int(newString[1])
daySum = dayIntA + dayIntB # Will be checked on next iteration.
print(daySum)
I'm guessing the reason you're getting the wrong answer is that you add dayStringA + dayStringA when you meant to add dayStringA + dayStringB, i.e. it's just a typo.
The other thing you need to fix is that in the loop, you don't change dayStringSum. This hasn't been a problem so far because dayStringSum is less than 10 in your example, so the loop never executes in the first place, but once you fix that typo, you're going to get an infinite loop and the program will never stop.
Here's what I mean: suppose your day is 29. When you get to this line:
while(dayStringSum >=10):
then dayStringSum will be 11. So then you set dayStringA to 1,
dayStringA= int(str(dayStringSum[0]))
and also dayStringB to 1.
dayStringB= int(str(dayStringSum[1]))
Then that's the end of the loop. So Python goes back to this line:
while(dayStringSum >=10):
What's dayStringSum? Why, it's still 11! You never changed it. So Python will keep looping, going through the same logic over and over again.
Now beyond that, there are a bunch of things that make this code way more complicated than it needs to be. I'm not going to go through them (Code Review would be the place for that), but in general, you don't need to convert things to ints if they are already ints, and likewise you don't need to use str on something that is already a string.
try sum(map(int,"265"))
that maps them to ints and sums them ...
>>> sum(map(int,"254"))
11
or
>>> sum(map(int,str(29)))
11
oh well since its homework I cant really just give away the answer ....
but
its similar to
sum1=0
for integer in [1,2,3]: sum1 += integer
print sum1
Easier way is to take modulus 9 of the number
>>> print(29%9)
2
day = 29
while day >= 10:
day = sum(int(digit) for digit in str(day))
(Also, whenever you're doing major manipulations of the individual digits of an integer, decimal.Decimal is useful, in particular its method
Decimal(29).as_tuple().digits which gives you (2, 9)).

Why don't these simple Python programs work: Euler 4 and 9

I was trying Project Euler and am stuck on this one:
A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 99.
Find the largest palindrome made from the product of two 3-digit numbers.
for i in range(1000,100,-1):
for j in range(1000,100,-1):
test = i*j
test = str(test) #turn product into string
test2 = test[2:] #take last two numbers
test2 = test2[::-1] #flip them
if test[:2] == test2: #if it's a palindrome, the first two should
print(i, "\t", j) #match the flip of last two
input("\n\nPress the ENTER key to exit.")
Nothing happens when it is run: the command line calculates, but doesn't print anything. The program does end though.
I know the bigger numbers have more than just the first and last two numbers, but there should be few enough palindromes that I can just look through them.
Here is the next one:
Find the Pythagorean triplet whose sum is 1000.
a^2 + b^2 = c^2, a+b+c=1000
for a in range(1,32):
for b in range(1,32):
c = (a**2 + b**2)**.5
if a + b + c == 1000:
print(a,"\t",b,"\t",c)
input("\n\nPress the ENTER key to exit.")
As with the last program, there is no output... But again, it does end.
But I noticed that they both have nested for loops. Could this have something to do with it?
Both your tests are wrong. In the first example, the line
test2 = test[2:] #take last two numbers
does not say what the comment says – this line strips off the first two characters from the string, leaving only the last digit. Instead of fixing this line, simply check if the whole string equals the reversed string:
if test == test[::-1]:
In the second example, you compare approximate floating point numbers to the exact integer 1000. Since the floating-pointed numbers will have rounding errors, you don't find an exact match. See also Floating Point Arithmetic: Issues and Limitations in the Python tutorial.
You should round c to the nearest integer, check if they really are a Pythagorean triple using pure integer arithmetic and then test if the sum is 1000.
As pointed out by DSM in the comments, your loops also stop to early. the maximum sum you will find with these values is about 106.
With the second problem: simple mistake;c is a floating point number and you are comparing a+b+c to 1000;raising to a floating point number gives a floating point number e.g. (3**2+4**2)**0.5 == 5.0
For the second problem, you don't have a large enough range. If the maximum of a and b are 31, then the greatest value of c can be (31^2 + 31^2)^0.5, so the sum of a + b + c you can possibly have is (2 + sqrt(2) * 31, which is less than 1000.
As for the floating point issue, make sure that you use the int() function to turn c into an integer. This may produce some overlap with rounding errors (I don't think it did for me when I tried that solution), but it should be trivially easy to check the few results you do get for the correct one, even if you do it manually within the one-minute limit.

Categories