Multiple of 4 using XOR (Python) - python

To check whether a number is a multiple of 4 or not without using +, -, * ,/ and % operators.
def multipleFour(n):
if n == 1:
return False
XOR = 0
for i in range(n):
XOR = XOR ^ 1
return XOR == n
multipleFour(20)
My answer returns False

You are mistaken in your for loop as well as xor statement. It should be like -
def multipleFour(n):
if n == 1:
return False
XOR = 0
for i in range(1, n+1):
XOR = XOR ^ i
return XOR == n
multipleFour(20)
i.e. your loop must run for i=1 to i=n and not i=0 to i=n-1. And it must be xor = xor ^ i
EDIT:
As pointed out in comments, for i in range(1, n+1) does not meet the condition of not using +, but by little modification, this thing can be solved as -
def multipleFour(n):
if n == 1:
return False
XOR = n
for i in range(1, n):
XOR = XOR ^ i
return XOR == n
multipleFour(20)

Your XOR starts with 0, and the only operation you ever employ on it is XOR ^ 1; the result can only ever be 0 or 1. Your code explicitly returns False on 1, and can't return True on any larger number; it should only return True for 0.
Meanwhile, it is very easy to check whether something is multiple of 4 "without using +, -, * ,/ and % operators.", using AND and NOT:
def multipleFour(n):
return not(n & 3)

You could check the binary and avoid xoring all integers from 0 to n:
0 0000
1 0001
2 0010
3 0011
4 0100 8 1000 12 1100
The binary signature of a multiple of four is '00'
def x_of_4(n):
return bin(n)[-2:] == '00'
However, although converting to a string makes it easy to visualize and understand, it is not the best of ideas, and this method fails for n = 0.
A better way to do the same is to bitwise-and-with 3 which will test the final two zeros of the binary representation (credits to #ShadowRanger in the comments:
def x_of_4(n):
return not n & 3

Related

Why are the zeros necessary in this code? What purpose do they serve? [duplicate]

I need to test whether each number from 1 to 1000 is a multiple of 3 or a multiple of 5.
I tried this code in Python 2.x:
n = 0
s = 0
while (n < 1001):
x = n/3
if isinstance(x, (int, long)):
print 'Multiple of 3!'
s = s + n
if False:
y = n/5
if isinstance(y, (int, long)):
s = s + n
print 'Number: '
print n
print 'Sum:'
print s
n = n + 1
The idea is to try dividing the number and see if the result is an integer. However, I'm not getting the expected result.
How do I test whether the number is an integer?
In 2.x, division like this will produce an integer, discarding the remainder; see How can I force division to be floating point? Division keeps rounding down to 0? for details.
In 3.x, the division will produce a floating-point value; the result is not "an integer" even if it is a whole number, so the isinstance check will fail. See Why does integer division yield a float instead of another integer? for details.
If you need the remainder from integer division rather than just testing for divisibility, see Find the division remainder of a number.
You do this using the modulus operator, %
n % k == 0
evaluates true if and only if n is an exact multiple of k. In elementary maths this is known as the remainder from a division.
In your current approach you perform a division and the result will be either
always an integer if you use integer division, or
always a float if you use floating point division.
It's just the wrong way to go about testing divisibility.
You can simply use % Modulus operator to check divisibility.
For example: n % 2 == 0 means n is exactly divisible by 2 and n % 2 != 0 means n is not exactly divisible by 2.
You can use % operator to check divisiblity of a given number
The code to check whether given no. is divisible by 3 or 5 when no. less than 1000 is given below:
n=0
while n<1000:
if n%3==0 or n%5==0:
print n,'is multiple of 3 or 5'
n=n+1
This code appears to do what you are asking for.
for value in range(1,1000):
if value % 3 == 0 or value % 5 == 0:
print(value)
Or something like
for value in range(1,1000):
if value % 3 == 0 or value % 5 == 0:
some_list.append(value)
Or any number of things.
I had the same approach. Because I didn't understand how to use the module(%) operator.
6 % 3 = 0
*This means if you divide 6 by 3 you will not have a remainder, 3 is a factor of 6.
Now you have to relate it to your given problem.
if n % 3 == 0
*This is saying, if my number(n) is divisible by 3 leaving a 0 remainder.
Add your then(print, return) statement and continue your
a = 1400
a1 = 5
a2 = 3
b= str(a/a1)
b1 = str(a/a2)
c =b[(len(b)-2):len(b)]
c1 =b[(len(b1)-2):len(b1)]
if c == ".0":
print("yeah for 5!")
if c1 == ".0":
print("yeah for 3!")
For small numbers n%3 == 0 will be fine. For very large numbers I propose to calculate the cross sum first and then check if the cross sum is a multiple of 3:
def is_divisible_by_3(number):
if sum(map(int, str(number))) % 3 != 0:
my_bool = False
return my_bool
Try this ...
public class Solution {
public static void main(String[] args) {
long t = 1000;
long sum = 0;
for(int i = 1; i<t; i++){
if(i%3 == 0 || i%5 == 0){
sum = sum + i;
}
}
System.out.println(sum);
}
}
The simplest way is to test whether a number is an integer is int(x) == x. Otherwise, what David Heffernan said.

Python - Fastest way to strip the trailing zeros from the bit representation of a number

This is the python version of the same C++ question.
Given a number, num, what is the fastest way to strip off the trailing zeros from its binary representation?
For example, let num = 232. We have bin(num) equal to 0b11101000 and we would like to strip the trailing zeros, which would produce 0b11101. This can be done via string manipulation, but it'd probably be faster via bit manipulation. So far, I have thought of something using num & -num
Assuming num != 0, num & -num produces the binary 0b1<trailing zeros>. For example,
num 0b11101000
-num 0b00011000
& 0b1000
If we have a dict having powers of two as keys and the powers as values, we could use that to know by how much to right bit shift num in order to strip just the trailing zeros:
# 0b1 0b10 0b100 0b1000
POW2s = { 1: 0, 2: 1, 4: 2, 8: 3, ... }
def stripTrailingZeros(num):
pow2 = num & -num
pow_ = POW2s[pow2] # equivalent to math.log2(pow2), but hopefully faster
return num >> pow_
The use of dictionary POW2s trades space for speed - the alternative is to use math.log2(pow2).
Is there a faster way?
Perhaps another useful tidbit is num ^ (num - 1) which produces 0b1!<trailing zeros> where !<trailing zeros> means take the trailing zeros and flip them into ones. For example,
num 0b11101000
num-1 0b11100111
^ 0b1111
Yet another alternative is to use a while loop
def stripTrailingZeros_iterative(num):
while num & 0b1 == 0: # equivalent to `num % 2 == 0`
num >>= 1
return num
Ultimately, I need to execute this function on a big list of numbers. Once I do that, I want the maximum. So if I have [64, 38, 22, 20] to begin with, I would have [1, 19, 11, 5] after performing the stripping. Then I would want the maximum of that, which is 19.
There's really no answer to questions like this in the absence of specifying the expected distribution of inputs. For example, if all inputs are in range(256), you can't beat a single indexed lookup into a precomputed list of the 256 possible cases.
If inputs can be two bytes, but you don't want to burn the space for 2**16 precomputed results, it's hard to beat (assuming that_table[i] gives the count of trailing zeroes in i):
low = i & 0xff
result = that_table[low] if low else 8 + that_table[i >> 8]
And so on.
You do not want to rely on log2(). The accuracy of that is entirely up to the C library on the platform CPython is compiled for.
What I actually use, in a context where ints can be up to hundreds of millions of bits:
assert d
if d & 1 == 0:
ntz = (d & -d).bit_length() - 1
d >>= ntz
A while loop would be a disaster in this context, taking time quadratic in the number of bits shifted off. Even one needless shift in that context would be a significant expense, which is why the code above first checks to see that at least one bit needs to shifted off. But if ints "are much smaller", that check would probably cost more than it saves. "No answer in the absence of specifying the expected distribution of inputs."
On my computer, a simple integer divide is fastest:
import timeit
timeit.timeit(setup='num=232', stmt='num // (num & -num)')
0.1088077999993402
timeit.timeit(setup='d = { 1: 0, 2 : 1, 4: 2, 8 : 3, 16 : 4, 32 : 5 }; num=232', stmt='num >> d[num & -num]')
0.13014470000052825
timeit.timeit(setup='import math; num=232', stmt='num >> int(math.log2(num & -num))')
0.2980690999993385
You say you "Ultimately, [..] execute this function on a big list of numbers to get odd numbers and find the maximum of said odd numbers."
So why not simply:
from random import randint
numbers = [randint(0, 10000) for _ in range(5000)]
odd_numbers = [n for n in numbers if n & 1]
max_odd = max(odd_numbers)
print(max_odd)
To do what you say you want to do ultimately, there seems to be little point in performing the "shift right until the result is odd" operation? Unless you want the maximum of the result of that operation performed on all elements, which is not what you stated?
I agree with #TimPeters answer, but if you put Python through its paces and actually generate some data sets and try the various solutions proposed, they maintain their spread for any number of integer size when using Python ints, so your best option is integer division for numbers up to 32-bits, after that see the chart below:
from pandas import DataFrame
from timeit import timeit
import math
from random import randint
def reduce0(ns):
return [n // (n & -n)
for n in ns]
def reduce1(ns, d):
return [n >> d[n & -n]
for n in ns]
def reduce2(ns):
return [n >> int(math.log2(n & -n))
for n in ns]
def reduce3(ns, t):
return [n >> t.index(n & -n)
for n in ns]
def reduce4(ns):
return [n if n & 1 else n >> ((n & -n).bit_length() - 1)
for n in ns]
def single5(n):
while (n & 0xffffffff) == 0:
n >>= 32
if (n & 0xffff) == 0:
n >>= 16
if (n & 0xff) == 0:
n >>= 8
if (n & 0xf) == 0:
n >>= 4
if (n & 0x3) == 0:
n >>= 2
if (n & 0x1) == 0:
n >>= 1
return n
def reduce5(ns):
return [single5(n)
for n in ns]
numbers = [randint(1, 2 ** 16 - 1) for _ in range(5000)]
d = {2 ** n: n for n in range(16)}
t = tuple(2 ** n for n in range(16))
assert(reduce0(numbers) == reduce1(numbers, d) == reduce2(numbers) == reduce3(numbers, t) == reduce4(numbers) == reduce5(numbers))
df = DataFrame([{}, {}, {}, {}, {}, {}])
for p in range(1, 16):
p = 2 ** p
numbers = [randint(1, 2 ** p - 1) for _ in range(4096)]
d = {2**n: n for n in range(p)}
t = tuple(2 ** n for n in range(p))
df[p] = [
timeit(lambda: reduce0(numbers), number=100),
timeit(lambda: reduce1(numbers, d), number=100),
timeit(lambda: reduce2(numbers), number=100),
timeit(lambda: reduce3(numbers, t), number=100),
timeit(lambda: reduce4(numbers), number=100),
timeit(lambda: reduce5(numbers), number=100)
]
print(f'Complete for {p} bit numbers.')
print(df)
df.to_csv('test_results.csv')
Result (when plotted in Excel):
Note that the plot that was previously here was wrong! The code and data were not though. The code has been updated to include #MarkRansom's solution, since it turns out to be the optimal solution for very large numbers (over 4k-bit numbers).
while (num & 0xffffffff) == 0:
num >>= 32
if (num & 0xffff) == 0:
num >>= 16
if (num & 0xff) == 0:
num >>= 8
if (num & 0xf) == 0:
num >>= 4
if (num & 0x3) == 0:
num >>= 2
if (num & 0x1) == 0:
num >>= 1
The idea here is to perform as few shifts as possible. The initial while loop handles numbers that are over 32 bits long, which I consider unlikely but it has to be provided for completeness. After that each statement shifts half as many bits; if you can't shift by 16, then the most you could shift is 15 which is (8+4+2+1). All possible cases are covered by those 5 if statements.

How to check if a given number is a power of two?

The code below isn't working right for some inputs.
a, i = set(), 1
while i <= 10000:
a.add(i)
i <<= 1
N = int(input())
if N in a:
print("True")
else:
print("False")
My initial idea was to check for each input if it's a power of 2 by starting from 1 and multiplying by 2 until exceeding the input number, comparing at each step. Instead, I store all the powers of 2 in a set beforehand, in order to check a given input in O(1). How can this be improved?
Bit Manipulations
One approach would be to use bit manipulations:
(n & (n-1) == 0) and n != 0
Explanation: every power of 2 has exactly 1 bit set to 1 (the bit in that number's log base-2 index). So when subtracting 1 from it, that bit flips to 0 and all preceding bits flip to 1. That makes these 2 numbers the inverse of each other so when AND-ing them, we will get 0 as the result.
For example:
n = 8
decimal | 8 = 2**3 | 8 - 1 = 7 | 8 & 7 = 0
| ^ | |
binary | 1 0 0 0 | 0 1 1 1 | 1 0 0 0
| ^ | | & 0 1 1 1
index | 3 2 1 0 | | -------
0 0 0 0
-----------------------------------------------------
n = 5
decimal | 5 = 2**2 + 1 | 5 - 1 = 4 | 5 & 4 = 4
| | |
binary | 1 0 1 | 1 0 0 | 1 0 1
| | | & 1 0 0
index | 2 1 0 | | ------
1 0 0
So, in conclusion, whenever we subtract one from a number, AND the result with the number itself, and that becomes 0 - that number is a power of 2!
Of course, AND-ing anything with 0 will give 0, so we add the check for n != 0.
math functions
You could always use math functions, but notice that using them without care could cause incorrect results:
math.log(x[, base]) with base=2:
import math
math.log(n, 2).is_integer()
math.log2(x):
math.log2(n).is_integer()
Worth noting that for any n <= 0, both functions will throw a ValueError as it is mathematically undefined (and therefore shouldn't present a logical problem).
math.frexp(x):
abs(math.frexp(n)[0]) == 0.5
As noted above, for some numbers these functions are not accurate and actually give FALSE RESULTS:
math.log(2**29, 2).is_integer() will give False
math.log2(2**49-1).is_integer() will give True
math.frexp(2**53+1)[0] == 0.5 will give True!!
This is because math functions use floats, and those have an inherent accuracy problem.
(Expanded) Timing
Some time has passed since this question was asked and some new answers came up with the years. I decided to expand the timing to include all of them.
According to the math docs, the log with a given base, actually calculates log(x)/log(base) which is obviously slow. log2 is said to be more accurate, and probably more efficient. Bit manipulations are simple operations, not calling any functions.
So the results are:
Ev: 0.28 sec
log with base=2: 0.26 sec
count_1: 0.21 sec
check_1: 0.2 sec
frexp: 0.19 sec
log2: 0.1 sec
bit ops: 0.08 sec
The code I used for these measures can be recreated in this REPL (forked from this one).
Refer to the excellent and detailed answer to "How to check if a number is a power of 2" — for C#. The equivalent Python implementation, also using the "bitwise and" operator &, is this:
def is_power_of_two(n):
return (n != 0) and (n & (n-1) == 0)
As Python has arbitrary-precision integers, this works for any integer n as long as it fits into memory.
To summarize briefly the answer cited above: The first term, before the logical and operator, simply checks if n isn't 0 — and hence not a power of 2. The second term checks if it's a power of 2 by making sure that all bits after that bitwise & operation are 0. The bitwise operation is designed to be only True for powers of 2 — with one exception: if n (and thus all of its bits) were 0 to begin with.
To add to this: As the logical and "short-circuits" the evaluation of the two terms, it would be more efficient to reverse their order if, in a particular use case, it is less likely that a given n be 0 than it being a power of 2.
In binary representation, a power of 2 is a 1 (one) followed by zeros. So if the binary representation of the number has a single 1, then it's a power of 2. No need here to check num != 0:
print(1 == bin(num).count("1"))
The bin builtin returns a string "0b1[01]?" (regex notation) for every strictly positive integer (if system memory suffices, that is), so that we can write the Boolean expression
'1' not in bin(abs(n))[3:]
that yields True for n that equals 0, 1 and 2**k.
1 is 2**0 so it is unquestionably a power of two, but 0 is not, unless you take into account the limit of x=2**k for k → -∞. Under the second assumption we can write simply
check0 = lambda n: '1' not in bin(abs(n))[3:]
and under the first one (excluding 0)
check1 = lambda n: '1' not in bin(abs(n))[3:] and n != 0
Of course the solution here proposed is just one of the many possible ones that
you can use to check if a number is a power of two... and for sure not the most
efficient one but I'm posting it in the sake of completeness :-)
Note: this should be a comment on Tomerikoo's answer (currently the most upvoted) but unfortunately Stack Overflow won't let me comment due to reputation points.
Tomerikoo's answer is very well explained and thought-out. While it covers most applications, but I believe needs a slight modification to make it more robust against a trivial case. Their answer is:
(n & (n-1) == 0) and n != 0
The second half checks if the input is an actual 0 which would invalidate the bitwise-and logic. There is another one trivial case when this could happen: input is 1 and the bitwise-and takes place with 0 again, just on the second term. Strictly speaking, 2^0=1 of course but I doubt that it's useful for most applications. A trivial modification to account for that would be:
(n & (n-1) == 0) and (n != 0 and n-1 != 0)
The following code checks whether n is a power of 2 or not:
def power_of_two(n):
count = 0
st = str(bin(n))
st = st[2:]
for i in range(0,len(st)):
if(st[i] == '1'):
count += 1
if(count == 1):
print("True")
else:
print("False")
Many beginners won't know how code like (n != 0) and (n & (n-1) == 0) works.
But if we want to check whether a number is a power of 2 or not, we can convert the number to binary format and see it pretty clearly.
For Example:
^ (to the power of)
2^0 = 1 (Bin Value : 0000 0001)
2^1 = 2 (Bin Value : 0000 0010)
2^2 = 4 (Bin Value : 0000 0100)
2^3 = 8 (Bin Value : 0000 1000)
2^4 = 16 (Bin Value : 0001 0000)
2^5 = 32 (Bin Value : 0010 0000)
2^6 = 64 (Bin Value : 0100 0000)
2^7 = 128 (Bin Value : 1000 0000)
If you look at the binary values of all powers of 2, you can see that there is only one bit True. That's the logic in this program.
So If we count the number of 1 bit's in a binary number and if it is equal to 1, then the given number is power of 2, otherwise it is not.
n = int(input())
if '1' in list(bin(n))[3:]: #also can use if '1' in bin(n)[3:] OR can also use format(n, 'b')[1:]
print("False")
else:
print("True")
For every number which is power of 2 say(N = 2^n), where n = +integer bin(N)=bin(2^(+int)) will have string of form: 0b10000000 e.i 0b1.....zero only if not 0, N is not power of 2.
Also, format(n, 'b') returns bin(n)[2:] so can be used
Source
>>> format(14, '#b'), format(14, 'b')
('0b1110', '1110')
>>> f'{14:#b}', f'{14:b}'
('0b1110', '1110')
Use *2 instead of bit shifts. Multiplication or addition are much more readable.
In python 3.10, int.bit_count counts the set bits of a number, so we can use
n.bit_count() == 1
Most of the above answers use bin() of format(int(input()), "b")
The below code also works: Ev(x) returns True if x is power of 2
# Ev(x) ~ ispoweroftwo(x)
def Ev(x):
if x==2: return True
elif x%2: return False
return Ev(x//2)
The above code is based on generating bin()
#This function returns binary of integers
def binary(x):
a = ""
while x!= 0:
a += str(x%2)
x = x//2
return a[::-1]
I = int(input())
print(format(I, "b")) # To cross-check if equal of not
print(binary(I))
I have tried to add my answer because I found what we are doing using bin(x)[3:] or format(x, "b") is almost like asking the boolean answer of whether or not a given number x is divisible by two.....and we keep asking the same

XOR on contiguous subarrays of an array

From an array, I need to find the value obtained by XOR-ing the contiguous subarrays, following by XOR-ing the values thus obtained.
INPUT
One line containing integers that are elements of the array.
e.g. [1,2,3]
OUTPUT
Print the answer corresponding to each test case in a separate line.
So far I managed to build two strategy using loops and a recursive approach.
None of my approaches are giving a good performance on large input size.
e.g. 1 XOR 2 XOR 3 XOR (1 XOR 2) XOR (2 XOR 3) XOR (1 XOR 2 XOR 3) = 2
Could you build a better algorithm? Maybe a dynamic programming approach?
from functools import reduce
# Calculate the XOR
def XOR(L):
return reduce(lambda x, y: x ^ y, L)
# Recursive approach
def allSubArraysXOR(L,L2=None):
if L2==None:
L2 = L[:-1]
if L==[]:
if L2==[]:
return 0
return allSubArraysXOR(L2,L2[:-1])
return XOR(L) ^ allSubArraysXOR(L[1:],L2)
# Loop - yielding approach
def getAllWindows(L):
for w in range(1, len(L)+1):
for i in range(len(L)-w+1):
yield XOR(L[i:i+w])
a = [int(a_temp) for a_temp in input().strip().split(' ')]
print(allSubArraysXOR(a))
# print(XOR(getAllWindows(a)))
We don't need to enumerate the (2**n) subarrays to solve this.
XOR has some useful properties that we can exploit to solve this in O(n) time. Specifically:
for any k: k XOR k == 0;
for any k: k XOR 0 == k.
XOR is both commutative and associative.
To solve your problem, we first need to count how many times each element appears in the subarrays. Any element that appears an even number of times can be disregarded. The rest need to be XORed together (each taken just once).
Let's see how this applies to your example:
1 XOR 2 XOR 3 XOR (1 XOR 2) XOR (2 XOR 3) XOR (1 XOR 2 XOR 3) = # open brackets
1 XOR 2 XOR 3 XOR 1 XOR 2 XOR 2 XOR 3 XOR 1 XOR 2 XOR 3 = # reorder
1 XOR 1 XOR 1 XOR 2 XOR 2 XOR 2 XOR 2 XOR 3 XOR 3 XOR 3 = # group
(1 XOR 1 XOR 1) XOR (2 XOR 2 XOR 2 XOR 2) XOR (3 XOR 3 XOR 3) = # remove pairs
1 XOR 0 XOR 3 =
1 XOR 3 =
2
The following is an O(n) implementation of this idea:
def xor_em(lst):
n = len(lst)
ret = 0
for i, el in enumerate(lst):
count = (i + 1) * (n - i)
if count % 2:
ret ^= el
return ret
print xor_em([1, 2, 3])
The counting of subarrays is done by
count = (i + 1) * (n - i)
using the observation that there are i + 1 elements to the left of the current element (including itself) and n - i to the right (also including itself). Multiplying the two gives the number of subarrays that start to the left of the current element, and end to the right of it.
We've now reduced the problem to looking for pairs (i + 1) and (n - i) whose product is odd. Observe that the only way to get an odd product is by multiplying two numbers that are themselves odd (this can be seen by thinking about the prime factorizations of the two multiplicands).
There are two cases to consider:
when n is even, one of (i + 1) and (n - i) is always even. This means that the algorithm always returns zero for lists of even length.
when n is odd, (i + 1) * (n - i) is odd for i = 0, 2, 4, ..., (n - 1).
This leads to the following simplified solution:
def xor_em(lst):
if len(lst) % 2 == 0:
return 0
else:
return reduce(operator.xor, lst[::2])

Explanation of Binary AND Operator

Can someone please explain the purpose of the bitwise, Binary AND Operator( & ) and how to use it? I was looking at different ways of making a isprime function and came across this.
def isprime(n):
# make sure n is a positive integer
n = abs(int(n))
# 0 and 1 are not primes
if n < 2:
return False
# 2 is the only even prime number
if n == 2:
return True
# all other even numbers are not primes
if not n & 1:
return False
# range starts with 3 and only needs to go up the squareroot of n
# for all odd numbers (counts by 2's)
for x in range(3, int(n**0.5)+1, 2):
if n % x == 0:
return False
return True
I also looked at Python Bitwise Operators Example but couldn't grasp it.
One number AND another is the bits of one number masked by the bits of another number. If a number AND 1 is 0 (not n & 1 would be True), that means it's divisible by two, since all multiples of 2 have a 0 as the rightmost binary digit.
11 = 00001011 (Not divisible by 2) 28 = 00011100 (Divisible by 2)
& 1 = 00000001 & 1 = 00000001
--------------- ---------------
00000001 00000000
For example,
12 & 7 =
1100 & 0111
= 0100
= 4
For the isPrime function, the first condition checks whether it is 0 or 1. The second condition checks whether it is 2. The third condition then checks if (n&1), which is a check whether the number is even. Every even number when converted to binary form has 0 in its last digit. So for example,
14 & 1 =
1110 & 0001
= 0
14 is proved to be even and henceforth not prime.

Categories