def pi_euler2(n):
pi=[1,2]
if n==1:
return 1
if n==2:
two=sum([x**-1 for x in pi])
return two
for i in range(3,n+1):
if isprime(i)==True:
if (i+1)%4==0:
i=abs(i)
pi.append(i)
if (i-1)%4==0:
pi.append(i*-1)
else:
for j in range(2,int(math.sqrt(i))+1):
if isinstance(i/j,int)==True:
k=i/j
print(k)
pi.append((pi[j-1])*pi[k-1])
return pi
I am trying to make a python program which estimates the value of pi by making it do an infinite series (up to length n). But the problem with my code is that for some reason it skips over the else statement (for when the number is not prime).
The problem is part of this section of the code
for i in range(3,n+1):
if isprime(i)==True:
if (i+1)%4==0:
i=abs(i)
pi.append(i)
if (i-1)%4==0:
pi.append(i*-1)
else:
for j in range(2,int(math.sqrt(i))+1):
if isinstance(i/j,int)==True:
k=i/j
print(k)
pi.append((pi[j-1])*pi[k-1])
The output only ever consists of prime numbers (e.g pi_euler2(50) outputs [1, 2, 3, -5, 7, 11, -13, -17, 19, 23, -29, 31, -37, -41, 43, 47])
The isprime function is
def isprime(n):
for j in range(2,int(n**0.5)+1):
if n%j == 0:
return False
return True
the problem isn't with else part of your code, it works every time. the problematic part of your code is: isinstance(i/j,int)
every time you divide 2 numbers in python, it gives you a decimal number like 9/3 isn't just 3. the output is 3.0
so the isinstance() gives false every time. hence no append in pi.
you can try to use if(i%j == 0).
then the if in j loop becomes:
if i%j==0: k=int(i/j) ...
and the output for 10 in your function comes out to be:
[1, 2, 3, 4, -5, 6, 7, 8, 9, -10] try and correct that
Also, your isprime function seems to be incomplete. It should look something like this.
def isprime(n):
if n < 2:
return False
for j in range(2, int(n ** 0.5) + 1):
if n % j == 0:
return False
return True
You could probably just use already-provided prime checking functions (libraries such as mpmath, sympy, etc. include this functionality) which could do the job more accurately and efficiently.
Related
So I programmed this code to find whether all numbers in a list are multiples of a number k: or not, but it doesn't seem to work. can anyone give some examples for me to draw ideas from?
Use %7 instead of //7. // will give you whole number quotient and % will give you remainder. Let use say some number 49, 49//7 is 7 and 49%7 is 0. Another example 26, 26//7 is 3 and 26%7 is 5
There two issues with your code.
First you need to use % to get the rest of the division x / k.
Second as you're doing it, you exit the function as soon as you have found a number
in your list that is a multiple of k: you don't check remaining items in your list.
Here is a modified version of your code:
k = 4
a: list= [3, 4, 4, 3]
def allMultiplesofK(k, a):
for x in list(a):
if x % k != 0:
return False
return True # all items of a are multiples of k
print(allMultiplesofK(k, a))
In your code the return inside the loop will quit the loop as soon as the condition will be satisfied, so, it will will not check all numbers in the list. You can use for example list comprehension and the all function from the standard library, see docs,
def allMultiplesofK(k, a):
return all(map(lambda p: p % k == 0, a))
return all([p % k == 0 for p in a]) # with list comprehension
k = 4
a: list= [3, 4, 4, 8]
print(allMultiplesofK(k, a))
# False
a: list= [12, 4, 4, 8]
print(allMultiplesofK(k, a))
# True
You aren't actually checking every item of the loop.
for x in list(a):
if x // k == 0:
return True
if x // k != 0:
return False
This is returning from the function after only checking the first item in the list.
Also the way you are checking if one number is divisible by another isn't quite right. You should be using the modulo operator "%". This operator gives you the remainder after the division.
3 % 4 = 3 # since 4 goes into 3, 0 times with 3 remaining.
Therefore your program should become:
k = 4
a: list= [3, 4, 4, 3]
def allMultiplesofK(k, a):
for x in list(a):
if x % k != 0:
return False
return True
print(allMultiplesofK(k, a))
Use modulo instead of floor division.
Floor division:
This will gives you the quotient
Modulus:
This will give you the remainder.
k = 4
a = [3, 4, 4, 3]
def allMultiplesofK(k, a):
for x in list(a):
if x % k == 0:
return True
else:
return False
print(allMultiplesofK(k, a))
output: False
But this will not give all numbers result i.e it will print last values 3%4 False.
result = [True if i % k == 0 else False for i in a]
print(result)
Output: [False, True, True, False]
Given an integer number, I want to find the biggest prime number under it. For example:
input 20 -> output 19
input 100 -> output 97.
I already have the simple program given below, but I'm curious about how to make it faster.
def isPrime(x):
for j in range(2,int(x**0.5)+1):
if x%j==0:
return False
return True
def findPrimeNum(num):
for i in range(num-1,1,-1):
if isPrime(i):
return i
findPrimeNum(600851475143) # -> 600851475067
The best way is probably to mirror what several number theory libraries use to implement an efficient next_prime function. The basic layout is identical to yours: an isPrime(x) function, and a loop counting down. Those provide two areas for optimization.
Optimizing isPrime
The recommended approach is to use a number theory library for Python like gmpy2, and a probabilistic primality test like Miller-Rabin repeated an appropriate number of times. This scales fairly well with larger numbers, and you can even get a deterministic primality test by using Miller-Rabin with enough small bases.
Optimizing iteration over possible primes
There is already a comprehensive guide for optimizing next_prime in practice, which basically involves choosing the first k primes (e.g. 2, 3 and 5) and computing all residues modulo their product that could potentially be a prime. Then, rather than iterating over all smaller numbers, you jump between those residues only. To adapt this to previousPrime, we just jump between residues in the opposite direction.
For 2, 3, and 5, those residues mod 30 are L = [1, 7, 11, 13, 17, 19, 23, 29]. For an integer x > 30, say x = 30*q + r, you would do a binary search over L for the largest element less than r, and iterate backwards in this list:
residues = [1, 7, 11, 13, 17, 19, 23, 29]
small_primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
def prevPrime(num):
if num <= 2:
return 0
q, r = divmod(num, 30)
if q == 0:
return small_primes[bisect_left(small_primes, num) - 1]
num = 30 * q
if r <= 2:
num -= 30
q -= 1
idx = len(residues) - 1
else:
idx = bisect_left(residues, r) - 1
num += residues[idx]
while not (isPrime(num)):
idx -= 1
if idx < 0:
q -= 1
idx = len(residues) - 1
num = 30 * q + residues[idx]
return num
I'm trying to find is a target sum could be found from an infinite stream of numbers in Python. The numbers are positive (numbers> 0), unique and the numbers are indefinite. I believe the answer would be to use dynamic programming or heap but can't quite figure out a logic.
Any help on possible data structure or flow of logic to try.
Thank you so much.
e.g
nums = [ 99,85,1,3,6,72,7,9,22,....]
targetSum = 27
output: True
Explanation: 1+6+22 = 27(targetSum)
You can use a set to keep track of all the possible sums given the numbers so far in the iterations. For each iteration, add the current number to each existing sum in the set to add to the set, and add the current number itself to the set. Return True when the target sum is indeed in the set:
def has_sum(nums, targetSum):
sums = set()
for i in nums:
sums.update([s + i for s in sums if s + i <= targetSum])
if i <= targetSum:
sums.add(i)
if targetSum in sums:
return True
return False
so that:
has_sum([99, 85, 1, 3, 6, 72, 7, 9, 22], 29)
returns True (because 1 + 6 + 22 = 29), and that:
has_sum([99, 85, 1, 3, 6, 72, 7, 9, 22], 27)
returns False (because the expected output in your question is incorrect).
#Pavis,
One idea that I can think of is to use tight graph. You can do the following:
add each number element that is less than the sum into the graph as a node
each new node is connected to every other node already present in the graph
after addition to graph, compute the sum using breadth first search from the lowest element
I think this process is slow tho
You can recursively try to satisfy the target sum with or without the first number in the given sequence, until there is no more number in the given sequence, or until the given target sum is no longer positive (since you mentioned in the comment that all given numbers are positive):
def has_sum(nums, targetSum):
if not nums or targetSum <= 0:
return False
first, *rest = nums
return first == targetSum or has_sum(rest, targetSum - first) or has_sum(rest, targetSum)
so that:
has_sum([99, 85, 1, 3, 6, 72, 7, 9, 22], 29)
returns True (because 1 + 6 + 22 = 29), and that:
has_sum([99, 85, 1, 3, 6, 72, 7, 9, 22], 27)
returns False (because the expected output in your question is incorrect).
EDIT: To avoid performance impact from copying the input sequence minus the first item to rest in every call, the code above can be improved with an index instead:
def has_sum(nums, targetSum, index=0):
if index == len(nums) or targetSum <= 0:
return False
num = nums[index]
return num == targetSum or has_sum(nums, targetSum - num, index + 1) or has_sum(nums, targetSum, index + 1)
I am trying to gain a better understanding of how list comprehensions work.
I have the following function that returns true or false if a number is prime (which I found somewhere on the forum but cant remember where):
import math
def is_prime(n):
if n % 2 == 0 and n > 2:
return False
for i in range(3, int(math.sqrt(n)) + 1, 2):
if n % i == 0:
return False
return True
if I run:
[x for x in range(2, num) if is_prime(x)]
i get the desired result
[2, 3, 5, 7, 11, 13, 17, 19]
in trying to convert the whole function to a list comprehension I came up with:
[x if not (x%2==0 and x > 2) else x for x in range (2, num)
for i in range(3, int(x**(1/2))+1, 2) if not (x%i==0)]
which produces:
[10, 11, 13, 14, 16, 17, 19]
not sure where I am going wrong and would appreciate some help. In truth I think it is better to use the function in this case, but like I said I am trying to understand the list comprehension and its capabilities.
You can do this:
[n for n in range(2, num) if n % 2 != 0 and n > 2 and all(n % i != 0 for i in range(3, int(math.sqrt(n)) + 1, 2))]
although one liner just for the sake of it is not necessarily a good thing. IMO using a prime tester function like you do is better...
NOTE: what doesn't work in your try is that you modified the logic of your outer list comprehension. You still want a structure like [n for n in range(...) if (expression testing if n is prime)].
The main problem is that you're making a convoluted translation. Try simplifying the original condition so that you return "x if x==2, else x ..." as you've already done. I'm just giving you a leading hint here; from what you've done already, I think you can figure it out.
If not, try simplifying the "else" expression so you learn the logic of that clause. Then I'm sure you'll get it. You're doing well.
There are logical errors in the code above
1/2 evaluates to 0, not to 0.5. To do that, either use 0.5 or 1/2.0 or 1.0/2
Also it does not take care of 2 as a special case. as (for i in range(3, int(x**(1/2.0))+1, 2) if not (x%i==0)) is not executed
for i in range(3, int(x**(1/2.0))+1, 2) if not (x%i==0) is also a logical error as whenever this condition is true, it causes multiple entries to be added
the correct way would be
[x for x in range (2, num) if x == 2 or (x > 2 and x % 2 == 1 and len([i for i in range(3, int(x**(1/2.0))+1, 2) if x%i == 0 ])==0)]
I'm doing the Project Euler problems, and I'm on number two. The question is:
Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:
1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.
I'm trying to solve this in python. I think I have the correct code, but for some reason When I run it with n being anything greater than or equal to 27, it will wait like a minute and just return 0. However, for anything 26 or lower, it runs fine. Here's my code:
def fib_seq(n):
if n == 0:
return n
elif n == 1:
return n
else:
return fib_seq(n-1) + fib_seq(n-2)
def get_fib_sum(n):
x = n
sum = 0
for i in range(n):
if fib_seq(x) > 4000000:
pass
elif fib_seq(x) % 2 == 0:
pass
else:
sum += fib_seq(x)
x = i
return sum
print get_fib_sum(27)
Is there anyway to fix this or at least get it to work? If it makes a difference, I'm using Wing IDE 101 Student Edition.
In your loop, you are using fib_seq(x) and it should be fib_seq(i)
Also, if you want to reduce time a bit more, you can use memoization technique
def fib_seq(n):
if n == 0:
return n
elif n == 1:
return n
else:
return fib_seq(n-1) + fib_seq(n-2)
def memoize(fn, arg):
memo = {}
if arg not in memo:
memo[arg] = fn(arg)
return memo[arg]
fibm = memoize(fib_seq,27)
print fibm
Why are you using recursion? your code is recalculating the ENTIRE fibonnaci sequence over and over and over and over and over... The code just wants the sum of the even terms. There is NO need for recursion. In pseudo-code:
t1 = 1
t2 = 2;
sum = 2;
do {
t3 = t1 + t2;
if (t3 is even) {
sum += t3;
}
t1 = t2;
t2 = t3;
} while (t2 <= 4000000)
Fibonacci sequence is often used as an example of how to write recursive code, which is ridiculous because it has a very straight-forward iterative solution:
def fib(n):
if n < 2:
return n
else:
a, b = 1, 1
for _ in range(2, n): # O(n)
a, b = b, a+b
return b
What is less obvious is that it also has a matrix representation,
F = [[0, 1]] # initial state
T = [[0, 1], # transition matrix
[1, 1]]
fib(n) = (F * T**n)[0][0]
which is extremely useful because T**n can be computed in O(log(n)) steps.
(As an aside, the eigenvector of the log of the transition matrix leads to the analytic solution,
phi = (1 + 5**0.5) / 2 # golden ratio
fib(n) = round(phi**n / 5**0.5, 0)
but that's not where I'm going with this.)
Looking at the terms produced in terms of odd-or-even, you see
n: 0, 1, 2, 3, 4, 5, 6, 7, 8, ...
f(n): 0, 1, 1, 2, 3, 5, 8, 13, 21, ...
e/o: even, odd, odd, even, odd, odd, even, odd, odd, ...
so what you need is fib(0) + fib(3) + fib(6) + ... and computing T**3 gives you the coefficients needed to step directly from term to term.
The rest is left as an exercise for the reader ;-)
It does a lot of recursion, that's why it's taking so long.
The get_fib_sum() will evaluate fib_seq(27) in a loop, which does a lot of recursion and takes a while. Since the result of fib_seq(27) is greater then 4000000 it will then will never add anything to sum, returning 0 in the end.