I'm trying to create a function that receives a number as an argument and performs actions on that number to find out its closest powers of 2 that will then add up to that number. For example, if the user enters 4, the function will append 4 because it is already a power of 2. If the user enters a 14 the function should see that 14 is not a power of 2 and the closest powers of 2 that make up 14 are 2,4, and 8.
Key notes: I am only going up to 2^9.
What i have so far:
def powers_finder(n):
powers=[]
i=0
total=0
while i<10:
value=2**i
total=total+value
i=i+1
#This if statement is for if the user enters a power of 2 as n
#Then the number will be appended right away into my powers list.
if value==n:
powers.append(value)
The problem here being if the user enters in lets say 5 as (n) 5 is made up of the power 2^2=4 and 2^0=1 4+1=5. How can i extend my function to include this process?
thank you!
The best and fastest way to do this is, of course, with binary numbers, but here's a way with a generator:
We have some nice answers for this question now. I figured I'd analyze them a bit with
dis
andtimeit
.Here is the test code I used:
And here are the results:
From the
timeit
results, we can see that @nullptr's solution is quite nice, as I suspected, followed by @moose's solution. After that came my combination of @moose's and @gbriones.gdl's solutions, followed very closely by @gbriones.gdl's solution. My generator solution was, shall we say, very suboptimal, but I kind of expected that.dis
results are included for completeness.One simple (but really not effective) way of doing this is to use backtracking. Note that the closest power of two is easily founded by using
math.log
function (The closest power of two of n is2^round(log(n, 2))
):Output:
Try with binaries:
Rather than solve the problem, how about some information to help you solve it? Take a look at a few examples, and solve them. Here are a few,
Suppose N=2, then the answer is = {2=2^1}.
Suppose N=3, then the answer is = {2=2^1,1=2^0} (note that 2**0=1)
Suppose N=4, then the answer is = {4=2^2}
...
Suppose N=63, then the answer is = {32=2^5, 16=2^4, 8=2^3, 4=2^2, 2=2^1, 1=2^0}
Suppose N=64, then the answer is = {64=2^6}
...
Suppose N=259, then the answer is = {256=2^8, 2=2^1, 1=2^0}
Do you see the pattern?
Want an algorithm?
Think about these simple steps, and combine them together in a loop,
Can you check if the number is odd? When the number is odd, then you have detected a bit 'on'. Subtract one (make the number even).
Can you divide by 2? What do you do with the result?
The idea is to convert the number to binary and then get powers of two from the binary representation: