# Logarithmic growth counter

I'm looking for a way to have an logarithmic incremental counter. The counter goal is related to a numeric value than goes from 1 to Infinity. The counter maximum value should be 1000. The sequence looks like this:

• number is below 10, increment by 1:

1,2,3...7,8,9,10

• number is above 10, increment by ^10 when the number reaches the counter

100, 1000 stop at 1000

This is what I wrote so far (javascript):

let i = 0
let mod = 10
let result = document.getElementById('result')
result.innerText = ''

while (++i < 7322) {
mod *= mod < 1000 && i === mod * 10 ? 10 : 1

if (i < 10 || i % mod === 0) {
//the further the i value is, the less this will be called
result.innerText += i + ' pass the test. Mod is ' + mod + '.\n'
}
}
<span id="result"></span>

I'm sure there is a more elegant way of doing this but can't get my hand on it. Do you have ideas on how to simplify the algorithm?

• Are you looking for elegance in providing values for i or mod? – greybeard Dec 20 '16 at 16:17
• For mod, i is just a random number – soyuka Dec 20 '16 at 16:18
• (The repetition of 10-in the title is distracting: can you explain or remove it?) – greybeard Dec 20 '16 at 16:24
• Done, I kinda had a hard time trying to explain. Finding a good title was even harder... – soyuka Dec 20 '16 at 16:25

Your solution is a bit wasteful by generating and testing all integers in the desired range while you actually only need a handful of them.

A big improvement in terms of performance is to avoid modulo arithmetic and increase the step-size tenfold whenever you finished iterating a sub-range 1-9, 10-99, 100-999 and so on:

let max = 7322;
let step = 1;
let next = 10;

while (step < 1000 && next < max) {
for (let i = step; i < next; i += step) {
console.log(i);
}
step = next;
next *= 10;
}

for (let i = step; i < max; i += step) {
console.log(i);
}

Of course, you might want to encapsulate above code in a function or even more versatile, a generator function and replace console.log(i); with yield i;.

However, since you only have four different step-sizes of 1, 10, 100, and 1000 you can encode them manually and come up with an even simpler generator function as follows:

// Generate logarithmic range from 1 to max (excluded):
function* logRange(max) {
for (let i = 1; i < max && i < 10; i += 1) yield i;
for (let i = 10; i < max && i < 100; i += 10) yield i;
for (let i = 100; i < max && i < 1000; i += 100) yield i;
for (let i = 1000; i < max; i += 1000) yield i;
}

// Example:
for (let i of logRange(7322)) console.log(i);

This avoids modulo arithmetic, computes only the desired numbers and is pretty easy to understand.

Your changes of mod coincide with the condition of "the if":

mod = 1;
while (++i < 12345) {
if (i % mod === 0) {
//the further the i value is, the less this will be called
result.innerText += i + ' pass the test. Mod is ' + mod + '.\n'
if (mod < 1000 && i === mod * 10)
mod = i
}
}


(Can't seem to get the snippets to work in firefox 50.1?!)