Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Finding the smallest good base in JavaScript
For an integer num, we call k (k >= 2) a good base of num, if all digits of num base k are 1.
For instance: 13 base 3 is 111, hence 3 is a good base for num = 13
Problem
We are required to write a JavaScript function that takes in string str that represents a number as the only argument. The function should return the string representation of the smallest possible number which is a good base for str.
For example, if the input to the function is:
const str = "4681";
Then the output should be:
const output = "8";
Output Explanation
Because 4681 base 8 is 11111
Algorithm Approach
The algorithm uses binary search to find the smallest good base. For a number N represented as m digits of 1s in base k, we have:
N = k^(m-1) + k^(m-2) + ... + k + 1
We iterate through possible lengths of 1s (from maximum to minimum) and use binary search to find if a valid base exists for each length.
Example
const str = "4681";
const smallestGoodBase = (n = '1') => {
const N = BigInt(n), bigint2 = BigInt(2), bigint1 = BigInt(1), bigint0 = BigInt(0);
let maxLen = countLength(N, bigint2); // result at most maxLen 1s
const findInHalf = (length, smaller = bigint2, bigger = N) => {
if (smaller > bigger) {
return [false];
}
if (smaller == bigger) {
return [valueOf1s(smaller, length) == N, smaller];
}
let mid = (smaller + bigger) / bigint2;
let val = valueOf1s(mid, length);
if (val == N) {
return [true, mid];
}
if (val > N) {
return findInHalf(length, smaller, mid - bigint1);
}
return findInHalf(length, mid + bigint1, bigger);
};
for (let length = maxLen; length > 0; length--) {
let [found, base] = findInHalf(length);
if (found) {
return '' + base;
}
}
return '' + (N - 1);
function valueOf1s(base, lengthOf1s) {
let t = bigint1;
for (let i = 1; i < lengthOf1s; i++) {
t *= base;
t += bigint1;
}
return t;
}
function countLength(N, base) {
let t = N, len = 0;
while (t > bigint0) {
t /= base;
len++;
}
return len;
}
};
console.log(smallestGoodBase(str));
8
How It Works
The function uses three helper functions:
-
valueOf1s(base, length): Calculates the value of 'length' number of 1s in the given base -
countLength(N, base): Determines the maximum possible length of 1s representation -
findInHalf(length, smaller, bigger): Binary search to find a valid base for given length
Additional Example
// Test with different numbers
console.log(smallestGoodBase("13")); // 13 = 111 in base 3
console.log(smallestGoodBase("4681")); // 4681 = 11111 in base 8
console.log(smallestGoodBase("1000000000000000000")); // Large number test
3 8 999999999999999999
Conclusion
This algorithm efficiently finds the smallest good base using binary search with BigInt for handling large numbers. The time complexity is O(log²N) where N is the input number.
