In numbers like 16, performing bitwise AND on all numbers from 1 to 15 gives result 0. I want to find out the first number that doesn't give 0 when bitwise AND is performed on it.
TLDR : Find smallest x such that x AND y ! = 0
y is given
You can do brute force approach:
while True:
y=int(input('y='))
x=1
while True:
if(x & y !=0):
print(x)
break
x*=2
The solution is to find the first bit from right, which is 1.
For example,
y = 16 = 0b10000
^
y = 12 = 0b1100
^
def get_x(y):
i = 0
while True:
if (y >> i) & 1 == 1:
break
i += 1
return 1 << i
This seems cleverer.
def get_x(y):
return y & (-y)
Find the lowest set bit
Related
from random import randrange
a = randrange(1, 9)
print (a)
if (a % 2) == 0:
y = a / 2
while True:
if (y % 2) == 0:
y = y / 2
print (y)
else:
b = (a * 3) + 1
while True:
if (b % 2) == 0:
b = b / 2
else:
b = (a * 3) + 1
print (b)
"I want to make a math problem solver in python that can find a random number
between 1 and 9. Then if it is odd so it multiply it with 3 and add 1 in it and if it
is even so it divide it by two and this process keep repeating. For example a number
computer choose is 7 so :
7*3 + 1 = 22
22/2 = 11
11*3 = 33
and so on.
It shouldn't stop until the answer is 0.Here is my code in which I tried but not sure where should I make it right?"
You have too many lines in there. You need to loop to stop repeating when the number becomes 1 (it will never become 0):
from random import randrange
a = randrange(1, 9)
while a != 1:
print(a)
if a % 2 == 0:
a = a // 2
else:
a = (a * 3) + 1
print(a)
You can use the following code to check for any number or any range of numbers. This code is created by using the recursive function approach.
def f(x): #creating a function
if x!=4:
a.append(x)
if x%2==0:
while x%2==0:
x=x/2
a.append(x)
x=3*x+1
f(x)
For checking a particular value, run this:
a=[]
f(2**100+1) #2 to the power 10, plus 1
a[-1]
For checking for a range of values, run this:
for i in range(1,100):
a=[]
f(i)
print(i, "gives output" ,a)
I call it impossible maths because never reaches zero, it just keeps on looping forever Collatz problem. But this function does that, it does not take any parameter.
import random as r
def impossible_math():
x = r.ran(1,9)
while x !=0:
if x%2 ==0:
x = x/2
print(x)
else:
x = (x*3)+1
print(x)
x = impossible_math()
Maybe it's too trivial question but I can't find answer if there is a some more elegant way to cast int value to 0 or 1 without using condition or type casting?
Now I have only following variants and both are ugly:
x = 5
a = some_int_value * (1 if x > 0 else 0)
b = some_int_value * int(bool(x))
ADDED
x is a non-negative value.
To paraphrase your condition, x can be 0 or a value larger than 0. If x > 0, you want to use the value some_int_value, otherwise you want 0 (which is identical to x). Then do:
c = x and some_int_value
If x is 0, i.e. falsey, the and expression returns x. If x is truthy (non-zero), it returns some_int_value.
Arguably even more comprehensible would be:
d = some_int_value if x > 0 else 0
Or:
e = 0
if x > 0:
e = some_int_value
Another way without functions, casting, or conditionals, but with comparisons:
d = some_int_value * (x > 0)
However, in terms of readability, a ternary ... if ... else ... should probably be preferred.
If you want a purely mathematical way, you can use exponentiation with 1 - 0x, since 0**x is 1 only if x == 0 and 0 otherwise. But whether that is in any way clear is another question. (Also note that this gives a division-by-zero for x < 0, but you said that you don't have those.)
>>> x = 5
>>> 1 - 0**x
1
>>> x = 0
>>> 1 - 0**x
0
I'm new to programming and i'm doing the Project Euler challenges to give me a reason to learn.
Find below my very simple python code
x = 1
thirdDivide = 0
fifthDivide=0
total = 0
print('Enter the max value')
maxValue = input()
while (x != maxValue):
thirdDivide = x / 3
fifthDivide = x / 5
if (thirdDivide).is_integer():
total = total + x
x = x + 1
elif (fifthDivide).is_integer():
total = total + x
x = x + 1
print ("The sum of the multiples of 3 and 5 between 0 and " + maxValue + " is " + total)
When I run it it asks for my max value, then ceases doing anything.
Thanks!
Assuming you are in Python 3, the fixes for using strings instead of floats, or floats instead of strings, infite loop is following:
x = 1
thirdDivide = 0
fifthDivide=0
total = 0
maxValue = float(input('Enter the max value: '))
while (x != maxValue):
thirdDivide = x / 3
fifthDivide = x / 5
if (thirdDivide).is_integer():
total = total + x
elif (fifthDivide).is_integer():
total = total + x
x = x + 1
print("The sum of the multiples of 3 and 5 between 0 and " + str(maxValue) + " is " + str(total))
Note, I dont check for correctness of your algoritm and whether it calculates what it is supposed to do. But now it produces some results and compiles.
You can solve it with a functional approach using filter and reduce:
def f(acc, v): return acc + v
def g(x): return x % 3 == 0 or x % 5 == 0
print reduce(f, filter(g, range(1000)))
How it works:
filter: takes two arguments:
The first is a function g applied for every element of range(1000). g takes one argument x and check if is multiple of 3 or 5 (checking the remainder of the modulo operation %).
The second is the range from 0 to 1000.
reduce: takes two arguments:
The first is a function f that takes two arguments: an accumulator acc and a variable v that represents the current element in the list.
The second argument is the filtered range returned before by filter.
Output:
with range(10) = 23
with range(1000) = 233168
Using lambda functions (same logic just different syntax):
print reduce(lambda acc, v: acc + v, filter(lambda x: x % 3 == 0 or x % 5 == 0, range(1000)))
You only increment x if thirdDivide.is_integer() or fifthDivide.is_integer() are true. So if neither it true, you'll just loop infinitely on the same value of x.
If neither thirdDivide nor fifthDivide is an integer, x is never updated -- you enter an infinite loop. You need to make sure you have a "base case" so that the iteration variable is always changing. Here's a slightly cleaner algorithm:
total = 0
for i in range(0, x):
if i % 3 == 0 or i % 5 == 0:
total += i
I think you'll find that for most iteration, for loops are easier to reason about. Happy coding!
As many said before, you are stuck in an infinite loop with x not being incremented. If you added a "else" statement at the end and printed the output you could see what they are talking about. You can do this in one line of code.
print(sum(x for x in range(maxValue) if x % 3 == 0 or x % 5 == 0))
from math import *
def prime():
a = 0
b = 0
x = 2*a+1
y = b
for a in range (1,5000) and b in range (0,5000) and y<x :
ctr = 0
if (x % y == 0):
ctr += 1
return [None]
else:
primes = (x)
ctr+= 1
return [None]
print (primes[999]);
I have a problem I need to solve but when it gets to the modulo ( %) sign it says TypeError: 'bool' object is not iterable"
Instead of comparing the values, you are assigning 0 to x % y, which is not possible. You can fix it like this
if (x % y == 0):
After fixing that,
for a in range (1,5000) and b in range (0,5000) and y<x :
this line will not work, you have to split the loops like this
for a in range (1,5000):
for b in range (0,5000):
...
...
The modulo sign is fine, note the ^ in the error message.
File "so-modulo-test.py", line 11
if (x % y = 0):
^
SyntaxError: invalid syntax
= indicates an assignment statement. You want ==, the equal comparison operator, as in
if x % y == 0:
Additionally, and is the logical AND, and not to be confused with how a human would talk. Your loop should look like:
for a in range (1,5000):
for b in range (0, x):
...
for given x < 10^15, quickly and accurately determine the maximum integer p such that 2^p <= x
Here are some things I've tried:
First I tried this but it's not accurate for large numbers:
>>> from math import log
>>> x = 2**3
>>> x
8
>>> p = int(log(x, 2))
>>> 2**p == x
True
>>> x = 2**50
>>> p = int(log(x, 2))
>>> 2**p == x #not accurate for large numbers?
False
I could try something like:
p = 1
i = 1
while True:
if i * 2 > n:
break
i *= 2
p += 1
not_p = n - p
Which would take up to 50 operations if p was 50
I could pre-compute all the powers of 2 up until 2^50, and use binary search to find p. This would take around log(50) operations but seems a bit excessive and ugly?
I found this thread for C based solutions: Compute fast log base 2 ceiling
However It seems a bit ugly and I wasn't exactly sure how to convert it to python.
In Python >= 2.7, you can use the .bit_length() method of integers:
def brute(x):
# determine max p such that 2^p <= x
p = 0
while 2**p <= x:
p += 1
return p-1
def easy(x):
return x.bit_length() - 1
which gives
>>> brute(0), brute(2**3-1), brute(2**3)
(-1, 2, 3)
>>> easy(0), easy(2**3-1), easy(2**3)
(-1, 2, 3)
>>> brute(2**50-1), brute(2**50), brute(2**50+1)
(49, 50, 50)
>>> easy(2**50-1), easy(2**50), easy(2**50+1)
(49, 50, 50)
>>>
>>> all(brute(n) == easy(n) for n in range(10**6))
True
>>> nums = (max(2**x+d, 0) for x in range(200) for d in range(-50, 50))
>>> all(brute(n) == easy(n) for n in nums)
True
You specify in comments your x is an integer, but for anyone coming here where their x is already a float, then math.frexp() would be pretty fast at extracting log base 2:
log2_slow = int(floor(log(x, 2)))
log2_fast = frexp(x)[1]-1
The C function that frexp() calls just grabs and tweaks the exponent. Some more 'splainin:
The subscript[1] is because frexp() returns a tuple (significand, exponent).
The subtract-1 accounts for the significand being in the range [0.5,1.0). For example 250 is stored as 0.5x251.
The floor() is because you specified 2^p <= x, so p == floor(log(x,2)).
(Derived from another answer.)
Be careful! The accepted answer returns floor(log(n, 2)), NOT ceil(log(n, 2)) like the title of the question implies!
If you came here for a clog2 implementation, do this:
def clog2(x):
"""Ceiling of log2"""
if x <= 0:
raise ValueError("domain error")
return (x-1).bit_length()
And for completeness:
def flog2(x):
"""Floor of log2"""
if x <= 0:
raise ValueError("domain error")
return x.bit_length() - 1
You could try the log2 function from numpy, which appears to work for powers up to 2^62:
>>> 2**np.log2(2**50) == 2**50
True
>>> 2**np.log2(2**62) == 2**62
True
Above that (at least for me) it fails due to the limtiations of numpy's internal number types, but that will handle data in the range you say you're dealing with.
Works for me, Python 2.6.5 (CPython) on OSX 10.7:
>>> x = 2**50
>>> x
1125899906842624L
>>> p = int(log(x,2))
>>> p
50
>>> 2**p == x
True
It continues to work at least for exponents up to 1e9, by which time it starts to take quite a while to do the math. What are you actually getting for x and p in your test? What version of Python, on what OS, are you running?
With respect to "not accurate for large numbers" your challenge here is that the floating point representation is indeed not as precise as you need it to be (49.999999999993 != 50.0). A great reference is "What Every Computer Scientist Should Know About Floating-Point Arithmetic."
The good news is that the transformation of the C routine is very straightforward:
def getpos(value):
if (value == 0):
return -1
pos = 0
if (value & (value - 1)):
pos = 1
if (value & 0xFFFFFFFF00000000):
pos += 32
value = value >> 32
if (value & 0x00000000FFFF0000):
pos += 16
value = value >> 16
if (value & 0x000000000000FF00):
pos += 8
value = value >> 8
if (value & 0x00000000000000F0):
pos += 4
value = value >> 4
if (value & 0x000000000000000C):
pos += 2
value = value >> 2
if (value & 0x0000000000000002):
pos += 1
value = value >> 1
return pos
Another alternative is that you could round to the nearest integer, instead of truncating:
log(x,2)
=> 49.999999999999993
round(log(x,2),1)
=> 50.0
I needed to calculate the upper bound power of two (to figure out how many bytes of entropy was needed to generate a random number in a given range using the modulus operator).
From a rough experiment I think the calculation below gives the minimum integer p such that val < 2^p
It's probably about as fast as you can get, and uses exclusively bitwise integer arithmetic.
def log2_approx(val):
from math import floor
val = floor(val)
approx = 0
while val != 0:
val &= ~ (1<<approx)
approx += 1
return approx
Your slightly different value would be calculated for a given n by
log2_approx(n) - 1
...maybe. But in any case, the bitwise arithmetic could give you a clue how to do this fast.