Python project euler [duplicate] - python

This question already has answers here:
How to find the sum of all the multiples of 3 or 5 below 1000 in Python?
(19 answers)
Closed 1 year ago.
I'm just starting to learn python, I tried to solve the first problem of project euler with python but I can't figure out a way to find the sum of my variables.
the question was to find the sum of all the multiples of 3 or 5 below 1000.
I tried this
def f(a):
for x in range(a):
if(x % 3 == 0 or x % 5 == 0):
i = 0
i = sum({x})
print(i)
f(100)
But it doesn't work, it just gives the value 99, and I have no idea why.I want to adapt it to a function like this.
Thank you in advance.

Try this:
def f(a):
foo = []
for x in range(a):
if(x % 3 == 0 or x % 5 == 0):
foo.append(x)
print(sum(foo))
f(100)
Or in one line using list comprehensions:
print(sum([i for i in range(some_value) if (i % 3 == 0 or i % 5 == 0)]))

There are quite a few errors in your code:
First of all, i = 0 is irrelevent to the rest of your code. All it's doing is defining i to be 0 after each iteration of the for loop.
Then, you are just taking the sum of the last number, because the other values are wiped out after each iteration.
So, what's the solution to this?
Creating a list to append to, so you have access to each value in a iterations:
l = []
def f(a):
for i in range(a):
if i % 3 == 0 or i % 5 == 0:
l.append(i)
print(sum(l))
f(100)
Output:
>>> 2318

How about this, it has limit of 1000 and does not use a list.
def is_multiple(x, a):
"""Returns true if x is a multiple of a"""
return x % a == 0
def f(a):
total = 0
for i in range(a+1): # tests from 0 to 100 if a is 100
if i >= 1000:
break # we don't process 1000 and above, get out of loop
if is_multiple(i, 3) or is_multiple(i, 5):
total += i # increment our total variable
return total
# Tests
n = 100
t = f(n)
print(f'num: {n}, total: {t}')
# num: 100, total: 2418
n = 1200
t = f(n)
num = f(n)
print(f'num: {n}, total: {t}')
# num: 1200, total: 233168

Related

Check if the digits in the number are in increasing sequence in python

I was working on a problem that determines whether the digits in the numbers are in the increasing sequence. Now, the approach I took to solve the problem was, For instance, consider the number 5678.
To check whether 5678 is an increasing sequence, I took the first digit and the next digit and the last digit which is 5,6,8 and substitute in range function range(first,last,(diff of first digit and the next to first digit)) i.e range(5,8+1,abs(5-6)).The result is the list of digits in the ascending order
To this problem, there is a constraint saying
For incrementing sequences, 0 should come after 9, and not before 1, as in 7890. Now my program breaks at the input 7890. I don't know how to encode this logic. Can someone help me, please?.
The code for increasing sequence was
len(set(['5','6','7','8']) - set(map(str,range(5,8+1,abs(5-6))))) == 0
You can simply check if the number, when converted to a string, is a substring of '1234567890':
str(num) in '1234567890'
you could zip the string representation of the number with a shifted self and iterate on consecutive digits together. Use all to check that numbers follow, using a modulo 10 to handle the 0 case.
num = 7890
result = all((int(y)-int(x))%10 == 1 for x,y in zip(str(num),str(num)[1:]))
I would create a cycling generator and slice that:
from itertools import cycle, islice
num = 5678901234
num = tuple(str(num))
print(num == tuple(islice(cycle(map(str, range(10))), int(num[0]), int(num[0]) + len(num))))
This is faster than solutions that check differences between individual digits. Of course, you can sacrifice the length to make it faster:
def digits(num):
while num:
yield num % 10
num //= 10
def check(num):
num = list(digits(num))
num.reverse()
for i, j in zip(islice(cycle(range(10)), num[0], num[0] + len(num)), num):
if i != j:
return False
return True
Since you already have the zip version, here is an alternative solution:
import sys
order = dict(enumerate(range(10)))
order[0] = 10
def increasing(n):
n = abs(n)
o = order[n % 10] + 1
while n:
n, r = divmod(n, 10)
if o - order[r] != 1:
return False
o = order[r]
return True
for n in sys.argv[1:]:
print n, increasing(int(n))
Here's my take that just looks at the digits and exits as soon as there is a discrepancy:
def f(n):
while (n):
last = n % 10
n = n / 10
if n == 0:
return True
prev = n % 10
print last, prev
if prev == 0 or prev != (last - 1) % 10:
return False
print f(1234)
print f(7890)
print f(78901)
print f(1345)
Somehow this question got me thinking of Palindromes and that got me to thinking of this in a different way.
5 6 7 8
8 7 6 5
-------------
13 13 13 13
9 0 1
1 0 9
---------
10 0 10
9 0 1 2
2 1 0 9
-------------
11 1 1 11
And that leads to this solution and tests.
pos_test_data = [5678, 901, 9012, 9012345678901]
neg_test_data = [5876, 910, 9021]
def monotonic_by_one(n):
fwd = str(n)
tgt = ord(fwd[0]) + ord(fwd[-1])
return all([ord(f) + ord(r) in (tgt, tgt - 10) for f, r in zip(fwd, reversed(fwd))])
print("Positive: ", all([monotonic_by_one(n) for n in pos_test_data]))
print("Negative: ", all([not monotonic_by_one(n) for n in neg_test_data]))
Results:
Positive: True
Negative: True
Instead of using to full list comprehension you could use a for loop and bail out at the first failure. I'd want to look at the size of the numbers being checked and time somethings to decide which was faster.
I would try this, a little verbose for readability:
seq = list(input())
seq1 = seq[1:]
seq2 = seq[:-1]
diff = [x-y for x,y in zip([int(x) if int(x)>0 else 10 for x in seq1],[int(x) if int(x)>0 else 10 for x in seq2])]
if any (t != 1 for t in diff) :
print('not <<<<<')
else :
print('<<<<<<')
A simple solution that checks the next number in the sequence and then using current_number + 1 == next_number to detect sequence.
import bisect
def find_next(x, a):
i = bisect.bisect_right(x, a)
if i:
return x[i]
return None
def is_sequence(x):
ans = True
for i in x[:-1]:
next_num = find_next(x, i)
if next_num and i+1 != next_num:
ans = False
break
return ans
print(is_sequence([1,2,3,4])) # True

Why are these lines of code in python only outputting the same answer?

I'm trying to get this program to return all possible multiples of 3 and 5 below 1001 and then add them all together and print it but for some reason these lines of code only seem to be printing one number and that number is the number 2 which is obviously wrong. Can someone point me in the right direction to why this code is grossly wrong?
n = 0
x = n<1001
while (n < 1001):
s = x%3 + x%5
print s
You've got a few mistakes:
x is a boolean type
Your loop never ends
adding values to mimic lists?
Edit
Didn't see the part where you wanted sum, so you could employ a for-in loop or just a simple one like so:
sum = 0
for i in range(1001):
if(i % 3 == 0 or i % 5):
sum += i
print(sum)
(Python 3)
You need to stop while at some point by incrementing n. Here is some code:
nums = []
n = 0
while (n < 1001):
# in here you check for the multiples
# then append using nums.append()
n += 1
This creates a loop and a list that accounts for every number in 0 to 1000. In the body, check for either condition and append to the list, then print out the values in the list.
num is a list where you are going to store all the values that apply, (those numbers who are divisible by 3 and 5, which you calculate with modulo). You append to that list when a condition is met. Here is some code:
nums = []
n = 0
while (n < 1001):
if(n % 3 == 0 or n % 5 ==0):
nums.append(n)
n += 1
print(n) #or for loop for each value
Explanation: a list of numbers called num stores the numbers that are divisible by 3 or 5. The loop starts at zero and goes to 1000, and for all the values that are divisible by 3 or 5, they will be added to the list. Then it prints the list.
Of course there is a simpler approach with a range:
for i in range(1001):
if(i % 3 == 0 or i % 5 == 0):
print(i)
This will print out all the values one by one. It is 1001 because the upper limit is exclusive.
true=1
false=0
so:
x = n<1001
we have x=1 because 0<1001 is true
s = x%3 + x%5
the remainder of 1/3 is 1 and 1/5 is 1
In your code:
1. x=n<1001 - generates a boolean value; on which we can't perform a mathematical operation.
In while loop:
your variable n,x are not changing; they are constant to same value for all the iterations.
Solution 1:
Below code will help you out.
s=0
for i in range(1,1002):
if( i%3 == 0 or i%5 == 0):
s = s + i
print(s)
Solution: 2
There is one more approach you can use.
var = [i for i in range(1,1002) if i%3==0 or i%5 ==0]
print(sum(var))

Sum of all the multiples of 3 or 5 below 1000

Beginner here- trying to make a simple python program that will compute/answer this problem:
If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.
Find the sum of all the multiples of 3 or 5 below 1000.
Currently this is what I have:
a = 0
b = 0
while a < 1000:
a = a + 3
print (a)
while b < 1000
b = b + 5
print (b)
This will print all the numbers being considered. I just need to add them together and that's my answer.
I would like one of two things to happen, instead of the code that I have written:
I would like all of this to happen internally, and therefore not have to use the "print" function. The just print the sum of all of those multiples.
I would like all of this stuff to print, but then I want to be able to print the sum of all of them too. Is there a way to make the computer take the value of everything it has printed?
Actually this problem can be solved in O(1) instead of O(N) without using any loops or lists:
The required sum is the sum of all multiples of 3 plus sum of all multiples of 5 minus the sum of multiples of (3*5=15) below the given number 1000 (LIMIT=999). The sums are calculated as a sum of arithmetic series.
It can be calculated in following way:
LIMIT=999
# Get the upper bounds for the arithmetic series
upper_for_three = LIMIT // 3
upper_for_five = LIMIT // 5
upper_for_fifteen = LIMIT // 15
# calculate sums
sum_three = 3*upper_for_three*(1 + upper_for_three) / 2
sum_five = 5*upper_for_five*(1 + upper_for_five) / 2
sum_fifteen = 15*upper_for_fifteen*(1 + upper_for_fifteen) / 2
# calculate total
total = sum_three + sum_five - sum_fifteen
# print result with Python 3
print(int(total))
The result is:
>>>
233168
It is possible to do this in one line in Python using a generator expression:
print(sum(x for x in range(1000) if x % 3 == 0 or x % 5 == 0))
The range(1000) produces all the integers from 0 to 999 inclusive. For each one of those integers, if it is divisible by 3 or divisible by 5, then it is included in the result. The sum(...) function adds up all those numbers, and finally print(...) prints the result.
I would use a for loop to iterate over each number in your selected range. Then you can check if the modulus % is equal to 0, meaning it has no remainder when divided by those values, if so, add it to the total.
total = 0
for num in range(1000):
if num % 3 == 0 or num % 5 == 0:
print(num)
total += num
>>> total
233168
While a for loop would work, you could also use a generator expression and sum:
sum(n for n in range(1000) if n % 3 == 0 or n % 5 == 0)
def sum_multiply (n):
data = []
for num in range (1, n):
if num % 3 == 0 or num % 5 == 0:
data.append(num)
return sum(data)
sum_multiply(1000)
total=0
i=0
while i<1000:
if i%3==0 or i%5==0:
print(num)
total+=i
i+=1
print("Total is: ")
**with python**
print(sum([i for i in range(1,1000) if i%3==0 or i%5==0 ]))

How to stop repetition in my code?

This code executes primes upto a given number. It works correctly as far as the prime generation is concerned but the output is painfully repetitive.
The code is:
numP = 1
x = 3
y = int(input('Enter number of primes to be found: '))
while numP<=y:
for n in range(2, x):
for b in range(2, n):
if n % b == 0:
break
else:
# loop fell through without finding a factor
print (n)
x += 2
numP += 1
The output is like (e.g. for y=4):
2
2
3
2
3
5
2
3
5
7
I want to avoid repetition and obtain output like:
2
3
5
7
How should the code be modified?
If you store the data in a set, you will avoid repetitions
There's no reason to loop n from 2..x. Get rid of that loop, and replace all references to 'n' with 'x'. I.e.:
def find_primes(y):
x = 3
numP = 0
while True:
for b in range(2, x):
if x % b == 0:
break
else:
# loop fell through without finding a factor
print (x)
numP += 1
if numP >= y:
return
x += 2

How to find the sum of all the multiples of 3 or 5 below 1000 in Python?

Not sure if I should've posted this on math.stackexchange instead, but it includes more programming so I posted it here.
The question seems really simple, but I've sat here for at least one hour now not figuring it out. I've tried different solutions, and read math formulas for it etc but it won't gives me the right answer when coding it! I made two different solutions for it, which both gives me the wrong answer. The first solution gives me 265334 while the second one gives me 232169. The answer is 233168, so the second solution is closer.
I should mention this is a question from Project Euler, the first one to be precise.
Here's my code. Any ideas what's wrong?
nums = [3, 5]
max = 999
result = 0
for num in nums:
for i in range(1,max):
if num*i < max:
result += num*i
print result
result = 0
for i in range(0,max):
if i%3 == 0 or i%5 == 0:
result += i
print result
You are overcomplicating things. You just need a list of numbers that are multiples of 3 or 5 which you can get easily with a list comprehension:
>>> [i for i in range(1000) if i % 3 == 0 or i % 5 == 0]
Then use sum to get the total:
>>> sum([i for i in range(1000) if i % 3 == 0 or i % 5 == 0])
<<< 233168
Or even better use a generator expression instead:
>>> sum(i for i in range(1000) if i % 3 == 0 or i % 5 == 0)
Or even better better (courtesy Exelian):
>>> sum(set(list(range(0, 1000, 3)) + list(range(0, 1000, 5))))
range(k,max) does not include max, so you're really checking up to and including 998 (while 999 is a multiple of 3). Use range(1,1000) instead.
I like this the most:
def divisibles(below, *divisors):
return (n for n in xrange(below) if 0 in (n % d for d in divisors))
print sum(divisibles(1000, 3, 5))
The problem with your first solution is that it double-counts multiples of 15 (because they are multiples of both 3 and 5).
The problem with your second solution is that it doesn't count 999 (a multiple of 3). Just set max = 1000 to fix this.
result = 0
for i in range(0,1000):
if (i % 3 == 0 or i % 5 == 0):
print i
result = result + i
print result
Output:
0
3
5
6
9
.
.
.
993
995
996
999
233168
max = 1000 # notice this here
result = 0
for i in range(0,max):
if i%3 == 0 or i%5 == 0:
result += i
print result
This works, but use 1000 for max, so it includes 999 too.
I know this was 3 months ago but as an experiment because I am new to python I decided to try and combine some of the other people answers and I came up with a method you can pass the max number to and the divisors as a list and it returns the sum:
def sum_of_divisors(below, divisors):
return sum((n for n in xrange(below) if 0 in (n % d for d in divisors)))
max = 1000
nums = [3, 5]
print sum_of_divisors(max, nums)
There are floor(999/3) multiples of 3, floor(999/5) multiples of 5, and floor(999/15) multiples of 15 under 1000.
For 3, these are: 3 + 6 + 9 + 12 +... + 999 = 3 * (1 + 2 + 3 + 4 +...+333)
= 3 * (333 * 334 / 2) because the sum of the integers from 1 to k is k*(k+1)/2.
Use the same logic for the sum of multiples of 5 and 15. This gives a constant time solution. Generalize this for arbitrary inputs.
I know this is from 6 years ago but I just thought id share a solution that found from a math formula that I thought was interesting as it removes the need to loop through all the numbers.
https://math.stackexchange.com/a/9305
def sum_of_two_multiples(nums, maxN):
"takes tuple returns multiples under maxN (max number - 1)"
n1, n2 = nums = nums[:2]
maxN -= 1
def k(maxN, kx):
n = int(maxN / kx)
return int(kx * (0.5 * n * (n+1)))
return sum([k(maxN, n) for n in nums]) - k(maxN, n1*n2)
Outputs the follows
print(sum_of_two_multiples((3,5), 10))
# 23
print(sum_of_two_multiples((3,5), 1000))
# 233168
print(sum_of_two_multiples((3,5), 10**12))
# 233333333333166658682880
I think only the last few lines from your code are important.
The or statement is the key statement in this code.
Also rater than setting the max value to 999, you should set it to 1000 so that it will cover all values.
Here is my code.
ans=0
for i in range(1,1000):
if(i%3==0 or i%5==0):
ans += i
print(ans)
input('press enter key to continue');#this line is only so that the screen stays until you press a key
t = int(input())
for a in range(t):
n = int(input().strip())
sum=0
for i in range(0,n):
if i%3==0 or i%5==0:
sum=sum+i
print(sum)
You can also use functional programming tools (filter):
def f(x):
return x % 3 == 0 or x % 5 == 0
filter(f, range(1,1000))
print(x)
Or use two lists with subtraction of multiples of 15 (which appears in both lists):
sum1 = []
for i in range(0,1000,3):
sum1.append(i)
sum2 = []
for n in range(0,1000,5):
sum2.append(n)
del sum2[::3] #delete every 3-rd element in list
print(sum((sum1)+(sum2)))
I like this solution but I guess it needs some improvements...
here is my solution:
for n in range(100):
if n % 5==0:
if n % 3==0:
print n, "Multiple of both 3 and 5" #if the number is a multiple of 5, is it a multiple of 3? if yes it has has both.
elif n % 5==0:
print n, "Multiple of 5"
elif n % 3==0:
print n, "Multiple of 3"
else:
print n "No multiples"
this is my solution
sum = 0
for i in range (1,1000):
if (i%3)==0 or (i%5)==0:
sum = sum + i
print(sum)
count = 0
for i in range(0,1000):
if i % 3 == 0 or i % 5 ==0:
count = count + i
print(count)
I know it was 7 years ago but I wanna share my solution to this problem.
x= set()
for i in range(1,1001):
if (i % 3) == 0:
x.add(i)
for j in range(1,1001):
if (j % 5) == 0:
x.add(j)
print(sum(x))
I had to do it in range 1 , 100
This is how I did it.
For i in range(1,100):
If i ÷ 3 == 0 and i ÷ 5 == 0:
print(i)
So with 1000 you just change the 100 to 1000
I had to find the multiples of 3 and 5 within 100 so if you need 3 or 5 just change it to or and it will give you more answers too. I'm just starting to learn so correct me if I'm wrong
Here is the code:
count = 1000
m = [3, 5, 3*5]
result = 0
Sum = 0
for j in m:
result = 0
for i in range(count):
if i*j < 1000:
result = result + i*j
elif i == (count - 1):
if j < 15:
Sum = result + Sum
elif j == 15:
Sum = Sum - result
print(Sum)
total = 0
maxrange = input("Enter the maximum range") #Get the maximum range from the keyboard
print("")
max = int(maxrange)
for i in range (0,max):
if i%3 == 0 or i%5 ==0:
total = total +i
print (total)

Categories

Resources