>>> k=1
>>> sum=0
>>> for i in range (2,10):
for j in range (2,i):
if ((i%j)==0):
k=0
if (k==1):
sum+=i
>>> print(sum)
5
I don't know why, but this code, instead of giving 17 as an output, always gives 5.
You need to set your k flag back to 1 each time the for i loop moves to the next number:
for i in range (2,10):
k = 1
for j in range (2,i):
if ((i%j)==0):
k=0
if (k==1):
sum+=i
Without doing that your code only ever finds 5 to be a prime number, and ignores anything after that.
Note that in Python, 0 is considered false when used in a boolean context (such as an if statement), 1 is true, so you can just use if k:. Better still, use True and False and better variable names, such as is_prime rather than k. You can drop a lot of those parentheses:
sum = 0
for num in range (2, 10):
is_prime = True
for i in range (2, int(num ** 0.5) + 1):
if not num % i:
is_prime = False
if is_prime:
sum += num
I also made use of the fact that you only need to check up to the square root of a number to see if there are divisors, cutting your loops down significantly.
Last but not least, you can make use of the for ... else construct; if you use break in a for loop, the else branch never gets executed, but if the for loop completes to the end without breaking out, it is; this removes the need for a boolean flag:
sum = 0
for num in range (2, 10):
for i in range (2, int(num ** 0.5) + 1):
if not num % i:
break
else:
sum += num
sum=0
limit=10
for n in range(2,limit+1):
if all(n % i for i in range(2, n)):
sum += n
print sum
Output: 17
Along side the #Martijn Pieters answer that note the problem you can use a generator expression within sum :
>>> sum(i for i in range(2,10) if all(i%j!=0 for j in range(2,i)))
17
Related
I would like to print the following pattern using python:
00X
0X0
X00
Additionally, I have to print this using loops ONLY, without using arrays. Well, I have written an initial code, but is not scalable. Here is the initial code:
for i in range (1):
for j in range (1):
print(0, 0, "X")
for i in range (1):
for j in range (1):
print(0, "X", 0)
for i in range (1):
for j in range (1):
print("X", 0, 0)
I am looking for a suitable alternative. Please also feel free to contribute on the [source code on my GitHub: https://github.com/micahondiwa/python/blob/main/0x00-python/31-pattern.py.
Thank you.
I tried using the for a loop. Although I got the output, the result is not scalable. I am expecting to find a solution that uses a function to implement a loop and print the pattern.
A nested loop will work. The outer loop goes from n-1 to 0 and the inner loop goes from 0 to n-1. When the outer and inner loop variables are equal, print an X.
def f(n):
for row in range(n-1, -1, -1):
for col in range(n):
if row == col:
print('X', end='')
else:
print('0', end='')
print()
Example run:
>>> f(5)
0000X
000X0
00X00
0X000
X0000
You can do it in a single loop:
SQUARE_SIZE = 8
for i in range(SQUARE_SIZE):
print("0"*(SQUARE_SIZE-i-1) + "X" + "0"*i)
Output:
0000000X
000000X0
00000X00
0000X000
000X0000
00X00000
0X000000
X0000000
Here n is the number of rows and columns.
for i in range(n):
for j in range(n):
if(j == n - 1 - i):
print("X", end="")
else:
print("0", end="")
print()
output:
n = 3
>>> 00X
>>> 0X0
>>> X00
From what I understood, you want to write a matrix, where there is X in the secondary diagonal and 0 in all other places, and you can't use arrays (which you don't need).
If I am correct, you basically want to do this (if we say the matrix is 10x10):
In the first row you want to write 9 zeros and 1 x
In the second row you want to write 8 zeros, 1 x, and 1 zero
In the third row you want to write 7 zeros, 1x, and 2 zeros
...
This shows the next pattern
In the first row (10-1) zeros and 1 x
In the second row (10-2) zeros, 1 x and 1 zero
In the third row (10-3) zeros, 1 x and 2 zeros
...
Now we see that we write (n-i-1) zeros, 1 x, and i zeros
So we can do it like this:
n = 10
for i in range(n):
print('0' * (n-i-1) + 'X' + '0' * i)
EDIT:
Since #micahondiwa said it needs to be implemented in function, here is the code sample:
def my_func(n):
for i in range(n):
print('0' * (n-i-1) + 'X' + '0' * i)
Q:
By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6th prime is 13.
What is the 10001st prime number?
My code is:
def is_prime(num):
if all(num % i != 0 for i in range(2, num)):
return True
else:
return False
def find_nth_prime(nth):
lst_prime = []
num = 2
while len(lst_prime) < nth:
if is_prime(num):
lst_prime.append(num)
print(len(lst_prime), ":", lst_prime[-1])
num += 1
When I try to run find_nth_prime(6) it get stuck after finding "3" as prime. What am I missing here?
In your if statement inside while loop it keeps repeating at n=4 since n +=1 never happens as 4 is not a prime. Therefore take it out of the if statement.
Try using https://pythontutor.com/. It helps you visualize your code
def find_nth_prime(nth):
lst_prime = []
num = 2
while len(lst_prime) < nth:
if is_prime(num):
lst_prime.append(num)
print(len(lst_prime), ":", lst_prime[-1])
num += 1
Also you can do some improvments to your is_prime function. In that you don't have to take the whole range (2, num). It is enough to take the range 2 to square root of num. (2,int(num**0.5)+1) or use sqrt from python's math library
I'm doing a question from a previous Waterloo ccc competition (https://cemc.uwaterloo.ca/contests/computing/2020/ccc/juniorEF.pdf problem J5)
and my code isn't working the way I expected
Here's the sample input I'm using:
3
4
3 10 8 14
1 11 12 12
6 2 3 9
Here's my code so far
y_size = int(input())
x_size = int(input())
mat = []
"ok".split()
for i in range(y_size):
row = input().split()
mat.append(row)
pos_list = [[0, 0]]
current_num = int(mat[0][0])
a = 0
def canEscape():
global a
global mat
global pos_list
global current_num
end = y_size * x_size
if y_size -1 * x_size -1 == current_num:
return True
for i in range(y_size):
print("______")
for j in range(x_size):
v = (i + 1) * (j + 1)
print(v)
print(current_num)
if v == current_num:
print("ok")
if v == end:
print("ok")
a += 1
current_num = mat[i][j]
pos_list.append([i, j])
canEscape()
pos_list.pop(-1)
a -= 1
current_num = mat[pos_list[a][0]][pos_list[a][1]]
canEscape()
The problem I'm having is that I expect if v == current_num: to be true when I call it again. Both current_num and v are equal to 8 but the code seems to carry on with the for-in loop and break, without entering the if statement. I've made the output print v followed by current_num for every iteration of the for loop to try and figure out the problem but it seems that both variables == 8 so I really don't know what I did wrong. Did I make a silly mistake or did I structure my whole program wrong?
I'm having trouble following what your program is doing at all. This problem involves integer factoring, and I do not see where you're factoring integers. You definitely are not understanding that aspect of the problem.
When you calculate what cells you can go to you look at the value of your current cell. Lets say it is 6. 6 has the factors 1, 2, 3, and 6 because all of those numbers can be multiplied by another number to equal 6. So, you can go to the cells (1, 6), (6, 1), (2, 3), and (3, 2), because those are the pairs of numbers that can be multiplied together to equal 6.
Also, you never convert the lines of input into integers. When you append to the matrix, you are appending a list of strings that happen to be numbers. You must convert those into integers.
Anyways, this program will solve the problem. I copy and pasted the factoring algorithm from other threads:
n_rows = int(input())
n_cols = int(input())
mat = []
for i in range(n_rows):
mat.append(list(map(lambda x: int(x), input().split()))) # Convert input strings to integers.
def reduce(f, l):
# This is just needed for the factoring function
# It's not relevant to the problem
r = None
for e in l:
if r is None:
r = e
else:
r = f(r, e)
return r
def factors(n):
# An efficient function for calculating factors.
return set(reduce(list.__add__,
([i, n//i] for i in range(1, int(n**0.5) + 1) if n % i == 0)))
def get_pairs(items):
for i in range(len(items) // 2):
yield (items[i],items[len(items) - 1 - i]) # use yield to save memory
if(len(items) % 2 != 0): # This is for square numbers.
n = items[len(items) // 2]
yield (n,n)
checked_numbers = set()
def isPath(r=1, c=1):
# check if the testing row or column is to large.
if r > n_rows or c > n_cols:
return False
y = r - 1
x = c - 1
n = mat[y][x]
# If we've already checked a number with a certain value we dont need to check it again.
if n in checked_numbers:
return False
checked_numbers.add(n)
# Check if we've reached the exit.
if(r == n_rows and c == n_cols):
return True
# Calculate the factors of the number, and then find all valid pairs with those factors.
pairs = get_pairs(sorted(list(factors(n))))
# Remember to check each pair with both combinations of every pair of factors.
# If any of the pairs lead to the exit then we return true.
return any([isPath(pair[0], pair[1]) or isPath(pair[1], pair[0]) for pair in pairs])
if isPath():
print("yes");
else:
print("no");
This works and it is fast. However, it if you are limited on memory and/or have a large data input size your program could easily run out of memory. I think it is likely that this will happen with some of the testing inputs but I'm not sure.. It is surely possible to write this program in a way that would use a fraction of the memory, perhaps by converting the factors function to a function that uses iterators, as well as converting the get_pairs function to somehow iterate as well.
I would imagine that this solution solves most of the testing inputs they have but will not solve the ones towards the end, because they will be very large and it will run out of memory.
sum_ans=17
for i in range(11,2000000):
for j in range(2,int(i**0.5)):
if i%j==0:
break
else:
sum_ans+=i
print(sum_ans)
The code i have return gives answer 143064094781 and the correct answer is 142913828922 but i can not figure out where i have gone wrong. So can any one help me.
Range's stop parameter is exclusive. This means that your code is only calculating j from 2 to 1 less than i**0.5. To fix this you can add 1, meaning that your end code will look a little like this, providing the correct output of 142913828922:
sum_ans=17
for i in range(11,2000000):
for j in range(2,int(i**0.5+1)):
if i%j==0:
break
else:
sum_ans+=i
print(sum_ans)
What about about this:
def isPrime(x):
prime = True
for i in range(2, x):
if x % i == 0:
prime = False
break
else:
continue
return prime
primes = (a for a in range(2, 2000000) if isPrime(a))
print(sum(primes))
# output
142913828922
This code will take a few minutes to execute. Buckle up!!
def sumPrimes(n):
sum =0
for i in range(2 ,n):
for j in range(2, int(i / 2) +1):
if (i % j) == 0:
break
else:
sum += i
return sum
print(sumPrimes(2000000))
If you iterating over all numbers below 2 million, you might as well sieve them using the Sieve of Eratoshenes:
from math import ceil, sqrt
def sieve(n):
nums = list(range(2,n+1))
primes = []
p = 2
k = 1+ ceil(sqrt(n))
while p < k:
primes.append(p)
nums = [num for num in nums[1:] if num % p > 0]
p = nums[0]
return primes + nums
Then sum(sieve(2000000)) evaluates to 142913828922. It takes about 5 seconds to run on my machine.
Hey guys so here is my question. I have written code that sums two prime numbers and prints the values less than or equal to 100 and even. How do I write it so that every combination of the number prints on the same line
like so
100 = 3 + 97 = 11 + 89
def isPrime(n):
limit = int(n ** 0.5) +1
for divisor in range (2, limit):
if (n % divisor == 0):
return False
return True
def main():
a = 0
b = 0
for n in range (4, 101):
if (n % 2 == 0):
for a in range (1, n + 1):
if isPrime(a):
for b in range (1, n + 1):
if isPrime(b):
if n == (a + b):
print ( n, "=", a, "+", b)
main()
any ideas?
I don't know too much about strings yet, but I was thinking we could set the string as n == a + b and some how repeat on the same line where n == n print the a + b statement or idk haha
One way to do this is to accumulate a and b pairs in some collection, then print a line containing all the pairs. Here's an example with some comments explaining whats going on and general Python tips:
def main():
for n in range (4, 101, 2): # range() can have third argument -> step
accumulator = []
for a in filter(isPrime, range(1, n + 1)): # filter() is useful if you want to skip some values
for b in filter(isPrime, range (1, n + 1)):
if n == (a + b):
accumulator.append((a,b)) # We accumulate instead of printing
str_accumulator = ["{} + {}".format(i[0], i[1]) for i in accumulator]
joined_accumulator = " = ".join(str_accumulator)
print("{} = {}".format(n, joined_accumulator))
Now, some explanation:
range(4, 101, 2) - as said in comment, it has an optional third argument. Some examples and explanations on how to use range in documentation.
filter() - Very useful generic iterator constructor. You pass a function that returns True/False, a collection, and you receive an iterator that spits out only those elements from the collection that are accepted by the function. See documentation.
str.format - For me, format is the best way to paste values into strings. It has PLENTY options and is very versatile. You should read the whole documentation here.
str.join - When you have a collection of string, and you want to make one string of them, join is what you want. It's much faster than str + str operation, and also you don't have to care if there is one or many elements in the collection. See documentation.