The tree is as follows:
(1,1)
/ \
(2,1) (1,2)
/ \ / \
(3,1)(2,3) (3,2)(1,3)
and onward
The root is (1,1), all values in the tree are tuples.
Where (x,y) is an element of the tree:
The leftChild will be (x+y,y)
The rightChild will be (x,x+y)
I am building a function that finds the distance from the root (1,1). I cannot build the tree from scratch as it will be too time consuming.
I have found that 1 distance from the tuple being searched for we must subtract the the max with the min. We can work backward.
1 2
(3,2)->(1,2)->(1,1)
(3,2)->(3-2,2) = (1,2)->(1,2-1) = (1,1)
given this is always true:
if x > y:
newtuple = (x-y,y)
distance += 1
else if y > x:
newtuple = (x,y-x)
distance += 1
Yet because possible test cases can go up to even x = 10^50, this is even too slow.
So I have found a formally to find the amount of subtractions of x with y or vice versa to make a x > y change to y < x and vice versa until (x,y) = (1,1).
So X - Y(a certain amount of times, say z) will make x less than y...
X - Y*z = y
find z via algebra... z = (Y-X)/(-Y)
This is my code so far:
from decimal import Decimal
import math
def answer(M,F):
M = int(M)
F = int(F)
i = 0
while True:
if M == 1 and F == 1:
return str(i)
if M > F:
x = math.ceil((F-M)/(-F))
M -= F*x
elif F > M:
x = math.ceil((M-F)/(-M))
F -= M*x
else:
if F == M and F != 1:
return "impossible"
i += x
if M < 1 or F < 1:
return "impossible"
return str(i)
And it's not passing some unknown test cases, yet passes all the test cases I can think of. What test cases could I be failing? Where is my code wrong?
p.s. used Decimal module, just removed from code to make more readible.
Floor division allows for no loss, but maybe -1 in error which I consider for the code below.
def answer(M,F):
M = int(M)
F = int(F)
i = 0
while True:
if M == 1 and F == 1:
return str(i)
if M > F:
x = F-M
x = x//(-F)
if F < M-(F*x):
x += 1
M -= F*x
elif F > M:
x = M-F
x = x//(-M)
if M < F-(M*x):
x += 1
F -= M*x
else:
if F == M and F != 1:
return "impossible"
i += x
if M < 1 or F < 1:
return "impossible"
return str(i)
Related
I need to generate the result of the log.
I know that:
Then I made my code:
def log(x, base):
log_b = 2
while x != int(round(base ** log_b)):
log_b += 0.01
print(log_b)
return int(round(log_b))
But it works very slowly. Can I use other method?
One other thing you might want to consider is using the Taylor series of the natural logarithm:
Once you've approximated the natural log using a number of terms from this series, it is easy to change base:
EDIT: Here's another useful identity:
Using this, we could write something along the lines of
def ln(x):
n = 1000.0
return n * ((x ** (1/n)) - 1)
Testing it out, we have:
print ln(math.e), math.log(math.e)
print ln(0.5), math.log(0.5)
print ln(100.0), math.log(100.0)
Output:
1.00050016671 1.0
-0.692907009547 -0.69314718056
4.6157902784 4.60517018599
This shows our value compared to the math.log value (separated by a space) and, as you can see, we're pretty accurate. You'll probably start to lose some accuracy as you get very large (e.g. ln(10000) will be about 0.4 greater than it should), but you can always increase n if you need to.
I used recursion:
def myLog(x, b):
if x < b:
return 0
return 1 + myLog(x/b, b)
You can use binary search for that.
You can get more information on binary search on Wikipedia:
Binary search;
Doubling search.
# search for log_base(x) in range [mn, mx] using binary search
def log_in_range(x, base, mn, mx):
if (mn <= mx):
med = (mn + mx) / 2.0
y = base ** med
if abs(y - x) < 0.00001: # or if math.isclose(x, y): https://docs.python.org/3/library/math.html#math.isclose
return med
elif x > y:
return log_in_range(x, base, med, mx)
elif x < y:
return log_in_range(x, base, mn, med)
return 0
# determine range using doubling search, then call log_in_range
def log(x, base):
if base <= 0 or base == 1 or x <= 0:
raise ValueError('math domain error')
elif 0 < base < 1:
return -log(x, 1/base)
elif 1 <= x and 1 < base:
mx = 1
y = base
while y < x:
y *= y
mx *= 2
return log_in_range(x, base, 0, mx)
elif 0 <= x < 1 and 1 < base:
mn = -1
y = 1/base
while y > x:
y = y ** 0.5
mn *= 2
return log_in_range(x, base, mn, 0)
import math
try :
number_and_base = input() ##input the values for number and base
##assigning those values for the variables
number = int(number_and_base.split()[0])
base = int(number_and_base.split()[1])
##exception handling
except ValueError :
print ("Invalid input...!")
##program
else:
n1 = 1 ##taking an initial value to iterate
while(number >= int(round(base**(n1),0))) : ##finding the most similer value to the number given, varying the vlaue of the power
n1 += 0.000001 ##increasing the initial value bit by bit
n2 = n1-0.0001
if abs(number-base**(n2)) < abs(base**(n1)-number) :
n = n2
else :
n = n1
print(math.floor(n)) ##output value
Comparison:-
This is how your log works:-
def your_log(x, base):
log_b = 2
while x != int(round(base ** log_b)):
log_b += 0.01
#print log_b
return int(round(log_b))
print your_log(16, 2)
# %timeit %run your_log.py
# 1000 loops, best of 3: 579 us per loop
This is my proposed improvement:-
def my_log(x, base):
count = -1
while x > 0:
x /= base
count += 1
if x == 0:
return count
print my_log(16, 2)
# %timeit %run my_log.py
# 1000 loops, best of 3: 321 us per loop
which is faster, using the %timeit magic function in iPython to time the execution for comparison.
It will be long process since it goes in a loop. Therefore,
def log(x,base):
result = ln(x)/ln(base)
return result
def ln(x):
val = x
return 99999999*(x**(1/99999999)-1)
log(8,3)
Values are nearly equal but not exact.
I'm a newbie in algorithms. I have recently started studying binary search and tryed to implement it on my own. The task is simple: we have an array of integers a and an integer x. If a contains x the result should be its index, otherwise the function should return -1.
Here is the code I have written:
def binary_search(a, x):
l = 0
r = len(a)
while r - l > 0:
m = (l + r) // 2
if a[m] < x:
l = m
else:
r = m
if a[l] == x:
return l
return -1
But this code stucks in infinite cycle on a = [1, 2] and x = 2. I suppose, that I have incorrect cycle condition (probably, should be r - l >= 0), but this solution does not help. Where am I wrong?
Let me do some desk checking. I'll assume a = [1, 2] and we are searching for a 2
So we start with
l = 0
r = 2
Since r - l = 2 > 0, we enter the while-loop.
m = (l + r) / 2 = (0 + 2) / 2 = 1
a[m] = a[1] = 2 == x (hence not less than x)
r = m = 1 (and l remains the same)
Now r - l = 1 - 0 = 1 > 0, so we continue
m = (l + r) / 2 = (0 + 1) / 2 = 0
a[m] = a[0] = 1 < x
l = m = 0 (and r remains the same)
After this iteration both r and l have the same value as before, which then produces an endless loop.
Ashok's answer is a great fix. But I think it'll be educational to do some desk checking on the fixed code and look what improves it.
Basically the problematic situation arises, when l + 1 = r.
Then m will always evaluate to l, a[l] < x and l is set to m again, which doesn't change the situation.
In a larger piece of code it'll make sense to make a table that contains a column for each variable to watch and a column to write down the code line that was evaluated. A column for remarks won't harm either.
As Mani mentioned you are not considering when A[m]==x. Include that case (at that point you've found a so just return m), and once you have that case we can let l=m+1 when we are still below x. Like this:
def binary_search(a, x):
l = 0
r = len(a)
while r - l > 0:
m = (l + r) // 2
if a[m] < x:
l = m + 1
elif a[m]==x:
return m
else:
r = m
if l<len(a) and a[l] == x:
return l
return -1
I need to build a python code for the following equation.
As I understood this equation has only 4 iterations and until it becomes true need to recall the function again. But when recalling the function the value which use to store the number of iterations will be lost.
The code which I have write is this.
def answer(z):
for i in 5:
if i == 4:
zn = z + 1/z
else:
y = 1 / z + zn
return y
z = float(input("Enter value for Z : "))
print("The Y Value is : %.4f" %answer(z))
I need to know to build the code for this equation.
You could use the following. Your algorithm needs to update the denominator several times.
def answer(z, n=4):
z_den = z
for i in range(n):
z_den = z + 1/z_den
final_answer = 1 / z_den
return final_answer
I think you could utilize recursion for this:
def answer(z, y = 0, n = 1):
if n == 1:
y = z + 1/z
answer(z, y, n+1)
elif n > 1 and n < 4:
y = z + 1/y
answer(z, y, n+1)
else:
print(1/y)
Where
answer(2) -> 0.4137931034482759
answer(10) -> 0.09901951266867294
answer(15) -> 0.0663729751856689
Given an arbitrary range of 1 to F and a starting point S with an ending point G such that the only directions we could go is L Left steps and R Right Steps (also arbitrary), create a general solution that will return the number of steps it would take to go from S to R if it is possible otherwise return not possible.
You are bound to the range [1, F] which means that you cannot move L or R steps if the next move will be more than F or less than 1
Example:
F = 100
S = 2
G = 1
L = 0
R = 1
Output: not possible
F = 10
S = 1
G = 10
L = 1
R = 2
Output: 6
Explanation: [1 -> 3(R) -> 5(R) -> 7(R) -> 9(R) -> 8(L) -> 10(R)]
I've been given this problem in our class and our current topic is binary search and divide and conquer. Here's my approach but this does not solve one hidden case.
F = int(input())
S = int(input())
G = int(input())
L = int(input())
R = int(input())
count = 0
while S != G:
dist = abs(S - G) # Takes the current distance from S to G
if S > G:
if S-L > 0:
S -= L
count += 1
else:
S += R
count += 1
else:
if S+R <= F:
S += R
count += 1
else:
S -= L
count += 1
if dist == abs(S - G): # If distance doesn't change after trying
print("not possible") # a move, conclude that it is not possible.
break
if S == G: print(count)
Mathematically this problem means that we are looking for
integer solutions (for x and y) of the following equation:
x * R - y * L = G - S
we can start by creating a function to check if there is a solution quickly:
def path(S, G, F, L, R):
x=0
while True:
y = (x * R - G + S) / L
if y>=0 and int(y)==y:
return(x,y)
else:
x+=1
This will work if there are solutions, but not if they are not.
It can be proved mathematically that there is no solution when L devides R but not G-S. Here is the proof:
If
R mod L =0 (L devides R)
(G - S)/L != 0 (L doesn't devide G-S)
then by deviding the whole equation (x * R - y * L = G - S) by L we take:
x * R/L - y = (G - S)/L <=>
y= (x * R/L) - (G - S)/L
Now, we want y mod 1 = 0 (means that y is integer) for x mod 1 =0 (x integers). Using common modulo operations we take:
y mod 1 = [(x * R/L) - (G - S)/L] mod 1 =
[(x * R/L) mod 1 - ((G - S)/L) mod 1] mod 1 =
[(x mod 1 * (R/L) mod 1) mod 1 - ((G - S)/L) mod 1] mod 1 =
[(x mod 1 * 0) mod 1 - ((G - S)/L) mod 1] mod 1 =
[((G - S)/L) mod 1] mod 1
This cannot be 0 if L doesn't devide G-S which eventally means that there are no pair of integers x,y that can satisfy the original condition.
Programatically this means for our code, the following additions:
def path(S, G, F, L, R):
if R%L==0 and (G-S)%L != 0 :
return 'No solutions'
x=0
while True:
y = (x * R - G + S) / L
if y>=0 and int(y)==y:
return(x,y)
else:
x+=1
I don;t know if mathematically we can prove that the above if is the only exception, it can probably be proved with some more modulo operations. Programatically we can add some clock in our code so that if there are no solutions, which means that it will go to infitive loop, we can return False after some time. Here is how we can do this:
How would I stop a while loop after n amount of time?
If the distance didn't change that doesn't mean it's impossible, you could have just jumped over the point and made it to the other side with the same distance, imagine L=2, R=1, S=3, G=2, you start distance 1 from goal, jump left (still distance 1) then jump right and win. What you need to check is whether you have gone in a loop and ended up at a location you have already tried before. You can either keep track of these locations (say in a set) or do some math ahead of time and figure out how many Ls and Rs it takes before you have definitely looped (probably not intended to figure this out).
F=int(input())
S=int(input())
G=int(input())
L=int(input())
R=int(input())
L*=-1
Fl=1-L
Fr=F-R
h0=set()
n=0
while True:
if S<G:
S+= R if S<=Fr else L
elif G<S:
S+= L if Fl<=S else R
else:
print(n)
break
if S in h0:
print('not possible')
break
h0.add(S)
n+=1
I want to solve for x (up to 6 decimal places) in the equation: n**x + x = 0. I want to do this using Binary Search.
I used the below code to get the square root of a positive integer, 'n'. Need to apply the same logic to solve the above problem somehow.
n=int(input())
#find square root of n here
def sqroot(n):
l = 0
r = n
while abs(l-r) > 10**(-5):
mid = (l+r)/2
if mid**2 > n:
r = mid
else:
l = mid
return round(mid,4)
print('%.4f' % sqroot(n))
The function seems to be monotonically increasing so binary search can be applied in the same way as for the square root.
In your function n was the target, now it is 0 and n is a parameter.
Note that this function seems to have a it's zero in the negative, so do not forget to extend the search space.
n = int(input())
def binarySearch(n):
# n is the parameter
l = -10
r = 10
while abs(l - r) > 10**(-5):
mid = (l + r) / 2
# Compute the value of the function and compare against 0.0
if (n**mid + mid) > 0.0:
r = mid
else:
l = mid
return round(mid, 4)
print('%.4f' % binarySearch(n))
n = int(input())
def binarySearch(n):
# n is the parameter
l = -10
r = 10
while abs(l - r) > 10**(-6):
mid = (l + r) / 2
# Compute the value of the function and compare against 0.0
if (n**mid + mid) > 0.0:
r = mid
else:
l = mid
return round(mid, 6)
print('%.6f' % binarySearch(n))