How do you find the first x prime numbers using python? - python

def xPrimes(x) :
y = 2
while y < x :
if isItPrime(y) == True :
y += 1
y += 1
print(primes)
I am a beginner in python and I'm having trouble having the program do what's needed. I also don't fully understand what my program does. When I did xPrimes(5), it gave me [2,3,5] instead of [2,3,5,7,11]. My code prints all prime numbers UP to x instead of x prime numbers. I suspect that I need a counter but I don't know where to implement it.

You just need to keep generating primes until you have x of them. If you're returning a list of the results, your counter is the length of that list.
def xPrimes(x: int) -> List[int]:
primes: List[int] = []
y = 1
while(len(primes) < x):
y += 1
if isItPrime(y):
primes.append(y)
return primes
Note that y is the prime number and x is the number of prime numbers and that these are completely different numbers. :)

What is primes here ?
you have to treat x as counter and do not compare with y as y is prime number not a counter
instead you can do something like this
def xPrimes(x) :
y = 2
index = 0
while index < x :
if isItPrime(y) == True :
y += 1
index+= 1
y += 1
print(primes)
you can see, I have use index as counter and incremented it when I got prime number

Homework is an adventure and chance to experiment!
First, you asked why xPrimes(5) gave you up to 5. You stop your loop when y < x, and y goes up each time. This shows you that you can get lost by using small variable names. You could make your code look like this by just renaming things:
def primes_up_to_number(stop_at) :
testing_number = 2
while testing_number < stop_at :
if isItPrime(testing_number) == True :
testing_number += 1
testing_number += 1
print(primes)
This is confusing to me, as you can't get the output [2, 3, 5]. When testing_number is 2, you add one to it, then add one again before you check isItPrime again, checking 4. I am assuming isItPrime updates some global array primes.
I think you want to change the code and meaning from stop_at to number_of_primes. If so, you should set a counter number_of_primes_found = 0 at start of the function and add one to it each time you find a prime. You should change the expression in the while loop to keep looping until that number of primes is found.
Have a great day! Keep coding! Keep notes.

Related

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))

Calculating Polygonal Numbers Taking A While To Calculate

I've created a function which, hopefully, creates a list of numbers that are both pentagonal and square.
Here is what i've got so far:
def sqpent(n):
i = 0
list = []
while n >= 0:
if n == 0:
list.append(0)
elif n == 1:
list.append(1)
elif (i*i == (i*(3*i-1)//2)):
list.append(i)
n -= 1
i += 1
But when it gets past the first two numbers it seems to be taking a while to do so...
You have two issues: the first is that the special-casing for n==0 and n==1 doesn't decrease n, so it goes into an infinite loop. The special-casing isn't really needed and can be dropped.
The second, and more significant one, is that in the test i*i == (i*(3*i-1)//2) you are assuming that the index i will be the same for the square and pentagonal number. But this will only happen for i==0 and i==1, so you won't find values past that.
I suggest:
Iterate over i instead of n to make things simpler.
Take the ith pentagonal number and check if it is a square number (e.g. int(sqrt(x))**2 == x).
Stop when you've reached n numbers.
Thanks to #interjay's advice, I came up with this answer which works perfectly:
import math
def sqpent(n):
counter = 0
i = 0
l = []
while counter < n:
x = (i*(3*i-1)//2)
#print(x)
if(int(math.sqrt(x))**2 == x):
#print("APPENDED: " + str(x))
l.append(x)
counter += 1
i += 1
return l
For an explanation:
It iterates through a value i, and gets the ith pentagonal number. Then it checks if it is a square and if so it appends it to a list which i ultimately return.
It does this until a final point when the counter reaches the number of items in the list you want.

Amicable Numbers

I am struggling with optimizing these functions that I have used to calculate the sum of the amicable pairs under 10000. An amicable pair is a pair (a, b) where the sum of the divisors of "a" excluding "a" itself equals b and the sum of the divisors of "b" excluding "b" itself equals "a".
I.e. divisors of 220 are 1, 2, 4, 5, 10, 11, 20, 22, 44, 55 and 110: The sum of which is 284. And the sum of the divisors of 284 (1, 2, 4, 71 and 142) equals 220.
My code is:
import math
def Divisorsbaritself(x):
divList = [1]
y = 2
while y <= math.sqrt(x):
if x % y == 0:
divList.append(y)
divList.append(int(x / y))
y += 1
return sum(divList)
def amicable():
solution = []
for i in range(10000):
if Divisorsbaritself(Divisorsbaritself(i)) == i:
solution.append(i)
return sum(solution)
print amicable()
I need help with understanding why the amicable function is not working. To me it makes logical sense that the if Divisorsbaritself(Divisorsbaritself(i)) == i: condition is the right condition to include i in the list, but it is giving me 40285, rather than 31626, the answer.
If Divisorsbaritself(i)==i you shouldn't count i.
def amicable():
solution = []
for i in range(10000):
if Divisorsbaritself(i)!=i and Divisorsbaritself(Divisorsbaritself(i)) == i:
solution.append(i)
return sum(solution)
But you should also fix the bug that would be an issue if i is a perfect square and in an amicable pair.
You can improve this with list comprehensions.
def amicable():
solution = [i for i in xrange(10000) if Divisorsbaritself(i)!=i and Divisorsbaritself(Divisorsbaritself(i)) == i]
return sum(solution)
They're amicable numbers only if they're different. So if divsum(i) is equal to i, then that's not included, despite the fact that means that divsum(divsum(i)) also equals i.
In addition, your current check counts the square root of a perfect square twice, even though it's only one factor.
And, on top of that, I wouldn't be using a list then summing it at the end when you can simply use an accumulator. And it's usually faster to do multiplication than square roots so you can change the while loop to take that into account.
Finally, for the love of whatever deities you believe in, comment your code! It'll make it so much easier to understand what's going on, both for others and for yourself six months down the track.
Incorporating those changes gives you the following DivisorsBarItself function:
def DivisorsBarItself(num):
# Maintain sum of factors.
divSum = 1
# Go through every integer up to but excluding sqrt(num).
testnum = 2
while testnum * testnum < num:
# If factor, add it and the complement (guaranteed integer).
if num % testnum == 0:
divSum += testnum + num/testnum
testnum += 1
# If perfect square, add the square root once.
if testnum * testnum == num:
divSum += testnum
# Return the sum.
return divSum
Fixing the logic for detecting amicable numbers and using a sum rather than a list gives you:
def AmicableSum():
# Set sum to zero and process all numbers below 10,000.
solution = 0
for num in range(10000):
# Get the "friend", add only if different and f(f(x)) = x.
numFriend = DivisorsBarItself(num)
if numFriend != num and DivisorsBarItself(numFriend) == num:
solution += num
return solution
print AmicableSum()
which gives the correct result of 31626.
I have fixed the bug now by going:
def Divisorsbaritself(x):
divList = [1]
y = 2
while y <= math.sqrt(x):
if x % y == 0:
if y is not int(x/y):
divList.append(y)
divList.append(int(x / y))
else:
divList.append(y)
y += 1
return sum(divList)
I have written the whole thing you said as a function
def devisor(a):
listOfFactors=[]
for possibleFactor in range(1,a):
if a%x==0:
listOfFactors.append(possibleFactor)
sumOfFactors=0
for item in z:
sumOfFactors+=item
factorsOfNewSumAddedUp=0
for x in range(1,sumOfFactors):
if temp%x==0:
factorsOfNewSumAddedUp+=x
if a==factorsOfNewSumAddedUp:
print("this is a divisor")

given and integer, return the next integer that is a prime number and a palindrome . Python

Given any random integer, create a function to find the next number that is a prime number and also a palindrome.
My attempt
def golf(number):
x = number + 1
for i in range(2, x):
if x % i == 0 or str(x) != str(x)[::-1]:
golf(number + 1)
return x
E.g golf(13) = 101
I'm actually looking for an alternative option than the recursion method i used. How can this best be accomplished without using recursion?
Thanks
Here's a variation on byron he's answer which adds several optimizations:
We can eliminate all even x values (other than 2) before doing any elaborate tests, since we can trivially tell they are not prime.
A small improvement is to only call str(x) once, and reuse the value later.
We can take advantage of the fact that all even-length palindromes are multiples of 11, which means that (except for 11 itself) they're not prime. We can jump ahead to the next odd-length x value.
Since we've already eliminated even numbers, our prime test only needs to test odd divisors. Further we can stop our loop when we reach sqrt(x), rather than going all the way to x itself.
Finally, there's no need to use a Boolean flag variable to carry the primeness out of the loop. If we don't break, the else block attached to the loop will be run.
The code:
import math
def next_prime_palindrome(x):
while True:
x += 1
if x > 2 and x % 2 == 0: # even numbers greater than 2 are non-prime
continue
s = str(x) # compute str(x) just once
if x > 11 and len(s) % 2 == 0: # all even-length palindromes are multiples of 11
x = 10 ** len(s) # so jump to the next odd-length integer
continue
if s != s[::-1]: # palindrome test
continue
for i in xrange(3, round(math.sqrt(x))+1, 2): # loop over odd potential divisors
if x % i == 0: # prime test
break
else: # this else block runs only if no break happened in the loop, so x is prime
return x
Here are some tests runs, showing a few cases where the optimizations save significant time:
>>> next_prime_palindrome(1)
2
>>> next_prime_palindrome(3)
5
>>> next_prime_palindrome(9)
11
>>> next_prime_palindrome(11)
101
>>> next_prime_palindrome(99999)
1003001
>>> next_prime_palindrome(999999999)
10000500001
A further improvement might be to directly generate palindromes, rather than working with integers to start with, and doing a palindrome test to filter them. That would get quite a bit further from your original design, so I'll leave that for someone else.
Palindrome are a sparser set of numbers than primes, and you can generate palindromes directly.
Consider the sequence 98.102
These are palidrome numbers you can base on these
989, 9889, 999, 9999, 10001, 100001, 10101, 101101, 10201, 102201
ADDED
Not also that all of the palidromes with an odd number of digits will come before the palidromes with an even number of digits.
If you write this as a generator (ie using yield) get get a straightforward algorithm for generating palindromic numbers in order.
For 1..9 you generate either 9 or 18 palindromes depending upon whether you consider 1 digit numbers palindromic.
For 10..99 you generate 90 even digit and 90 odd digit palindromes.
For 100..999 you generate 900 even digit and 900 odd digit palindromes.
You have just generated all 1989 (or 1997 if including single digit numbers) of the palindromic numbers less than 1 million. There are 78,498 primes less than 1 million
Any algorithm that is based on generating primes then testing for a palindrome will be much slower that generating palindromes and then testing for primes
def golf(number):
primes = []
i = 2
while i <= number:
if isPrime(i, primes):
primes.append(i)
i += 1
answer = primes[-1] + 1
while True:
if isPrime(answer, primes):
primes.append(answer)
if str(answer) == str(answer)[::-1]:
return answer
answer += 1
def isPrime(n, primes):
for (p for p in primes if p<=n**0.5):
if n%p == 0:
return False
return True
Your solution can be slightly modified in order to create an iterative solution:
def golf(number):
x = number + 1
while True:
is_golf = True
for i in range(2, x):
if x % i == 0 or str(x) != str(x)[::-1]:
is_golf = False
break
if is_golf:
return x
x += 1
improved according to Blckknght's advice, thanks.
def golf(number):
x = number
while True:
x += 1
if str(x) != str(x)[::-1]:
continue
for i in xrange(2, x):
if x % i == 0 :
break
else:
return x

Changed parameter in for loop but returns same numbers(Python)

can anyone point out the problem in this code that causes the list to end up with the same elements?
numbers = []
def add_tolist(x,y):
i = 0
for i in range(x):
numbers.append(i)
i += y
for num in numbers:
print num
add_tolist(10,1) returns the same numbers in the list as add_tolist(10,2)
I have a feeling its something really obvious that I am overlooking.
You don't need to assign a value to i and increment it like in C. In python for-in statement is kind of different. You should check this or this.
About range and its steppings, you should check this
Using all of those, I think this is what you want to achieve.
numbers = []
def add_tolist(x,y):
for i in range(0,x,y):
numbers.append(i)
for num in numbers:
print (num)
>>> add_tolist(10,2)
0 2 4 6 8
>>> add_tolist(10,1)
0 1 2 3 4 5 6 7 8 9
You're not doing anything with y until after you've already created the list of numbers.
It seems your original indentation got lost.
If not: (The program shouldn't even run, if not...)
def add_tolist(x,y):
i = 0
for i in range(x):
numbers.append(i)
This doesn't use the parameter y.
i += y
is at the same indentation level as numbers = []
What did you expect it to do?

Categories

Resources