How to calculate these 2 Equations in python - python

How can i calculate these in python??
A = (x**1/1!) - (x**3/3!) + (x**5/5!) - ... - (x**51/51!)
B = 1 - (x**2/2!) + (x**4/4!) - ... - (x**50/50!)
I tried this code for calculating A and B but
A^2 + B^2 ~= 1
but i get 2.xxxxxxxxx
def factorial(n):
fac = 1
for i in range(2, n+1):
fac *= i
return fac
def calcA(x):
c = True
A = 0
for i in range(1, 51, 2):
if c:
A += (x**i)/factorial(i)
else:
A -= (x**i)/factorial(i)
c = not c
return A
def calcB(x):
B = 1
c = False
for i in range(2, 50, 2):
if c:
B += (x**i)/factorial(i)
else:
B -= (x**i)/factorial(i)
c = not c
return B
I tried this but output is not correct
it should be almost 1

Might as well use the factorial function from the math module. It will be faster than doing it in pure Python.
You can also restructure the code to be more concise by using cycle from itertools as follows:
from math import factorial as FACTORIAL
from operator import sub as SUB, add as ADD
from itertools import cycle as CYCLE
def calcA(x):
A = 0
func = CYCLE((ADD, SUB))
for i in range(1, 52, 2):
A = next(func)(A, x**i/FACTORIAL(i))
return A
def calcB(x):
B = 1
func = CYCLE((SUB, ADD))
for i in range(2, 51, 2):
B = next(func)(B, x**i/FACTORIAL(i))
return B
print(calcA(2)**2+calcB(2)**2)
Output:
1.0000000000000002
Note:
float precision is such that upper range limits of 24 (for A) and 23 (for B) will produce the same result

Note that this:
for i in range(10):
print(i)
will print 0, 1, 2, 3, 4, ..., 9. Not 10!
Similar for range(1, 51, 2) it will start with 1 then 3 and stop at 49.
Change your ranges into: range(1, 53, 2) and range(2, 52, 2) and you will get approximately 1

Related

Fib2 function without recursion in Python

I need help for defining the fibanocci 2 function. The fibanocci 2 function is decribed as :
fib2(n) = {0 if n <= 0, 1 if n = 1, 2 if n = 2, ( fib2( n - 1) * fib2( n - 2)) - fib2( n - 3) else}
We need to define this function iterative.
I tried my best but i couldn't write a working code.
def fib2(n: int) -> int:
if n <= 0:
return 0
elif n == 1:
return 1
elif n == 2:
return 2
else:
n = ((n - 1) * (n - 2) - (n - 3)
return n
a = fib2(7)
print (a)
assert (fib2(7) == 37)
the output from this fib2 function is 26 but it should be 37.
Thank you in advance
For the iterative version you have to use a for loop.
And just add the 3 previous numbers to get the next one.
Here is a piece of code:
def fib3(n):
a = 0
b = 1
c = 0
for n in range(n):
newc = a+b+c
a = b
b = c
c = newc
return newc
print(fib3(7))
assert (fib3(7) == 37)
You can not change the value of a parameter.
Please try to return directly :
Return ((fb2(n-1)×fb2(n-2))-fb2(n-3))
So it will work as a recursive function.
def fibo(n):
current = 0
previous_1 = 1
previous_2 = 0
for i in range(1,n):
current = previous_1 + previous_2
previous_2 = previous_1
previous_1 = current
return current
To do it iteratively, the best way is to write it on paper to understand how it works.
Mathematically fibo is Fn = Fn-1 + Fn-2 . Therefore, you can create variables called previous_1 and previous_2 which represents the elements of Fn and you simply update them on each run.
Fn is current

Showing the 10 first prime Fibonacci numbers in python

There is a problem we need to solve in my university where we need to print the 10 smallest prime fibonacci numbers in an ascending order.So far i have found this code but it takes about 2 min to print them and was wondering if there was a faster way to print them.
import math
def isSquare(n):
sr = (int)(math.sqrt(n))
return (sr * sr == n)
def printPrimeAndFib(n):
prime = [True] * (n + 1)
p = 2
while (p * p <= n):
if (prime[p] == True):
for i in range(p * 2, n + 1, p):
prime[i] = False
p = p + 1
list=[]
for i in range(2, n + 1):
if (prime[i] and (isSquare(5 * i * i + 4) > 0 or
isSquare(5 * i * i - 4) > 0)):
list.append(i)
print(list)
n = 500000000
printPrimeAndFib(n)
With a Fibonacci generator and a prime filter. Takes about 0.002 seconds.
from itertools import islice
from math import isqrt
def fibonacci():
a, b = 0, 1
while True:
yield a
a, b = b, a + b
def is_prime(n):
return n > 1 and all(map(n.__mod__, range(2, isqrt(n) + 1)))
fibonacci_primes = filter(is_prime, fibonacci())
print(list(islice(fibonacci_primes, 10)))
Output:
[2, 3, 5, 13, 89, 233, 1597, 28657, 514229, 433494437]
This approach generates Fibonacci numbers until it finds 10 that are prime; takes approx 0.001-0.002 seconds
from math import sqrt
def isprime(x):
#deal with prime special cases 1 and 2
if x==2:
return True
if x == 1 or x%2==0:
return False
#Fast-ish prime checking - only scan odds numbers up to sqrt(x)
for n in range(3,int(sqrt(x))+1,2):
if x%n==0:
return False
return True
fib_primes = []
current=1
previous=1
while (len(fib_primes)<10):
if isprime(current):
fib_primes.append(current)
next = current+previous
previous = current
current = next
print(fib_primes)

python: codingbat no_teen_sum - why my function isn't working as expected?

Below is the code I used for the no_teen_sum and subsequent fixed_teen functions.
The first code is what I submitted - and worked for all test cases:
def no_teen_sum(a, b, c):
# checks if value is a teen then child conditional checks whether
# fix_teen passes the value, otherwise initialize the value as 0
if 13 <= a <= 19:
if fix_teen(a):
a = a
else:
a = 0
if 13 <= b <= 19:
if fix_teen(b):
b = b
else:
b = 0
if 13 <= c <= 19:
if fix_teen(c):
c = c
else:
c = 0
return a + b + c
And the fix_teen function that is called:
def fix_teen(n):
# checks if n is 15 or 16 but checking if it is found in the set
# written this way to be expandable without becoming verbose
if n in {15, 16}:
return True
However, looking at this I saw a lot of repitition and realized maybe I had misread what the question was asking. It was valid in terms of finding a solution but not as clean as it could be. So I tried to work on an improvement.
Improved code:
def no_teen_sum(a, b, c):
fix_teen(a)
fix_teen(b)
fix_teen(c)
return a + b + c
And the modified fix_teen function:
def fix_teen(n):
# checks if n is a teen
if 13 <= n <= 19:
# checks if n is 15 or 16 but checking if it is found in the set
# if True then leave n as it is
if n in {15, 16}:
n = n
return n
# if it fails then n = 0
else:
n = 0
return n
# if n is not in the teens return it as is
return n
The issue I am having for example a test case of (1, 2, 18) is that it returns 21. It should return 3. I tried putting print statements in between each 'fix_teen' call in the main function to see what value it had for a, b, c and it just left them as is (1, 2, 18) rather than (1, 2, 0)
The weird part is if I called fixed_teen(18) independently it returns 0.
Your no_teen_sum(a, b, c) function is returning a + b + c (which is literally what gets passed to the function)! You should make a, b and c equal to the result from the fix_teen function to get the desired result!
def no_teen_sum(a, b, c):
a = fix_teen(a)
b = fix_teen(b)
c = fix_teen(c)
return a + b + c
def no_teen_sum(a, b, c):
return print(fix_teen(a) + fix_teen(b) + fix_teen(c))
def fix_teen(n):
if n in (13, 14, 17, 18, 19):
return 0
return n
no_teen_sum(1, 2, 3)
no_teen_sum(2, 13, 1)
no_teen_sum(2, 1, 14)
def no_teen_sum(a, b, c):
return fix_teen(a) + fix_teen(b) + fix_teen(c)
def fix_teen(n):
teen = [13, 14, 17, 18, 19]
if n in teen :
return 0
else:
return n

Code optimization - amount of combinations

There is a number C given (C is an integer) and there is given a list of numbers (let's call it N, all the numbers in list N are integers).
My task is to find the amount of possibilities to represent C.
For example:
input:
C = 4
N = [1, 2]
output:
3
Because:
4 = 1 + 1 + 1 + 1 = 1 + 1 + 2 = 2 + 2
My code is working pretty well for small numbers. However I have no idea how can I optimize it so it will work for bigger integers too. Any help will be appreciated!
There is my code:
import numpy
import itertools
def amount(C):
N = numpy.array(input().strip().split(" "),int)
N = list(N)
N = sorted(N)
while C < max(N):
N.remove(max(N))
res = []
for i in range(1, C):
for j in list(itertools.combinations_with_replacement(N, i)):
res.append(sum(list(j)))
m = 0
for z in range (0, len(res)):
if res[z] == C:
m += 1
if N[0] == 1:
return m + 1
else:
return m
Complexity of your algorithm is O(len(a)^С). To solve this task more efficiently, use dynamic programming ideas.
Assume dp[i][j] equals to number of partitions of i using terms a[0], a[1], ..., a[j]. Array a shouldn't contain duplicates. This solution runs in O(C * len(a)^2) time.
def amount(c):
a = list(set(map(int, input().split())))
dp = [[0 for _ in range(len(a))] for __ in range(c + 1)]
dp[0][0] = 1
for i in range(c):
for j in range(len(a)):
for k in range(j, len(a)):
if i + a[k] <= c:
dp[i + a[k]][k] += dp[i][j]
return sum(dp[c])
please check this first : https://en.wikipedia.org/wiki/Combinatorics
also this https://en.wikipedia.org/wiki/Number_theory
if i were you , i would divide the c on the n[i] first and check the c is not prim number
from your example : 4/1 = [4] =>integer count 1
4/2 = [2] => integer counter became 2 then do partitioning the [2] to 1+1 if and only if 1 is in the set
what if you have 3 in the set [1,2,3] , 4/3 just subtract 4-3=1 if 1 is in the set , the counter increase and for bigger results i will do some partitioning based on the set

Rabin-Miller Strong Pseudoprime Test Implementation won't work

Been trying to implement Rabin-Miller Strong Pseudoprime Test today.
Have used Wolfram Mathworld as reference, lines 3-5 sums up my code pretty much.
However, when I run the program, it says (sometimes) that primes (even low such as 5, 7, 11) are not primes. I've looked over the code for a very long while and cannot figure out what is wrong.
For help I've looked at this site aswell as many other sites but most use another definition (probably the same, but since I'm new to this kind of math, I can't see the same obvious connection).
My Code:
import random
def RabinMiller(n, k):
# obviously not prime
if n < 2 or n % 2 == 0:
return False
# special case
if n == 2:
return True
s = 0
r = n - 1
# factor n - 1 as 2^(r)*s
while r % 2 == 0:
s = s + 1
r = r // 2 # floor
# k = accuracy
for i in range(k):
a = random.randrange(1, n)
# a^(s) mod n = 1?
if pow(a, s, n) == 1:
return True
# a^(2^(j) * s) mod n = -1 mod n?
for j in range(r):
if pow(a, 2**j*s, n) == -1 % n:
return True
return False
print(RabinMiller(7, 5))
How does this differ from the definition given at Mathworld?
1. Comments on your code
A number of the points I'll make below were noted in other answers, but it seems useful to have them all together.
In the section
s = 0
r = n - 1
# factor n - 1 as 2^(r)*s
while r % 2 == 0:
s = s + 1
r = r // 2 # floor
you've got the roles of r and s swapped: you've actually factored n − 1 as 2sr. If you want to stick to the MathWorld notation, then you'll have to swap r and s in this section of the code:
# factor n - 1 as 2^(r)*s, where s is odd.
r, s = 0, n - 1
while s % 2 == 0:
r += 1
s //= 2
In the line
for i in range(k):
the variable i is unused: it's conventional to name such variables _.
You pick a random base between 1 and n − 1 inclusive:
a = random.randrange(1, n)
This is what it says in the MathWorld article, but that article is written from the mathematician's point of view. In fact it is useless to pick the base 1, since 1s = 1 (mod n) and you'll waste a trial. Similarly, it's useless to pick the base n − 1, since s is odd and so (n − 1)s = −1 (mod n). Mathematicians don't have to worry about wasted trials, but programmers do, so write instead:
a = random.randrange(2, n - 1)
(n needs to be at least 4 for this optimization to work, but we can easily arrange that by returning True at the top of the function when n = 3, just as you do for n = 2.)
As noted in other replies, you've misunderstood the MathWorld article. When it says that "n passes the test" it means that "n passes the test for the base a". The distinguishing fact about primes is that they pass the test for all bases. So when you find that as = 1 (mod n), what you should do is to go round the loop and pick the next base to test against.
# a^(s) = 1 (mod n)?
x = pow(a, s, n)
if x == 1:
continue
There's an opportunity for optimization here. The value x that we've just computed is a20 s (mod n). So we could test it immediately and save ourselves one loop iteration:
# a^(s) = ±1 (mod n)?
x = pow(a, s, n)
if x == 1 or x == n - 1:
continue
In the section where you calculate a2j s (mod n) each of these numbers is the square of the previous number (modulo n). It's wasteful to calculate each from scratch when you could just square the previous value. So you should write this loop as:
# a^(2^(j) * s) = -1 (mod n)?
for _ in range(r - 1):
x = pow(x, 2, n)
if x == n - 1:
break
else:
return False
It's a good idea to test for divisibility by small primes before trying Miller–Rabin. For example, in Rabin's 1977 paper he says:
In implementing the algorithm we incorporate some laborsaving steps. First we test for divisibility by any prime p < N, where, say N = 1000.
2. Revised code
Putting all this together:
from random import randrange
small_primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31] # etc.
def probably_prime(n, k):
"""Return True if n passes k rounds of the Miller-Rabin primality
test (and is probably prime). Return False if n is proved to be
composite.
"""
if n < 2: return False
for p in small_primes:
if n < p * p: return True
if n % p == 0: return False
r, s = 0, n - 1
while s % 2 == 0:
r += 1
s //= 2
for _ in range(k):
a = randrange(2, n - 1)
x = pow(a, s, n)
if x == 1 or x == n - 1:
continue
for _ in range(r - 1):
x = pow(x, 2, n)
if x == n - 1:
break
else:
return False
return True
In addition to what Omri Barel has said, there is also a problem with your for loop. You will return true if you find one a that passes the test. However, all a have to pass the test for n to be a probable prime.
I'm wondering about this piece of code:
# factor n - 1 as 2^(r)*s
while r % 2 == 0:
s = s + 1
r = r // 2 # floor
Let's take n = 7. So n - 1 = 6. We can express n - 1 as 2^1 * 3. In this case r = 1 and s = 3.
But the code above finds something else. It starts with r = 6, so r % 2 == 0. Initially, s = 0 so after one iteration we have s = 1 and r = 3. But now r % 2 != 0 and the loop terminates.
We end up with s = 1 and r = 3 which is clearly incorrect: 2^r * s = 8.
You should not update s in the loop. Instead, you should count how many times you can divide by 2 (this will be r) and the result after the divisions will be s. In the example of n = 7, n - 1 = 6, we can divide it once (so r = 1) and after the division we end up with 3 (so s = 3).
Here's my version:
# miller-rabin pseudoprimality checker
from random import randrange
def isStrongPseudoprime(n, a):
d, s = n-1, 0
while d % 2 == 0:
d, s = d/2, s+1
t = pow(a, d, n)
if t == 1:
return True
while s > 0:
if t == n - 1:
return True
t, s = pow(t, 2, n), s - 1
return False
def isPrime(n, k):
if n % 2 == 0:
return n == 2
for i in range(1, k):
a = randrange(2, n)
if not isStrongPseudoprime(n, a):
return False
return True
If you want to know more about programming with prime numbers, I modestly recommend this essay on my blog.
You should also have a look at Wikipedia, where known "random" sequences gives guaranteed answers up to a given prime.
if n < 1,373,653, it is enough to test a = 2 and 3;
if n < 9,080,191, it is enough to test a = 31 and 73;
if n < 4,759,123,141, it is enough to test a = 2, 7, and 61;
if n < 2,152,302,898,747, it is enough to test a = 2, 3, 5, 7, and 11;
if n < 3,474,749,660,383, it is enough to test a = 2, 3, 5, 7, 11, and 13;
if n < 341,550,071,728,321, it is enough to test a = 2, 3, 5, 7, 11, 13, and 17;

Categories