Cycle Detection Algorithm - algorithm

Say I have a function f:
f(0) = 0
f(i) = (i - 1) % 4
f(0..12):
0 0 1 2 3 0 1 2 3 0 1 2 3
I want to find the cycle start and the cycle length, which are 1 and 4, respectively.
The tortoise and hare algorithm works with iterated functions, but I don't have an iterated function.
Are there other algorithms that work with non-iterated functions or can the tortoise and hare algorithm be modified for this?
Edit:
Using Jason S's answer, I managed to come up with this, which seems to be working:
public static Tuple<int, int> ModifiedTortoiseHare(Func<int, int> f, int x0 = 0, int checks = 4)
{
for (; ; x0++)
{
int lam = 0, tortoise, hare;
do
{
lam++;
tortoise = f(x0 + lam);
hare = f(x0 + 2 * lam);
} while (tortoise != hare);
int mu = -1;
do
{
mu++;
tortoise = f(x0 + mu);
hare = f(x0 + mu + lam);
} while (tortoise != hare);
if (mu != 0) continue;
bool correct = true;
int lamCheckMax = lam * checks;
for (int x = 0; x < lamCheckMax; x++)
{
if (f(x0 + x + mu) != f(x0 + x + mu + lam))
{
correct = false;
if (mu != 0) x0 += mu - 1;
break;
}
}
if (correct) return Tuple.Create(x0 + mu, lam);
}
}

If the function is a "black box", and you have the ability to find f(x) for any individual x (whether valid for real numbers or only integers), but you don't know anything else, there is no general way to find a cycle start and length. For example, consider the function
f(k) = (k - 1) % 4 + g(k)
g(k) = max(0, k-1000000)
then f(k) looks like it repeats every 4 integers, but then when you get to k = 1000000, then the pattern stops.
If the function has a finite range, and you can test for all integers, the tortoise/hare algorithm (= Floyd's cycle-finding algorithm) can be used to help.
Instead of iterating function evaluation, calculate f(k0 + k) and f(k0 + 2*k) until they match, at which point the suspected period is k, and you just need to repeat through all values to verify that the cycle continues.
Your question appears to be an equivalent problem as "How should I find repeated word sequences?" which has a number of answers.

for the fn you have given since its dividing by 4 the length is four and since there is no value added to it 0 is actually the start of the cycle and not 1.you can actually observe this if you do implement it using a graph as has been pointed out.
Since these are fn values you could use a linked list instead, and on every value the fn returns, add it to the list if its not already there, else u can have a cycle.assuming that there is only 1 cycle..

Related

Max Product of a string that requires K multiplication operators to be inserted

Maximum Product.
The input to the problem is a string Z = z1,z2.....zn where each zi is any number between 1...9 and an integer k where 0 <= k < n.
An example string is Z = 8473817, which is of length n = 7. We want to insert k multiplication operators X into the string so that the mathematical result of the expression
is the largest possible. There are n - 1 possible locations for the operators,
namely, after the ith character where i = 1,....., n - 1.
For example, for input Z = 21322 and k = 2, then one possible way to insert the X operators
is: 2 X 1 X 322 = 644, another possibility is 21 X 3 X 22 = 1386.
Design a dynamic programming to output the maximum product
obtainable from inserting exactly k multiplication operators X into the string.
You can assume that all the multiplication operations in your algorithm take
O(1) time.
I am approaching this using the Matrix Chain Multiplication method where you compute smaller subproblem along the upper diagonal.
This works when K=1 i.e. one multiplication operator is inserted.
In the picture below, I have used 8473817 as an example and shown that 8473 X 817 yields the highest product.
How do I scale this solution for K > 1 and K < N.
Update: adding a pseudo code.
let A(i,j) store the max product for the strings A(i...j) 1 < i < j < n
for i = 1 -> n:
A(i,i) = Z(i)
for s = 1 -> n-1:
for i = 1 -> n-s:
j = i + s
A(i,j) = 0
for l = i -> j-1:
A(i,j) = max (A(i,j), A(i,l) * A(l+1,j)
return A(1,n)
The above code works when k = 1. How do I scale this up when k > 1 and less than n
Update
Based on #trincot solution, I revamped the soln to not use memoization
Sub problem Defn
Let T(i) store the start offset where inserting the X operator in Z yields max value for i : 1 < i < k.
Pseudo code
`
T(0) = 0
for i = 1 -> k:
max = 0
for j = T(i-1) + 1 -> n:
result = Z[1..j] * Z[j+1..n]
if result > max
max = result
T(i) = j
val = 1
for i = 1 -> k:
val = val * Z[T(i-1)+1...T(i)]
val = val * Z[T(k)+1..n]
Your pseudo code is a dynamic programming solution where you use memoization for every possible slice of z (2 dimensions, starting and ending offset). However, you would only need to memoize the best result for any suffix of z, so you would only need one (starting) offset. A second dimension in your memoization would then be used for the value of k (the number of remaining multiplications).
So you would still need a 2-dimensional table for memoization, but one index would be for k and the other for an offset in z.
Here is an implementation in JavaScript:
function solve(z, k) {
// Initialise a kxl array (where l is the length of z), filled with zeroes.
const memo = Array.from({length: k + 1}, () => Array(z.length + 1).fill(0));
function recur(z, k) {
if (k == 0) return z;
let result = memo[k][z.length];
if (result == 0) {
for (let i = 1; i <= z.length - k; i++) {
result = Math.max(result, +z.slice(0, i) * recur(z.slice(i), k - 1));
}
memo[k][z.length] = result;
}
return result;
}
return recur(z, k);
}
// A few example runs:
console.log(solve('8473817', 1)); // 6922441
console.log(solve('21322', 2)); // 1368
console.log(solve('191111', 2)); // 10101
Bottom up
The same can be done in an iterative algorithm -- bottom-up instead of top-down. Here we can save one dimension of the memoization array, as the same array can be re-used for the next value of k as it increases from 0 to its final value:
function solve(z, k) {
const memo = Array(z.length);
// Initialise for k=0:
// the best product in a suffix is the suffix itself
for (let i = 0; i < z.length; i++) {
memo[i] = +z.slice(i);
}
for (let kk = 1; kk <= k; kk++) {
for (let i = 0; i < z.length - kk; i++) {
// find best position for multiplication
let result = 0;
for (let j = i + 1; j < z.length - kk + 1; j++) {
result = Math.max(result, +z.slice(i, j) * memo[j]);
}
memo[i] = result;
}
}
return memo[0];
}
// A few example runs:
console.log(solve('8473817', 1)); // 6922441
console.log(solve('21322', 2)); // 1368
console.log(solve('191111', 2)); // 10101
(Code not supplied because this is homework.)
You have found that you can use the method once and get a solution for k=1.
Can you do it and find the best solution ending at every position in the string?
Now can you use the output of that second generalization and a similar method to get a complete solution for k=2?
Now can you write this a loop to solve for arbitrary k?
If you can do all that, then finishing is easy.
You have n-1 positions and k operators to insert. To me that looks like a binary number with n-1 bits including k 1's and the other positions set to 0.
Systematically generate all permutations of [0..01..1], insert multiplication operators at the 1 positions and calculate the result for each permutation.

how to get to the target floor in minimum time if one can move to N + 1, N - 1 and 2 * N in one minute?

This is a problem I was asked to solve during an interview, but the code I implemented during interview cannot pass all test cases, the problem is just as title said, given N and T (T >= N), which are initial floor and target floor respectively, one can move to current floor + 1, current floor - 1 or 2 * current floor in one minute, what's the minimum time need to reach the target? I think it's a typical DP problem, this is how I did in interview
#lru_cache(None)
def solve(cur):
if cur >= target: return cur - target
if cur * 2 >= target:
# if current floor * 2 < target, we can move to current floor + 1 each time or move backward to (target + 1) // 2 and move current floor * 2 next time, and if target is odd, we need extra 1 move
return min(target - cur, cur - (target + 1) // 2 + 1 + (target % 2))
return min(solve(cur + 1), solve(cur * 2)) + 1
I test it with some cases, it seems to work, I cannot figure out why it cannot pass all test cases during interview,
Update---------------------------------------------------------------
I tried using Dijkstra to solve this, but the code become a bit of mess, than I thought if the problem askes to find shortest distance, maybe we can use BFS, and I think it's the right solution, so below is the code
def solve():
while(True):
N, T = map(int, input().split())
q = deque([N])
vis = [False] * (T * 2)
vis[N] = True
steps = 0
while q:
for _ in range(len(q)):
u = q.popleft()
if u == T:
print(f'reach target in {steps} minutes')
break
cand = [u - 1, u + 1, u * 2] if u < T else [u - 1]
for v in cand:
if v > 0 and not vis[v]:
vis[v] = True
q.append(v)
steps += 1
An easy way is to start from the target T and to found how many iterations we need to go down to initial value N. Here, the allowed operations are +1, -1 and division by 2.
The key point is that division by 2 is only allowed for even value of T. Moreover, if T is even effectively, then it seems clear that division by 2 is the road to take, except if T is near enough to N. This little issue is solved by comparing 1 + nsteps(N, T/2) with T - N.
If T is odd, we must have to compare nsteps(N, T-1) with nsteps(N, T+1).
Last but not least, if T is less than N, then the number of steps is equal to N - T.
Complexity: ??
Here is a simple C++ implementation to illustrate the algorithm. It should be easy to adapt it in any language.
#include <iostream>
#include <algorithm>
int nsteps (int n, int t) {
if (t <= n) {
return n - t;
}
if (t%2 == 0) {
return std::min (1 + nsteps(n, t/2), t-n);
}
return 1 + std::min (nsteps(n, t-1), nsteps(n, t+1));
}
int main () {
int n, t;
std::cin >> n >> t;
std::cout << nsteps (n, t) << std::endl;
return 0;
}
In practice, as noted in a comment by #David Eisenstat, it is still slow, at least in some occasions. For example, for an input 1 1431655765, it needs 10891541 calls of the function. I modified the code hereafter, by using the value of T modulo 4 in order to speed it up: if T is large enough, we can decide betweens the two roads when Tis odd. In the same test case, only 46 calls are needed now.
In this case, the complexity seems indeed equal to O(log T).
int cpt2 = 0;
long long int nsteps2 (long long int n, long long int t) {
cpt2++;
if (t <= n) {
return n - t;
}
if (t%2 == 0) {
return std::min (1ll + nsteps2(n, t/2), t-n);
}
if (t/4 < n) return 1ll + std::min (nsteps2(n, t-1), nsteps2(n, t+1));
if (t%4 == 1) return 1ll + nsteps2(n, t-1);
else return 1ll + nsteps2(n, t+1);
}
As you mentioned, we can make use of normal BFS search for this question as the direction for our movement between floor is given already as floor + 1 or floor - 1 or floor / 2. As per my understanding a floor / 2 movement is only possible if we are at an even floor.
Here is my java code for the same :
int findSteps(int n, int t) {
if (n > t) {
return n - t;
}
if (n == t) {
return 0;
}
Queue<Integer> queue = new LinkedList<>();
Set<Integer> visited = new HashSet<>();
queue.offer(n);
visited.add(n);
int steps = 0;
while (!queue.isEmpty()) {
int size = queue.size();
for (int i=0; i<size; i++) {
int currentFloor = queue.poll();
if (currentFloor == t)
return steps;
int possibleMove1 = currentFloor + 1;
int possibleMove2 = currentFloor - 1;
int possibleMove3 = currentFloor % 2 == 0 ? currentFloor / 2 : -1;
// out of bound conditions or visited condition
if (possibleMove1 < t && possibleMove1 > n && !visited(possibleMove1)) {
queue.offer(possibleMove1);
visited.add(possibleMove1);
}
if (possibleMove2 < t && possibleMove2 > n && !visited(possibleMove2)) {
queue.offer(possibleMove2);
visited.add(possibleMove2);
}
if (possibleMove3 < t && possibleMove3 > n && !visited(possibleMove3)) {
queue.offer(possibleMove1);
visited.add(possibleMove1);
}
}
steps += 1;
}
return -1;
}
Note : There is some repeating codes that can be moved to a separate function and use that function instead.

Take every k-th element from the (1 .. n) natural numbers series

For example, we have series 1, 2, 3, 4, 5. We take every 3 element =>
3, 1, 5, 2, 4 (chosen element shouldn't remain, we can take while series is not empty). Naive implementation by circle doubly linked list is not good idea cause of performance. Can you give me an advice which data structures and algorithms are more applicable?
Build a complete binary tree containing the numbers 1 to n, e.g. for n=15 that would be:
In each branch, store the number of nodes to the left of it; this will allow us to quickly find the i-th node. (You'll see that this tree has a very predictable structure and values, and generating it is much more efficient than building a same-sized binary tree with randomly-ordered values. It's also an ideal candidate for a tree-in-an-array.)
Then, to find the i-th number, start at the root node, and at every node, if i is one greater than the number of nodes to the left, you've found the i-th number, else go left (if i is not greater than the number of nodes to the left) or right (if i is more than 1 greater than the number of nodes to the left).
Whenever you go left, decrement the count of nodes to the left of this node (because we'll be removing one).
Whenever you go right, decrease the number you're looking for by the number of nodes to the left of the node, plus 1 (or plus 0 if the value in the node has been erased).
When you've found the i-th node, read its value (to add to the removal order list) and then set its value to 0. Thereafter, if the i-th node we're looking for has had its value erased, we'll go right and then take the leftmost node.
We start with a value i = k, and then every time we've erased the number in the i-th node, we'll decrement the total number of nodes and set i = (i + k - 1) % total (or if that is zero: i = total).
This gives a log2N lookup time and a total complexity of N×LogN.
Example walk-through: with n=15 (as in the image above) and k=6, the first steps are 6, 12, 3, 10, 2. At that point the situation is:
We've just removed the second number, and now i = 2 + 6 - 1 = 7. We start at the root node, which has 4 nodes to the left of it and still has its value, so we go right and subtract 5 from the 7 we're looking for and get 2. We arrive at node 12 (which has been erased) and find there are 2 nodes to the left of it, so we decrement the number of nodes to the left of it and then go left. We come to node 10 (which has been erased) and find that it has 1 node to the left of it, and 1 = 2 - 1 so this is the node we're looking for; however, since its value has been erased, we go right and subtract 1 from the 2 we're looking for and get 1. We arrive at node 11, which has 0 nodes to the left of it (because it's a leaf), and 0 = 1 - 1, so this is the node we're looking for.
We then decrement the total number of nodes from 10 to 9, and update i from 7 to (7 + 6 - 1) % 9 = 3 and go on to find the third node (which is now the one with value 5).
Here's a simple implementation in JavaScript. It solves series of 100,000 numbers in less than a second, and it could probably be made faster and more space-efficient by using a tree-in-an-array structure.
(Unlike in the explanation above, the indexes of the numbers are zero-based, to simplify the code; so index 0 is the first number in the tree, and we look for the node with a number of left-connected children that equals the target index.)
function Tree(size) { // CONSTRUCTOR
var height = Math.floor(Math.log(size) / Math.log(2));
this.root = addNode(height, 1 << height, size);
this.size = size;
function addNode(height, value, max) { // RECURSIVE TREE-BUILDER
var node = {value: value > max ? 0 : value, lower: (1 << height) - 1};
if (height--) {
node.left = addNode(height, value - (1 << height), max);
if (value < max) { // DON'T ADD UNNECESSARY RIGHT NODES
node.right = addNode(height, value + (1 << height), max);
}
}
return node;
}
}
Tree.prototype.cut = function(step) { // SEE ANSWER FOR DETAILS
var sequence = [], index = (step - 1) % this.size;
while (this.size) {
var node = this.root, target = index;
while (node.lower != target || node.value == 0) {
if (target < node.lower) {
--node.lower;
node = node.left;
} else {
target -= node.lower + (node.value ? 1 : 0);
node = node.right;
}
}
sequence.push(node.value);
node.value = 0;
index = (index + step - 1) % --this.size;
}
return sequence;
}
var tree = new Tree(15);
var sequence = tree.cut(6);
document.write("15/6→" + sequence + "<BR>");
tree = new Tree(100000);
sequence = tree.cut(123456);
document.write("100000/123456→" + sequence);
NOTE:
If you look at the tree for n=10, you'll see that the node to the right of the root has an incomplete tree with 2 nodes to its left, but the algorithm as implemented in the code example above gives it an incorrect left-node count of 3 instead of 2:
However, nodes with an incomplete tree to their left never hold a value themselves, and never have nodes to their right. So you always go left there anyway, and the fact that their left-node count is too high is of no consequence.
If you just need the last number, it's known as Josephus problem and there're well-known formulas for computing the answer in O(N) time.
I don't know if one can adapt it to run a full simulation, so I'll describe a straightforward O(N log N) solution here:
Let's keep all numbers in a treap with implicit keys. We need to find the k-th element and delete it at each step (in fact, there can be a shift, so it's more like (cur_shift + k) % cur_size, but it doesn't really matter). A treap can do it. We just need to split it into 3 parts [0, k - 1], [k, k] and [k + 1, cur_size - 1], print the number in the node that corresponds to the second part and merge the first and last part back together. It requires O(log N) time per step, so it should be good enough for the given constraints.
Here is an implementation with an array representation of the binary tree, only storing the size of the left sub-tree as node value. The input array is not actually stored, but silently assumed to be the leaves at the bottom level, below the binary tree:
function josephusPermutation(size, step) {
var len = 1 << 32 - Math.clz32(size-1), // Smallest power of 2 >= size
tree = Array(len).fill(0), // Create tree in array representation
current = 0,
skip = step - 1,
result = Array(size).fill(0),
goRight, leftSize, order, i, j;
// Initialise tree with sizes of left subtrees as node values
(function init(i) {
if (i >= len) return +(i - len < size); // Only count when within size
var left = tree[i] = init(i*2); // recursive, only store left-size
return left + (left ? init(i*2+1) : 0); // return sum of left and right
})(1);
for (j = 0; j < result.length; j++, size--) {
current = (current + skip) % size; // keep within range
order = current;
for (i = 1; i < len; i = i*2+goRight) {
leftSize = tree[i];
goRight = order >= leftSize;
if (goRight) {
order -= leftSize; // Moving rightward, counting what is at left side.
} else {
tree[i]--; // we will remove value at left side
}
}
result[j] = 1 + i - len;
}
return result;
}
var sequence = josephusPermutation(100000, 123456);
console.log(sequence.join(','));
Below is an implementation of Lei Wang and Xiaodong Wang's (2013) 1 O(n log k) algorithm (very similar to, if not based on, the algorithm by Errol Lloyd, published in 1983). The idea is to divide the original sequence into n/m binary trees of height log k. The algorithm is actually designed for the "feline" Josephus problem, where the participants can have more than one life (listed in the array variable below, global.l).
I also like the O(1) space algorithms by Knuth, Ahrens, and Kaplansky, (outlined in a master's thesis by Gregory Wilson, California State University, Hayward, 19792), which take a longer time to process, although can be quite fast depending on the parameters.
Knuth’s algorithm for J(n,d,t) (t is the ith hit), a descending sequence:
Let x1 = d * t and for k = 2,3,...,
let x_k = ⌊(d * x_(k−1) − d * n − 1) / (d − 1)⌋
Then J(n,d,t) = x_p where x_p is the first term in the sequence <= n.
Ahrens’ algorithm for J(n,d,t), an ascending sequence:
Let a1 = 1 and for k = 2,3,...
let a_k = ⌈(n − t + a_(k−1)) * d / (d − 1)⌉
If a_r is the first term in the sequence such that a_r + 1 ≥ d * t + 1
then J(n,d,t) = d * t + 1 − a_r.
Kaplansky’s algorithm for J(n,d,t):
Let Z+ be the set of positive integers and for k =1,2,...,t
define a mapping P_k : Z+ → Z+ by P_k(m) = (m+d−1)−(n−k+1)(m−k+d−1)/(n−k+1)
Then, J(n,d,t) = P1 ◦ P2 ◦···◦Pt(t).
JavaScript code:
var global = {
n: 100000,
k: 123456,
l: new Array(5).fill(1),
m: null,
b: null,
a: [],
next: [],
prev: [],
i: 0,
limit: 5,
r: null,
t: null
}
function init(params){
global.m = Math.pow(2, Math.ceil(Math.log2(params.k)));
params.b = Math.ceil(params.n / global.m);
for (let i=0; i<params.b; i++){
let s = i * global.m,
t = (i + 1) * global.m,
u = [];
for (let j=0; j<global.m; j++)
u[j] = 0;
for (let j=s; j<=Math.min(t-1,params.n-1); j++)
u[j-s] = -(j + 1);
global.a[i] = [];
build(u, global.a[i]);
t = (i + 1) % params.b;
params.next[i] = t;
params.prev[t] = i;
}
}
function build(u,v){
function count(_v, i){
if (global.m < i + 2){
if (_v[i] < 0)
return 1;
else
return 0;
} else {
_v[i] = count(_v, 2*i + 1);
_v[i] = _v[i] + count(_v, 2*i + 2);
return _v[i];
}
}
for (let i=0; i<global.m; i++)
v[global.m + i - 1] = u[i];
count(v, 0);
}
function algorithmL(n, b){
global.r = 0;
global.t = b - 1;
while (global.i < global.limit){
tree(global, global);
let j = leaf(global, global);
hit(global.i,j,global,global);
global.i = global.i + 1;
}
}
function tree(params_r,params_t){
if (params_t.t === global.next[params_t.t] && params_r.r < global.k){
params_r.r = global.k + global.a[params_t.t][0] - 1 - (global.k - params_r.r - 1) % global.a[params_t.t][0];
} else {
while (params_r.r < global.k){
params_t.t = global.next[params_t.t];
params_r.r = params_r.r + global.a[params_t.t][0];
}
}
}
function size(t,j){
if (global.a[t][j] < 0)
return 1
return global.a[t][j];
}
function leaf(params_r,params_t){
let j = 0,
nxt = params_r.r - global.k;
while (j + 1 < global.m){
let rs = size(params_t.t, 2*j + 2);
if (params_r.r - rs < global.k){
j = 2*j + 2;
} else {
j = 2*j + 1;
params_r.r = params_r.r - rs;
}
}
params_r.r = nxt;
return j;
}
function hit(i,j,params_r,params_t){
let h = -global.a[params_t.t][j];
console.log(h);
if (global.l[h-1] > 1)
global.l[h-1] = global.l[h-1] - 1;
else
kill(i,j,params_r,params_t);
}
function kill(i,j,params_r,params_t){
global.a[params_t.t][j] = 0;
while (j > 0){
j = Math.floor((j - 1) / 2);
global.a[params_t.t][j] = global.a[params_t.t][j] - 1;
}
if (params_t.t !== global.next[params_t.t]){
if (global.a[params_t.t][0] + global.a[global.next[params_t.t]][0] === global.m){
params_r.r = params_r.r + global.a[global.next[params_t.t]][0];
combine(params_t);
} else if (global.a[params_t.t][0] + global.a[global.prev[params_t.t]][0] === global.m){
t = global.prev[params_t.t];
combine(params_t);
}
}
}
function combine(params_t){
let x = global.next[params_t.t],
i = 0,
u = [];
for (let j=0; j<global.m; j++)
if (global.a[params_t.t][global.m + j - 1] < 0){
u[i] = global.a[params_t.t][global.m + j - 1];
i = i + 1;
}
for (let j=0; j<global.m; j++)
if (global.a[x][global.m + j - 1] < 0){
u[i] = global.a[x][global.m + j - 1];
i = i + 1;
}
build(u,global.a[params_t.t]);
global.next[params_t.t] = global.next[global.next[params_t.t]];
global.prev[global.next[params_t.t]] = params_t.t;
}
init(global);
algorithmL(global.n, global.b);
(1) L. Wang and X. Wang. A Comparative Study on the Algorithms for a Generalized Josephus Problem. Applied Mathematics & Information Sciences, 7, No. 4, 1451-1457 (2013).
(2) References from Wilson (1979):
Knuth, D. E., The Art of Computer Programming, Addison-Wesley, Reading Mass., Vol I Fundamental Algorithms, 1968, Ex. 22, p158; Vol. III, Sorting and Searching, Ex. 2, pp. 18-19; Vol. I, 2-nd ed., p.181.
Ahrens, W., Mathematische Unterhaltungen und Spiele, Teubner: Leipzig, 1901, Chapter 15, 286-301.
Kaplansky, I. and Herstein I.N., Matters Mathematical, Chelsea, New York, 1978, pp. 121-128.

convert decimal to base x

I'm trying to solve a problem which asks to find all squares of 1 <= N <= 300 that are palindromic when expressed in base B. I've got my solution however, it's way too slow and what is slowing it down is my solution to converting a number to base B.
long around(long n)
{
long around = 0;
while (n > 0){
around = around * 10 + (n % 10);
n = n / 10;
}
return around;
}
long convert(int n, int b)
{
long x = 0;
while (true){
x = x * 10 + (n % b);
if (n == 1)
break;
n = n / b;
}
return around(x);
}
Please recommend any faster solutions to converting decimal to base B or give any tips to improve my current solutions performance.
The problem is your convert function, which runs into an infinite loop. You are only breaking when n == 1, but what if it never becomes 1?
Consider n = 4 and b = 5. Then 4 / 5 will be 0. Once n is zero, it will always be zero, and never 1.
You should break out of the loop when n < b.

How to check if an integer is a power of 3?

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.

Resources