//First I created a simulation to verify my understanding of this problem
function f(n){
var set = [];
for (var i=0;i<n;i++){//initialize circle
set.push(i+1);
}
//starting by the second
//until there is one left
//remove current position
//so by moving 1 I skip 1
for (var i = 1; (set.length>1);i = (i+1)%set.length){
set.splice(i, 1);
console.log(set);
}
return set[0];
}
/*
By doing this I had noticed a pattern:
every base 2 number returns 1 while the other are the nth odd number after last base 2 result and next.
nth odd formula: odd(n) = n*2+1
for (var i=1;i<65;i++) console.log("f("+i + ")=" + f(i));
f(1)=1
f(2)=1 2^1
f(3)=3 1º odd(1) = 1*2+1 = 3
f(4)=1 2^2
f(5)=3 1º odd(1) = 1*2+1 = 3
f(6)=5 2º odd(2) = 2*2+1 = 5
f(7)=7 3º odd(3) = 3*2+1 = 7
f(8)=1 2^3
f(9)=3 1º odd(1) = 1*2+1 = 3
f(10)=5 2º odd(2) = 2*2+1 = 5
f(11)=7 3º odd(3) = 3*2+1 = 7
f(12)=9 4º odd(4) = 4*2+1 = 9
f(13)=11 5º odd(5) = 5*2+1 = 11
f(14)=13 6º odd(6) = 6*2+1 = 13
f(15)=15 7º odd(7) = 7*2+1 = 15
f(16)=1 2^4
*/
//therefore, there is always an a that is 2^a<=n<2^(a+1)
//since, when n is equal 2^a, the result is odd(0)=1, we can use the remaining of a division by 2^a
//therefore, it is the final formula:
// f(n) = odd(n mod 2^a)
//which is f(n) = (n mod 2^a)*2+1 where 2^a<=n<2^(a+1)
// here is my code implementation
function f2(n){
var a=0;
while(1<<a<=n) a++;//find 'a'
a--;
return (n%(1<<a))*2+1;// (n mod 2^a)*2+1
}
//my unit test to validate my formula
function validate (f, f2, n){
var i=3;
var flg = true
while (i++<n && flg){
flg = flg && f(i)==f2(i)
}
return flg;
}
f(n) = (n mod 2^a)*2+1 where 2^a<=n<2^(a+1)
Log in or sign up for Devpost to join the conversation.