# dok/example/100-doors

## The problem

There are 100 doors in a row that are all initially closed.

You make 100 passes by the doors.

The first time through, visit every door and  toggle  the door  (if the door is closed,  open it;   if it is open,  close it).

The second time, only visit every 2nd door   (door #2, #4, #6, ...),   and toggle it.

The third time, visit every 3rd door   (door #3, #6, #9, ...), etc,   until you only visit the 100th door.


## Dok

var a::Array[Of::Bool](0, 99, with init-value False)

repeat {
with i -from 0 -to 99
repeat {
with j -from i -to 99
invert a[j]
}
}

repeat {
with i -from 0 -to 99
do IO.!!println("door ${i} is${ when a[i] { return "open" } -else { return "closed" } }")
}


## Red

Red [Doors""]

doors: make bitset! len: 100
repeat step len [
repeat n to-integer len / step [
m: step * n
doors/:m: not doors/:m
]
]


## Smalltalk

|a|
a := Array new: 100 .
1 to: 100 do: [ :i | a at: i put: false ].

1 to: 100 do: [ :pass |
pass to: 100 by: pass do: [ :door |
a at: door put: (a at: door) not .
]
].

"output"
1 to: 100 do: [ :door |
( 'door #%1 is %2' %
{ door . (a at: door) ifTrue: [ 'open' ] ifFalse: [ 'closed' ] } ) displayNl
]


## F#

type doorState=Open|Closed
let flip=function Open->Closed |_->Open
let Doors=Array.create 100 Closed
for n in 1..100 do {n-1..n..99}|>Seq.iter(fun n->Doors[n]<-flip Doors[n])
Doors|>Array.iteri(fun n g->if g=Open then printf "%d " (n+1)); printfn ""


## CL

(define-modify-macro toggle () not)

(defun 100-doors ()
(let ((doors (make-array 100)))
(dotimes (i 100)
(loop for j from i below 100 by (1+ i)
do (toggle (svref doors j))))
(dotimes (i 100)
(format t "door ~a: ~:[closed~;open~]~%" (1+ i) (svref doors i)))))