100 chairs in a circle problem solving with Angular.js and visualization Here is the problem statement:


  Take a second to imagine that you are in a room with 100 chairs arranged in a circle. These chairs are numbered sequentially from One to One Hundred. At some point in time, the person in chair #1 will be told to leave the room. The person in chair #2 will be skipped, and the person in chair #3 will be told to leave. Next to go is person in chair #6. In other words, 1 person will be skipped initially, and then 2, 3, 4.. and so on. This pattern of skipping will keep going around the circle until there is only one person remaining- The survivor! Note that each chair is removed when the person leaves the room.


Please review my attempt below considering the following points:


Correctness (I am getting the winner as # 31)
Any chances for optimization




var myApp = angular.module('myApp',[]);

myApp.controller('MyCtrl', [ '$scope', '$interval', '$log', function($scope, $interval, $log){

  $scope.init = function(){
    $scope.people = [];
    $scope.logs = [];

    // get the 100 people/chair
    for(var i=1; i&lt;=100; i++){
      $scope.people.push({ index: i });
    }
  };

  $scope.startFiring = function(){

    var fireIndex = 0, // for removing the person at this index
        skipCount = 0; // for incremental counting 

    if($scope.people.length &gt;= 1){ // if start button clicked again
      $scope.gotWinner = false; // hide the winner
      $interval.cancel(fireInterval); // stop the interval
      $scope.init();
    }

    var fireInterval = $interval(function(){
      
      $scope.disableStartButton = true;

      if ($scope.people.length &gt; 1) { // if more than 1 people
        $scope.logs.push({text: 'Firing #' + $scope.people[fireIndex].index}); // show the log
        
        $scope.people.splice(fireIndex, 1); // fire!
        
        // increment
        skipCount += 1;
        fireIndex += skipCount;

        //if fireIndex becomes greater than $scope.people.length, then set fireIndex to remainder from fireIndex / $scope.people.length
        if(fireIndex &gt; $scope.people.length){
          fireIndex %= $scope.people.length;
        }

      } else {
        $interval.cancel(fireInterval); // stop the interval
        $scope.gotWinner = true; // show the winner
        $scope.disableStartButton = false;
      }
    }, 500); // every 1/2 sec.

  };

  $scope.init(); // intialize the chair/people when the view is loaded or start is clicked again

}]);
body{
  font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
}

span{
  display: inline-block;
  padding: 5px;
  margin: 4px;
  border-radius: 3px;
  background: #000000;
  color: #FFFFFF;
}
&lt;!DOCTYPE html&gt;
&lt;html&gt;
  &lt;head&gt;
    &lt;meta charset="utf-8"&gt;
    &lt;title&gt;JS Bin&lt;/title&gt;
  &lt;/head&gt;
  &lt;body ng-app='myApp'&gt;
    &lt;div ng-controller="MyCtrl"&gt;
      &lt;div&gt;
        &lt;span ng-repeat="person in people"&gt;{{person.index}}&lt;/span&gt;
      &lt;/div&gt;
      &lt;button ng-click="startFiring()" ng-disabled="disableStartButton"&gt;Start!&lt;/button&gt;
      &lt;p ng-show="gotWinner"&gt;And the winner is.... # &lt;strong&gt;{{people[0].index}}!&lt;/strong&gt;&lt;/p&gt;
      &lt;p ng-show="logs.length !== 0"&gt;Logs:&lt;/p&gt;
      &lt;ul&gt;
        &lt;li ng-repeat="log in logs | orderBy:'-'"&gt;{{log.text}}&lt;/li&gt;
      &lt;/ul&gt;
    &lt;/div&gt;
    &lt;script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"&gt;&lt;/script&gt;
  &lt;/body&gt;
&lt;/html&gt;
Mathematical % simplification

Remember that $$a\  \%\   b == a  \ \ if\ b &gt; a$$

I don't know the math, but Python confirms:

&gt;&gt;&gt; import random
&gt;&gt;&gt; def random_ints():
    for _ in range(1000): yield random.randint(1, 100)
&gt;&gt;&gt; all(a % b == a for a in random_ints() for b in random_ints() if b &gt; a)
True


So:

    fireIndex += skipCount;

    //if fireIndex becomes greater than $scope.people.length, then set fireIndex to remainder from fireIndex / $scope.people.length
    if(fireIndex &gt; $scope.people.length){
      fireIndex %= $scope.people.length;
    }


can be simplified to

fireIndex = (fireIndex + skipCount) % $scope.people.length


Comments

Some comments are good, but you should avoid writing comments next to obvious code:

  if ($scope.people.length &gt; 1) { // if more than 1 people


It is already obvious from the code that you are checking if there are more than 1 people, the comment just doubles the effort required to change the code.

The below comment is very confusing instead:

if($scope.people.length &gt;= 1){ // if start button clicked again


Probably you changed the code but not comment.