Random Number List Missing Number 1 - javascript

I have an issue with a function I have written: although it mostly works, there is one issue where sometimes the number 1 isn't added to the list. The code is supposed to make a list of numbers from 1 - 10, however the number 1 is sometimes missing, where I presumably the issue is it is being overwritten when number 10 is already there before number 1
The code is written using the Code.org AppLab, written in a pseudo-code that is similar to JavaScript.
function randomizer(stringName, numbersShuffled) {
//This creates a string of Numbers that will eventually be converted to a list
for (var i = 0; i < numbersShuffled; i++) {
var tempNum = randomNumber(1, numbersShuffled);
console.log(numbersShuffled);
if (stringName.includes(tempNum)) {
console.log(stringName);
if (tempNum == 1 && stringName.includes(10)) {
tempNum = randomNumber(1, numbersShuffled);
}
while ((stringName.includes(tempNum))) {
tempNum = randomNumber(1, numbersShuffled);
}
}
stringName = (stringName + " ") + tempNum;
}
console.log(stringName);
The issue is that usually the number 1 is missing if number 10 is already in place in the list.enter code here

Related

get always 10 numbers from randoms - Javascript [duplicate]

This question already has answers here:
Want to produce random numbers between 1-45 without repetition
(4 answers)
Closed 4 years ago.
I need help with my code. I want to get 10 random numbers every time it rolls and it can't have duplicated, this is my code:
for(let j = 1; j <= 21; j++) {
const number = (Math.floor((Math.random() * j) + 1))
const genNumber = array.indexOf(number);
if (genNumber === -1) {
array.push(number);
}
}
I have no idea how I can get exactly 10 numbers every time, anyway it can be written with js or jquery it doesnt metter for me. Hope I can get help here.
I don't really understand what your code is intended to do, but to get exactly 10 unique random numbers I'd use a Set and loop until it's filled. I have no idea why you loop 21 times for 10 items though...
let s = new Set();
while (s.size < 10) {
s.add((Math.floor(Math.random() * 21 /* ??? */) + 1));
}
console.log([...s]);
You're almost there, but instead of using a for loop, use a while loop that continues as long as there are less than 10 things in the array:
const array = [];
const j = 21; // Pick numbers between 1 and 21 (inclusive)
while (array.length < 10) {
const number = (Math.floor((Math.random() * j) + 1))
const genNumber = array.indexOf(number);
if (genNumber === -1) {
array.push(number);
}
}
console.log(array);

Number of digits within an interval

I need to calculate how many times each digit appears within the numeric sequence from 1 to given number.
Example:
Input: 12
Output: 5 2 1 1 1 1 1 1 1 1
Explanation:
1 2 3 4 5 6 7 8 9 1 0 1 1 1 2
The first number is the quantity of ones, the second one – of twos...the last one of zeros
So far, I have written a function that splits any integer into parts (2512 will be 2000 500 10 2). Maybe it can be useful for future executions:
function splitToParts(x) {
var multiplier = 1;
while (x > 0) {
var result = x % 10;
if (result > 0) {
parts.unshift(result * multiplier);
}
x = Math.floor(x / 10);
multiplier *= 10;
}
}
2000, 500 and 10 are just not digits, so for direct counting they are not feasible to work with. A simple approach would be saying that you are always interested in the least significant digit (the "ones"), and "consume" the number as long as it is not 0.
For a single number it would be this simple:
function digits(number){
var retval=[0,0,0,0,0,0,0,0,0,0];
while(number>0){
retval[number%10]++;
number=Math.floor(number/10);
}
return retval;
}
console.log(digits(123).join()); // join just makes it a single line, looks better
Then one may make the statistics updateable via accepting an argument for it. It does not even have to be mandatory, the function can simply create it if it is missing:
function digits(number,stats){
var retval=stats || [0,0,0,0,0,0,0,0,0,0];
while(number>0){
retval[number%10]++;
number=Math.floor(number/10);
}
return retval;
}
var stats=digits(123);
console.log(stats.join());
console.log(digits(234,stats).join());
And make it a loop:
function digits(number,stats){
var retval=stats || [0,0,0,0,0,0,0,0,0,0];
while(number>0){
retval[number%10]++;
number=Math.floor(number/10);
}
return retval;
}
function intervalDigits(min,max){
var stats;
for(var i=min;i<=max;i++)
stats=digits(i,stats);
return stats;
}
console.log(intervalDigits(1,12).join());
That would be a "brute force", but working solution in JavaScript.
Then one can go for maths instead of brute forcing, and start working with the 2000-500-10-2 "decomposition", finding patterns in "contribution" to the statistics for digits at 'ones', 'tens', 'hundreds', and so on. These contributions will not be trivial, so the existing snippets may come useful to check what happens around different "transitions".
function digits(number,stats){
var retval=stats || [0,0,0,0,0,0,0,0,0,0];
while(number>0){
retval[number%10]++;
number=Math.floor(number/10);
}
return retval;
}
function intervalDigits(min,max){
var stats;
for(var i=min;i<=max;i++)
stats=digits(i,stats);
return stats;
}
for(var i=1;i<21;i++)console.log("1-"+i,intervalDigits(1,i).join());
console.log("---");
for(var i=95;i<115;i++)console.log("1-"+i,intervalDigits(1,i).join());
console.log("---");
var x100=intervalDigits(1,100);
var x200=intervalDigits(1,200);
var x300=intervalDigits(1,300);
console.log("1-100",x100.join());
console.log("1-200",x200.join());
console.log("1-300",x300.join());
console.log("---");
console.log("1-100 -> 1-200",x200.map((x,i)=>x-x100[i]).join());
console.log("1-200 -> 1-300",x300.map((x,i)=>x-x200[i]).join());
console.log("1-100 -> 1-300",x300.map((x,i)=>x-x100[i]).join());
Given the range of 1018, you are most likely expected to pursue this track (too), but here and now this 'starter pack' is what I have had time for.

How can I prepend characters to a string using loops?

I have an input field that expects a 10 digit number. If the user enters and submits a number less than 10 digits, the function would simply add a "0" until the inputed value is 10 digits in length.
I haven't really used, or understand how recursive functions really work, but I'm basically looking at an efficient way of doing this. One minor issue I'm having is figuring out how to prepend the "0"s at the beginning of the string rather than appended to the end.
My thinking:
function lengthCheck(sQuery) {
for (var i = 0; i < sQuery.length; i++) {
if (sQuery.length !== 10) {
sQuery += "0";
//I'd like to add the 0s to the beggining of the sQuery string.
console.log(sQuery);
lengthCheck(sQuery);
} else return sQuery
}
}
Change:
sQuery += "0"; // added at end of string
to:
sQuery = "0" + sQuery; // added at start of string
To remove the for loop/recursion, you could slice out the desired length in one step:
function padZeros(sQuery) {
// the max amount of zeros you want to lead with
const maxLengthZeros = "0000000000";
// takes the 10 rightmost characters and outputs them in a new string
return (maxLengthZeros + sQuery).slice(-10);
}
Simple generic function using ES6 repeat:
// edge case constraints not implemented for brevity
function padZeros(sQuery = "", maxPadding = 10, outputLength = 10) {
// the max amount of zeros you want to lead with
const maxLengthZeros = "0".repeat(maxPadding);
// returns the "outputLength" rightmost characters
return (maxLengthZeros + sQuery).slice(-outputLength);
}
console.log('padZeros: ' + padZeros("1234567890"));
console.log('padZeros: ' + padZeros("123"));
console.log('padZeros: ' + padZeros(""));
Alternate version that doesn't affect strings over your set limit:
function padZerosIfShort(inputString = "", paddedOutputLength = 10) {
let inputLen = inputString.length;
// only padded if under set length, otherwise returned untouched
return (paddedOutputLength > inputLen)
? "0".repeat(paddedOutputLength - inputLen) + inputString
: inputString;
}
console.log('padZerosIfShort: ' + padZerosIfShort("1234567890", 5));
console.log('padZerosIfShort: ' + padZerosIfShort("123", 5));
console.log('padZerosIfShort: ' + padZerosIfShort("", 5));
It will ultimately depend on your needs how you want to implement this behavior.
The += operator adds things to the end of strings similar to:
sQuery=sQuery+"0"
You can add characters to the front of a string like this
sQuery="0"+sQuery
I also found something interesting here. it works like this:
("00000" + sQuery).slice(-5)
You would add zeros to the front then slice off everything except the last 5. so to get 10 characters you would use:
("0000000000" + n).slice(-10)
You don't need recursion to solve this, just a simple for loop should do the trick. Try this:
function lengthCheck (sQuery) {
for (var i = sQuery.length; i<10; i++) {
sQuery = "0" + sQuery;
}
return sQuery;
}
You're looking to pad the string with zeroes. This is an example I've used before from here and will shorten your code a little bit:
function lengthCheck (sQuery) {
while (sQuery.length < 10)
sQuery = 0 + sQuery;
return sQuery;
}
I believe this has already been answered here (or similar enough to provide you the solution): How to output integers with leading zeros in JavaScript

Pick random combination from 194481 possibilities

I have a file of 194481 permutations for
0,1,2,3,4,5,6,...,21
which looks like this;
[0,0,0,0],[0,0,0,1],[0,0,0,2],[0,0,0,3],[0,0,0,4],[0,0,0,5],[0,0,0,6],[0,0,0,7],[0,0,0,8],[0,0,0,9],[0,0,0,10],[0,0,0,11],[0,0,0,12],[0,0,0,13],[0,0,0,14],[0,0,0,15],[0,0,0,16],[0,0,0,17],[0,0,0,18],[0,0,0,19],[0,0,0,20],[0,0,1,0],[0,0,1,1],[0,0,1,2],[0,0,1,3],[0,0,1,4],[0,0,1,5],[0,0,1,6],[0,0,1,7],[0,0,1,8],[0,0,1,9],[0,0,1,10],[0,0,1,11],[0,0,1,12],[0,0,1,13],[0,0,1,14],[0,0,1,15],[0,0,1,16],[0,0,1,17],[0,0,1,18],[0,0,1,19],[0,0,1,20],[0,0,2,0],[0,0,2,1],[0,0,2,2],[0,0,2,3],[0,0,2,4],[0,0,2,5],[0,0,2,6],[0,0,2,7],[0,0,2,8],[0,0,2,9],[0,0,2,10],[0,0,2,11],[0,0,2,12],[0,0,2,13],[0,0,2,14],[0,0,2,15],[0,0,2,16],[0,0,2,17],[0,0,2,18],[0,0,2,19],[0,0,2,20],[0,0,3,0],[0,0,3,1],[0,0,3,2],[0,0,3,3],[0,0,3,4],[0,0,3,5],[0,0,3,6],[0,0,3,7],[0,0,3,8],[0,0,3,9],[0,0,3,10],[0,0,3,11],[0,0,3,12],[0,0,3,13],[0,0,3,14],[0,0,3,15],[0,0,3,16],[0,0,3,17],[0,0,3,18],[0,0,3,19],[0,0,3,20],[0,0,4,0],[0,0,4,1],[0,0,4,2],[0,0,4,3],[0,0,4,4],[0,0,4,5],[0,0,4,6],[0,0,4,7],[0,0,4,8],[0,0,4,9],[0,0,4,10],[0,0,4,11],[0,0,4,12],[0,0,4,13],[0,0,4,14],[0,0,4,15],[0,0,4,16],[0,0,4,17],[0,0,4,18],[0,0,4,19],[0,0,4,20],[0,0,5,0],[0,0,5,1],[0,0,5,2],[0,0,5,3],[0,0,5,4],[0,0,5,5],[0,0,5,6],[0,0,5,7],[0,0,5,8],[0,0,5,9],[0,0,5,10],[0,0,5,11],[0,0,5,12],[0,0,5,13],[0,0,5,14],[0,0,5,15],[0,0,5,16],[0,0,5,17],[0,0,5,18],[0,0,5,19],[0,0,5,20],[0,0,6,0],[0,0,6,1],[0,0,6,2],[0,0,6,3],[0,0,6,4],[0,0,6,5],[0,0,6,6],[0,0,6,7],[0,0,6,8],[0,0,6,9],[0,0,6,10],[0,0,6,11],[0,0,6,12],[0,0,6,13],[0,0,6,14],[0,0,6,15],[0,0,6,16],[0,0,6,17],[0,0,6,18],[0,0,6,19],[0,0,6,20],[0,0,7,0],[0,0,7,1],[0,0,7,2],[0,0,7,3],[0,0,7,4],[0,0,7,5],[0,0,7,6],[0,0,7,7],[0,0,7,8],[0,0,7,9],[0,0,7,10],[0,0,7,11],[0,0,7,12],[0,0,7,13],[0,0,7,14],[0,0,7,15],[0,0,7,16],[0,0,7,17],[0,0,7,18],[0,0,7,19],[0,0,7,20],[0,0,8,0],[0,0,8,1],[0,0,8,2],[0,0,8,3],[0,0,8,4],[0,0,8,5],[0,0,8,6],[0,0,8,7],[0,0,8,8],[0,0,8,9],[0,0,8,10],[0,0,8,11],[0,0,8,12],[0,0,8,13],[0,0,8,14],[0,0,8,15],[0,0,8,16],[0,0,8,17],[0,0,8,18],[0,0,8,19],[0,0,8,20],[0,0,9,0],[0,0,9,1],[0,0,9,2],[0,0,9,3],[0,0,9,4],[0,0,9,5],[0,0,9,6],[0,0,9,7],[0,0,9,8],[0,0,9,9],[0,0,9,10],[0,0,9,11],[0,0,9,12],[0,0,9,13],[0,0,9,14],[0,0,9,15],[0,0,9,16],[0,0,9,17],[0,0,9,18],[0,0,9,19],[0,0,9,20],[0,0,10,0],[0,0,10,1],[0,0,10,2],[0,0,10,3],[0,0,10,4],[0,0,10,5],[0,0,10,6],[0,0,10,7],[0,0,10,8],[0,0,10,9],[0,0,10,10],[0,0,10,11],[0,0,10,12],[0,0,10,13],[0,0,10,14],[0,0,10,15],[0,0,10,16],[0,0,10,17],[0,0,10,18],[0,0,10,19],[0,0,10,20],[0,0,11,0],[0,0,11,1],[0,0,11,2],[0,0,11,3],[0,0,11,4],[0,0,11,5],[0,0,11,6],[0,0,11,7],[0,0,11,8],[0,0,11,9],[0,0,11,10],[0,0,11,11],[0,0,11,12],[0,0,11,13],[0,0,11,14],[0,0,11,15],[0,0,11,16],[0,0,11,17],[0,0,11,18],[0,0,11,19],[0,0,11,20],[0,0,12,0],[0,0,12,1],[0,0,12,2],[0,0,12,3],[0,0,12,4],[0,0,12,5],[0,0,12,6],[0,0,12,7],[0,0,12,8],[0,0,12,9],[0,0,12,10],[0,0,12,11],[0,0,12,12],[0,0,12,13],[0,0,12,14],[0,0,12,15],[0,0,12,16],[0,0,12,17],[0,0,12,18],[0,0,12,19],[0,0,12,20],[0,0,13,0],[0,0,13,1],[0,0,13,2],[0,0,13,3],[0,0,13,4],[0,0,13,5],[0,0,13,6],[0,0,13,7],[0,0,13,8],[0,0,13,9],[0,0,13,10],[0,0,13,11],[0,0,13,12],[0,0,13,13],[0,0,13,14],[0,0,13,15],[0,0,13,16],[0,0,13,17],[0,0,13,18],[0,0,13,19],[0,0,13,20],[0,0,14,0],[0,0,14,1],[0,0,14,2],[0,0,14,3],[0,0,14,4],[0,0,14,5],[0,0,14,6],[0,0,14,7],[0,0,14,8],[0,0,14,9],[0,0,14,10],[0,0,14,11],[0,0,14,12],[0,0,14,13],[0,0,14,14],[0,0,14,15],[0,0,14,16],[0,0,14,17],[0,0,14,18],[0,0,14,19],[0,0,14,20],[0,0,15,0],[0,0,15,1],[0,0,15,2],[0,0,15,3],[0,0,15,4],[0,0,15,5],[0,0,15,6],[0,0,15,7],[0,0,15,8],[0,0,15,9],[0,0,15,10],[0,0,15,11],[0,0,15,12],[0,0,15,13],[0,0,15,14],[0,0,15,15],[0,0,15,16],[0,0,15,17],[0,0,15,18],[0,0,15,19],[0,0,15,20],[0,0,16,0],[0,0,16,1],[0,0,16,2],[0,0,16,3],[0,0,16,4],[0,0,16,5],[0,0,16,6],[0,0,16,7],[0,0,16,8],[0,0,16,9],[0,0,16,10],[0,0,16,11],[0,0,16,12],[0,0,16,13],[0,0,16,14],[0,0,16,15],[0,0,16,16],[0,0,16,17],[0,0,16,18],[0,0,16,19],[0,0,16,20],[0,0,17,0],[0,0,17,1],[0,0,17,2],[0,0,17,3],[0,0,17,4],[0,0,17,5],[0,0,17,6],[0,0,17,7],[0,0,17,8],[0,0,17,9],[0,0,17,10],[0,0,17,11],[0,0,17,12],[0,0,17,13],[0,0,17,14],[0,0,17,15],[0,0,17,16],[0,0,17,17]... etc.
It ends at [20,20,20,20].
I need to pick 50 combinations from the file and assign it to a variable so it would be like
var combinationsArr = [
[0,0,17,9],[0,0,17,10],[0,0,17,11],[0,0,17,12]
]; //BUT 50 of them
it's okay if it is just in order like [0,0,0,0],[0,0,0,1],[0,0,0,2],[0,0,0,3],[0,0,0,4],[0,0,0,5],[0,0,0,6],[0,0,0,7],[0,0,0,8],[0,0,0,9],[0,0,0,10],[0,0,0,11],[0,0,0,12] and doesn't have to be super random like [1,2,3,4],[9,12,13,15],[20,12,6,7]
as long as it is able to pick 50 of them.
I am doing this because 194481 combinations are a lot and makes my program carsh. so I just decided i'll put it in a text file and pick random points from the text file like from [0,0,0,1] to [0,0,0,50] OR
from [0,1,0,0] to [0,1,0,49] if that's possible.
because i have to generate a random combination. I have another array of combinations which are not supposed to be generated. Let's call it notAllowedArr.
var notAllowedArr = [
[0,0,17,9],[0,0,17,12]
];
I am thinking, i'll just generate 50 combinations and remove the ones listed in notAllowedArr then pick one from combinationsArr as the final result. I will still have to find code to remove those from combinationsArr but the result should be like.
var combinationsArr = [[0,0,17,10],[0,0,17,11]];
then i'll have a code to pick a random value from combinationsArr.
example. combinationsArr[0].
so the final result would be; [0,0,17,10]
Does anyone have a better solution?
If I understand correctly, you need to pick one random combination, which is not present in a list of forbidden combinations.
You can consider a combination of four numbers from 0 to 20 as a number from 0 to 194480 in base-21 notation. So instead of having to store all combinations in a file, we just pick a random number and convert it to base-21.
To choose a random number in a range where some values are forbidden, choose a number in the range from 0 to the maximum minus the number of forbidden values; then iterate over the forbidden values from small to large, and increment the random number every time you find a smaller or equal forbidden value.
This will make sure that every combination has the same probability of being chosen, and avoids the possibility of repeatedly choosing a forbidden combination.
function randomBase21(skip) {
var dec = [], result = [], num;
// CONVERT FORBIDDEN COMBINATIONS FROM BASE-21 TO DECIMAL AND SORT
for (var i = 0; i < skip.length; i++) {
dec[i] = skip[i][0] * 9261 + skip[i][1] * 441 + skip[i][2] * 21 + skip[i][3];
}
dec.sort(function(a, b){return a - b});
// GENERATE RANDOM NUMBER FROM 0 TO MAX - NUMBER OF FORBIDDEN COMBINATIONS
num = Math.floor(Math.random() * (194481 - skip.length));
// INCREMENT RANDOM NUMBER FOR EVERY SMALLER FORBIDDEN COMBINATION
for (var i = 0; i < skip.length && num >= dec[i]; i++) {
++num;
}
// CONVERT RANDOM NUMBER TO FOUR BASE-21 DIGITS
for (var i = 3; i >= 0; i--, num /= 21) {
result[i] = Math.floor(num % 21);
}
return result;
}
var notAllowed = [[0,0,17,9],[0,0,17,12],[20,19,17,12],[15,16,17,12]];
document.write(randomBase21(notAllowed));
Something like this should work (off the top of my head and not tested/debugged):
var samples = new Array();
for(var index = 0; index < 50; index++) {
samples.push(generatePermutation());
}
function generatePermutation() {
var result = [Math.floor(Math.random() * 20) + 1,
Math.floor(Math.random() * 20) + 1,
Math.floor(Math.random() * 20) + 1,
Math.floor(Math.random() * 20) + 1];
}
I just thought of a better way.
I think I will make a function that generates a random combination.
Then check if it exists in notAllowedArr. If it exists, it will generate another one. If not then that will return that combination :D
I think this will work faster ^^;

Looping over numbers

So this is the question that is given.
You are in a room with a circle of 100 chairs. The chairs are numbered sequentially from 1 to 100.
At some point in time, the person in chair #1 will be asked to leave. The person in chair #2 will be skipped, and the person in chair #3 will be asked to leave. This pattern of skipping one person and asking the next to leave will keep going around the circle until there is one person left, the survivor.
And this is the answer I came up with. I believe this is the right answer, I've done it on paper about 10 times as well and came up with 74 every time.
Is this a trick question or something? Because I'm not sure what to do from here.
Here is the jsfiddle http://jsfiddle.net/cQUaH/
var console = {
log : function(s) {
document.body.innerHTML += s + "<br>";
}
};
var chairArr = [];
for (var i = 1; i <= 100; i++){
chairArr.push(i);
}
var j = 2;
while(chairArr.length > 1) {
console.log('removing ' + chairArr[j]);
chairArr.splice(j, 1);
j++;
if(j >= chairArr.length) {
console.log('--- Finished pass');
console.log('--- Array state:');
console.log(chairArr);
j = (j == chairArr.length) ? 0 : 1;
}
}
console.log('--- Final result: ' + chairArr);
//result 74
With a minor change in indices, you have the Josephus problem. In the traditional formulation, person 1 kills person 2, 3 kills 4, etc. To convert to that form, kill off person 1, as your problem states, and then renumber people 2-100 by subtracting 1, giving people 1-99.
A good treatment of the Josephus problem, including an account of its origin in the Jewish Revolt of 70-73 CE, is in Concrete Mathematics, 2nd edition, by Graham, Knuth, and Patashnik, Section 1.3. Both Wikipedia and Wolfram MathWorld have articles on the problem, Wikipedia even includes the original description by Josephus in The Jewish War.
The book gives a mildly complicated recursion for the solution, and a simpler algorithm. If the number of people is n, and n = 2^l + m where l is as large as possible, then the answer is 2m+1. So, since 99 = 2^6 + 35, the solution is 2*35 + 1 = 71. But you need to reverse the renumbering, so the real answer is 72.
As far as your programming problem, however, why don't you take as your basic operation Remove the first person in the circle and move the second person to the end. So, with 5 people, [1,2,3,4,5], you remove the first getting [2,3,4,5]and moving the new first element to the end getting [3,4,5,2].
var killAndRotate = function(array) { // say [1,2,3,4,5]
var dead = array.shift(), // dead = 1, array = [2,3,4,5]
skipped = array.shift(); // skipped = 2, array = [3,4,5]
array.push(skipped); // array = [3,4,5,2]
}
And then the main loop becomes:
while (chairArray.length > 1) {
killAndRotate(chairArray);
}
alert(chairArray[0]); // or console.log, or return.
// In turn, array is:
// [1,2,3,4,5]
// [3,4,5,2]
// [5,2,4]
// [4,2]
// [2] and we alert, log, or return 2.
Added
The easy way to find that result for the original Josephus problem is to see that:
If there are 2^l people, then in the first pass all the even-numbered people are killed, so the first person remains alive.
1 2 3 4 5 6 7 8
X X X X
Now there are 2^(l - 1) people. Again, the first person survives:
1 2 3 4 5 6 7 8
X X X X
X X
Repeat the process; the first person survives each pass, and so is the last survivor.
Now, suppose there are m extra people with m < 2^l. Here, l = 3 and m = 5. Kill the first m people to die.
1 2 3 4 5 6 7 8 9 10 11 12 13
X X X X X Y
Now, there are 2^l people left, and person 2 m + 1 = 11 is the first in line. So he survives.
One should also point out that adding a new index variable and splicing can lead to programmer error. Since you only need to remove from the front and add to the back, use the basic methods of arrays.
It seems to me the answer is 72. When you realize that rather than removing numbers you can skip them, the code becomes very short and straight-forward.
var chairArr = [];
for (var i = 1; i <= 100; i++)
chairArr.push(i);
for (i = 1; i < chairArr.length-2; i = i + 2)
chairArr.push(chairArr[i]);
console.log('--- Final result: ' + chairArr[i]);
What have you described here is the Josephus problem, and can be solved using dynamic programming:
function josephus(n, k)
{
if (n == 1) {
return 1;
} else {
return ((josephus(n-1, k) + k - 1) % n) + 1;
}
}
alert(josephus(100, 2));
Source: Wikipedia
The n denotes the number of chairs and k indicates every kth person leaving.
The result here is 73.
Update
Unfortunately, I didn't read the problem properly. The above code solves a slightly different problem; instead of killing off the first person in round one, the second person is killed instead. Being a survivor hinges on details :)
Solving your code problem is rather simple, start with the first person instead of the third in the first round.
var chairArr = [];
for (var i = 1; i <= 100; i++){
chairArr.push(i);
}
var j = 0;
while (chairArr.length > 1) {
chairArr.splice(j, 1);
j = (j + 1) % n;
}
You don't need an iteration to find the result, there is a formula that can be use to obtain the final chair:
function findChair (input) {
return (input - Math.pow(2, Math.floor(Math.log2(input)))) * 2 || (input === 1 ? 0 : input)
}
And for the original Josephus problem, which you kill the even numbers instead, the formula can be simplified:
function findChair (input) {
return (input - Math.pow(2, Math.floor(Math.log2(input)))) * 2 + 1
}
The cool thing about the original problem, is that you can work with binary. For example:
100 = 1100100
Take the first '1' and place it to the last:
1001001 = 73

Categories