4
\$\begingroup\$

100 Doors

100 doors is a relatively simple mathematical problem. If you have 100 doors that are initially closed, and follow this procedure:

Walk past the doors 100 times, the first time you toggle every door (if the door is closed, you open it, and vice versa). The second time, you only visit every second door, the third time every third door. This continues until you only visit the 100th door.

.. what doors are remaining open?

class Door {
  state {_state}
  construct new() {
    _state = false
  }
  changeState() {
    _state = !_state
  }
}

class Doors {
  get {_array}
  construct new(size) {
    _array = []
    for (i in 1..size) {
      _array.add(Door.new())
    }
  }
}

var doors = Doors.new(100)
var step = 1
var result = 1

while (step != 100) {
  var count = 1
  var stepNextPoint = step

  for (door in doors.get) {
    if (count >= stepNextPoint) {
      door.changeState()
      stepNextPoint = stepNextPoint + step
    }
    count = count + 1
  }

  step = step + 1
}

for (door in doors.get) {
  if (door.state) {
    System.print("%(result) door is open")
  }
  result = result + 1
}
\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

Your code is clean, and (based on my "literature research") your code is right. There are parts of your code though, that should be simplified, and an algorithmic change that should be applied to the way you iterate the doors. Let's go through these in detail...

Your primary loop is incrementing the step variable. You've implemented it like:

var step = 1

while (step != 100) {
  .....
  step = step + 1
}

That is OK, but it would be better to implement it using the range operator (semi-inclusive ... instead of inclusive ..) and a for-loop:

for (step in [1...100]) {
    ......
}

The next issue is algorithmic - you're looping over every door even when you only need to toggle every step doors. This code:

  var stepNextPoint = step
  for (door in doors.get) {
    if (count >= stepNextPoint) {
      door.changeState()
      stepNextPoint = stepNextPoint + step
    }
    count = count + 1
  }

should be inverted, and should become:

  var stepNextPoint = step
  while (stepNextPoint < 100) {
      doors.get[stepNextPoint].changeState()
      stepNextPoint = stepNextPoint + step
  }

These changes all make me realize that the value 100 is repeated in many places... the 100-value should be encoded as a variable, and the whole logic block should probably be expressed as a function call taking 100 as a parameter, and then just called from the main routine.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.