Из вашего последнего редактирования кажется, что это больше невозможно сделать с логарифмами, поэтому вам нужно будет подсчитать вместо этого:
function findLevel(input) {
let level = 1;
let limit = 3;
let increment = 3*3;
while (input > limit) {
++level;
limit += increment;
increment *= 3;
}
return level;
}
Вы не указали поведение для самих пределов, т. Е. Принадлежит ли 3 уровню 1 (диапазон 0-3) или 2 (диапазон 3-12). Предполагается, что он относится к нижнему уровню, то есть 3 находится на уровне 1, а не 2. Измените input > limit
на input >= limit
, если это неверно, то есть 3 на уровне 2.
// Print the inclusive integer ranges for each level
let lastLevelStart = 0;
let lastLevel = findLevel(lastLevelStart);
for (let i = 1; i <= 10000; ++i) {
let level = findLevel(i);
if (level != lastLevel) {
console.log(`level ${lastLevel}: ${lastLevelStart} to ${i-1} inclusive`);
lastLevel = level;
lastLevelStart = i;
}
}
уровень 1: от 0 до 3 включительно
уровень 2: от 4 до 12 включительно
уровень 3: от 13 до 39 включительно
уровень 4: от 40 до 120 включительно
уровень 5: от 121 до 363 включительно
уровень 6: от 364 до 1092 включительно
уровень 7: от 1093 до 3279 включительно
уровень 8: от 3280 до 9840 включительно
Очевидно, что для расчета необходимого числа циклов выходного уровня, и при повторном использовании он будет многократно вычислять одни и те же предельные значения снова и снова (хотя и с использованием только целочисленных математических выражений, что сравнительно дешево). Поэтому, если вы называете это очень много раз или вам нужно иметь дело с более чем небольшим количеством уровней, то вы можете вычислить верхние границы для первых 1000 уровней (скажем) в массив, а затем просто отсканировать это, чтобы найти уровень, или даже двоичный поиск в этом массиве, чтобы найти ответ в более постоянное время (сначала проверяя, что входное значение <= верхнее предварительно вычисленное значение, и возвращаясь к этому методу, если нет). </p>