I have a mission to write a recursive function named Reduce. This function should reduce all the zeros from number and return new number.
for example:
Reduce(-160760) => -1676
Reduce(1020034000) => 1234
I started to to something but I got stuck in the condition. here's the code I wrote so far:
def Reduce(num):
while num != 0:
if num % 10 != 0:
newNum = (num % 10) +
Reduce(num//10)
def reduce(num):
if num == 0: return 0
if num < 0: return -reduce(-num)
if num % 10 == 0:
return reduce(num // 10)
else:
return num % 10 + 10 * reduce(num // 10)
String version of recursive function:
def reduce(n):
return int(reduce_recursive(str(n), ''))
def reduce_recursive(num, res):
if not num: # if we've recursed on the whole input, nothing left to do
return res
if num[0] == '0': # if the character is '0', ignore it and recurse on the next character
return reduce_recursive(num[1:], res)
return reduce_recursive(num[1:], res+num[0]) # num[0] is not a '0' so we add it to the result and we move to the next character
>>> reduce(1200530060)
12536
I have a (decimal.Decimal) column in a dataframe as below:
dt = pd.DataFrame({"OPEN": [-0.00010,-0.0114, 0.0066,-0.0044,-0.0012,-0.0005,
0.0005,-0.0037, -0.0029, 0.0034, 0.0003, 0.0001 ]})
dt["OPEN"] = dt["OPEN"].apply(Decimal)
and I would like to apply the following method over the Open column:
def label_change_price(delta):
if 0 < abs(delta) < 0.0001:
print(" Return value: ",0, "Delta: ",delta)
return 0
elif 0.0001 <= abs(delta) < 0.0002:
print(" Return value: ",1, "Delta: ",delta)
return int(np.sign(delta)) * 1
elif 0.0002 <= abs(delta) < 0.0003:
print(" Return value: ",2, "Delta: ",delta)
return int(np.sign(delta)) * 2
elif 0.0003 <= abs(delta):
print(" Return value: ",3, "Delta: ",delta)
return int(np.sign(delta)) * 3
When i run the code, for the very first row (-0.00010) it print
Return value: 0 Delta: -0.00010
which is wrong, as it must return 1, however it returns 0.
In other word, the first condition in if comes True and it does not continue to the second elif.
So, I am wondering, why my second elif 0.0001 <= abs(delta) < 0.0002: is not working well, when the delta is 0.0001 ? And how i can fix it ?
You might try comparisons like this:
if abs(Decimal(0)) < abs(delta) < abs(Decimal(0.0001)):
Comparisons seem tricksy:
from decimal import Decimal
Decimal(0.0001) == 0.0001
# True
abs(Decimal(0.0001)) == 0.0001
# False
Decimal(0.0001) == Decimal(0.0001)
# True
abs(Decimal(0.0001)) == Decimal(0.0001)
# False
abs(Decimal(0.0001)) == abs(Decimal(0.0001))
# True
For a=13 and a precision epsilon=10^-7. How many times do you apply the newton recursion formula in newton_sqrt(13,10^-7)? Hint: use global variables.
My current newton_sqrt(a, epsilon) function is the following:
def newton_sqrt(a, epsilon):
global count
if a < 0:
print("Error: a < 0")
return -1
elif a == 0.0:
return 0
else:
x = abs(a)
newx = 0.5*(x + a/x)
if abs(x - newx) > epsilon:
newton_sqrt(newx, epsilon)
count = count + 1
if not abs(x-newx) > epsilon:
print (count)
return newx
newton_sqrt(13, 0.000001)
For whatever reason, I get
918488688 None
as my output.
Please help.
There is no output since you never reach the print line:
basically, you have:
if x:
if not x:
print(something)
what you want, i'm guessing is:
if x:
#do something
else:
#do somthing else
not knowing the math of your function I would change it into:
def newton_sqrt(a, epsilon, count):
if a < 0:
print("Error: a < 0")
return -1
elif a == 0.0:
return 0
else:
x = abs(a)
newx = 0.5*(x + a/x)
if abs(x - newx) > epsilon:
count = count + 1
newton_sqrt(newx, epsilon, count)
else:
print (count)
return newx
which will give you:
newton_sqrt(13, 0.000001, 0)
23
First, let's be clear that your newton_sqrt() function doesn't work. Either you're trying to instrument the recursion depth to fix it, or you're unaware it's broken.
A working newton_sqrt() would be along the lines of:
import sys
def newton_sqrt(a, epsilon, x=None):
if a < 0:
print("Error: a < 0", file=sys.stderr)
return -1
if a == 0:
return 0
if x is None: # initial guess
x = a
new_x = (x + a / x) / 2 # refine guess
if abs(new_x * new_x - a) < epsilon: # test guess
return new_x
return newton_sqrt(a, epsilon, new_x) # (better) guess again
print(newton_sqrt(13, 1e-06))
Once that's working, instrumenting the recursion depth using a global variable, count, is simple:
import sys
count = 0
def newton_sqrt(a, epsilon, x=None):
global count
count += 1
if a < 0:
print("Error: a < 0", file=sys.stderr)
return -1
if a == 0:
return 0
if x is None: # initial guess
x = a
new_x = (x + a / x) / 2 # refine guess
if abs(new_x * new_x - a) < epsilon: # test guess
return new_x
return newton_sqrt(a, epsilon, new_x) # (better) guess again
print(newton_sqrt(13, 1e-06), count)
OUTPUT
> python3 test.py
3.6055513629176015 5
>
Where 3.6055513629176015 is the square root of 13 and 5 is the recursion depth needed to compute it with an error of less than 1e-06.
I tried searching StackOverflow and some other sources to find the fastest way to get a prime number within some interval but I didn't find any efficient way, so here is my code:
def prime(lower,upper):
prime_num = []
for num in range(lower, upper + 1):
# all prime numbers are greater than 1
if num > 1:
for i in range(2, num):
if (num % i) == 0:
break
else:
prime_num.append(num)
return prime_num
Can I make this more efficient?
I tried finding my answer in Fastest way to find prime number but I didn't find prime numbers in intervals.
I wrote an equation based prime finder using MillerRabin, it's not as fast as a next_prime finder that sieves, but it can create large primes and you get the equation it used to do it. Here is an example. Following that is the code:
In [5]: random_powers_of_2_prime_finder(1700)
Out[5]: 'pow_mod_p2(27667926810353357467837030512965232809390030031226210665153053230366733641224969190749433786036367429621811172950201894317760707656743515868441833458231399831181835090133016121983538940390210139495308488162621251038899539040754356082290519897317296011451440743372490592978807226034368488897495284627000283052473128881567140583900869955672587100845212926471955871127908735971483320243645947895142869961737653915035227117609878654364103786076604155505752302208115738401922695154233285466309546195881192879100630465, 2**1700-1, 2**1700) = 39813813626508820802866840332930483915032503127272745949035409006826553224524022617054655998698265075307606470641844262425466307284799062400415723706121978318083341480570093257346685775812379517688088750320304825524129104843315625728552273405257012724890746036676690819264523213918417013254746343166475026521678315406258681897811019418959153156539529686266438553210337341886173951710073382062000738529177807356144889399957163774682298839265163964939160419147731528735814055956971057054406988006642001090729179713'
or use to get the answer directly:
In [6]: random_powers_of_2_prime_finder(1700, withstats=False)
Out[6]: 4294700745548823167814331026002277003506280507463037204789057278997393231742311262730598677178338843033513290622514923311878829768955491790776416394211091580729947152858233850115018443160652214481910152534141980349815095067950295723412327595876094583434338271661005996561619688026571936782640346943257209115949079332605276629723961466102207851395372367417030036395877110498443231648303290010952093560918409759519145163112934517372716658602133001390012193450373443470282242835941058763834226551786349290424923951
The code:
import random
import math
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 ltrailing(N):
return len(str(bin(N))) - len(str(bin(N)).rstrip('0'))
def pow_mod_p2(x, y, z):
"4-5 times faster than pow for powers of 2"
number = 1
while y:
if y & 1:
number = modular_powerxz(number * x, z)
y >>= 1
x = modular_powerxz(x * x, z)
return number
def modular_powerxz(num, z, bitlength=1, offset=0):
xpowers = 1<<(z.bit_length()-bitlength)
if ((num+1) & (xpowers-1)) == 0:
return ( num & ( xpowers -bitlength)) + 2
elif offset == -1:
return ( num & ( xpowers -bitlength)) + 1
elif offset == 0:
return ( num & ( xpowers -bitlength))
elif offset == 1:
return ( num & ( xpowers -bitlength)) - 1
elif offset == 2:
return ( num & ( xpowers -bitlength)) - 2
def MillerRabin(N, primetest, iterx, powx, withstats=False):
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
PRIMES=list(primes_sieve2(1000000))
def mr_isprime(N, withstats=False):
if N == 2:
return True
if N % 2 == 0:
return False
if N < 2:
return False
if N in PRIMES:
return True
for xx in PRIMES:
if N % xx == 0:
return False
iterx = ltrailing(N - 1)
k = pow_mod_p2(N, (1<<N.bit_length())-1, 1<<N.bit_length()) - 1
t = N >> iterx
tests = [k+1, k+2, k, k-2, k-1]
for primetest in tests:
if primetest >= N:
primetest %= N
if primetest >= 2:
if MillerRabin(N, primetest, iterx, t, withstats) == False:
return False
return True
def lars_last_modulus_powers_of_two(hm):
return math.gcd(hm, 1<<hm.bit_length())
def random_powers_of_2_prime_finder(powersnumber, primeanswer=False, withstats=True):
while True:
randnum = random.randrange((1<<(powersnumber-1))-1, (1<<powersnumber)-1,2)
while lars_last_modulus_powers_of_two(randnum) == 2 and mr_isprime(randnum//2) == False:
randnum = random.randrange((1<<(powersnumber-1))-1, (1<<powersnumber)-1,2)
answer = randnum//2
# This option makes the finding of a prime much longer, i would suggest not using it as
# the whole point is a prime answer.
if primeanswer == True:
if mr_isprime(answer) == False:
continue
powers2find = pow_mod_p2(answer, (1<<powersnumber)-1, 1<<powersnumber)
if mr_isprime(powers2find) == True:
break
else:
continue
if withstats == False:
return powers2find
elif withstats == True:
return f"pow_mod_p2({answer}, 2**{powersnumber}-1, 2**{powersnumber}) = {powers2find}"
return powers2find
def nextprime(N):
N+=2
while not mr_isprime(N):
N+=2
return N
def get_primes(lower, upper):
lower = lower|1
upper = upper|1
vv = []
if mr_isprime(lower):
vv.append(lower)
else:
vv=[nextprime(lower)]
while vv[-1] < upper:
vv.append(nextprime(vv[-1]))
return vv
Here is an example like yours:
In [1538]: cc = get_primes(1009732533765201, 1009732533767201)
In [1539]: print(cc)
[1009732533765251, 1009732533765281, 1009732533765289, 1009732533765301, 1009732533765341, 1009732533765379, 1009732533765481, 1009732533765493, 1009732533765509, 1009732533765521, 1009732533765539, 1009732533765547, 1009732533765559, 1009732533765589, 1009732533765623, 1009732533765749, 1009732533765751, 1009732533765757, 1009732533765773, 1009732533765821, 1009732533765859, 1009732533765889, 1009732533765899, 1009732533765929, 1009732533765947, 1009732533766063, 1009732533766069, 1009732533766079, 1009732533766093, 1009732533766109, 1009732533766189, 1009732533766211, 1009732533766249, 1009732533766283, 1009732533766337, 1009732533766343, 1009732533766421, 1009732533766427, 1009732533766457, 1009732533766531, 1009732533766631, 1009732533766643, 1009732533766667, 1009732533766703, 1009732533766727, 1009732533766751, 1009732533766763, 1009732533766807, 1009732533766811, 1009732533766829, 1009732533766843, 1009732533766877, 1009732533766909, 1009732533766933, 1009732533766937, 1009732533766973, 1009732533767029, 1009732533767039, 1009732533767093, 1009732533767101, 1009732533767147, 1009732533767159, 1009732533767161, 1009732533767183, 1009732533767197, 1009732533767233]
Yes. In general, use:
Sieve of Eratosthenes
Miller-Rabin Primality Test
Other options include trying a compiled language, like C++, but I think that isn't what you're looking for, since you've asked about Python.
Yes, you can make it more efficient. As has been mentioned, for very large numbers use Miller-Rabin. For smaller ranges use the Sieve of Eratosthenes. However, apart from that, your prime checker code is very inefficient.
2 is the only even prime number, which can save you doing half the work you do.
You only need to check up to the square root of the number you are testing. In any pair of factors: f and n/f, one is guaranteed to be less then or equal to the square root of the number being tested. Once you find a factor then the number is composite.
My Python is not good, so this is in pseudocode:
isPrime(num)
// Negatives, 0, 1 are not prime.
if (num < 2) return false
// Even numbers: 2 is the only even prime.
if (num % 2 == 0) return (num == 2)
// Odd numbers have only odd factors.
limit <- 1 + sqrt(num)
for (i <- 3 to limit step 2)
if (num % i == 0) return false
// No factors found so num is prime
return true
end isPrime
I made a code that measure number of steps it takes to return to 1 in a Collatz Conjecture. Here Is my code
counter = 0
def collatz(n):
global counter
counter += 1
if n <= 0 :
return "Invalid Number"
elif n == 1 :
return counter
elif n % 2 == 1 :
n = 3*n + 1
return collatz(n)
elif n % 2 == 0 :
n = n/2
return collatz(n)
print(collatz(9921615699))
print(collatz(9921615699))
I expect the Last two print commands to print 311 and 311. Instead, they print 311 and 622. I guess that was easy enough to see in the code what is wrong. How can i fix that? how can counter reset each time a command is completed and not when the function is run.
Instead of using global variable you could make the counter a parameter with default value:
def collatz(n, counter=0):
counter += 1
if n <= 0 :
return "Invalid Number"
elif n == 1 :
return counter
elif n % 2 == 1 :
n = 3*n + 1
return collatz(n, counter)
elif n % 2 == 0 :
n = n/2
return collatz(n, counter)
You're using recursion, so just use it properly:
def collatz(n, counter=0):
counter += 1
if n <= 0 :
return "Invalid Number"
elif n == 1 :
return counter
elif n % 2 == 1 :
n = 3*n + 1
return collatz(n, counter)
elif n % 2 == 0 :
n = n/2
return collatz(n, counter)
print(collatz(9921615699))
print(collatz(9921615699))
You were using global in your original version which is usually not what you want to do. You got to see first-hand why.
You could have reset the counter, e.g.
result = counter
counter = 0
return result
But that's pretty nasty, let's not do that. When you're implementing a recursive algorithm there's probably no good reason to have a global variable.