Estimating in Python - python

I am trying to write a python function which will give me back the first value of a number k which will function 2 >= function 1
function 1(p) => 1 + 1/1! + 1/2! + 1/p!
function 2(k) => (1 + 1/k)^k
So I input use 2 for example in function 1. It would take estimate e at 2.5 but it would take k being 6 for it to get close which is 2.522.
I want to return the 6.
I get this far but I am not sure where to go from there.
for x in range(p):
factorial(x):
if x == 0:
return 0
else:
return x * factorial(x-1)
result = 1 + 1/factorial(p)

I think you need two separate functions, and no loops are needed.
def factorial(x):
if x in {0, 1}:
return 1 # This needs to be 1, otherwise you multiply everything by 0
else:
return x * factorial(x-1)
def summ(p):
if p == 0:
return 1
elif p == 1:
return 2
else:
return 1/factorial(p) + summ(p-1)
Regarding the rest of the question, I think this will help
def f2(k):
return 1 if k == 0 else (1 + 1/k)**k
max_iter = 10 # TODO: increase
k = 0
delta = 0.000001
while max_iter > 0:
f1_result = summ(k)
f2_result = f2(k)
check = f1_result <= f2_result
print("k={}: {:6.8f} <= {:6.8f} == {}".format(k, f1_result, f2_result, check))
k += 1
max_iter -= 1
# if check:
# break
# TODO: Check if difference is within acceptable delta value
Output
k=0: 1.00000000 <= 1.00000000 == True
k=1: 2.00000000 <= 2.00000000 == True
k=2: 2.50000000 <= 2.25000000 == False
k=3: 2.66666667 <= 2.37037037 == False
k=4: 2.70833333 <= 2.44140625 == False
k=5: 2.71666667 <= 2.48832000 == False
k=6: 2.71805556 <= 2.52162637 == False
k=7: 2.71825397 <= 2.54649970 == False
k=8: 2.71827877 <= 2.56578451 == False
k=9: 2.71828153 <= 2.58117479 == False
From larger numbers, this check still fails at k=996 and throws a recursion error.
k=996: 2.71828183 <= 2.71691848 == False
Traceback (most recent call last):
File "python", line 22, in <module>
File "python", line 13, in summ
File "python", line 5, in factorial
File "python", line 5, in factorial
File "python", line 5, in factorial
[Previous line repeated 992 more times]
RecursionError: maximum recursion depth exceeded
Therefore, it would help if you wrote a factorial function using a loop rather than recursion.
Edit
I think I understand what you are trying to get now
in1 = int(input("value 1:"))
v1 = summ(in1)
v2 = 0
max_iter = 50 # Recursion execution limit
while f2(v2) <= v1 and max_iter > 0:
v2 += 1
max_iter -= 1
print(v2)
Output
value 1: <enter 2>
6

Related

Having trouble with implementeing the Miller-Rabin compositeness in Python

I'm not sure if this is the right place to post this question so if it isn't let me know! I'm trying to implement the Miller Rabin test in python. The test is to find the first composite number that is a witness to N, an odd number. My code works for numbers that are somewhat smaller in length but stops working when I enter a huge number. (The "challenge" wants to find the witness of N := 14779897919793955962530084256322859998604150108176966387469447864639173396414229372284183833167 in which my code returns that it is prime when it isn't) The first part of the test is to convert N into the form 2^k + q, where q is a prime number.
Is there some limit with python that doesn't allow huge numbers for this?
Here is my code for that portion of the test.
def convertN(n): #this turns n into 2^x * q
placeholder = False
list = []
#this will be x in the equation
count = 1
while placeholder == False:
#x = result of division of 2^count
x = (n / (2**count))
#y tells if we can divide by 2 again or not
y = x%2
#if y != 0, it means that we cannot divide by 2, loop exits
if y != 0:
placeholder = True
list.append(count) #x
list.append(x) #q
else:
count += 1
#makes list to return
#print(list)
return list
The code for the actual test:
def test(N):
#if even return false
if N == 2 | N%2 == 0:
return "even"
#convert number to 2^k+q and put into said variables
n = N - 1
nArray = convertN(n)
k = nArray[0]
q = int(nArray[1])
#this is the upper limit a witness can be
limit = int(math.floor(2 * (math.log(N))**2))
#Checks when 2^q*k = 1 mod N
for a in range(2,limit):
modu = pow(a,q,N)
for i in range(k):
print(a,i,modu)
if i==0:
if modu == 1:
break
elif modu == -1:
break
elif i != 0:
if modu == 1:
#print(i)
return a
#instead of recalculating 2^q*k+1, can square old result and modN that.
modu = pow(modu,2,N)
Any feedback is appreciated!
I don't like unanswered questions so I decided to give a small update.
So as it turns out I was entering the wrong number from the start. Along with that my code should have tested not for when it equaled to 1 but if it equaled -1 from the 2nd part.
The fixed code for the checking
#Checks when 2^q*k = 1 mod N
for a in range(2,limit):
modu = pow(a,q,N)
witness = True #I couldn't think of a better way of doing this so I decided to go with a boolean value. So if any of values of -1 or 1 when i = 0 pop up, we know it's not a witness.
for i in range(k):
print(a,i,modu)
if i==0:
if modu == 1:
witness = False
break
elif modu == -1:
witness = False
break
#instead of recalculating 2^q*k+1, can square old result and modN that.
modu = pow(modu,2,N)
if(witness == True):
return a
Mei, i wrote a Miller Rabin Test in python, the Miller Rabin part is threaded so it's very fast, faster than sympy, for larger numbers:
import math
def strailing(N):
return N>>lars_last_powers_of_two_trailing(N)
def lars_last_powers_of_two_trailing(N):
""" This utilizes a bit trick to find the trailing zeros in a number
Finding the trailing number of zeros is simply a lookup for most
numbers and only in the case of 1 do you have to shift to find the
number of zeros, so there is no need to bit shift in 7 of 8 cases.
In those 7 cases, it's simply a lookup to find the amount of zeros.
"""
p,y=1,2
orign = N
N = N&15
if N == 1:
if ((orign -1) & (orign -2)) == 0: return orign.bit_length()-1
while orign&y == 0:
p+=1
y<<=1
return p
if N in [3, 7, 11, 15]: return 1
if N in [5, 13]: return 2
if N == 9: return 3
return 0
def primes_sieve2(limit):
a = [True] * limit
a[0] = a[1] = False
for (i, isprime) in enumerate(a):
if isprime:
yield i
for n in range(i*i, limit, i):
a[n] = False
def llinear_diophantinex(a, b, divmodx=1, x=1, y=0, offset=0, withstats=False, pow_mod_p2=False):
""" For the case we use here, using a
llinear_diophantinex(num, 1<<num.bit_length()) returns the
same result as a
pow(num, 1<<num.bit_length()-1, 1<<num.bit_length()). This
is 100 to 1000x times faster so we use this instead of a pow.
The extra code is worth it for the time savings.
"""
origa, origb = a, b
r=a
q = a//b
prevq=1
#k = powp2x(a)
if a == 1:
return 1
if withstats == True:
print(f"a = {a}, b = {b}, q = {q}, r = {r}")
while r != 0:
prevr = r
a,r,b = b, b, r
q,r = divmod(a,b)
x, y = y, x - q * y
if withstats == True:
print(f"a = {a}, b = {b}, q = {q}, r = {r}, x = {x}, y = {y}")
y = 1 - origb*x // origa - 1
if withstats == True:
print(f"x = {x}, y = {y}")
x,y=y,x
modx = (-abs(x)*divmodx)%origb
if withstats == True:
print(f"x = {x}, y = {y}, modx = {modx}")
if pow_mod_p2==False:
return (x*divmodx)%origb, y, modx, (origa)%origb
else:
if x < 0: return (modx*divmodx)%origb
else: return (x*divmodx)%origb
def MillerRabin(arglist):
""" This is a standard MillerRabin Test, but refactored so it can be
used with multi threading, so you can run a pool of MillerRabin
tests at the same time.
"""
N = arglist[0]
primetest = arglist[1]
iterx = arglist[2]
powx = arglist[3]
withstats = arglist[4]
primetest = pow(primetest, powx, N)
if withstats == True:
print("first: ",primetest)
if primetest == 1 or primetest == N - 1:
return True
else:
for x in range(0, iterx-1):
primetest = pow(primetest, 2, N)
if withstats == True:
print("else: ", primetest)
if primetest == N - 1: return True
if primetest == 1: return False
return False
# For trial division, we setup this global variable to hold primes
# up to 1,000,000
SFACTORINT_PRIMES=list(primes_sieve2(100000))
# Uses MillerRabin in a unique algorithimically deterministic way and
# also uses multithreading so all MillerRabin Tests are performed at
# the same time, speeding up the isprime test by a factor of 5 or more.
# More k tests can be performed than 5, but in my testing i've found
# that's all you need.
def sfactorint_isprime(N, kn=5, trialdivision=True, withstats=False):
from multiprocessing import Pool
if N == 2:
return True
if N % 2 == 0:
return False
if N < 2:
return False
# Trial Division Factoring
if trialdivision == True:
for xx in SFACTORINT_PRIMES:
if N%xx == 0 and N != xx:
return False
iterx = lars_last_powers_of_two_trailing(N)
""" This k test is a deterministic algorithmic test builder instead of
using random numbers. The offset of k, from -2 to +2 produces pow
tests that fail or pass instead of having to use random numbers
and more iterations. All you need are those 5 numbers from k to
get a primality answer. I've tested this against all numbers in
https://oeis.org/A001262/b001262.txt and all fail, plus other
exhaustive testing comparing to other isprimes to confirm it's
accuracy.
"""
k = llinear_diophantinex(N, 1<<N.bit_length(), pow_mod_p2=True) - 1
t = N >> iterx
tests = []
if kn % 2 == 0: offset = 0
else: offset = 1
for ktest in range(-(kn//2), (kn//2)+offset):
tests.append(k+ktest)
for primetest in range(len(tests)):
if tests[primetest] >= N:
tests[primetest] %= N
arglist = []
for primetest in range(len(tests)):
if tests[primetest] >= 2:
arglist.append([N, tests[primetest], iterx, t, withstats])
with Pool(kn) as p:
s=p.map(MillerRabin, arglist)
if s.count(True) == len(arglist): return True
else: return False
sinn=14779897919793955962530084256322859998604150108176966387469447864639173396414229372284183833167
print(sfactorint_isprime(sinn))

How can I convert my function output in List?

I am trying to use Fibonacci series and get Cubes of the series. My Fibonacci function is giving an output but I want that output to be in a List form.
Following is my code
cube = lambda x : x ** 3
def fibonacci(n):
a = 0
b = 1
count = 0
if n < 0:
print("Incorrect input")
elif n == 0:
return a
elif n == 1:
return b
else:
while count < n:
print(a)
c = a + b
a = b
b = c
count += 1
if __name__ == "__main__":
n = int(input())
print(list(map(cube,fibonacci(n))))
I am getting the following output with error:
6
0
1
1
2
3
5
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-38-58624b7f0dd2> in <module>
1 if __name__ == "__main__":
2 n = int(input())
----> 3 print(list(map(cube,fibonacci(n))))
TypeError: 'NoneType' object is not iterable
I am very new to coding. Please help!
If you'd your Fibonacci function to return a list, change it as follows:
def fibonacci(n):
a = 0
b = 1
count = 0
res = []
if n < 0:
print("Incorrect input")
elif n == 0:
return [a]
elif n == 1:
return [b]
else:
while count < n:
res.append(a)
c = a + b
a = b
b = c
count += 1
return res
You can then run:
n = 5
print(list(map(cube,fibonacci(n))))
Which results in:
[0, 1, 1, 8, 27]
While you could build a list right away as shown here, this task can be solved more efficiently using generators.
The idea is that with the generator you do the computation when actually required and you do not (need to) store potentially large intermediate objects.
Also, note how swapping is done in Python and why name = lambda ... is an anti-pattern in Python.
def fibonacci(n):
a = 0
b = 1
count = 0
if n < 0:
print("Incorrect input")
return
elif n == 0:
yield a
elif n == 1:
yield b
else:
while count < n:
yield a
a, b = b, a + b
count += 1
def cube(x):
return x ** 3
n = 8
print(list(fibonacci(n)))
# [0, 1, 1, 2, 3, 5, 8, 13]
print(list(map(cube, fibonacci(n))))
# [0, 1, 1, 8, 27, 125, 512, 2197]

Project Euler #37 issue

I tried to solve Project Euler #37:
The number 3797 has an interesting property. Being prime itself, it is possible to continuously remove digits from left to right, and remain prime at each stage: 3797, 797, 97, and 7. Similarly we can work from right to left: 3797, 379, 37, and 3.
Find the sum of the only eleven primes that are both truncatable from left to right and right to left.
NOTE: 2, 3, 5, and 7 are not considered to be truncatable primes.
I wrote my code in Python but I am facing weird issues.
Here's my code:
def isPrime(n):
if n == 2 or n == 3 or n == 5: return True
if n < 2 or n%2 == 0: return False
if n < 9: return True
if n%3 == 0: return False
if n%5 == 0: return False
r = int(n**0.5)
f = 5
while f <= r:
if n%f == 0: return False
if n%(f+2) == 0: return False
f +=6
return True
def gen(nb):
results = []
nb_str = str(nb)
for k in range(0, len(nb_str) - 1):
results.append(nb_str[k:])
results.append(nb_str[-k:])
return results
def check(nb):
for t in gen(nb):
if not isPrime(int(t)):
return False
return True
c = 0
s = 0
i = 2
while c != 11:
if check(i):
c += 1
s += i
i += 1
print(s)
Where does the error come from? (The expected result is 748317)
I suspect the errors coming from the results list
Yes, the gen() function is not working correctly as your slicing is off, also, you count 2, 3, 5 and 7 as truncatable primes which the question denies.
The second slice should be the other way around:
>>> s = 'abcd'
>>> for i in range(1,len(s)-1):
... print(s[i:])
... print(s[:-i])
...
bcd
abc
cd
ab
which we can see produces the right strings.
Altogether then, the function should be:
def gen(nb):
results = [nb]
nb_str = str(nb)
for k in range(1, len(nb_str)):
results.append(int(nb_str[k:]))
results.append(int(nb_str[:-k]))
return results
note I also added a string to int conversion - not sure how Python didn't make that obvious for you :/
And before get the full solution, Project Euler nearly always gives you an example which you can use to check your code:
>>> check(3797)
True
You must also add a condition in the check function to return False if the number is 2, 3, 5 or 7 as this is stated clearly in the question.
And the result is the expected: 748317.
Joe Iddon has explained the error in your code, but you can speed it up a little by turning gen into an actual generator. That way, you can stop checking the results for a given nb as soon as you detect a composite number (and gen will stop generating them). I've also made a few minor tweaks to your primality tester. Remember, the or operator short-circuits, so if a is True-ish in a or b then it doesn't bother evaluating b.
def isPrime(n):
if n in {2, 3, 5, 7}:
return True
if n < 2 or n%2 == 0:
return False
if n%3 == 0 or n%5 == 0:
return False
r = int(n**0.5)
f = 5
while f <= r:
if n%f == 0 or n%(f+2) == 0:
return False
f += 6
return True
def gen(nb):
yield nb
nb_str = str(nb)
for k in range(1, len(nb_str)):
yield int(nb_str[k:])
yield int(nb_str[:-k])
def check(nb):
for t in gen(nb):
if not isPrime(t):
return False
return True
c = s = 0
# Don't check single digit primes
i = 11
while c < 11:
if check(i):
c += 1
s += i
print(i)
i += 2
print('sum', s)
output
23
37
53
73
313
317
373
797
3137
3797
739397
sum 748317
In fact, you can get rid of the check function, and replace it with all, which also short-circuits, like or does. So you can replace the
if check(i):
with
if all(map(isPrime, gen(i))):

Writing a program that finds perfect numbers - error

I'm working on a program that finds perfect numbers (i.e., 6, because its factors, 1, 2, and 3, add up to itself). My code is
k=2
mprim = []
mprimk = []
pnum = []
def isprime(n):
"""Returns True if n is prime."""
if n == 2:
return True
if n == 3:
return True
if n % 2 == 0:
return False
if n % 3 == 0:
return False
i = 5
w = 2
while i * i <= n:
if n % i == 0:
return False
i += w
w = 6 - w
return True
def mprime(k):
while k < 50:
check = (2**k)-1
if isprime(check) == True:
mprim.append(check)
mprimk.append(k)
print check
k+=1
else:
k+=1
mprime(k)
def isperf(lst):
for i in lst:
prm = (((2**i)-1)(2**i))/(2)
pnum.append(prm)
isperf(mprimk)
print pnum
The first part, that checks if a number is prime, and produces mercenne primes, is working alright. Its the second part I'm having trouble with. I have read that if 2^k - 1 is prime, then ((2^k - 1)(2^k))/2 is a perfect number, so I am using that formula.
The error it gives is
Traceback (most recent call last):
File "python", line 47, in <module>
File "python", line 44, in isperf
TypeError: 'int' object is not callable
Line 47 is isperf(mprimk) and line 44 is prm = (((2**i)-1)(2**i))/(2). Any assistance would be appreciated.
Thanks!
The error clearly states that you are trying to call an int type, which isn't callable.
In practice it means you trying to do something like 123()
And code responsible for it is ((2**i)-1)(2**i) because you forgot * and it should be (((2**i)-1)*(2**i))/(2)

Why does this code print None?

The Ackermann's Function had been tried to implement through the following code
def A(m, n):
if m == 0:
return n + 1
elif m > 0 and n == 1:
A(m - 1, 1)
elif m > 0 and n > 0:
A(m - 1, A(m, n - 1))
print A(4, 5)
Your function doesn't return anything for 2 of the 3 branches of the if statements; only if m == 0 do you explicitly return a value.
You need to return the results of recursive calls too:
def A(m, n):
if m == 0:
return n + 1
elif m > 0 and n == 1:
return A(m - 1, 1)
elif m > 0 and n > 0:
return A(m - 1, A(m, n - 1))
Without an explicit return, the function ends with the default return value of None.

Categories