It's theoretical question.
exercise from leetcode as basis.
My solution for task is binary search. But question is not about it.
I found perfect solution on Discuss tab.
(next code has been taken from there)
class Solution:
def mySqrt(self, x: int) -> int:
low, high= 1, x
while low<high:
high = (low + high) // 2
low = x // high
return high
It works perfect. My question is:
For regular binary search we take middle of sequence and depending of comparison result remove excessive part (left or right) next repeat till result.
What is this implementation based on?
This solution cut part of sequence right after middle and small part from start.
This code isn't based on binary search. It's based instead on adapting the ancient "Babylonian method" to integer arithmetic. That in turn can be viewed as anticipating an instance of Newton's more-general method for finding a root of an equation.
Keeping distinct low and high variables isn't important in this code. For example, it's more commonly coded along these lines:
def intsqrt(n):
guess = n # must be >= true floor(sqrt(n))
while True:
newguess = (guess + (n // guess)) // 2
if guess <= newguess:
return guess
guess = newguess
but with more care taken to find a better initial guess.
BTW, binary search increases the number of "good bits" by 1 per iteration. This method approximately doubles the number of "good bits" per iteration, so is much more efficient the closer the guess gets to the final result.
This method is subtle, though was known of the Babylonians (see Tim's answer).
Assume that h > √x. Then
l = x/h < √x and
(l+h)/2 > √x.
The first property is obvious. For the second, observe that 1. and 2. imply
x+h² > 2h√x or (h-√x)^2 > 0, which is true.
So h remains above √x, but it gets closer and closer (because (l+h)/2 < h). And when the computation is made with integers, there is a moment such that l≥h.
How was this method discovered ?
Assume that you have an approximation h of √x and we want to improve it, with a correction δ. We write x = (h-δ)² = h²-2hδ + δ² = x. If we neglect δ², then we draw h-δ = (h²+x)/2h = (h+x/h)/2, which is our (h+l)/2.
I have a function (we can call it f(x)), that will give me a number.
The value of x is between 0 and 1: f(0) will find the biggest number, f(1), the smallest.
But I don't know if, for example, f(0.2) will give me a different number from f(0); so I have to do a research to find all the number using binary search.
I know that I can iterate from x = 0 to x = 1, but I want to do less function call possible.
Have you any suggest?
I can start by calling f(0), f(1), f(0.5), and then f(0.25) or f(0.75) and so on and so on.
(Mathematically I can divide x endlessly, here I can choose a precision limit)
First you must be sure that the function is monotone. If this is not sure you cannot use a binary search.
Secondly define the accuracy you want.
Than perform the binary search until no improvement is made or the desired accuracy is reached.
Alrighty, first post here, so please forgive and ignore if the question is not workable;
Background:
I'm in computer science 160. I haven't taken any computer related classes since high school, so joining this class was a big shift for me. It all seemed very advanced. We have been working in Python and each week we are prompted to write a program.
I have been working with this problem for over a week and am having a hard time even starting.
The prompt is to read an integer containing only 1's and 0's,
process the binary number digit by digit and report the decimal equivalent. Now, I have gotten some tips from a classmate and it sent me at least in a direction.
Set up a couple of counters;
using the % operator to check the remainder of the number divided by 2, and slicing off the last number (to the right) to move on to and process the next digit.
I am having an incredibly hard time wrapping my head around what formula to use on the binary digits themselves which will convert the number to decimal.
setbitval = 0
counter = 0
user = int(input("enter a binary value. "))
if user % 2 == 1:
user = (user/10) - .1
setbitval += 1
This is all I've got so far.. My thinking is getting in the way. I've searched and searched, even through these forums.
Any information or thoughts are extremely appreciated,
T
Edit: okay guys, everyone's help has been extremely useful but I'm having a problem checking if the user input is not a binary number.
for i in reversed(bits):
decimal += 2**counter * int(i)
counter += 1
This is the formula someone here gave me and I've been trying different iterations of "for i in bits: if i in bits: != 0 or 1" and also "if i in bits: >= 1 or <=0".
Any thoughts?
you can use this code:
binary= raw_input("Binary: ")
d= int(binary, 2)
print d
To convert binary value to decimal you need to do the following:
Take the least significant bit and multiply it by 2^0, then take the next least significant beat and multiply it by 2^1, next one by 2^2 and so on...
Let's say, for example you need to convert a number 1010 to decimal:
You would have 0*2^0 + 1*2^1 + 0*2^2 + 1*2^3 = 0 + 2 + 0 + 8 = 10
So in your python code, you need to:
read the int that the user inputted (representing the binary value).
convert that int and convert it to string, so you can break it into list of digits
make a list of digits from the string you created (a list int python can be created from a string not an int, that's why you need the conversion to string first)
go trough that list of bits in reverse and multiply every bit by 2^k, k being the counter starting from 0
Here's the code that demonstrates what I just tried to explain:
user_input = int(input("enter a binary value"))
bits = list(str(user_input))
decimal = 0
counter = 0
for i in reversed(bits):
decimal += 2**counter * int(i)
counter+=1
print 'The decimal value is: ', decimal
I'll agree this is close to the "code this for me" territory, but I'll try to answer in a way that gets you on the right track, instead of just posting a working code snippet.
A simple way of doing this is just to use int()'s base argument, but I'm guessing that is disallowed.
You already have a way of testing the current bit in your question, namely checking whether n % 2 == 1. If this is the case, we need to add a power of two.
Then, we need some way of going to the next bit. In binary, we would use bit shifts, but sadly, we don't have those. a >> b is equivalent to a // (2**b) - can you write a decimal equivalent to that?
You also need to keep a counter of which power of two the current bit represents, a loop, and some way of detecting an end condition. Those are left as exercises to the reader.
I’d recommend reading the following articles on Wikipedia:
https://en.wikipedia.org/wiki/Radix
https://en.wikipedia.org/wiki/Binary_number
The first one gives you an idea how the numeral systems work in general and the second one explains and shows the formula to convert between binary and decimal systems.
Try to implement the solution after reading this. That’s what I did when I dealt with this problem. If that doesn’t help, let me know and I’ll post the code.
Hopefully, this code clarifies things a bit.
x = input("Enter binary number: ").strip()
decimal = 0
for i in range(len(x)):
decimal += int(x[i]) * 2**abs((i - (len(x) - 1)))
print(decimal)
This code takes in a binary number as a string, converts it to a decimal number and outputs it as an integer. The procedure is the following:
1st element of binary number * 2^(length of binary number - 1)
2nd element of binary number * 2^(length of binary number - 2)
and so on till we get to the last element and ...2^0
If we take number 10011, the conversion using this formula will look like this:
1*2^4 + 0*2^3 + 0*2^2 + 1*2^1 + 1*2^0, which equals to 19.
This code, however, assumes that the binary number is valid. Let me know if it helps.
Another implementation using while loop might look like this. Maybe it'll be easier to understand than the code with the for loop.
x = input("Enter binary number: ").strip()
decimal = 0
index = 0
exp = len(x) - 1
while index != len(x):
decimal += int(x[index]) * 2**exp
index += 1
exp -= 1
print(decimal)
In this one we start from the beginning of the number with the highest power, which is length of binary number minus one, we loop through the number, lowering the power and changing index.
Regarding checking if number is binary.
Try using helper function to determine if number is binary and then insert this function inside your main function. For example:
def is_binary(x):
""" Returns True if number x is binary and False otherwise.
input: x as a string
"""
for i in list(x):
if i not in ["1", "0"]:
return False
return True
def binary_decimal(x):
""" Converts binary to decimal.
input: binary number x as a string
output: decimal number as int
"""
if not is_binary(x):
return "Number is invalid"
decimal = 0
for i in range(len(x)):
decimal += int(x[i]) * 2**abs((i - (len(x) - 1)))
return decimal
The first function checks if number consists only of ones and zeros and the second function actually converts your number only if it's binary according to the first function.
You can also try using assert statement or try / except if you'd better raise an error if number is not binary instead of simply printing the message.
Of course, you can implement this solution without any functions.
Lately I've been solving some challenges from Google Foobar for fun, and now I've been stuck in one of them for more than 4 days. It is about a recursive function defined as follows:
R(0) = 1
R(1) = 1
R(2) = 2
R(2n) = R(n) + R(n + 1) + n (for n > 1)
R(2n + 1) = R(n - 1) + R(n) + 1 (for n >= 1)
The challenge is writing a function answer(str_S) where str_S is a base-10 string representation of an integer S, which returns the largest n such that R(n) = S. If there is no such n, return "None". Also, S will be a positive integer no greater than 10^25.
I have investigated a lot about recursive functions and about solving recurrence relations, but with no luck. I outputted the first 500 numbers and I found no relation with each one whatsoever. I used the following code, which uses recursion, so it gets really slow when numbers start getting big.
def getNumberOfZombits(time):
if time == 0 or time == 1:
return 1
elif time == 2:
return 2
else:
if time % 2 == 0:
newTime = time/2
return getNumberOfZombits(newTime) + getNumberOfZombits(newTime+1) + newTime
else:
newTime = time/2 # integer, so rounds down
return getNumberOfZombits(newTime-1) + getNumberOfZombits(newTime) + 1
The challenge also included some test cases so, here they are:
Test cases
==========
Inputs:
(string) str_S = "7"
Output:
(string) "4"
Inputs:
(string) str_S = "100"
Output:
(string) "None"
I don't know if I need to solve the recurrence relation to anything simpler, but as there is one for even and one for odd numbers, I find it really hard to do (I haven't learned about it in school yet, so everything I know about this subject is from internet articles).
So, any help at all guiding me to finish this challenge will be welcome :)
Instead of trying to simplify this function mathematically, I simplified the algorithm in Python. As suggested by #LambdaFairy, I implemented memoization in the getNumberOfZombits(time) function. This optimization sped up the function a lot.
Then, I passed to the next step, of trying to see what was the input to that number of rabbits. I had analyzed the function before, by watching its plot, and I knew the even numbers got higher outputs first and only after some time the odd numbers got to the same level. As we want the highest input for that output, I first needed to search in the even numbers and then in the odd numbers.
As you can see, the odd numbers take always more time than the even to reach the same output.
The problem is that we could not search for the numbers increasing 1 each time (it was too slow). What I did to solve that was to implement a binary search-like algorithm. First, I would search the even numbers (with the binary search like algorithm) until I found one answer or I had no more numbers to search. Then, I did the same to the odd numbers (again, with the binary search like algorithm) and if an answer was found, I replaced whatever I had before with it (as it was necessarily bigger than the previous answer).
I have the source code I used to solve this, so if anyone needs it I don't mind sharing it :)
The key to solving this puzzle was using a binary search.
As you can see from the sequence generators, they rely on a roughly n/2 recursion, so calculating R(N) takes about 2*log2(N) recursive calls; and of course you need to do it for both the odd and the even.
Thats not too bad, but you need to figure out where to search for the N which will give you the input. To do this, I first implemented a search for upper and lower bounds for N. I walked up N by powers of 2, until I had N and 2N that formed the lower and upper bounds respectively for each sequence (odd and even).
With these bounds, I could then do a binary search between them to quickly find the value of N, or its non-existence.
How can I increment a floating point value in python by the smallest possible amount?
Background: I'm using floating point values as dictionary keys.
Occasionally, very occasionally (and perhaps never, but not certainly never), there will be collisions. I would like to resolve these by incrementing the floating point value by as small an amount as possible. How can I do this?
In C, I would twiddle the bits of the mantissa to achieve this, but I assume that isn't possible in Python.
Since Python 3.9 there is math.nextafter in the stdlib. Read on for alternatives in older Python versions.
Increment a python floating point value by the smallest possible amount
The nextafter(x,y) functions return the next discretely different representable floating-point value following x in the direction of y. The nextafter() functions are guaranteed to work on the platform or to return a sensible value to indicate that the next value is not possible.
The nextafter() functions are part of POSIX and ISO C99 standards and is _nextafter() in Visual C. C99 compliant standard math libraries, Visual C, C++, Boost and Java all implement the IEEE recommended nextafter() functions or methods. (I do not honestly know if .NET has nextafter(). Microsoft does not care much about C99 or POSIX.)
None of the bit twiddling functions here fully or correctly deal with the edge cases, such as values going though 0.0, negative 0.0, subnormals, infinities, negative values, over or underflows, etc. Here is a reference implementation of nextafter() in C to give an idea of how to do the correct bit twiddling if that is your direction.
There are two solid work arounds to get nextafter() or other excluded POSIX math functions in Python < 3.9:
Use Numpy:
>>> import numpy
>>> numpy.nextafter(0,1)
4.9406564584124654e-324
>>> numpy.nextafter(.1, 1)
0.10000000000000002
>>> numpy.nextafter(1e6, -1)
999999.99999999988
>>> numpy.nextafter(-.1, 1)
-0.099999999999999992
Link directly to the system math DLL:
import ctypes
import sys
from sys import platform as _platform
if _platform == "linux" or _platform == "linux2":
_libm = ctypes.cdll.LoadLibrary('libm.so.6')
_funcname = 'nextafter'
elif _platform == "darwin":
_libm = ctypes.cdll.LoadLibrary('libSystem.dylib')
_funcname = 'nextafter'
elif _platform == "win32":
_libm = ctypes.cdll.LoadLibrary('msvcrt.dll')
_funcname = '_nextafter'
else:
# these are the ones I have access to...
# fill in library and function name for your system math dll
print("Platform", repr(_platform), "is not supported")
sys.exit(0)
_nextafter = getattr(_libm, _funcname)
_nextafter.restype = ctypes.c_double
_nextafter.argtypes = [ctypes.c_double, ctypes.c_double]
def nextafter(x, y):
"Returns the next floating-point number after x in the direction of y."
return _nextafter(x, y)
assert nextafter(0, 1) - nextafter(0, 1) == 0
assert 0.0 + nextafter(0, 1) > 0.0
And if you really really want a pure Python solution:
# handles edge cases correctly on MY computer
# not extensively QA'd...
import math
# 'double' means IEEE 754 double precision -- c 'double'
epsilon = math.ldexp(1.0, -53) # smallest double that 0.5+epsilon != 0.5
maxDouble = float(2**1024 - 2**971) # From the IEEE 754 standard
minDouble = math.ldexp(1.0, -1022) # min positive normalized double
smallEpsilon = math.ldexp(1.0, -1074) # smallest increment for doubles < minFloat
infinity = math.ldexp(1.0, 1023) * 2
def nextafter(x,y):
"""returns the next IEEE double after x in the direction of y if possible"""
if y==x:
return y #if x==y, no increment
# handle NaN
if x!=x or y!=y:
return x + y
if x >= infinity:
return infinity
if x <= -infinity:
return -infinity
if -minDouble < x < minDouble:
if y > x:
return x + smallEpsilon
else:
return x - smallEpsilon
m, e = math.frexp(x)
if y > x:
m += epsilon
else:
m -= epsilon
return math.ldexp(m,e)
Or, use Mark Dickinson's excellent solution
Obviously the Numpy solution is the easiest.
Python 3.9 and above
Starting with Python 3.9, released 2020-10-05, you can use the math.nextafter function:
math.nextafter(x, y)
Return the next floating-point value after x towards y.
If x is equal to y, return y.
Examples:
math.nextafter(x, math.inf) goes up: towards positive infinity.
math.nextafter(x, -math.inf) goes down: towards minus infinity.
math.nextafter(x, 0.0) goes towards zero.
math.nextafter(x, math.copysign(math.inf, x)) goes away from zero.
See also math.ulp().
First, this "respond to a collision" is a pretty bad idea.
If they collide, the values in the dictionary should have been lists of items with a common key, not individual items.
Your "hash probing" algorithm will have to loop through more than one "tiny increments" to resolve collisions.
And sequential hash probes are known to be inefficient.
Read this: http://en.wikipedia.org/wiki/Quadratic_probing
Second, use math.frexp and sys.float_info.epsilon to fiddle with mantissa and exponent separately.
>>> m, e = math.frexp(4.0)
>>> (m+sys.float_info.epsilon)*2**e
4.0000000000000018
Forgetting about why we would want to increment a floating point value for a moment, I would have to say I think Autopulated's own answer is probably correct.
But for the problem domain, I share the misgivings of most of the responders to the idea of using floats as dictionary keys. If the objection to using Decimal (as proposed in the main comments) is that it is a "heavyweight" solution, I suggest a do-it-yourself compromise: Figure out what the practical resolution is on the timestamps, pick a number of digits to adequately cover it, then multiply all the timestamps by the necessary amount so that you can use integers as the keys. If you can afford an extra digit or two beyond the timer precision, then you can be even more confident that there will be no or fewer collisions, and that if there are collisions, you can just add 1 (instead of some rigamarole to find the next floating point value).
I recommend against assuming that floats (or timestamps) will be unique if at all possible. Use a counting iterator, database sequence or other service to issue unique identifiers.
Instead of incrementing the value, just use a tuple for the colliding key. If you need to keep them in order, every key should be a tuple, not just the duplicates.
A better answer (now I'm just doing this for fun...), motivated by twiddling the bits. Handling the carry and overflows between parts of the number of negative values is somewhat tricky.
import struct
def floatToieee754Bits(f):
return struct.unpack('<Q', struct.pack('<d', f))[0]
def ieee754BitsToFloat(i):
return struct.unpack('<d', struct.pack('<Q', i))[0]
def incrementFloat(f):
i = floatToieee754Bits(f)
if f >= 0:
return ieee754BitsToFloat(i+1)
else:
raise Exception('f not >= 0: unsolved problem!')
Instead of resolving the collisions by changing the key, how about collecting the collisions? IE:
bag = {}
bag[1234.] = 'something'
becomes
bag = collections.defaultdict(list)
bag[1234.].append('something')
would that work?
For colliding key k, add: k / 250
Interesting problem. The amount you need to add obviously depends on the magnitude of the colliding value, so that a normalized add will affect only the least significant bits.
It's not necessary to determine the smallest value that can be added. All you need to do is approximate it. The FPU format provides 52 mantissa bits plus a hidden bit for 53 bits of precision. No physical constant is known to anywhere near this level of precision. No sensor is able measure anything near it. So you don't have a hard problem.
In most cases, for key k, you would be able to add k/253, because of that 52-bit fraction plus the hidden bit.
But it's not necessary to risk triggering library bugs or exploring rounding issues by shooting for the very last bit or anything near it.
So I would say, for colliding key k, just add k / 250 and call it a day.1
1. Possibly more than once until it doesn't collide any more, at least to foil any diabolical unit test authors.
import sys
>>> sys.float_info.epsilon
2.220446049250313e-16
Instead of modifying your float timestamp, use a tuple for every key as Mark Ransom suggests where the tuple (x,y) is composed of x=your_unmodified_time_stamp and y=(extremely unlikely to be a same value twice).
So:
x just is the unmodified timestamp and can be the same value many times;
y you can use:
a random integer number from a large range,
serial integer (0,1,2,etc),
UUID.
While 2.1 (random int from a large range) there works great for ethernet, I would use 2.2 (serializer) or 2.3 (UUID). Easy, fast, bulletproof. For 2.2 and 2.3 you don't even need collision detection (you might want to still have it for 2.1 as ethernet does.)
The advantage of 2.2 is that you can also tell, and sort, data elements that have the same float time stamp.
Then just extract x from the tuple for any sorting type operations and the tuple itself is a collision free key for the hash / dictionary.
Edit
I guess example code will help:
#!/usr/bin/env python
import time
import sys
import random
#generator for ints from 0 to maxinteger on system:
serializer=(sn for sn in xrange(0,sys.maxint))
#a list with guranteed collisions:
times=[]
for c in range(0,35):
t=time.clock()
for i in range(0,random.choice(range(0,4))):
times.append(t)
print len(set(times)), "unique items in a list of",len(times)
#dictionary of tuples; no possibilities of collisions:
di={}
for time in times:
sn=serializer.next()
di[(time,sn)]='Element {}'.format(sn)
#for tuples of multiple numbers, Python sorts
# as you expect: first by t[0] then t[1], until t[n]
for key in sorted(di.keys()):
print "{:>15}:{}".format(key, di[key])
Output:
26 unique items in a list of 55
(0.042289, 0):Element 0
(0.042289, 1):Element 1
(0.042289, 2):Element 2
(0.042305, 3):Element 3
(0.042305, 4):Element 4
(0.042317, 5):Element 5
# and so on until Element n...
Here it part of it. This is dirty and slow, but maybe that is how you like it. It is missing several corner cases, but maybe this gets someone else close.
The idea is to get the hex string of a floating point number. That gives you a string with the mantissa and exponent bits to twiddle. The twiddling is a pain since you have to do all it manually and keep converting to/from strings. Anyway, you add(subtract) 1 to(from) the last digit for positive(negative) numbers. Make sure you carry through to the exponent if you overflow. Negative numbers are a little more tricky to make you don't waste any bits.
def increment(f):
h = f.hex()
# decide if we need to increment up or down
if f > 0:
sign = '+'
inc = 1
else:
sign = '-'
inc = -1
# pull the string apart
h = h.split('0x')[-1]
h,e = h.split('p')
h = ''.join(h.split('.'))
h2 = shift(h, inc)
# increase the exponent if we added a digit
h2 = '%s0x%s.%sp%s' % (sign, h2[0], h2[1:], e)
return float.fromhex(h2)
def shift(s, num):
if not s:
return ''
right = s[-1]
right = int(right, 16) + num
if right > 15:
num = right // 16
right = right%16
elif right < 0:
right = 0
num = -1
else:
num = 0
# drop the leading 0x
right = hex(right)[2:]
return shift(s[:-1], num) + right
a = 1.4e4
print increment(a) - a
a = -1.4e4
print increment(a) - a
a = 1.4
print increment(a) - a
I think you mean "by as small an amount possible to avoid a hash collision", since for example the next-highest-float may already be a key! =)
while toInsert.key in myDict: # assumed to be positive
toInsert.key *= 1.000000000001
myDict[toInsert.key] = toInsert
That said you probably don't want to be using timestamps as keys.
After Looking at Autopopulated's answer I came up with a slightly different answer:
import math, sys
def incrementFloatValue(value):
if value == 0:
return sys.float_info.min
mant, exponent = math.frexp(value)
epsilonAtValue = math.ldexp(1, exponent - sys.float_info.mant_dig)
return math.fsum([value, epsilonAtValue])
Disclaimer: I'm really not as great at maths as I think I am ;) Please verify this is correct before using it. Also I'm not sure about performance
some notes:
epsilonAtValue calculates how many bits are used for the mantissa (the maximum minus what is used for the exponent).
I'm not sure if the math.fsum() is needed but hey it doesn't seem to hurt.
It turns out that this is actually quite complicated (maybe why seven people have answered without actually providing an answer yet...).
I think this is the right solution, it certainly seems to handle 0 and positive values correctly:
import math
import sys
def incrementFloat(f):
if f == 0.0:
return sys.float_info.min
m, e = math.frexp(f)
return math.ldexp(m + sys.float_info.epsilon / 2, e)