I'm totally hooked on CodeEval, and one of the problems on there caught my attention. Here it is, copied from here:
Challenge Description:
Flavius Josephus was a famous Jewish historian of the first century, at the time of the destruction of the Second Temple. According to legend, during the Jewish-Roman war he was trapped in a cave with a group of soldiers surrounded by Romans. Preferring death to capture, the Jews decided to form a circle and, proceeding around it, to kill every j'th person remaining until no one was left. Josephus found the safe spot in the circle and thus stayed alive.Write a program that returns a list of n people, numbered from 0 to n-1, in the order in which they are executed. Input sample:
Your program should accept as its first argument a path to a filename. Each line in this file contains two comma separated positive integers n and m , where n is the number of people and every m'th person will be executed. e.g.
10,3
5,2
Output sample:
Print out the list of n people(space delimited) in the order in which they will be executed. e.g.
2 5 8 1 6 0 7 4 9 3
1 3 0 4 2
Here's my solution in JavaScript, which succeeded in all test cases:
var fs = require("fs"); //object for reading in a file
fs.readFileSync(process.argv[2]).toString().split('\n').forEach(function (line) {
if (line != "") {
var lineSplit = line.split(",");
var maxNum = parseInt(lineSplit[0], 10); //the number of people in the circle (n)
var spacer = parseInt(lineSplit[1], 10); //Every m'th person is executed
var counter = spacer - 1; //We're working with a zero-based array, so decrement accordingly
var people = [];
var deadPeople = [];
for (var i = 0; i < maxNum; i++) {
var person = [];
person = new Array(i.toString(), 1);
people[i] = person; //a new person is added with a status of 1 (alive)
}
while(deadPeople.length < maxNum){
people[counter][1] = 0; //sadness
deadPeople.push(people[counter][0]);
counter += spacer;
while(people.length > 0 && counter >= people.length){
counter = counter - people.length;
regroup(people);
}
}
console.log(deadPeople.join(" "));
}
});
function regroup(arr) {
arr.forEach(function(element, index, array) {
if (element[1] === 0) {
array.splice(index, 1);
}
});
}
All comments are welcome, but I'm especially interested in efficiency.