I've decided I want to work on the Euler problems in order to improve my Python skills, but I ran into a problem with the first one. You see, I wrote the program I thought would work trying to get an answer, and compared it to the one found on the solutions page located here. Here is the code that I wrote:
total = 0
for x in range(1000):
if x % 5 != 0 and x % 3 != 0:
total += x
print(total)
This gives me the answer 266,332, when the correct answer is 233,168 according to the solution linked before. I don't know why I got the wrong answer, and any help would be appreciated. Thanks!
You're missing a not in your application of De Morgan's Law:
total = 0
for x in range(1000):
if not (x % 5 != 0 and x % 3 != 0):
total += x
print(total)
not (x % 5 != 0 and x % 3 != 0) is equivalent to x % 5 == 0 or x % 3 == 0, the latter of which is stated in the page you link as the equivalent not x%5 or not x%3.
You are using the wrong condition. You have to test, when the rest is 0? With 3 and with 5. Additionally you have to use OR instead AND because you want both group of numbers.
If you use AND you are going to get only the numbers that are multiple of both, multiple of 3 and multiple of 5.
Try:
total = 0
for x in range(1000):
if x % 5 == 0 or x % 3 == 0:
total += x
print(total)
A couple of things are wrong with the program. For starters, your if statement checks the wrong condition--it checks to see whether or not it is NOT divisible by 3 or 5. It should be if x%3==0 or x%5==0:
Second, you have an indentation error, so nothing is being executed by the if statement. Indent the total+=x statement.
Your final code will look like this:
total = 0
for x in range(1000):
if x % 5 == 0 or x % 3 == 0:
total += x
print(total)
Best of luck, and happy coding!
try this:
def sumOfMultiples(number):
sum = 0
for i in range(1,number):
if i % 2 == 0 or i % 3 == 0:
sum += i
return sum
print (sumOfMultiples(15))
Related
So I have very, very limited coding knowledge and half the code I used here I learned today but what I was attempting to do was to create a list that was 2020 positive whole numbers long and which excluded all numbers that were divisible by 3 or 4 but not by 5. I was trying to figure out what the 2020th number was but I noticed that in my final list with the numbers excluded, it was still leaving them in towards the end!
This is the code I wrote:
numbers = [*range(1, 2165, 1)]
#print(numbers)
list1 = [ x for x in range(1, 2165) if x % 3 == 0 and x % 4 == 0 and x % 5 != 0 ]
#print(list1)
for x in list1:
numbers.remove(x)
print(len(numbers))
print(numbers)
Like I said I'm not very good at coding but it did seem to be working early on in the list as 12 was excluded and 60 was left in but towards the end, 2139 was left, which is divisible by 3.
I would appreciate any help.
2020 positive whole numbers long
For things like this, rather than iterating over a fixed range (in your case, from 1 to 2165, which doesn't produce 2020 numbers matching your conditions), it's usually more straightforward to build a generator that gives you numbers that you want, and take numbers from it via next() until you have as many as you need. In this case, given your conditions
def my_generator():
x = 0
while True:
x += 1
# skip all numbers that are divisible by (3 or 4) but are not divisible by 5
if ((x % 3 == 0) or (x % 4 == 0)) and (x % 5) != 0:
continue
yield x
# initialize the generator, and then grab exactly 2020 numbers from it
gen = my_generator()
numbers = [next(gen) for _ in range(2020)]
print("The 2020th number meeting the conditions is", numbers[-1])
# 3367
Note that, in your original question, your if condition was coded incorrectly, and I've fixed it here.
It might simplify your debugging if you just built the list directly by explicitly declaring the condition you're trying to match on rather than doing it in multiple steps. You can generate numbers in a single comprehension:
[x for x in range(1, 2165) if not(x % 3 == 0 and x % 4 == 0 and x % 5 != 0)]
or the logical equivalent:
[x for x in range(1, 2165) if x % 3 != 0 or x % 4 != 0 or x % 5 == 0]
If you're not convinced this is the same, you can test it against the numbers list generated by your original code:
>>> numbers == [x for x in range(1, 2165) if not(x % 3 == 0 and x % 4 == 0 and x % 5 != 0)]
True
2139 appears in this list because 2139 % 4 != 0.
If this doesn't match the condition you're trying to capture, having the code simplified should make it easier to find and fix the problem.
not really familiar with while loops but I thought it was an alternative so this may be an elementary mistake.
I need to look for the sum of natural numbers under 1000 that are multiples of 3 and 5. E.g for under 10
multiples of 3 and 5 < 10 = 3,5,6,9
sum = 23
My code using a for loop works and is as follows (this was my initial solution):
def multiple():
lst = []
for x in range(334): #didn't know how else to use a for loop but to find the largest value of x using a calculator
if 3*x < limit:
lst.append(3*x)
if 5*x< 1000:
lst.append(5*x)
if (3*x > 1000) and (5*x > 1000): #unnecessary in a forloop with a range but this is just to maintain symmetry with while loop
break
lst2 = list(set(lst)) #remove duplicates
print(sum(lst2))
multiple()
My code using a while loop(this solution doesn't even come out in te console --> maybe this is were the error lies):
def multiple():
lst = []
while True:
x = 1
if 3*x < 1000:
lst.append(3*x)
if 5*x< 1000:
lst.append(5*x)
if (3*x > 1000) and (5*x > 1000):
break
x += 1
lst2 = list(set(lst)) #remove duplicates
print(sum(lst2))
multiple()
Desired output:
233168
In addition to how to rectify the while loop, any improvements on my for loop or while loop would also be welcome. Thanks
Critically Debugging
Since you're new, let's take this opportunity to analyze the bug before we solve it. Note first that you did not notice any printouts at all. Therefore, your print() statement was either not running, or was printing only spaces. We can rule out the latter since sum() will return an integer.
Therefore, the print() is never run. The function is defined and called correctly, so that's not the issue. Now notice while True:; this is an early warning sign. If the while loop never ends, the print() will never run. We do notice there are multiple break statements that should stop the loop, but it's likely there's an issue with them.
Now we check how the loop updates. First, note the i+=1. That seems right. However, i=1 is also within the while loop. This cannot be correct, since every iteration i will be reset. This would cause the loop to run forever.
This type of critical analysis of code is only built through practice, but hopefully this answer offers some insight into how you could have fixed this issue yourself (and how I looked through your code).
Also note that adding print statements into the while loop to test would have allowed you to notice that i was always 1.
Working Code
def multiple():
lst = []
x = 1 # moved from line below
while True:
# x = 1 should not go here
if 3*x < 1000:
lst.append(3*x)
if 5*x< 1000:
lst.append(5*x)
if (3*x > 1000) and (5*x > 1000):
break
x += 1
lst2 = list(set(lst)) #remove duplicates
print(sum(lst2))
multiple()
A fairly straight forward approach is to iterate over every number from 1 to 1000 and check if it is divisible by 3 or 5, and then sum them all up.
total = sum(x for x in range(1, 1001) if x%3 == 0 or x%5 == 0)
total
# returns:
234168
Another solution:
Using for loop:
def multiple():
sum = 0
for _ in xrange(1, 1001):
if _ % 3 == 0 or _ % 5 == 0:
sum += _
return sum
print(multiple())
Using while loop:
def multiple():
sum = 0
cnt = 1
while cnt <= 1000:
if cnt % 3 == 0 or cnt % 5 == 0:
sum += cnt
cnt += 1
return sum
print(multiple())
output:
234168
#!/usr/bin/env python
def multiple():
lst = []
x=1
while (3*x < 1000) or (5*x < 1000):
if 3*x < 1000:
lst.append(3*x)
if 5*x < 1000:
lst.append(5*x)
x += 1
lst2 = list(set(lst)) #remove duplicates
print(sum(lst2))
multiple()
I've just started learning python. I am trying to check if the integer x is palindrome then divide it by a number between range (starting from largest y i.e. 999 ) y=999,998,...,100. If x/y=z and z is also a 3 digit integer then finish. Otherwise subtract 1 from x and do the same procedure.
def EuQ4():
x=998001
p=999
while 10000 < x:
x=x-1
if str(x)== str(x)[::-1]:
while p>100:
if x%p==0:
Pal=x/p
if Pal < 999:
print (Pal,p)
break
else:
x=x-1
else:
p=p-1
else:
x=x-1
EuQ4()
This is question 4 from Project Euler i.e. Find the largest palindrome made from the product of two 3-digit numbers.
You have a few logic errors in here. Some cause loops that just never end. For example, what happens when x % p == 0 but Pal is larger 999? You would get an infinite loop.
I made a few modifications, but it could still use some work.
def EuQ4():
x = 998001
while 10000 < x:
if str(x) == str(x)[::-1]:
print("{} is a pali!".format(x))
# Move it here so each time it stats at the right
# number or else it will just skip it after it does it once.
p = 999
while p > 100:
if x % p == 0:
pali = int(x / p)
if pali < 999:
print(pali, p)
return
p -= 1
x -= 1
EuQ4()
Edit:
I found these mistakes by using the debugger in my IDE. You could have easily done the same thing by going through the code line by line a few times.
I am sorry but it was hurting my head to read your question. If you are trying to learn Python while attempting these questions then I would propose this alternate answer - it does not answer your question but it does lead to the solution and I think it is more Pythonic. The question asks to find the largest palindrone made from the product of two 3 digit numbers. So the inputs should be 3 digit numbers. This code will allow you to specify the number of digits, max and min (as integers).
I am not proposing that this be the best solution the the Euler Problem posed rather it is a solution that gives you exposure to a range of features in Python.
def min_value(integer):
min_val = '1'
for n in range(0,integer-1):
min_val+='0'
return int(min_val)
def max_value(integer):
max_val = '9'
for n in range(0,integer-1):
max_val += '9'
return int(max_val) +1
def find_max_palindrones(x,y):
minimum_value = min_value(x)
maximum_value = max_value(y)
palindrones = []
working_range = [number for number in range(minimum_value,maximum_value,1)]
for x_value in working_range:
for y_value in working_range:
product = x_value * y_value
orig_order = [item for item in str(product)]
rev_order = [item for item in str(product)[::-1]]
if orig_order == rev_order:
palindrones.append(product)
max_p = max(palindrones)
return max_p
>>>find_max_palindrones(3,3)
906609
Put p=999 befor while p > 100 or use for p in range(999, 100, -1).
p = 999
while p > 100
And I think you call x=x-1 too many times.
I have a line of code in my program that checks if a number is divisible by several numbers.
However, the way I currently have it is extremely inefficient and ugly.
It currently looks like:
if(x % 1 == 0 and x % 2 == 0 and x % 3 == 0) and so forth for several other numbers. I was hoping someone could teach me how I could take out the long and chain and help me replace it with something that makes more sense so instead it will look like:
if(x % a[1,2,3] == 0)
Is this possible and if so can anyone please help me?
EDIT: The x % 1 == 0, x % 2 == 0, etc.. Is not the full equation. I am checking far more than % 1,2, and 3. I am looking for a solution that can take say.. 1 through 15. That is why I am not using x % 6.
if all(x % k == 0 for k in [1, 2, 3]):
print 'yay'
n = 1*2*3
if(x%n == 0):
#do stuff
Will work for any set of prime numbers.
for 1 through 15,you can use all(x % (k+1) == 0 for k in range(15)). for example::
>>> for x in range(10):
... if all(x % (k+1) == 0 for k in range(3)): #checks weather x is divisible by 1,2,3
... print x
...
0
6
lcm = LCM of set of number to divide i.e. (1,2,3....)
if(x % lcm == 0)
//pass
i = 0
num = 0
while i <= 1000:
if i % 3 and i % 5 == 0:
num + i = num <--- Adding Up Numbers Divisable by 3 & 5...
i += 1
print num
Error:* can't assign to operator (line 5)
Are you sure you don't want:
num = num + i
or equivalently:
num += i
?
Note that this can be done a little easier using sum, range and a generator expression:
sum( x for x in range(0,1000,5) if x % 3 == 0 )
#^only take every 5th element (0, 5, 10, 15 ...)
#^ Also only take elements divisible by 3
If you're planning on running this code on only python 2.x, you can change range to xrange in the above expression. Also, when reading other people's code, you'll sometimes see if x % 3 == 0 written as if not x % 3 in this type of context, but I prefer the first version (it seems a little more explicit to me).
num + i = num <--- Adding Up Numbers Divisable by 3 & 5...
You cannot assign a value to an expression.
Also, why not just add 5 each time and check that it is divisible by 3? You'll already know it is divisible by 5...