Can anyone tell me an efficient approach to perform the division operation without using '/'. I can calculate the integer value in log(n) steps using a method similar to binary search.
115/3
57 * 3 > 115
28 * 3 < 115
47 * 3 > 115
.
.
.
38 * 3 is quotient value .....
But is there any other more efficient method?
The typical way is to shift and subtract. This is basically pretty similar to long division as we learned it in school. The big difference is that in decimal division you need to estimate the next digit of the result. In binary, that's trivial. The next digit is always either 0 or 1. If the (left-shifted) divisor is less than or equal to the current dividend value, you subtract it, and the current bit of the result is a 1. If it's greater, then the current bit of the result is a 0. Code looks like this:
unsigned divide(unsigned dividend, unsigned divisor) {
unsigned denom=divisor;
unsigned current = 1;
unsigned answer=0;
if ( denom > dividend)
return 0;
if ( denom == dividend)
return 1;
while (denom <= dividend) {
denom <<= 1;
current <<= 1;
}
denom >>= 1;
current >>= 1;
while (current!=0) {
if ( dividend >= denom) {
dividend -= denom;
answer |= current;
}
current >>= 1;
denom >>= 1;
}
return answer;
}
This works pretty much like when we do long division by hand. For example, let's consider 972/5. In decimal long division, we do something like this:
____
5)972
Then we figure each digit individually. 5 goes into 9 once, so we write down a 1 in that digit of the answer, and subtract 1*5 from (that digit) of the dividend, then "bring down" the next digit of the dividend:
1
----
5)972
5
---
47
We continue doing the same until we've filled in all the digits:
194
----
5)972
5
---
47
45
---
22
20
---
2
So, our answer is 194 remainder 2.
Now let's consider the same thing, but in binary. 972 in binary is 11 1100 1100, and 5 is 101. Now there is one fundamental difference between doing the division in binary vs. decimal: in decimal a particular digit could be anything from 0 to 9, so we had to multiply to find the intermediate result we were going to subtract from the dividend. In binary the digit is only ever going to be a 0 or a 1. We never need to multiply because we would only ever multiply by 0 or 1 (which we normally handle in an if statement--either we subtract or we don't).
-----------
101)1111001100
So, our first step is to figure out which will be the first digit in the result. We do that by comparing 101 to 1111001100, and shifting it left until it's greater. That gives us:
|
1111001100
10100000000
As we do that shifting, we count the number of places we've shifted so we know which digit of the result we're filling in at any given time. I've shown that with the vertical bar above. Then we shift the intermediate result right one place, and shift the vertical bar right with it to signify where we're doing to fill in a result digit:
|
1111001100
1010000000
From there we check if the shifted divisor is less than the dividend. If it is, we fill in a 1 in the proper place in the answer, and subtract the shifted divisor from the intermediate result [and to help keep columns straight, I'm going to insert some spaces]:
1
-----------------------------
101)1 1 1 1 0 0 1 1 0 0
1 0 1 0 0 0 0 0 0 0
----------------------------
1 0 1
We continue the same way, filling in digits of the result, and subtracting the shifted divisor from the intermediate result until we've filled in all the digits. In a further attempt at helping keep things straight, I'm going to write in each digit of the result at the far right next to the subtrahend:
1 1 0 0 0 0 1 0
-----------------------------
101)1 1 1 1 0 0 1 1 0 0
1 0 1 1
-----------------------------
1 0 1
1 0 1 1
-----------------------------
0 0 0 0
--------------------------
0 0 0 0
-------------------------
0 0 1 0
-------------------------
0 1 1 0
-------------------------
1 1 0
1 0 1 1
------------------------
0 1 0 0
So, we get a result of 11000010, remainder 10. Converting those to decimal, we get the expected 194 and 2 respectively.
Let's consider how that relates to the code above. We start by shifting the divisor left until it's greater than the dividend. We then repeatedly shift it right and for each right shift check whether that value is less than the intermediate we got after the last subtraction. If it's less, we subtract again and fill in a 1 for that digit in our result. If it's greater, we "subtract 0" (don't do anything) and fill in a '0' for that digit in the result (which, again, doesn't require us to do anything, since those digits are already set to 0's).
When we've filled in all the digits, that's our result, and any amount left that we haven't subtracted yet is our remainder.
Some have asked why I used |= instead of += in the code. I hope this helps explain why. Although in this case they produce the same result, I don't think of adding each digit to the existing partial answer. Rather, I think of it that spot in the answer as being empty, and the or just fills it in.
Options:
Code your own division algorithm based on the long division algorithm you learned in grade school.
Take the -1 power of the denominator, and multiply onto the numerator
Take the logs of the numerator and denominator, subtract, and then raise the base of the log to that same power
Simple Python implementation using basic high school math. A denominator is simply a number to the power of negative 1.
def divide(a, b):
return a * b ** -1
Following is the Java code for dividing number without using division operator.
private static int binaryDivide(int dividend, int divisor) {
int current = 1;
int denom = divisor;
// This step is required to find the biggest current number which can be
// divided with the number safely.
while (denom <= dividend) {
current <<= 1;
denom <<= 1;
}
// Since we may have increased the denomitor more than dividend
// thus we need to go back one shift, and same would apply for current.
denom >>= 1;
current >>= 1;
int answer = 0;
// Now deal with the smaller number.
while (current != 0) {
if (dividend >= denom) {
dividend -= denom;
answer |= current;
}
current >>= 1;
denom >>= 1;
}
return answer;
}
(This is a solution to the problem where you are not allowed to use multiplication either).
I like this solution: https://stackoverflow.com/a/5387432/1008519, but I find it somewhat hard to reason about (especially the |-part). This solution makes a little more sense in my head:
var divide = function (dividend, divisor) {
// Handle 0 divisor
if (divisor === 0) {
return NaN;
}
// Handle negative numbers
var isNegative = false;
if (dividend < 0) {
// Change sign
dividend = ~dividend+1;
isNegative = !isNegative;
}
if (divisor < 0) {
// Change sign
divisor = ~divisor+1;
isNegative = !isNegative;
}
/**
* Main algorithm
*/
var result = 1;
var denominator = divisor;
// Double denominator value with bitwise shift until bigger than dividend
while (dividend > denominator) {
denominator <<= 1;
result <<= 1;
}
// Subtract divisor value until denominator is smaller than dividend
while (denominator > dividend) {
denominator -= divisor;
result -= 1;
}
// If one of dividend or divisor was negative, change sign of result
if (isNegative) {
result = ~result+1;
}
return result;
}
Initialize the result to 1 (since we are going to double our denominator until it is bigger than the dividend)
Double the denominator (with bitwise shifts) until it is bigger than the dividend
Since we know our denominator is bigger than our dividend, we can subtract the divisor until it is less than the dividend
Return the recorded actions it took to get as close to the denominator as possible using the divisor
Here are some test runs:
console.log(divide(-16, 3)); // -5
console.log(divide(16, 3)); // 5
console.log(divide(16, 33)); // 0
console.log(divide(16, 0)); // NaN
console.log(divide(384, 15)); // 25
Here is a gist handling both the 0 divisor case and negative dividend and/or divisor: https://gist.github.com/mlunoe/e34f14cff4d5c57dd90a5626266c4130
Since the OP said it's an interview question, I think the interviewer wants to see the following things in addition to your coding skills. (Suppose you are using Java)
How to deal with negative numbers? It's common to convert both the dividend and the divisor to positive numbers. However, you may forget that Math.abs(Integer.MIN_VALUE) is still Integer.MIN_VALUE. Therefore, when the dividend is Integer.MIN_VALUE, you should calculate it separately.
What's the result of "Integer.MIN_VALUE/-1"? There is no such value in Integer. You should discuss it with the interviewer. You can throw an exception for this condition.
Here is the Java code for this question and you can validate it leetcode:divide two integers:
public int divide(int dividend, int divisor) {
if(divisor == 0)
throw new Exception("Zero as divisor!");
int a = Math.abs(dividend);
int b = Math.abs(divisor);
boolean isPos = true;
if(dividend < 0) isPos = !isPos;
if(divisor < 0) isPos = !isPos;
if(divisor == Integer.MIN_VALUE){
if(dividend == Integer.MIN_VALUE) return 1;
else return 0;
}
if(dividend == Integer.MIN_VALUE) {
if(divisor == -1){
// the result is out of Integer's range.
throw new Exception("Invalid result.");
} else {
// Because Math.abs(Integer.MIN_VALUE) = Integer.MIN_VALUE
// we avoid it by adding a positive divisor to Integer.MIN_VALUE
// here I combined two cases: divisor > 0 and divisor < 0
return divide((dividend + b), divisor) - divisor/b;
}
}
int res = 0;
int product = b;
while(a >= b){
int multiplier = 1;
while(a - product >= product){
product = product << 1;// "product << 1" is actually "product * 2"
multiplier = multiplier << 1;
}
res += multiplier;
a -= product;
product = b;
}
return isPos?res:-res;
}
The main concept :
Let's say we are calc 20/4, so
4*(1+1) = 8 *(1+1) = 16 *(1+1) == 32 (which is bigger) X
so go back to 16 and try 16*(1+0.5) == 24 (bigger) X
so go back to 16 and try 16*(1+0.25) == 20
The code:
float product=1,multiplier=2,a=1;
int steps=0;
void divCore(float number, float divideBy,float lastDivison)
{
steps++;
//epsilon check e.g (10/3) will never ends
if(number - divideBy < 0.01)
return;
else
{
lastDivison = divideBy;
divideBy *= multiplier;
if(number >= divideBy)
{
product *= multiplier;
divCore(number,divideBy,lastDivison);
}
else
{
a *= 0.5;
multiplier = 1 + a;
divCore(number,lastDivison,lastDivison);
}
}
}
float Divide(float numerator, float denominator)
{
//init data
int neg=(numerator<0)?-1:1;
neg*=(denominator<0)?-1:1;
product = 1;
multiplier = 2;
a = 1;
steps =0;
divCore(abs(numerator),abs(denominator),0);
return product*neg;
}
Division of two numbers without using /
int div(int a,int b){
if(b == 0)
return -1; //undefined
else if (b == 1)
return a;
else if(b > 1){
int count = 0;
for(int i=b;i<=a;i+=b){
count++;
}
}
return count;
}
Here is a simple divide method for ints without using a '/' operator:-
public static int divide(int numerator, int denominator) throws Exception {
int q = 0;
boolean isNumPos = (numerator >= 0) ? true : false;
boolean isDenPos = (denominator >= 0) ? true : false;
if (denominator == 0) throw new Exception("Divide by 0: not an integer result");
numerator = Math.abs(numerator);
denominator = Math.abs(denominator);
while (denominator <= numerator) {
numerator -= denominator;
q++;
}
return (isNumPos ^ isDenPos) ? -q : q;
}
Here's one in JavaScript:
function divideWithoutDivision(a, b, precision) {
precision = precision > 0 ? precision : 10
var result = 0
var decimalPosition = 1
var A = a*0.1
var howManyTimes = 0
while (precision--) {
A = A * 10
howManyTimes = 0
while (A >= b) {
A = A - b
howManyTimes += 1
}
result = result + howManyTimes*decimalPosition
decimalPosition = decimalPosition * 0.1
}
return result
}
document.write('<br>20/3 = ', divideWithoutDivision(20, 3))
document.write('<br>10/3 = ', divideWithoutDivision(10, 3))
document.write('<br>10/4 = ', divideWithoutDivision(10, 4))
document.write('<br>17/14 = ', divideWithoutDivision(17, 14))
document.write('<br>23/4 = ', divideWithoutDivision(23, 4))
It could be further improved by rounding after the last decimal place of the precision.
Perhaps you can devise a way to do it using sequences of >> (bit shifts) with other bitwise operators. There's an example in psuedo-code in the Wikipedia: Bitwise Operator article.
Well, if this is only integer/integer = int type division, it's pretty easy to get the integer part of x / n = int.dec by adding n+n+n+n until n is greater than x, then subtracting one from your 'n' count.
To get int/int = real without using *, /, %, or other math functions, you could do several things. You could return the remainder as a rational, for example. That has the advantage of being exact. You could also use string modification to turn your r into r0... (you pick the precision) and then repeat the same addition trick, then concatenate the results.
And of course, you could try having fun with bit shifting.
I don't know if this is so much a 'silly trick' as it is a test of how well you can use simple things (addition, subtraction) to build a complex thing (division). This is a skill that your potential employer might need, because there isn't an operator for everything. A question like this should (theoretically) weed out people who can't design algorithms from people who can.
I do think it's a problem that the answer is so readily available on the internet, but that's an implementation issue.
This is the function that solved my problem:
func printRemainderAndQuotient(numerator: Int,divisor: Int) {
var multiplier = 0
var differene = numerator - divisor
var dynamicNumber = 0
if divisor == 0 {
print("invalid divisor")
return
}
if divisor == numerator {
print("quotient : " + "1")
print("remainder : " + "0")
return
}
while differene >= divisor {
multiplier = multiplier + 1
dynamicNumber = divisor * multiplier
differene = numerator - dynamicNumber
}
print("quotient : " + "\(multiplier)")
print("remainder : " + "\(differene)")
}
If you take the division as a subtraction, what it basically is, you could use a method "decrement" what allows you to not use any operator at all, except for ~ at the end, to invert the result later into a positive integer or any other value.
private static int decrement(int i) {
System.out.println("Value of decrement : ");
System.out.println(i);
return i - 1;
}
private static int divide(int n, int d) {
assert n > 0 && d > 0;
int counter = 0;
while (n >= d) {
for (int i = d; i > 0; i = decrement(i)) {
n = decrement(n);
}
counter = decrement(counter);
}
counter =~decrement(counter);
System.out.println(counter);
return counter;
}
well, let's see... x/y = e^(ln(x)-ln(y))
private int divideBy2(int number){
int count = 1;
while(count<=number){
if(count*2==number){
return count;
}
count++;
}
return count;
}
Related
Came across some code where the number of digits was being determined by casting the number to a string then using a len().
Function numOfDigits_len(n As Long) As Long
numOfDigits_len = Len(Str(n)) - 1
End Function
Now although this works I knew it would be slow compared to any method that didn't use strings, so I wrote one that uses log().
Function numOfDigits_log(n As Long) As Long
numOfDigits_log = Int(Log(n) / Log(10)) + 1
End Function
Cut run time by 1/2 which was great but there was something weird happening in a specific case.
n numOfDigits_log(n)
===== ====================
999 3
1000 3
1001 4
It would not handle 1000 properly. I figured it is because of floating point and rounding issues.
Function numOfDigits_loop(ByVal n As Long) As Long
Do Until n = 0
n = n \ 10
numOfDigits_loop = numOfDigits_loop + 1
Loop
End Function
Wrote this which turned out to be ~10% slower as numbers got larger than 10^6 and seems to become slowly larger as n gets bigger. Which is fine if I was being pragmatic but I would like to find something more ideal.
Now my question is, is there a way to use the log() method accurately. I could do something like
Function numOfDigits_log(n As Long) As Long
numOfDigits_log = Int(Log(n) / Log(10) + 0.000000001) + 1
End Function
But it seems very "hacky". Is there a nicer way that's faster or as fast as the log() method?
Note: I realize this kind of optimization is pointless in a lot of cases but now that I've come across this I would like to "fix" it
I've answered this before, but I couldn't find it, so here's the basics:
int i = ... some number >= 0 ...
int n = 1;
if (i >= 100000000){i /= 100000000; n += 8;}
if (i >= 10000){i /= 10000; n += 4;}
if (i >= 100){i /= 100; n += 2;}
if (i >= 10){i /= 10; n += 1;}
That's in C, but you get the idea.
A while loop guarantees correctness, i.e. it doesn't use any floating point calculations
int numDigits = 0;
while(num != 0) {
num /= 10;
numDigits++;
}
You can also speed this up by using a larger divisor
int numDigits = 0;
if(num >= 100000 || num <= -100000) {
int prevNum;
while(num != 0) {
prevNum = num;
num /= 100000;
numDigits += 5;
}
num = prevNum;
numDigits -= 5;
}
while(num != 0) {
num /= 10;
numDigits++;
}
You'll love this.
We live in a base 10 number system! That means all you have to do is ROUND UP.
the length of some number ALWAYS = ceiling (log n). So for instance: 7456412 (a 7-digit number). Log (7456412) = 6.8...round up and you have 7. log (9999) = 3.9999. Round up and it's 4.
The special case is when you DON'T have to round, or when you have some power of 10. For instance: log(1000) = 3. if you can detect when you have a power of 10, add one to the log result and you win!
the way you could do this detection is something like
double log10;
int clog10;
int length;
log10 = (Log(n) / Log(10)); // can also use a private static final long hardcoded for Log(10)
clog10 = ceiling(log10);
if (Int(log10) == clog10)
length = clog10 + 1;
else
length = clog10;
This is an interview question: "Given 2 integers x and y, check if x is an integer power of y" (e.g. for x = 8 and y = 2 the answer is "true", and for x = 10 and y = 2 "false").
The obvious solution is:int n = y; while(n < x) n *= y; return n == x
Now I am thinking about how to improve it.
Of course, I can check some special cases: e.g. both x and y should be either odd or even numbers, i.e. we can check the least significant bit of x and y. However I wonder if I can improve the core algorithm itself.
You'd do better to repeatedly divide y into x. The first time you get a non-zero remainder you know x is not an integer power of y.
while (x%y == 0) x = x / y
return x == 1
This deals with your odd/even point on the first iteration.
It means logy(x) should be an integer. Don't need any loop. in O(1) time
public class PowerTest {
public static boolean isPower(int x, int y) {
double d = Math.log(Math.abs(x)) / Math.log(Math.abs(y));
if ((x > 0 && y > 0) || (x < 0 && y < 0)) {
if (d == (int) d) {
return true;
} else {
return false;
}
} else if (x > 0 && y < 0) {
if ((int) d % 2 == 0) {
return true;
} else {
return false;
}
} else {
return false;
}
}
/**
* #param args
*/
public static void main(String[] args) {
System.out.println(isPower(-32, -2));
System.out.println(isPower(2, 8));
System.out.println(isPower(8, 12));
System.out.println(isPower(9, 9));
System.out.println(isPower(-16, 2));
System.out.println(isPower(-8, -2));
System.out.println(isPower(16, -2));
System.out.println(isPower(8, -2));
}
}
This looks for the exponent in O(log N) steps:
#define MAX_POWERS 100
int is_power(unsigned long x, unsigned long y) {
int i;
unsigned long powers[MAX_POWERS];
unsigned long last;
last = powers[0] = y;
for (i = 1; last < x; i++) {
last *= last; // note that last * last can overflow here!
powers[i] = last;
}
while (x >= y) {
unsigned long top = powers[--i];
if (x >= top) {
unsigned long x1 = x / top;
if (x1 * top != x) return 0;
x = x1;
}
}
return (x == 1);
}
Negative numbers are not handled by this code, but it can be done easyly with some conditional code when i = 1
This looks to be pretty fast for positive numbers as it finds the lower and upper limits for desired power and then applies binary search.
#include <iostream>
#include <cmath>
using namespace std;
//x is the dividend, y the divisor.
bool isIntegerPower(int x, int y)
{
int low = 0, high;
int exp = 1;
int val = y;
//Loop by changing exponent in the powers of 2 and
//Find out low and high exponents between which the required exponent lies.
while(1)
{
val = pow((double)y, exp);
if(val == x)
return true;
else if(val > x)
break;
low = exp;
exp = exp * 2;
high = exp;
}
//Use binary search to find out the actual integer exponent if exists
//Otherwise, return false as no integer power.
int mid = (low + high)/2;
while(low < high)
{
val = pow((double)y, mid);
if(val > x)
{
high = mid-1;
}
else if(val == x)
{
return true;
}
else if(val < x)
{
low = mid+1;
}
mid = (low + high)/2;
}
return false;
}
int main()
{
cout<<isIntegerPower(1024,2);
}
double a=8;
double b=64;
double n = Math.log(b)/Math.log(a);
double e = Math.ceil(n);
if((n/e) == 1){
System.out.println("true");
} else{
System.out.println("false");
}
I would implement the function like so:
bool IsWholeNumberPower(int x, int y)
{
double power = log(x)/log(y);
return floor(power) == power;
}
This shouldn't need check within a delta as is common with floating point comparisons, since we're checking whole numbers.
On second thoughts, don't do this. It does not work for negative x and/or y. Note that all other log-based answers presented right now are also broken in exactly the same manner.
The following is a fast general solution (in Java):
static boolean isPow(int x, int y) {
int logyx = (int)(Math.log(x) / Math.log(y));
return pow(y, logyx) == x || pow(y, logyx + 1) == x;
}
Where pow() is an integer exponentiation function such as the following in Java:
static int pow(int a, int b) {
return (int)Math.pow(a, b);
}
(This works due to the following guarantee provided by Math.pow: "If both arguments are integers, then the result is exactly equal to the mathematical result of raising the first argument to the power of the second argument...")
The reason to go with logarithms instead of repeated division is performance: while log is slower than division, it is slower by a small fixed multiple. At the same time it does remove the need for a loop and therefore gives you a constant-time algorithm.
In cases where y is 2, there is a quick approach that avoids the need for a loop. This approach can be extended to cases where y is some larger power of 2.
If x is a power of 2, the binary representation of x has a single set bit. There is a fairly simple bit-fiddling algorithm for counting the bits in an integer in O(log n) time where n is the bit-width of an integer. Many processors also have specialised instructions that can handle this as a single operation, about as fast as (for example) an integer negation.
To extend the approach, though, first take a slightly different approach to checking for a single bit. First determine the position of the least significant bit. Again, there is a simple bit-fiddling algorithm, and many processors have fast specialised instructions.
If this bit is the only bit, then (1 << pos) == x. The advantage here is that if you're testing for a power of 4, you can test for pos % 2 == 0 (the single bit is at an even position). Testing for a power of any power of two, you can test for pos % (y >> 1) == 0.
In principle, you could do something similar for testing for powers of 3 and powers of powers of 3. The problem is that you'd need a machine that works in base 3, which is a tad unlikely. You can certainly test any value x to see if its representation in base y has a single non-zero digit, but you'd be doing more work that you're already doing. The above exploits the fact that computers work in binary.
Probably not worth doing in the real world, though.
Here is a Python version which puts together the ideas of #salva and #Axn and is modified to not generate any numbers greater than those given and uses only simple storage (read, "no lists") by repeatedly paring away at the number of interest:
def perfect_base(b, n):
"""Returns True if integer n can be expressed as b**e where
n is a positive integer, else False."""
assert b > 1 and n >= b and int(n) == n and int(b) == b
# parity check
if not b % 2:
if n % 2:
return False # b,n is even,odd
if b == 2:
return n & (n - 1) == 0
if not b & (b - 1) and n & (n - 1):
return False # b == 2**m but n != 2**M
elif not n % 2:
return False # b,n is odd,even
while n >= b:
d = b
while d <= n:
n, r = divmod(n, d)
if r:
return False
d *= d
return n == 1
Previous answers are correct, I liked Paul's answer the best. It's Simple and clean.
Here is the Java implementation of what he suggested:
public static boolean isPowerOfaNumber(int baseOrg, int powerOrg) {
double base = baseOrg;
double power = powerOrg;
while (base % power == 0)
base = base / power;
// return true if base is equal 1
return base == 1;
}
in the case the number is too large ... use log function to reduce time complexity:
import math
base = int(input("Enter the base number: "))
for i in range(base,int(input("Enter the end of range: "))+1):
if(math.log(i) / math.log(base) % 1 == 0 ):
print(i)
If you have access to the largest power of y, that can be fitted inside the required datatype, this is a really slick way of solving this problem.
Lets say, for our case, y == 3. So, we would need to check if x is a power of 3.
Given that we need to check if an integer x is a power of 3, let us start thinking about this problem in terms of what information is already at hand.
1162261467 is the largest power of 3 that can fit into an Java int.
1162261467 = 3^19 + 0
The given x can be expressed as [(a power of 3) + (some n)]. I think it is fairly elementary to be able to prove that if n is 0(which happens iff x is a power of 3), 1162261467 % x = 0.
So, to check if a given integer x is a power of three, check if x > 0 && 1162261467 % x == 0.
Generalizing. To check if a given integer x is a power of a given integer y, check if x > 0 && Y % x == 0: Y is the largest power of y that can fit into an integer datatype.
The general idea is that if A is some power of Y, A can be expressed as B/Ya, where a is some integer and A < B. It follows the exact same principle for A > B. The A = B case is elementary.
I found this Solution
//Check for If A can be expressed as power of two integers
int isPower(int A)
{
int i,a;
double p;
if(A==1)
return 1;
for(int a=1; a<=sqrt(A);++a )
{
p=log(A)/log(a);
if(p-int(p)<0.000000001)
return 1;
}
return 0;
}
binarycoder.org
So I just got back for the ACM Programing competition and did pretty well but there was one problem that not one team got.
The Problem.
Start with an integer N0 which is greater than 0. Let N1 be the number of ones in the binary representation of N0. So, if N0 = 27, N1 = 4. For all i > 0, let Ni be the number of ones in the binary representation of Ni-1. This sequence will always converge to one. For any starting number, N0, let K be the minimum value of i >= 0 for which N1 = 1. For example, if N0 = 31, then N1 = 5, N2 = 2, N3 = 1, so K = 3.
Given a range of consecutive numbers and a value of X how many numbers in the range have a K value equal to X?
Input
There will be several test cases in the input. Each test case will consist of three integers on a single line:
LO HI X
Where LO and HI (1 <= LO <= HI <= 10^18) are the lower and upper limits of a range of integers, and X (0 <= X <= 10) is the target value for K. The input will end with a line of three 0s.
Output
For each test case output a single integer, representing the number of integers in the range from LO to HI (inclusive) which have a K value equal to X in the input. Print each Integer on its own line with no spaces. Do not print any blank lines between answers.
Sample Input
31 31 3
31 31 1
27 31 1
27 31 2
1023 1025 1
1023 1025 2
0 0 0
Sample Output
1
0
0
3
1
1
If you guys want I can include our answer or our problem, because finding for a small range is easy but I will give you a hint first your program needs to run in seconds not minutes. We had a successful solution but not an efficient algorithm to use a range similar to
48238 10^18 9
Anyway good luck and if the community likes these we had some more we could not solve that could be some good brain teasers for you guys. The competition allows you to use Python, C++, or Java—all three are acceptable in an answer.
So as a hint my coach said to think of how binary numbers count rather than checking every bit. I think that gets us a lot closer.
I think a key is first understanding the pattern of K values and how rapidly it grows. Basically, you have:
K(1) = 0
K(X) = K(bitcount(X))+1 for X > 1
So finding the smallest X values for a given K we see
K(1) = 0
K(2) = 1
K(3) = 2
K(7) = 3
K(127) = 4
K(170141183460469231731687303715884105727) = 5
So for an example like 48238 10^18 9 the answer is trivially 0. K=0 only for 1, and K=1 only for powers of 2, so in the range of interest, we'll pretty much only see K values of 2, 3 or 4, and never see K >= 5
edit
Ok, so we're looking for an algorithm to count the number of values with K=2,3,4 in a range of value LO..HI without iterating over the entire range. So the first step is to find the number of values in the range with bitcount(x)==i for i = 1..59 (since we only care about values up to 10^18 and 10^18 < 2^60). So break down the range lo..hi into subranges that are a power of 2 size and differ only in their lower n bits -- a range of the form x*(2^n)..(x+1)*(2^n)-1. We can break down the arbitray lo..hi range into such subranges easily. For each such subrange there will be choose(n, i) values with i+bitcount(x) set bits.
So we just add all the subranges together to get a vector of counts for 1..59, which we then iterate over, adding together those elements with the same K value to get our answer.
edit (fixed again to be be C89 compatible and work for lo=1/k=0)
Here's a C program to do what I previously described:
#include <stdio.h>
#include <string.h>
#include <assert.h>
int bitcount(long long x) {
int rv = 0;
while(x) { rv++; x &= x-1; }
return rv; }
long long choose(long long m, long long n) {
long long rv = 1;
int i;
for (i = 0; i < n; i++) {
rv *= m-i;
rv /= i+1; }
return rv; }
void bitcounts_p2range(long long *counts, long long base, int l2range) {
int i;
assert((base & ((1LL << l2range) - 1)) == 0);
counts += bitcount(base);
for (i = 0; i <= l2range; i++)
counts[i] += choose(l2range, i); }
void bitcounts_range(long long *counts, long long lo, long long hi) {
int l2range = 0;
while (lo + (1LL << l2range) - 1 <= hi) {
if (lo & (1LL << l2range)) {
bitcounts_p2range(counts, lo, l2range);
lo += 1LL << l2range; }
l2range++; }
while (l2range >= 0) {
if (lo + (1LL << l2range) - 1 <= hi) {
bitcounts_p2range(counts, lo, l2range);
lo += 1LL << l2range; }
l2range--; }
assert(lo == hi+1); }
int K(int x) {
int rv = 0;
while(x > 1) {
x = bitcount(x);
rv++; }
return rv; }
int main() {
long long counts[64];
long long lo, hi, total;
int i, k;
while (scanf("%lld%lld%d", &lo, &hi, &k) == 3) {
if (lo < 1 || lo > hi || k < 0) break;
if (lo == 0 || hi == 0 || k == 0) break;
total = 0;
if (lo == 1) {
lo++;
if (k == 0) total++; }
memset(counts, 0, sizeof(counts));
bitcounts_range(counts, lo, hi);
for (i = 1; i < 64; i++)
if (K(i)+1 == k)
total += counts[i];
printf("%lld\n", total); }
return 0; }
which runs just fine for values up to 2^63-1 (LONGLONG_MAX).
For 48238 1000000000000000000 3 it gives 513162479025364957, which certainly seems plausible
edit
giving the inputs of
48238 1000000000000000000 1
48238 1000000000000000000 2
48238 1000000000000000000 3
48238 1000000000000000000 4
gives outputs of
44
87878254941659920
513162479025364957
398959266032926842
Those add up to 999999999999951763 which is correct. The value for k=1 is correct (there are 44 powers of two in that range 2^16 up to 2^59). So while I'm not sure the other 3 values are correct, they're certainly plausible.
The idea behind this answer can help you develop very fast solution. Having ranges 0..2^N the complexity of a potential algorithm would be O(N) in the worst case (Assuming that complexity of a long arithmetic is O(1)) If programmed correctly it should easily handle N = 1000000 in a matter of milliseconds.
Imagine we have the following values:
LO = 0; (0000000000000000000000000000000)
HI = 2147483647; (1111111111111111111111111111111)
The lowest possible N1 in range LO..HI is 0
The highest possible N1 in range LO..HI is 31
So the computation of N2..NN part is done only for one of 32 values (i.e. 0..31).
Which can be done simply, even without a computer.
Now lets compute the amount of N1=X for a range of values LO..HI
When we have X = 0 we have count(N1=X) = 1 this is the following value:
1 0000000000000000000000000000000
When we have X = 1 we have count(N1=X) = 31 these are the following values:
01 1000000000000000000000000000000
02 0100000000000000000000000000000
03 0010000000000000000000000000000
...
30 0000000000000000000000000000010
31 0000000000000000000000000000001
When we have X = 2 we have the following pattern:
1100000000000000000000000000000
How many unique strings can be formed with 29 - '0' and 2 - '1'?
Imagine the rightmost '1'(#1) is cycling from left to right, we get the following picture:
01 1100000000000000000000000000000
02 1010000000000000000000000000000
03 1001000000000000000000000000000
...
30 1000000000000000000000000000001
Now we've got 30 unique strings while moving the '1'(#1) from left to right, it is now impossible to
create a unique string by moving the '1'(#1) in any direction. This means we should move '1'(#2) to the right,
let's also reset the position of '1'(#1) as left as possible remaining uniqueness, we get:
01 0110000000000000000000000000000
now we do the cycling of '1'(#1) once again
02 0101000000000000000000000000000
03 0100100000000000000000000000000
...
29 0100000000000000000000000000001
Now we've got 29 unique strings, continuing this whole operation 28 times we get the following expression
count(N1=2) = 30 + 29 + 28 + ... + 1 = 465
When we have X = 3 the picture remains similar but we are moving '1'(#1), '1'(#2), '1'(#3)
Moving the '1'(#1) creates 29 unique strings, when we start moving '1'(#2) we get
29 + 28 + ... + 1 = 435 unique strings, after that we are left to process '1'(#3) so we have
29 + 28 + ... + 1 = 435
28 + ... + 1 = 406
...
+ 1 = 1
435 + 406 + 378 + 351 + 325 + 300 + 276 +
253 + 231 + 210 + 190 + 171 + 153 + 136 +
120 + 105 + 091 + 078 + 066 + 055 + 045 +
036 + 028 + 021 + 015 + 010 + 006 + 003 + 001 = 4495
Let's try to solve the general case i.e. when we have N zeros and M ones.
Overall amount of permutations for the string of length (N + M) is equal to (N + M)!
The amount of '0' duplicates in this string is equal to N!
The amount of '1' duplicates in this string is equal to M!
thus receiving overall amount of unique strings formed of N zeros and M ones is
(N + M)! 32! 263130836933693530167218012160000000
F(N, M) = ============= => ========== = ====================================== = 4495
(N!) * (M!) 3! * 29! 6 * 304888344611713860501504000000
Edit:
F(N, M) = Binomial(N + M, M)
Now let's consider a real life example:
LO = 43797207; (0000010100111000100101011010111)
HI = 1562866180; (1011101001001110111001000000100)
So how do we apply our unique permutations formula to this example? Since we don't know how
many '1' is located below LO and how many '1' is located above HI.
So lets count these permutations below LO and above HI.
Lets remember how we cycled '1'(#1), '1'(#2), ...
1111100000000000000000000000000 => 2080374784
1111010000000000000000000000000 => 2046820352
1111001000000000000000000000000 => 2030043136
1111000000000000000000000000001 => 2013265921
1110110000000000000000000000000 => 1979711488
1110101000000000000000000000000 => 1962934272
1110100100000000000000000000000 => 1954545664
1110100010000000000000000000001 => 1950351361
As you see this cycling process decreases the decimal values smoothly. So we need to count amount of
cycles until we reach HI value. But we shouldn't be counting these values by one because
the worst case can generate up to 32!/(16!*16!) = 601080390 cycles, which we will be cycling very long :)
So we need cycle chunks of '1' at once.
Having our example we would want to count the amount of cycles of a transformation
1111100000000000000000000000000 => 1011101000000000000000000000000
1011101001001110111001000000100
So how many cycles causes the transformation
1111100000000000000000000000000 => 1011101000000000000000000000000
?
Lets see, the transformation:
1111100000000000000000000000000 => 1110110000000000000000000000000
is equal to following set of cycles:
01 1111100000000000000000000000000
02 1111010000000000000000000000000
...
27 1111000000000000000000000000001
28 1110110000000000000000000000000
So we need 28 cycles to transform
1111100000000000000000000000000 => 1110110000000000000000000000000
How many cycles do we need to transform
1111100000000000000000000000000 => 1101110000000000000000000000000
performing following moves we need:
1110110000000000000000000000000 28 cycles
1110011000000000000000000000000 27 cycles
1110001100000000000000000000000 26 cycles
...
1110000000000000000000000000011 1 cycle
and 1 cycle for receiving:
1101110000000000000000000000000 1 cycle
thus receiving 28 + 27 + ... + 1 + 1 = 406 + 1
but we have seen this value before and it was the result for the amount of unique permutations, which was
computed for 2 '1' and 27 '0'. This means that amount of cycles while moving
11100000000000000000000000000 => 01110000000000000000000000000
is equal to moving
_1100000000000000000000000000 => _0000000000000000000000000011
plus one additional cycle
so this means if we have M zeros and N ones and want to move the chunk of U '1' to the right we will need to
perform the following amount of cycles:
(U - 1 + M)!
1 + =============== = f(U, M)
M! * (U - 1)!
Edit:
f(U, M) = 1 + Binomial(U - 1 + M, M)
Now let's come back to our real life example:
LO = 43797207; (0000010100111000100101011010111)
HI = 1562866180; (1011101001001110111001000000100)
so what we want to do is count the amount cycles needed to perform the following
transformations (suppose N1 = 6)
1111110000000000000000000000000 => 1011101001000000000000000000000
1011101001001110111001000000100
this is equal to:
1011101001000000000000000000000 1011101001000000000000000000000
------------------------------- -------------------------------
_111110000000000000000000000000 => _011111000000000000000000000000 f(5, 25) = 118756
_____11000000000000000000000000 => _____01100000000000000000000000 f(2, 24) = 301
_______100000000000000000000000 => _______010000000000000000000000 f(1, 23) = 24
________10000000000000000000000 => ________01000000000000000000000 f(1, 22) = 23
thus resulting 119104 'lost' cycles which are located above HI
Regarding LO, there is actually no difference in what direction we are cycling
so for computing LO we can do reverse cycling:
0000010100111000100101011010111 0000010100111000100101011010111
------------------------------- -------------------------------
0000000000000000000000000111___ => 0000000000000000000000001110___ f(3, 25) = 2926
00000000000000000000000011_____ => 00000000000000000000000110_____ f(2, 24) = 301
Thus resulting 3227 'lost' cycles which are located below LO this means that
overall amount of lost cycles = 119104 + 3227 = 122331
overall amount of all possible cycles = F(6, 25) = 736281
N1 in range 43797207..1562866180 is equal to 736281 - 122331 = 613950
I wont provide the remaining part of the solution. It is not that hard to grasp the remaining part. Good luck!
I think it's a problem in Discrete mathematics,
assuming LOW is 0,
otherwise we can insert a function for summing numbers below LOW,
from numbers shown i understand the longest number will consist up to 60 binary digit at most
alg(HIGH,k)
l=len(HIGH)
sum=0;
for(i=0;i<l;i++)
{
count=(l choose i);
nwia=numbers_with_i_above(i,HIGH);
if canreach(i,k) sum+=(count-nwia);
}
all the numbers appear
non is listed twice
numbers_with_i_above is trivial
canreach with numbers up to 60 is easy
len is it length of a binary represention
Zobgib,
The key to this problem is not to understand how rapidly the growth of K's pattern grows, but HOW it grows, itself. The first step in this is to understand (as your coach said) how binary numbers count, as this determines everything about how K is determined. Binary numbers follow a pattern that is distinct when counting the number of positive bits. Its a single progressive repetitive pattern. I am going to demonstrate in an unusual way...
Assume i is an integer value. Assume b is the number of positive bits in i
i = 1;
b = 1;
i = 2; 3;
b = 1; 2;
i = 4; 5; 6; 7;
b = 1; 2; 2; 3;
i = 8; 9; 10; 11; 12; 13; 14; 15;
b = 1; 2; 2; 3; 2; 3; 3; 4;
i = 16; 17; 18; 19; 20; 21; 22; 23; 24; 25; 26; 27; 28; 29; 30; 31;
b = 1; 2; 2; 3; 2; 3; 3; 4; 2; 3; 3; 4; 3; 4; 4; 5;
I assure you, this pattern holds to infinity, but if needed you
should be able to find or construct a proof easily.
If you look at the data above, you'll notice a distinct pattern related to 2^n. Each time you have an integer exponent of 2, the pattern will reset by including the each term of previous pattern, and then each term of the previous pattern incremented by 1. As such, to get K, you just apply the new number to the pattern above. The key is to find a single expression (that is efficient) to receive your number of bits.
For demonstration, yet again, you can further extrapolate a new pattern off of this, because it is static and follows the same progression. Below is the original data modified with its K value (based on the recursion).
Assume i is an integer value. Assume b is the number of positive bits in i
i = 1;
b = 1;
K = 1;
i = 2; 3;
b = 1; 2;
K = 1; 2;
i = 4; 5; 6; 7;
b = 1; 2; 2; 3;
K = 1; 2; 2; 3;
i = 8; 9; 10; 11; 12; 13; 14; 15;
b = 1; 2; 2; 3; 2; 3; 3; 4;
K = 1; 2; 2; 3; 2; 3; 3; 2;
i = 16; 17; 18; 19; 20; 21; 22; 23; 24; 25; 26; 27; 28; 29; 30; 31;
b = 1; 2; 2; 3; 2; 3; 3; 4; 2; 3; 3; 4; 3; 4; 4; 5;
K = 1; 2; 2; 3; 2; 3; 3; 2; 2; 3; 3; 2; 3; 2; 2; 3;
If you notice, K follows a similar patterning, with a special condition... Everytime b is a power of 2, it actually lowers the K value by 2. Soooo, if you follow a binary progression, you should be able to easily map your K values. Since this pattern is dependant on powers of 2, and the pattern is dependant upon finding the nearest power of 2 and starting there, I propose the following solution. Take your LOW value and find the nearest power of 2 (p) such that 2^p < LOW. This can be done by "counting the bits" for just the lowest number. Again, once you know which exponent it is, you don't have to count the bits for any other number. You just increment through the pattern and you will have your b and hence K (which is following the same pattern).
Note: If you are particularly observant, you can use the previous b or K to determine the next. If the current i is odd, add 1 to the previous b. If the current i is divisible by 4, then you decrement b by either 1 or 2, dependent upon whether it's in the first 1/2 of the pattern or second half. And, of course, if i is a power of 2, start over at 1.
Fuzzical Logic
Pseudo-code Example (non-Optimized)
{ var LOW, HIGH
var power = 0
//Get Nearest Power Of 2
for (var i = 0 to 60) {
// Compare using bitwise AND
if (LOW bitAND (2 ^ i) = (2 ^ i)) {
if ((2 ^ i) <= LOW) {
set power to i
}
else {
// Found the Power: end the for loop
set i to 61
}
}
}
// Automatically 1 at a Power of 2
set numOfBits to 1
array numbersWithPositiveBits with 64 integers = 0
// Must create the pattern from Power of 2
set foundLOW to false
for (var j = (2^power) to HIGH) {
set lenOfPatten to (power + 1)
// Don't record until we have found the LOW value
if ((foundLOW is false) bitAND (j is equal to LOW)) {
set foundLOW to true
}
// If j is odd, increment numOfBits
if ((1 bitAND j) is equal to 1) {
increment numOfBits
}
else if (j modulus 4 == 0) {
decrement numOfBits accordingly //Figure this one out yourself, please
}
else if ((j - (2^power)) == (power + 1)) {
// We are at the next power
increment power
// Start pattern over
set numOfBits to 1
}
// Record if appropriate
if (foundLOW is equal to true) {
increment element numOfBits in array numbersWithPositiveBits
}
}
// From here, derive your K values.
You can solve this efficiently as follows:
ret = 0;
for (i = 1; i <= 64; i++) {
if (computeK(i) != desiredK) continue;
ret += numBelow(HIGH, i) - numBelow(LO - 1, i);
}
return ret;
The function numBelow(high, numSet) computes the number of integers less than or equal to high and greater than zero that have numSet bits set. To implement numBelow(high, numSet) efficiently, you can use something like the following:
numBelow(high, numSet) {
t = floor(lg(high));
ret = 0;
if (numBitsSet(high) == numSet) ret++;
while (numSet > 0 && t > 0) {
ret += nchoosek(t - 1, numSet);
numSet--;
while (--t > 0 && (((1 << t) & high) == 0));
}
return ret;
}
This is a full working example with c++17
#include <bits/stdc++.h>
using namespace std;
#define BASE_MAX 61
typedef unsigned long long ll;
ll combination[BASE_MAX][BASE_MAX];
vector<vector<ll>> NK(4);
int count_bit(ll n) {
int ret = 0;
while (n) {
if (n & 1) {
ret++;
}
n >>= 1;
}
return ret;
}
int get_leftmost_bit_index(ll n) {
int ret = 0;
while (n > 1) {
ret++;
n >>= 1;
}
return ret;
}
void pre_calculate() {
for (int i = 0; i < BASE_MAX; i++)
combination[i][0] = 1;
for (int i = 1; i < BASE_MAX; i++) {
for (int j = 1; j < BASE_MAX; j++) {
combination[i][j] = combination[i - 1][j] + combination[i - 1][j - 1];
}
}
NK[0].push_back(1);
for (int i = 2; i < BASE_MAX; i++) {
int bitCount = count_bit(i);
if (find(NK[0].begin(), NK[0].end(), bitCount) != NK[0].end()) {
NK[1].push_back(i);
}
}
for (int i = 1; i < BASE_MAX; i++) {
int bitCount = count_bit(i);
if (find(NK[1].begin(), NK[1].end(), bitCount) != NK[1].end()) {
NK[2].push_back(i);
}
}
for (int i = 1; i < BASE_MAX; i++) {
int bitCount = count_bit(i);
if (find(NK[2].begin(), NK[2].end(), bitCount) != NK[2].end()) {
NK[3].push_back(i);
}
}
}
ll how_many_numbers_have_n_bit_in_range(ll lo, ll hi, int bit_count) {
if (bit_count == 0) {
if (lo == 0) return 1;
else return 0;
}
if (lo == hi) {
return count_bit(lo) == bit_count;
}
int lo_leftmost = get_leftmost_bit_index(lo); // 100 -> 2
int hi_leftmost = get_leftmost_bit_index(hi); // 1101 -> 3
if (lo_leftmost == hi_leftmost) {
return how_many_numbers_have_n_bit_in_range(lo & ~(1LL << lo_leftmost), hi & ~(1LL << hi_leftmost),
bit_count - 1);
}
if (lo != 0) {
return how_many_numbers_have_n_bit_in_range(0, hi, bit_count) -
how_many_numbers_have_n_bit_in_range(0, lo - 1, bit_count);
}
ll ret = combination[hi_leftmost][bit_count];
ret += how_many_numbers_have_n_bit_in_range(1LL << hi_leftmost, hi, bit_count);
return ret;
}
int main(void) {
pre_calculate();
while (true) {
ll LO, HI;
int X;
scanf("%lld%lld%d", &LO, &HI, &X);
if (LO == 0 && HI == 0 && X == 0)
break;
switch (X) {
case 0:
cout << (LO == 1) << endl;
break;
case 1: {
int ret = 0;
ll power2 = 1;
for (int i = 0; i < BASE_MAX; i++) {
power2 *= 2;
if (power2 > HI)
break;
if (power2 >= LO)
ret++;
}
cout << ret << endl;
break;
}
case 2:
case 3:
case 4: {
vector<ll> &addedBitsSizes = NK[X - 1];
ll ret = 0;
for (auto bit_count_to_added: addedBitsSizes) {
ll result = how_many_numbers_have_n_bit_in_range(LO, HI, bit_count_to_added);
ret += result;
}
cout << ret << endl;
break;
}
default:
cout << 0 << endl;
break;
}
}
return 0;
}
I tried to solve it myself but I could not get any clue.
Please help me to solve this.
Are you supposed to use itoa() for this assignment? Because then you could use that to convert to a base 3 string, drop the last character, and then restore back to base 10.
Using the mathematical relation:
1/3 == Sum[1/2^(2n), {n, 1, Infinity}]
We have
int div3 (int x) {
int64_t blown_up_x = x;
for (int power = 1; power < 32; power += 2)
blown_up_x += ((int64_t)x) << power;
return (int)(blown_up_x >> 33);
}
If you can only use 32-bit integers,
int div3 (int x) {
int two_third = 0, four_third = 0;
for (int power = 0; power < 31; power += 2) {
four_third += x >> power;
two_third += x >> (power + 1);
}
return (four_third - two_third) >> 2;
}
The 4/3 - 2/3 treatment is used because x >> 1 is floor(x/2) instead of round(x/2).
EDIT: Oops, I misread the title's question. Multiply operator is forbidden as well.
Anyway, I believe it's good not to delete this answer for those who didn't know about dividing by non power of two constants.
The solution is to multiply by a magic number and then to extract the 32 leftmost bits:
divide by 3 is equivalent to multiply by 1431655766 and then to shift by 32, in C:
int divideBy3(int n)
{
return (n * 1431655766) >> 32;
}
See Hacker's Delight Magic number calculator.
x/3 = e^(ln(x) - ln(3))
Here's a solution implemented in C++:
#include <iostream>
int letUserEnterANumber()
{
int numberEnteredByUser;
std::cin >> numberEnteredByUser;
return numberEnteredByUser;
}
int divideByThree(int x)
{
std::cout << "What is " << x << " divided by 3?" << std::endl;
int answer = 0;
while ( answer + answer + answer != x )
{
answer = letUserEnterANumber();
}
}
;-)
if(number<0){ // Edited after comments
number = -(number);
}
quotient = 0;
while (number-3 >= 0){ //Edited after comments..
number = number-3;
quotient++;
}//after loop exits value in number will give you reminder
EDIT: Tested and working perfectly fine :(
Hope this helped. :-)
long divByThree(int x)
{
char buf[100];
itoa(x, buf, 3);
buf[ strlen(buf) - 1] = 0;
char* tmp;
long res = strtol(buf, &tmp, 3);
return res;
}
Sounds like homework :)
I image you can write a function which iteratively divides a number. E.g. you can model what you do with a pen and a piece of paper to divide numbers. Or you can use shift operators and + to figure out if your intermediate results is too small/big and iteratively apply corrections. I'm not going to write down the code though ...
unsigned int div3(unsigned int m) {
unsigned long long n = m;
n += n << 2;
n += n << 4;
n += n << 8;
n += n << 16;
return (n+m) >> 32;
}
int divideby3(int n)
{
int x=0;
if(n<3) { return 0; }
while(n>=3)
{
n=n-3;
x++;
}
return x;
}
you can use a property from the numbers: A number is divisible by 3 if its sum is divisible by3.
Take the individual digits from itoa() and then use switch function for them recursively with additions and itoa()
Hope this helps
This is very easy, so easy I'm only going to hint at the answer --
Basic boolean logic gates (and,or,not,xor,...) don't do division. Despite this handicap CPUs can do division. Your solution is obvious: find a reference which tells you how to build a divisor with boolean logic and write some code to implement that.
How about this, in some kind of Python like pseudo-code. It divides the answer into an integer part and a fraction part. If you want to convert it to a floating point representation then I am not sure of the best way to do that.
x = <a number>
total = x
intpart = 0
fracpart = 0
% Find the integer part
while total >= 3
total = total - 3
intpart = intpart + 1
% Fraction is what remains
fracpart = total
print "%d / 3 = %d + %d/3" % (x, intpart, fracpart)
Note that this will not work for negative numbers. To fix that you need to modify the algorithm:
total = abs(x)
is_neg = abs(x) != x
....
if is_neg
print "%d / 3 = -(%d + %d/3)" % (x, intpart, fracpart)
for positive integer division
result = 0
while (result + result + result < input)
result +=1
return result
Convert 1/3 into binary
so 1/3=0.01010101010101010101010101
and then just "multiply" whit this number using shifts and sum
There is a solution posted on http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=3776384&page=1&extra=#pid22323016
int DividedBy3(int A) {
int p = 0;
for (int i = 2; i <= 32; i += 2)
p += A << i;
return (-p);
}
Please say something about that, thanks:)
Here's a O(log(n)) way to do it with no bit shifting, so it can handle numbers up-to and including your biggest register size.
(c-style code)
long long unsigned Div3 (long long unsigned n)
{
// base case:
if (n < 6)
return (n >= 3);
long long unsigned division = 0;
long long unsigned remainder = 0;
// Used for results for only a single power of 2
// Initialise for 2^0
long long unsigned tmp_div = 0;
long long unsigned tmp_rem = 1;
for (long long unsigned pow_2 = 1; pow_2 && (pow_2 <= n); pow_2 += pow_2)
{
if (n & pow_2)
{
division += tmp_div;
remainder += tmp_rem;
}
if (tmp_rem == 1)
{
tmp_div += tmp_div;
tmp_rem = 2;
}
else
{
tmp_div += tmp_div + 1;
tmp_rem = 1;
}
}
return division + Div3(remainder);
}
It uses recursion, but note that the number drops exponentially in size at each iteration, so the time complexity (TC) is really:
O(TC) = O(log(n) + log(log(n)) + log(log(log(n))) + ... + z)
where z < 6.
Proof that it's O(log(n)):
We note that the number at each recursion strictly decreases (by at least 1):
So series = [log(log(n))] + [log(log(log(n)))] + [...] + [z]) has at most log(log(n)) sums.
implies:
series <= log(log(n))*log(log(n))
implies:
O(TC) = O(log(n) + log(log(n))*log(log(n)))
Now we note for n sufficiently large:
sqrt(x) > log(x)
iff:
x/sqrt(x) > log(x)
implies:
x/log(x) > log(x)
iff:
x > log(x)*log(x)
So O(x) > O(log(x)*log(x))
Now let x = log(n)
implies:
O(log(n)) > O(log(log(n))*log(log(n)))
and given:
O(TC) = O(log(n) + log(log(n))*log(log(n)))
implies:
O(TC) = O(log(n))
Slow and naive, but it should work, if an exact divisor exists. Addition is allowed, right?
for number from 1 to input
if number == input+input+input
return number
Extending it for fractional divisors is left as an exercise to the reader.
Basically test for +1 and +2 I think...
I saw this question, and pop up this idea.
There exists a constant time (pretty fast) method for integers of limited size (e.g. 32-bit integers).
Note that for an integer N that is a power of 3 the following is true:
For any M <= N that is a power of 3, M divides N.
For any M <= N that is not a power 3, M does not divide N.
The biggest power of 3 that fits into 32 bits is 3486784401 (3^20). This gives the following code:
bool isPower3(std::uint32_t value) {
return value != 0 && 3486784401u % value == 0;
}
Similarly for signed 32 bits it is 1162261467 (3^19):
bool isPower3(std::int32_t value) {
return value > 0 && 1162261467 % value == 0;
}
In general the magic number is:
== pow(3, floor(log(MAX) / log(3)))
Careful with floating point rounding errors, use a math calculator like Wolfram Alpha to calculate the constant. For example for 2^63-1 (signed int64) both C++ and Java give 4052555153018976256, but the correct value is 4052555153018976267.
while (n % 3 == 0) {
n /= 3;
}
return n == 1;
Note that 1 is the zeroth power of three.
Edit: You also need to check for zero before the loop, as the loop will not terminate for n = 0 (thanks to Bruno Rothgiesser).
I find myself slightly thinking that if by 'integer' you mean 'signed 32-bit integer', then (pseudocode)
return (n == 1)
or (n == 3)
or (n == 9)
...
or (n == 1162261467)
has a certain beautiful simplicity to it (the last number is 3^19, so there aren't an absurd number of cases). Even for an unsigned 64-bit integer there still be only 41 cases (thanks #Alexandru for pointing out my brain-slip). And of course would be impossible for arbitrary-precision arithmetic...
I'm surprised at this. Everyone seems to have missed the fastest algorithm of all.
The following algorithm is faster on average - and dramatically faster in some cases - than a simple while(n%3==0) n/=3; loop:
bool IsPowerOfThree(uint n)
{
// Optimizing lines to handle the most common cases extremely quickly
if(n%3 != 0) return n==1;
if(n%9 != 0) return n==3;
// General algorithm - works for any uint
uint r;
n = Math.DivRem(n, 59049, out r); if(n!=0 && r!=0) return false;
n = Math.DivRem(n+r, 243, out r); if(n!=0 && r!=0) return false;
n = Math.DivRem(n+r, 27, out r); if(n!=0 && r!=0) return false;
n += r;
return n==1 || n==3 || n==9;
}
The numeric constants in the code are 3^10, 3^5, and 3^3.
Performance calculations
In modern CPUs, DivRem is a often single instruction that takes a one cycle. On others it expands to a div followed by a mul and an add, which would takes more like three cycles altogether. Each step of the general algorithm looks long but it actually consists only of: DivRem, cmp, cmove, cmp, cand, cjmp, add. There is a lot of parallelism available, so on a typical two-way superscalar processor each step will likely execute in about 4 clock cycles, giving a guaranteed worst-case execution time of about 25 clock cycles.
If input values are evenly distributed over the range of UInt32, here are the probabilities associated with this algorithm:
Return in or before the first optimizing line: 66% of the time
Return in or before the second optimizing line: 89% of the time
Return in or before the first general algorithm step: 99.998% of the time
Return in or before the second general algorithm step: 99.99998% of the time
Return in or before the third general algorithm step: 99.999997% of the time
This algorithm outperforms the simple while(n%3==0) n/=3 loop, which has the following probabilities:
Return in the first iteration: 66% of the time
Return in the first two iterations: 89% of the time
Return in the first three iterations: 97% of the time
Return in the first four iterations: 98.8% of the time
Return in the first five iterations: 99.6% of the time ... and so on to ...
Return in the first twelve iterations: 99.9998% of the time ... and beyond ...
What is perhaps even more important, this algorithm handles midsize and large powers of three (and multiples thereof) much more efficiently: In the worst case the simple algorithm will consume over 100 CPU cycles because it will loop 20 times (41 times for 64 bits). The algorithm I present here will never take more than about 25 cycles.
Extending to 64 bits
Extending the above algorithm to 64 bits is trivial - just add one more step. Here is a 64 bit version of the above algorithm optimized for processors without efficient 64 bit division:
bool IsPowerOfThree(ulong nL)
{
// General algorithm only
ulong rL;
nL = Math.DivRem(nL, 3486784401, out rL); if(nL!=0 && rL!=0) return false;
nL = Math.DivRem(nL+rL, 59049, out rL); if(nL!=0 && rL!=0) return false;
uint n = (uint)nL + (uint)rL;
n = Math.DivRem(n, 243, out r); if(n!=0 && r!=0) return false;
n = Math.DivRem(n+r, 27, out r); if(n!=0 && r!=0) return false;
n += r;
return n==1 || n==3 || n==9;
}
The new constant is 3^20. The optimization lines are omitted from the top of the method because under our assumption that 64 bit division is slow, they would actually slow things down.
Why this technique works
Say I want to know if "100000000000000000" is a power of 10. I might follow these steps:
I divide by 10^10 and get a quotient of 10000000 and a remainder of 0. These add to 10000000.
I divide by 10^5 and get a quotient of 100 and a remainder of 0. These add to 100.
I divide by 10^3 and get a quotient of 0 and a remainderof 100. These add to 100.
I divide by 10^2 and get a quotient of 1 and a remainder of 0. These add to 1.
Because I started with a power of 10, every time I divided by a power of 10 I ended up with either a zero quotient or a zero remainder. Had I started out with anything except a power of 10 I would have sooner or later ended up with a nonzero quotient or remainder.
In this example I selected exponents of 10, 5, and 3 to match the code provided previously, and added 2 just for the heck of it. Other exponents would also work: There is a simple algorithm for selecting the ideal exponents given your maximum input value and the maximum power of 10 allowed in the output, but this margin does not have enough room to contain it.
NOTE: You may have been thinking in base ten throughout this explanation, but the entire explanation above can be read and understood identically if you're thinking in in base three, except the exponents would have been expressed differently (instead of "10", "5", "3" and "2" I would have to say "101", "12", "10" and "2").
This is a summary of all good answers below this questions, and the performance figures can be found from the LeetCode article.
1. Loop Iteration
Time complexity O(log(n)), space complexity O(1)
public boolean isPowerOfThree(int n) {
if (n < 1) {
return false;
}
while (n % 3 == 0) {
n /= 3;
}
return n == 1;
}
2. Base Conversion
Convert the integer to a base 3 number, and check if it is written as a leading 1 followed by all 0. It is inspired by the solution to check if a number is power of 2 by doing n & (n - 1) == 0
Time complexity: O(log(n)) depending on language and compiler, space complexity: O(log(n))
public boolean isPowerOfThree(int n) {
return Integer.toString(n, 3).matches("^10*$");
}
3. Mathematics
If n = 3^i, then i = log(n) / log(3), and thus comes to the solution
Time complexity: depending on language and compiler, space complexity: O(1)
public boolean isPowerOfThree(int n) {
return (Math.log(n) / Math.log(3) + epsilon) % 1 <= 2 * epsilon;
}
4. Integer Limitations
Because 3^19 = 1162261467 is the largest power of 3 number fits in a 32 bit integer, thus we can do
Time complexity: O(1), space complexity: O(1)
public boolean isPowerOfThree(int n) {
return n > 0 && 1162261467 % n == 0;
}
5. Integer Limitations with Set
The idea is similar to #4 but use a set to store all possible power of 3 numbers (from 3^0 to 3^19). It makes code more readable.
6. Recursive (C++11)
This solution is specific to C++11, using template meta programming so that complier will replace the call isPowerOf3<Your Input>::cValue with calculated result.
Time complexity: O(1), space complexity: O(1)
template<int N>
struct isPowerOf3 {
static const bool cValue = (N % 3 == 0) && isPowerOf3<N / 3>::cValue;
};
template<>
struct isPowerOf3<0> {
static const bool cValue = false;
};
template<>
struct isPowerOf3<1> {
static const bool cValue = true;
};
int main() {
cout<<isPowerOf3<1162261467>::cValue;
return 0;
}
if (log n) / (log 3) is integral then n is a power of 3.
Recursively divide by 3, check that the remainder is zero and re-apply to the quotient.
Note that 1 is a valid answer as 3 to the zero power is 1 is an edge case to beware.
Very interesting question, I like the answer from starblue,
and this is a variation of his algorithm which will converge little bit faster to the solution:
private bool IsPow3(int n)
{
if (n == 0) return false;
while (n % 9 == 0)
{
n /= 9;
}
return (n == 1 || n == 3);
}
Between powers of two there is at most one power of three.
So the following is a fast test:
Find the binary logarithm of n by finding the position of the leading 1 bit in the number. This is very fast, as modern processors have a special instruction for that. (Otherwise you can do it by bit twiddling, see Bit Twiddling Hacks).
Look up the potential power of three in a table indexed by this position and compare to n (if there is no power of three you can store any number with a different binary logarithm).
If they are equal return yes, otherwise no.
The runtime depends mostly on the time needed for accessing the table entry. If we are using machine integers the table is small, and probably in cache (we are using it many millions of times, otherwise this level of optimization wouldn't make sense).
Here is a nice and fast implementation of Ray Burns' method in C:
bool is_power_of_3(unsigned x) {
if (x > 0x0000ffff)
x *= 0xb0cd1d99; // multiplicative inverse of 59049
if (x > 0x000000ff)
x *= 0xd2b3183b; // multiplicative inverse of 243
return x <= 243 && ((x * 0x71c5) & 0x5145) == 0x5145;
}
It uses the multiplicative inverse trick for to first divide by 3^10 and then by 3^5. Finally, it needs to check whether the result is 1, 3, 9, 27, 81, or 243, which is done by some simple hashing that I found by trial-and-error.
On my CPU (Intel Sandy Bridge), it is quite fast, but not as fast as the method of starblue that uses the binary logarithm (which is implemented in hardware on that CPU). But on a CPU without such an instruction, or when lookup tables are undesirable, it might be an alternative.
How large is your input? With O(log(N)) memory you can do faster, O(log(log(N)). Precompute the powers of 3 and then do a binary search on the precomputed values.
Simple and constant-time solution:
return n == power(3, round(log(n) / log(3)))
For really large numbers n, you can use the following math trick to speed up the operation of
n % 3 == 0
which is really slow and most likely the choke point of any algorithm that relies on repeated checking of remainders. You have to understand modular arithmetic to follow what I am doing, which is part of elementary number theory.
Let x = Σ k a k 2 k be the number of interest. We can let the upper bound of the sum be ∞ with the understanding that a k = 0 for some k > M. Then
0 ≡ x ≡ Σ k a k 2 k ≡ Σ k a 2k 2 2k + a 2k+1 2 2k+1 ≡ Σ k 2 2k ( a 2k + a 2k+1 2) ≡ Σ k a 2k + a 2k+1 2 (mod 3)
since 22k ≡ 4 k ≡ 1k ≡ 1 (mod 3).
Given a binary representation of a number x with 2n+1 bits as
x0 x1 x2 ... x2n+1
where xk ∈{0,1} you can group odd even pairs
(x0 x1) (x2 x3) ... (x2n x2n+1).
Let q denote the number of pairings of the form (1 0) and let r denote the number of pairings of the form (0 1). Then it follows from the equation above that 3 | x if and only if 3 | (q + 2r). Furthermore, you can show that 3|(q + 2r) if and only if q and r have the same remainder when divided by 3.
So an algorithm for determining whether a number is divisible by 3 could be done as follows
q = 0, r = 0
for i in {0,1, .., n}
pair <- (x_{2i} x_{2i+1})
if pair == (1 0)
switch(q)
case 0:
q = 1;
break;
case 1:
q = 2;
break;
case 2:
q = 0;
break;
else if pair == (0 1)
switch(r)
case 0:
r = 1;
break;
case 1:
r = 2;
break;
case 2:
r = 0;
return q == r
This algorithm is more efficient than the use of %.
--- Edit many years later ----
I took a few minutes to implement a rudimentary version of this in python that checks its true for all numbers up to 10^4. I include it below for reference. Obviously, to make use of this one would implement this as close to hardware as possible. This scanning technique can be extended to any number that one wants to by altering the derivation. I also conjecture the 'scanning' portion of the algorithm can be reformulated in a recursive O(log n) type formulation similar to a FFT, but I'd have to think on it.
#!/usr/bin/python
def bits2num(bits):
num = 0
for i,b in enumerate(bits):
num += int(b) << i
return num
def num2bits(num):
base = 0
bits = list()
while True:
op = 1 << base
if op > num:
break
bits.append(op&num !=0)
base += 1
return "".join(map(str,map(int,bits)))[::-1]
def div3(bits):
n = len(bits)
if n % 2 != 0:
bits = bits + '0'
n = len(bits)
assert n % 2 == 0
q = 0
r = 0
for i in range(n/2):
pair = bits[2*i:2*i+2]
if pair == '10':
if q == 0:
q = 1
elif q == 1:
q = 2
elif q == 2:
q = 0
elif pair == '01':
if r == 0:
r = 1
elif r == 1:
r = 2
elif r == 2:
r = 0
else:
pass
return q == r
for i in range(10000):
truth = (i % 3) == 0
bits = num2bits(i)
check = div3(bits)
assert truth == check
You can do better than repeated division, which takes O(lg(X) * |division|) time. Essentially you do a binary search on powers of 3. Really we will be doing a binary search on N, where 3^N = input value). Setting the Pth binary digit of N corresponds to multiplying by 3^(2^P), and values of the form 3^(2^P) can be computed by repeated squaring.
Algorithm
Let the input value be X.
Generate a list L of repeated squared values which ends once you pass X.
Let your candidate value be T, initialized to 1.
For each E in reversed L, if T*E <= X then let T *= E.
Return T == X.
Complexity:
O(lg(lg(X)) * |multiplication|)
- Generating and iterating over L takes lg(lg(X)) iterations, and multiplication is the most expensive operation in an iteration.
The fastest solution is either testing if n > 0 && 3**19 % n == 0 as given in another answer or perfect hashing (below). First I'm giving two multiplication-based solutions.
Multiplication
I wonder why everybody missed that multiplication is much faster than division:
for (int i=0, pow=1; i<=19, pow*=3; ++i) {
if (pow >= n) {
return pow == n;
}
}
return false;
Just try all powers, stop when it grew too big. Avoid overflow as 3**19 = 0x4546B3DB is the biggest power fitting in signed 32-bit int.
Multiplication with binary search
Binary search could look like
int pow = 1;
int next = pow * 6561; // 3**8
if (n >= next) pow = next;
next = pow * 81; // 3**4
if (n >= next) pow = next;
next = pow * 81; // 3**4; REPEATED
if (n >= next) pow = next;
next = pow * 9; // 3**2
if (n >= next) pow = next;
next = pow * 3; // 3**1
if (n >= next) pow = next;
return pow == next;
One step is repeated, so that the maximum exponent 19 = 8+4+4+2+1 can exactly be reached.
Perfect hashing
There are 20 powers of three fitting into a signed 32-bit int, so we take a table of 32 elements. With some experimentation, I found the perfect hash function
def hash(x):
return (x ^ (x>>1) ^ (x>>2)) & 31;
mapping each power to a distinct index between 0 and 31. The remaining stuff is trivial:
// Create a table and fill it with some power of three.
table = [1 for i in range(32)]
// Fill the buckets.
for n in range(20): table[hash(3**n)] = 3**n;
Now we have
table = [
1162261467, 1, 3, 729, 14348907, 1, 1, 1,
1, 1, 19683, 1, 2187, 81, 1594323, 9,
27, 43046721, 129140163, 1, 1, 531441, 243, 59049,
177147, 6561, 1, 4782969, 1, 1, 1, 387420489]
and can test very fast via
def isPowerOfThree(x):
return table[hash(x)] == x
Your question is fairly easy to answer by defining a simple function to run the check for you. The example implementation shown below is written in Python but should not be difficult to rewrite in other languages if needed. Unlike the last version of this answer, the code shown below is far more reliable.
Python 3.6.0 (v3.6.0:41df79263a11, Dec 23 2016, 08:06:12) [MSC v.1900 64 bit (AMD64)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> import math
>>> def power_of(number, base):
return number == base ** round(math.log(number, base))
>>> base = 3
>>> for power in range(21):
number = base ** power
print(f'{number} is '
f'{"" if power_of(number, base) else "not "}'
f'a power of {base}.')
number += 1
print(f'{number} is '
f'{"" if power_of(number, base) else "not "}'
f'a power of {base}.')
print()
1 is a power of 3.
2 is not a power of 3.
3 is a power of 3.
4 is not a power of 3.
9 is a power of 3.
10 is not a power of 3.
27 is a power of 3.
28 is not a power of 3.
81 is a power of 3.
82 is not a power of 3.
243 is a power of 3.
244 is not a power of 3.
729 is a power of 3.
730 is not a power of 3.
2187 is a power of 3.
2188 is not a power of 3.
6561 is a power of 3.
6562 is not a power of 3.
19683 is a power of 3.
19684 is not a power of 3.
59049 is a power of 3.
59050 is not a power of 3.
177147 is a power of 3.
177148 is not a power of 3.
531441 is a power of 3.
531442 is not a power of 3.
1594323 is a power of 3.
1594324 is not a power of 3.
4782969 is a power of 3.
4782970 is not a power of 3.
14348907 is a power of 3.
14348908 is not a power of 3.
43046721 is a power of 3.
43046722 is not a power of 3.
129140163 is a power of 3.
129140164 is not a power of 3.
387420489 is a power of 3.
387420490 is not a power of 3.
1162261467 is a power of 3.
1162261468 is not a power of 3.
3486784401 is a power of 3.
3486784402 is not a power of 3.
>>>
NOTE: The last revision has caused this answer to become nearly the same as TMS' answer.
Set based solution...
DECLARE #LastExponent smallint, #SearchCase decimal(38,0)
SELECT
#LastExponent = 79, -- 38 for bigint
#SearchCase = 729
;WITH CTE AS
(
SELECT
POWER(CAST(3 AS decimal(38,0)), ROW_NUMBER() OVER (ORDER BY c1.object_id)) AS Result,
ROW_NUMBER() OVER (ORDER BY c1.object_id) AS Exponent
FROM
sys.columns c1, sys.columns c2
)
SELECT
Result, Exponent
FROM
CTE
WHERE
Exponent <= #LastExponent
AND
Result = #SearchCase
With SET STATISTICS TIME ON it record the lowest possible, 1 millisecond.
Another approach is to generate a table on compile time. The good thing is, that you can extend this to powers of 4, 5, 6, 7, whatever
template<std::size_t... Is>
struct seq
{ };
template<std::size_t N, std::size_t... Is>
struct gen_seq : gen_seq<N-1, N-1, Is...>
{ };
template<std::size_t... Is>
struct gen_seq<0, Is...> : seq<Is...>
{ };
template<std::size_t N>
struct PowersOfThreeTable
{
std::size_t indexes[N];
std::size_t values[N];
static constexpr std::size_t size = N;
};
template<typename LambdaType, std::size_t... Is>
constexpr PowersOfThreeTable<sizeof...(Is)>
generatePowersOfThreeTable(seq<Is...>, LambdaType evalFunc)
{
return { {Is...}, {evalFunc(Is)...} };
}
template<std::size_t N, typename LambdaType>
constexpr PowersOfThreeTable<N> generatePowersOfThreeTable(LambdaType evalFunc)
{
return generatePowersOfThreeTable(gen_seq<N>(), evalFunc);
}
template<std::size_t Base, std::size_t Exp>
struct Pow
{
static constexpr std::size_t val = Base * Pow<Base, Exp-1ULL>::val;
};
template<std::size_t Base>
struct Pow<Base, 0ULL>
{
static constexpr std::size_t val = 1ULL;
};
template<std::size_t Base>
struct Pow<Base, 1ULL>
{
static constexpr std::size_t val = Base;
};
constexpr std::size_t tableFiller(std::size_t val)
{
return Pow<3ULL, val>::val;
}
bool isPowerOfThree(std::size_t N)
{
static constexpr unsigned tableSize = 41; //choosen by fair dice roll
static constexpr PowersOfThreeTable<tableSize> table =
generatePowersOfThreeTable<tableSize>(tableFiller);
for(auto a : table.values)
if(a == N)
return true;
return false;
}
I measured times (C#, Platform target x64) for some solutions.
using System;
class Program
{
static void Main()
{
var sw = System.Diagnostics.Stopwatch.StartNew();
for (uint n = ~0u; n > 0; n--) ;
Console.WriteLine(sw.Elapsed); // nada 1.1 s
sw.Restart();
for (uint n = ~0u; n > 0; n--) isPow3a(n);
Console.WriteLine(sw.Elapsed); // 3^20 17.3 s
sw.Restart();
for (uint n = ~0u; n > 0; n--) isPow3b(n);
Console.WriteLine(sw.Elapsed); // % / 10.6 s
Console.Read();
}
static bool isPow3a(uint n) // Elric
{
return n > 0 && 3486784401 % n == 0;
}
static bool isPow3b(uint n) // starblue
{
if (n > 0) while (n % 3 == 0) n /= 3;
return n == 1;
}
}
Another way (of splitting hairs).
using System;
class Program
{
static void Main()
{
Random rand = new Random(0); uint[] r = new uint[512];
for (int i = 0; i < 512; i++)
r[i] = (uint)(rand.Next(1 << 30)) << 2 | (uint)(rand.Next(4));
var sw = System.Diagnostics.Stopwatch.StartNew();
for (int i = 1 << 23; i > 0; i--)
for (int j = 0; j < 512; j++) ;
Console.WriteLine(sw.Elapsed); // 0.3 s
sw.Restart();
for (int i = 1 << 23; i > 0; i--)
for (int j = 0; j < 512; j++) isPow3c(r[j]);
Console.WriteLine(sw.Elapsed); // 10.6 s
sw.Restart();
for (int i = 1 << 23; i > 0; i--)
for (int j = 0; j < 512; j++) isPow3b(r[j]);
Console.WriteLine(sw.Elapsed); // 9.0 s
Console.Read();
}
static bool isPow3c(uint n)
{ return (n & 1) > 0 && 3486784401 % n == 0; }
static bool isPow3b(uint n)
{ if (n > 0) while (n % 3 == 0) n /= 3; return n == 1; }
}
Python program to check whether the number is a POWER of 3 or not.
def power(Num1):
while Num1 % 3 == 0:
Num1 /= 3
return Num1 == 1
Num1 = int(input("Enter a Number: "))
print(power(Num1))
Python solution
from math import floor
from math import log
def IsPowerOf3(number):
p = int(floor(log(number) / log(3)))
power_floor = pow(3, p)
power_ceil = power_floor * 3
if power_floor == number or power_ceil == number:
return True
return False
This is much faster than the simple divide by 3 solution.
Proof: 3 ^ p = number
p log(3) = log(number) (taking log both side)
p = log(number) / log(3)
Here's a general algorithm for finding out if a number is a power of another number:
bool IsPowerOf(int n,int b)
{
if (n > 1)
{
while (n % b == 0)
{
n /= b;
}
}
return n == 1;
}
#include<iostream>
#include<string>
#include<cmath>
using namespace std;
int main()
{
int n, power=0;
cout<<"enter a number"<<endl;
cin>>n;
if (n>0){
for(int i=0; i<=n; i++)
{
int r=n%3;
n=n/3;
if (r==0){
power++;
}
else{
cout<<"not exactly power of 3";
return 0;
}
}
}
cout<<"the power is "<<power<<endl;
}
This is a constant time method! Yes. O(1). For numbers of fixed length, say 32-bits.
Given that we need to check if an integer n is a power of 3, let us start thinking about this problem in terms of what information is already at hand.
1162261467 is the largest power of 3 that can fit into an Java int.
1162261467 = 3^19 + 0
The given n can be expressed as [(a power of 3) + (some x)]. I think it is fairly elementary to be able to prove that if x is 0(which happens iff n is a power of 3), 1162261467 % n = 0.
The general idea is that if X is some power of 3, X can be expressed as Y/3a, where a is some integer and X < Y. It follows the exact same principle for Y < X. The Y = X case is elementary.
So, to check if a given integer n is a power of three, check if n > 0 && 1162261467 % n == 0.
Python:
return n > 0 and 1162261467 % n == 0
OR Calculate log:
lg = round(log(n,3))
return 3**lg == n
1st approach is faster than the second one.