100 doors: Difference between revisions

From Rosetta Code
Content added Content deleted
m (→‎{{header|Java}}: changed second for loop to correctly start at j=i as opposed to j=1)
No edit summary
Line 4,694: Line 4,694:


END Doors.</lang>
END Doors.</lang>

=={{header|XPL0}}==
<lang XPL0>include c:\cxpl\codes; \intrinsic 'code' declarations
int Door(100); \You have 100 doors in a row
define Open, Closed;
int D, Pass, Step;

[for D:= 0 to 100-1 do \that are all initially closed
Door(D):= Closed;

Step:= 1; \The first time through, you visit every door
for Pass:= 1 to 100 do \You make 100 passes by the doors
[D:= Step-1;
repeat \if the door is closed, you open it; if it is open, you close it
if Door(D)=Closed then Door(D):= Open else Door(D):= Closed;
D:= D+Step;
until D>=100;
Step:= Step+1; \The second time you only visit every 2nd door
]; \The third time, every 3rd door
\until you only visit the 100th door
\What state are the doors in after the last pass?
Text(0, "Open: "); \Which are open?
for D:= 0 to 100-1 do
if Door(D)=Open then [IntOut(0, D+1); ChOut(0,^ )];
CrLf(0);

Text(0, "Closed: "); \Which are closed?
for D:= 0 to 100-1 do
if Door(D)=Closed then [IntOut(0, D+1); ChOut(0,^ )];
CrLf(0);

\Optimized: The only doors that remain open are those that are perfect squares
Text(0, "Open: ");
D:= 1;
repeat IntOut(0, D*D); ChOut(0,^ );
D:= D+1;
until D*D>100;
CrLf(0);
]</lang>


=={{header|XSLT}}==
=={{header|XSLT}}==

Revision as of 23:22, 22 April 2012

Task
100 doors
You are encouraged to solve this task according to the task description, using any language you may know.

Problem: You have 100 doors in a row that are all initially closed. You make 100 passes by the doors. The first time through, you visit every door and toggle the door (if the door is closed, you open it; if it is open, you close it). The second time you only visit every 2nd door (door #2, #4, #6, ...). The third time, every 3rd door (door #3, #6, #9, ...), etc, until you only visit the 100th door.

Question: What state are the doors in after the last pass? Which are open, which are closed? [1]

Alternate: As noted in this page's discussion page, the only doors that remain open are whose numbers are perfect squares of integers. Opening only those doors is an optimization that may also be expressed.

4DOS Batch

<lang 4DOS Batch> @echo off set doors=%@repeat[C,100] do step = 1 to 100

 do door = %step to 100 by %step
   set doors=%@left[%@eval[%door-1],%doors]%@if[%@instr[%@eval[%door-1],1,%doors]==C,O,C]%@right[%@eval[100-%door],%doors]
 enddo

enddo </lang>

The SET line consists of three functions: <lang> %@left[n,string] ^: Return n leftmost chars in string %@right[n,string] ^: Return n rightmost chars in string %@if[condition,true-val,false-val] ^: Evaluate condition; return true-val if true, false-val if false </lang>

Here @IF is used to toggle between C and O.

6502 Assembly

Works with: [6502asm.com] version 1.2

optimized (Largely inspired by the optimized C implementation) <lang 6502asm>

                       ;assume all memory is initially set to 0
         inc $1        ;start out with a delta of 1

openloop: inc $200,X ;open a door at X

         inc $1        ;add 2 to delta
         inc $1
         txa           ;add delta to X
         adc $1
         tax
         cpx #$65      ;check to see if we're at the 100th door
         bmi openloop  ;jump back to openloop if less than 100</lang>

8086 Assembly

See 100 doors/8086 Assembly

ABAP

unoptimized <lang ABAP>form open_doors_unopt.

 data: lv_door  type i,
       lv_count type i value 1.
 data: lt_doors type standard table of c initial size 100.
 field-symbols: <wa_door> type c.
 do 100 times.
   append initial line to lt_doors assigning <wa_door>.
   <wa_door> = 'X'.
 enddo.
 while lv_count < 100.
   lv_count = lv_count + 1.
   lv_door = lv_count.
   while lv_door < 100.
     read table lt_doors index lv_door assigning <wa_door>.
     if <wa_door> = ' '.
       <wa_door> = 'X'.
     else.
       <wa_door> = ' '.
     endif.
     add lv_count to lv_door.
   endwhile.
 endwhile.
 loop at lt_doors assigning <wa_door>.
   if <wa_door> = 'X'.
     write : / 'Door', (4) sy-tabix right-justified, 'is open' no-gap.
   endif.
 endloop.

endform.</lang>

optimized

Using <lang ABAP>form open_doors_opt.

 data: lv_square type i value 1,
       lv_inc    type i value 3.
 data: lt_doors  type standard table of c initial size 100.
 field-symbols: <wa_door> type c.
 do 100 times.
   append initial line to lt_doors assigning <wa_door>.
   if sy-index = lv_square.
     <wa_door> = 'X'.
     add: lv_inc to lv_square, 2 to lv_inc.
     write : / 'Door', (4) sy-index right-justified, 'is open' no-gap.
   endif.
 enddo.

endform.</lang>

ACL2

<lang lisp>(defun rep (n x)

  (if (zp n)
      nil
      (cons x
            (rep (- n 1) x))))

(defun toggle-every-r (n i bs)

  (if (endp bs)
      nil
      (cons (if (zp i)
                (not (first bs))
                (first bs))
            (toggle-every-r n (mod (1- i) n) (rest bs)))))

(defun toggle-every (n bs)

  (toggle-every-r n (1- n) bs))

(defun 100-doors (i doors)

  (if (zp i)
      doors
      (100-doors (1- i) (toggle-every i doors))))</lang>

ActionScript

Works with: ActionScript version 3.0

unoptimized <lang actionscript>package {

   import flash.display.Sprite;                                              
   public class Doors extends Sprite {
       public function Doors() {
           // Initialize the array
           var doors:Array = new Array(100);
           for (var i:Number = 0; i < 100; i++) {
               doors[i] = false;
           // Do the work
           for (var pass:Number = 0; pass < 100; pass++) {
               for (var j:Number = pass; j < 100; j += (pass+1)) {
                   doors[j] = !doors[j];
               }
           }
           trace(doors);
       }
   }

}</lang>

Ada

unoptimized <lang ada>with Ada.Text_Io; use Ada.Text_Io;

procedure Doors is
   type Door_State is (Closed, Open);
   type Door_List is array(Positive range 1..100) of Door_State;
   The_Doors : Door_List := (others => Closed);
begin
   for I in 1..100 loop
      for J in The_Doors'range loop
         if J mod I = 0 then
            if The_Doors(J) = Closed then
                The_Doors(J) := Open;
            else
               The_Doors(J) := Closed;
            end if;
         end if;
      end loop;
   end loop;
   for I in The_Doors'range loop
      Put_Line(Integer'Image(I) & " is " & Door_State'Image(The_Doors(I)));
   end loop;
end Doors;</lang>

optimized <lang ada>with Ada.Text_Io; use Ada.Text_Io;

with Ada.Numerics.Elementary_Functions; use Ada.Numerics.Elementary_Functions;

procedure Doors_Optimized is
   Num : Float;
begin
   for I in 1..100 loop
      Num := Sqrt(Float(I));
      Put(Integer'Image(I) & " is ");
      if Float'Floor(Num) = Num then
         Put_Line("Opened");
      else
         Put_Line("Closed");
      end if;
   end loop;
end Doors_Optimized;</lang>

Aikido

<lang aikido> var doors = new int [100]

foreach pass 100 {

   for (var door = pass ; door < 100 ; door += pass+1) {
       doors[door] = !doors[door]
   }

}

var d = 1 foreach door doors {

   println ("door " + d++ + " is " + (door ? "open" : "closed"))

}

</lang>

ALGOL 68

unoptimized <lang algol68># declare some constants # INT limit = 100;

PROC doors = VOID: (

 MODE DOORSTATE = BOOL;
 BOOL closed = FALSE;
 BOOL open = NOT closed;
 MODE DOORLIST = [limit]DOORSTATE;
 DOORLIST the doors;
 FOR i FROM LWB the doors TO UPB the doors DO the doors[i]:=closed OD;
 FOR i FROM LWB the doors TO UPB the doors DO
   FOR j FROM LWB the doors TO UPB the doors DO
     IF j MOD i = 0 THEN
       the doors[j] :=  NOT the doors[j]
     FI
   OD
 OD;
 FOR i FROM LWB the doors TO UPB the doors DO
   printf(($g" is "gl$,i,(the doors[i]|"opened"|"closed")))
 OD

); doors;</lang> optimized <lang algol68>PROC doors optimised = ( INT limit )VOID:

 FOR i TO limit DO
   REAL num := sqrt(i);
   printf(($g" is "gl$,i,(ENTIER num = num |"opened"|"closed") ))
 OD

doors optimised(limit)</lang>

AmigaE

<lang amigae>PROC main()

 DEF t[100]: ARRAY,
     pass, door
 FOR door := 0 TO 99 DO t[door] := FALSE
 FOR pass := 0 TO 99
   door := pass
   WHILE door <= 99
     t[door] := Not(t[door])
     door := door + pass + 1
   ENDWHILE
 ENDFOR
 FOR door := 0 TO 99 DO WriteF('\d is \s\n', door+1,
                               IF t[door] THEN 'open' ELSE 'closed')

ENDPROC</lang>

APL

Works with: Dyalog APL

unoptimized <lang APL>out←doors num ⍝ Simulates the 100 doors problem for any number of doors ⍝ Returns a boolean vector with 1 being open

out←⍳num ⍝ num steps out←⍳¨out ⍝ Count out the spacing for each step out←1=out ⍝ Make that into a boolean vector out←⌽¨out ⍝ Flip each vector around out←(num∘⍴)¨out ⍝ Copy each out to the right size out←≠/out ⍝ XOR each vector, toggling each marked door out←⊃out ⍝ Disclose the results to get a vector</lang> Sample Output:

 10 10⍴doors 100
1 0 0 1 0 0 0 0 1 0
0 0 0 0 0 1 0 0 0 0
0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 1  

optimized <lang APL>out←doorsOptimized num;marks ⍝ Returns a boolean vector of the doors that would be left open

marks←⌊num*0.5 ⍝ Take the square root of the size, floored marks←(⍳marks)*2 ⍝ Get each door to be opened out←num⍴0 ⍝ Make a vector of 0s out[marks]←1 ⍝ Set the marked doors to 1</lang> Sample Output:

 10 10⍴doorsOptimized 100
1 0 0 1 0 0 0 0 1 0
0 0 0 0 0 1 0 0 0 0
0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 1  

Alternate 1-line version Note that ⎕IO = 1

2|+/[1]0=D∘.|D←⍳100

The idea is that the n:th door will be flipped the same number of times as there are divisors for n. So first we make D all ints 1..100 (D←⍳100).
The next step is to find the remainders of every such int when divided by every other (D∘.|D).
This results in a 100×100 matrix which we turn into a binary one by testing if the values are equal to zero i.e. divisors.
Next: sum along axis 1, i.e. the columns. This tells us the number of divisors. Finally calculate the remainder of these when divided by 2, i.e. find which n have an odd number of divisors, i.e. will be flipped an odd number of times and thus end up open.

AppleScript

<lang AppleScript>set is_open to {} repeat 100 times

  set end of is_open to false

end repeat with pass from 1 to 100

 repeat with door from pass to 100 by pass
   set item door of is_open to not item door of is_open
 end

end set open_doors to {} repeat with door from 1 to 100

  if item door of is_open then
    set end of open_doors to door
  end

end set text item delimiters to ", " display dialog "Open doors: " & open_doors</lang>

Arbre

<lang Arbre> openshut(n):

 for x in [1..n]
   x%n==0

pass(n):

 if n==100
   openshut(n)
 else
   openshut(n) xor pass(n+1)

100doors():

 pass(1) -> io

</lang>

Argile

<lang Argile>use std, array

close all doors for each pass from 1 to 100

 for (door = pass) (door <= 100) (door += pass)
   toggle door

let int pass, door.

.: close all doors :. {memset doors 0 size of doors} .:toggle <int door>:. {  !!(doors[door - 1]) }

let doors be an array of 100 bool

for each door from 1 to 100

 printf "#%.3d %s\n" door (doors[door - 1]) ? "[ ]", "[X]"</lang>

AutoHotkey

Standard Approach

<lang autohotkey>Loop, 100

 Door%A_Index% := "closed"

Loop, 100 {

 x := A_Index, y := A_Index
 While (x <= 100)
 {
   CurrentDoor := Door%x%
   If CurrentDoor contains closed
   {
     Door%x% := "open"
     x += y
   }
   else if CurrentDoor contains open
   {
     Door%x% := "closed"
     x += y
   }
 }

}

Loop, 100 {

  CurrentDoor := Door%A_Index%
  If CurrentDoor contains open
     Res .= "Door " A_Index " is open`n"

} MsgBox % Res</lang>

Alternative Approach

Making use of the identity:

<lang autohotkey>increment := 3, square := 1 Loop, 100

   If (A_Index = square) 
       outstring .= "`nDoor " A_Index " is open" 
       ,square += increment, increment += 2 

MsgBox,, Succesfull, % SubStr(outstring, 2)</lang>

Optimized

<lang autohotkey>While (Door := A_Index ** 2) <= 100

  Result .= "Door " Door " is open`n"

MsgBox, %Result%</lang>

Axiom

Unoptimized:<lang Axiom>(open,closed,change,open?) := (true,false,not,test); doors := bits(100,closed); for i in 1..#doors repeat

 for j in i..#doors by i repeat
   doors.j := change doors.j

[i for i in 1..#doors | open? doors.i] </lang>Optimized:<lang Axiom>[i for i in 1..100 | perfectSquare? i] -- or [i^2 for i in 1..sqrt(100)::Integer]</lang>

AWK

unoptimized <lang awk>BEGIN {

 for(i=1; i <= 100; i++)
 {
   doors[i] = 0 # close the doors
 }
 for(i=1; i <= 100; i++)
 {
   for(j=i; j <= 100; j += i)
   {
     doors[j] = (doors[j]+1) % 2
   }
 }
 for(i=1; i <= 100; i++)
 {
   print i, doors[i] ? "open" : "close"
 }

}</lang> optimized <lang awk>BEGIN {

 for(i=1; i <= 100; i++) {
   doors[i] = 0 # close the doors
 }
 for(i=1; i <= 100; i++) {
   if ( int(sqrt(i)) == sqrt(i) ) {
     doors[i] = 1
   }
 }
 for(i=1; i <= 100; i++)
 {
   print i, doors[i] ? "open" : "close"
 }

}</lang>

Batch File

unoptimized <lang dos> @echo off setlocal enableDelayedExpansion

0 = closed
1 = open
SET /A treats undefined variable as 0
Negation operator ! must be escaped because delayed expansion is enabled

for /l %%p in (1 1 100) do for /l %%d in (%%p %%p 100) do set /a "door%%d=^!door%%d" for /l %%d in (1 1 100) do if !door%%d!==1 (

 echo door %%d is open

) else echo door %%d is closed </lang>

optimized <lang dos> @echo off setlocal enableDelayedExpansion set /a square=1, incr=3 for /l %%d in (1 1 100) do (

 if %%d neq !square! (echo door %%d is closed) else (
   echo door %%d is open
   set /a square+=incr, incr+=2
 )

) </lang>

BASIC

Works with: QuickBasic version 4.5

unoptimized <lang qbasic>DIM doors(0 TO 99) FOR pass = 0 TO 99 FOR door = pass TO 99 STEP pass + 1 PRINT doors(door) PRINT NOT doors(door) doors(door) = NOT doors(door) NEXT door NEXT pass FOR i = 0 TO 99 PRINT "Door #"; i + 1; " is "; IF NOT doors(i) THEN PRINT "closed" ELSE PRINT "open" END IF NEXT i</lang> optimized <lang qbasic>DIM doors(0 TO 99) FOR door = 0 TO 99 IF INT(SQR(door)) = SQR(door) THEN doors(door) = -1 NEXT door FOR i = 0 TO 99 PRINT "Door #"; i + 1; " is "; IF NOT doors(i) THEN PRINT "closed" ELSE PRINT "open" END IF NEXT i</lang>

BBC BASIC

<lang bbcbasic> DIM doors%(100)

     FOR pass% = 1 TO 100
       FOR door% = pass% TO 100 STEP pass%
         doors%(door%) EOR= TRUE
       NEXT door%
     NEXT pass%
     
     FOR door% = 1 TO 100
       IF doors%(door%) PRINT "Door " ; door% " is open"
     NEXT door%</lang>

Befunge

Works with: CCBI version 2.1

<lang befunge>108p0>:18p;;>:9g!18g9p08g]

  • `!0\|+relet|-1`*aap81::+]
+1<r]!g9;>$08g1+
08paa[
  • `#@_^._aa</lang>

BlitzMax

Works with: BlitzMax version 1.37

optimized <lang BlitzMax>Graphics 640,480 i=1 While ((i*i)<=100) a$=i*i DrawText a$,10,20*i Print i*i i=i+1 Wend Flip WaitKey </lang>

Bracmat

Bracmat is not really at home in tasks that involve addressing things by index number. Here are four solutions that each do the task, but none should win a price for cleanliness.

Solution 1. Use an indexable array. Local variables are stored in stacks. Each stack corresponds to one variable name and vice versa. Stacks can also be used as arrays, but because of how local variables are implemented, arrays cannot be declared as local variables. <lang bracmat>( 100doors-tbl = door step

 .   tbl$(doors.101) { Create an array. Indexing is 0-based. Add one extra for addressing element nr. 100 }
   & 0:?step
   &   whl
     ' ( 1+!step:~>100:?step   { ~> means 'not greater than', i.e. 'less than or equal' }
       & 0:?door
       &   whl
         ' ( !step+!door:~>100:?door
           & 1+-1*!(!door$doors):?doors  { <number>$<variable> sets the current index, which stays the same until explicitly changed. }
           )
       )
   & 0:?door
   &   whl
     ' ( 1+!door:~>100:?door
       &   out
         $ ( door
             !door
             is
             ( !(!door$doors):1&open
             | closed
             )
           )
       )
   & tbl$(doors.0)  { clean up the array }

)</lang>

Solution 2. Use one variable for each door. In Bracmat, a variable name can be any non-empty string, even a number, so we use the numbers 1 .. 100 as variable names, but also as door numbers. When used as variable an extra level of indirection is needed. See the occurrences of ?! and !! in the following code. <lang bracmat>( 100doors-var = step door

 .   0:?door
   &   whl
     ' ( 1+!door:~>100:?door
       & closed:?!door { this creates a variable and assigns a value 'closed' to it }
       )
   & 0:?step
   &   whl
     ' ( 1+!step:~>100:?step
       & 0:?door
       &   whl
         ' ( !step+!door:~>100:?door
           &   ( !!door:closed&open
               | closed
               )
             : ?!door   
           )
       )
   & 0:?door
   &   whl
     ' ( 1+!door:~>100:?door
       & out$(door !door is !!door)
       )
   & 0:?door
   &   whl
     ' ( 1+!door:~>100:?door
       & tbl$(!door.0)         { cleanup the variable }
       )

)</lang>

Solution 3. Use a list and a dedicated positioning pattern to address the right door in the list. Create a new list by concatenating the skipped elements with the toggled elements. This solution is computationally unfavourable because of the many concatenations. <lang bracmat>( 100doors-list = doors door doorIndex step

 .   :?doors
   & 0:?door
   &   whl
     ' ( 1+!door:~>100:?door
       & closed !doors:?doors
       )
   & 0:?skip
   &   whl
     ' ( :?ndoors
       &   whl
         ' ( !doors:?skipped [!skip %?door ?doors  { the [<number> pattern only succeeds when the scanning cursor is at position <number> }
           &     !ndoors
                 !skipped
                 ( !door:open&closed
                 | open
                 )
             : ?ndoors
           )
       & !ndoors !doors:?doors
       & 1+!skip:<100:?skip
       )
   & out$!doors

)</lang>

Solution 4. Use a list of objects. Each object can be changed without the need to re-create the whole list. <lang bracmat>( 100doors-obj = doors door doorIndex step

 .   :?doors
   & 0:?door
   &   whl
     ' ( 1+!door:~>100:?door
       & new$(=closed) !doors:?doors
       )
   & 0:?skip
   &   whl
     ' ( !doors:?tododoors
       &   whl
         ' ( !tododoors:? [!skip %?door ?tododoors
           &   ( !(door.):open&closed
               | open
               )
             : ?(door.)
           )
       & 1+!skip:<100:?skip
       )
   & out$!doors

)</lang>

These four functions are called in the following way: <lang bracmat>100doors-tbl$ & 100doors-var$ & 100doors-list$ & 100doors-obj$;</lang>

C

unoptimized

Uses: C Runtime (Components:{{#foreach: component$n$|{{{component$n$}}}Property "Uses Library" (as page type) with input value "Library/C Runtime/{{{component$n$}}}" contains invalid characters or is incomplete and therefore can cause unexpected results during a query or annotation process., }})

<lang c>#include <stdio.h>

int main() {

 char is_open[100] = { 0 };
 int pass, door;
 // do the 100 passes
 for (pass = 0; pass < 100; ++pass)
   for (door = pass; door < 100; door += pass+1)
     is_open[door] = !is_open[door];
 // output the result
 for (door = 0; door < 100; ++door)
   printf("door #%d is %s.\n", door+1, (is_open[door]? "open" : "closed"));
 return 0;

}</lang>

optimized

This optimized version makes use of the fact that finally only the doors with square index are open, as well as the fact that .

Uses: C Runtime (Components:{{#foreach: component$n$|{{{component$n$}}}Property "Uses Library" (as page type) with input value "Library/C Runtime/{{{component$n$}}}" contains invalid characters or is incomplete and therefore can cause unexpected results during a query or annotation process., }})

<lang c>#include <stdio.h>

int main() {

 int square = 1, increment = 3, door;
 for (door = 1; door <= 100; ++door)
 {
   printf("door #%d", door);
   if (door == square)
   {
     printf(" is open.\n");
     square += increment;
     increment += 2;
   }
   else
     printf(" is closed.\n");
 }
 return 0;

}</lang>

The following ultra-short optimized version demonstrates the flexibility of C loops, but isn't really considered good C style:

<lang c>#include <stdio.h>

int main() {

 int door, square, increment;
 for (door = 1, square = 1, increment = 1; door <= 100; door++ == square && (square += increment += 2))
   printf("door #%d is %s.\n", door, (door == square? "open" : "closed"));
 return 0;

}</lang>

Or really optimize it -- square of an integer is, well, computable:<lang C>#include <stdio.h>

int main() { int i; for (i = 1; i * i <= 100; i++) printf("door %d open\n", i * i);

return 0; }</lang>

C++

Works with: GCC version 4.1.2 20061115 (prerelease) (SUSE Linux)

unoptimized <lang cpp>#include <iostream>

int main() {

 bool is_open[100] = { false };
 // do the 100 passes
 for (int pass = 0; pass < 100; ++pass)
   for (int door = pass; door < 100; door += pass+1)
     is_open[door] = !is_open[door];
 // output the result
 for (int door = 0; door < 100; ++door)
   std::cout << "door #" << door+1 << (is_open[door]? " is open." : " is closed.") << std::endl;
 return 0;

}</lang>

optimized This optimized version makes use of the fact that finally only the doors with square index are open, as well as the fact that .

<lang cpp>#include <iostream>

int main() {

 int square = 1, increment = 3;
 for (int door = 1; door <= 100; ++door)
 {
   std::cout << "door #" << door;
   if (door == square)
   {
     std::cout << " is open." << std::endl;
     square += increment;
     increment += 2;
   }
   else
     std::cout << " is closed." << std::endl;
 }
 return 0;

}</lang>

The only calculation that's really needed: <lang cpp>#include <iostream> //compiled with "Dev-C++" , from RaptorOne

int main() {

   for(int i=1; i*i<=100; i++)
           std::cout<<"Door "<<i*i<<" is open!"<<std::endl;

}</lang>

C#

Unoptimized <lang csharp>using System; class Program {

   static void Main()
   {
       //To simplify door numbers, uses indexes 1 to 100 (rather than 0 to 99)
       bool[] doors = new bool[101];
       for (int pass = 1; pass <= 100; pass++)
           for (int current = pass; current <= 100; current += pass)
               doors[current] = !doors[current];
       for (int i = 1; i <= 100; i++)
           Console.WriteLine("Door #{0} " + (doors[i] ? "Open" : "Closed"), i);
   }

}</lang> Optimized <lang csharp>using System; class Program {

   static void Main()
   {
       int door = 1, inrementer = 0;
       for (int current = 1; current <= 100; current++)
       {
           Console.Write("Door #{0} ", current);
           if (current == door)
           {
               Console.WriteLine("Open");
               inrementer++;
               door += 2 * inrementer + 1;
           }
           else
               Console.WriteLine("Closed");
       }
   }

}</lang> Optimized for brevity <lang csharp>using System; class Program {

   static void Main()
   {
       double n;
       for (int t = 1; t <= 100; ++t)
               Console.WriteLine(t + ": " + (((n = Math.Sqrt(t)) == (int)n) ? "Open" : "Closed"));
   }

}</lang>

C1R

<lang c>100_doors</lang>

CLIPS

Unoptimized

<lang clips>(deffacts initial-state

 (door-count 100)

)

(deffunction toggle

 (?state)
 (switch ?state
   (case "open" then "closed")
   (case "closed" then "open")
 )

)

(defrule create-doors-and-visits

 (door-count ?count)
 =>
 (loop-for-count (?num 1 ?count) do
   (assert (door ?num "closed"))
   (assert (visit-from ?num ?num))
 )
 (assert (doors initialized))

)

(defrule visit

 (door-count ?max)
 ?visit <- (visit-from ?num ?step)
 ?door <- (door ?num ?state)
 =>
 (retract ?visit)
 (retract ?door)
 (assert (door ?num (toggle ?state)))
 (if
   (<= (+ ?num ?step) ?max)
   then
   (assert (visit-from (+ ?num ?step) ?step))
 )

)

(defrule start-printing

 (doors initialized)
 (not (visit-from ? ?))
 =>
 (printout t "These doors are open:" crlf)
 (assert (print-from 1))

)

(defrule print-door

 (door-count ?max)
 ?pf <- (print-from ?num)
 (door ?num ?state)
 =>
 (retract ?pf)
 (if
   (= 0 (str-compare "open" ?state))
   then
   (printout t ?num " ")
 )
 (if
   (< ?num ?max)
   then
   (assert (print-from (+ ?num 1)))
   else
   (printout t crlf "All other doors are closed." crlf)
 )

)</lang>

Optimized

<lang clips>(deffacts initial-state

 (door-count 100)

)

(deffunction is-square

 (?num)
 (= (sqrt ?num) (integer (sqrt ?num)))

)

(defrule check-doors

 (door-count ?count)
 =>
 (printout t "These doors are open:" crlf)
 (loop-for-count (?num 1 ?count) do
   (if (is-square ?num) then
     (printout t ?num " ")
   )
 )
 (printout t crlf "All other doors are closed." crlf)

)</lang>

Clojure

Unoptimized / mutable array <lang clojure>(defn doors []

 (let [doors (into-array (repeat 100 false))]
   (doseq [pass   (range 1 101) 
           i      (range (dec pass) 100 pass) 
           :while (< i 100)]
     (aset doors i (not (aget doors i))))
   doors))   

(defn open-doors [] (for [[d n] (map vector (doors) (iterate inc 1)) :when d] n))

(defn print-open-doors []

 (println 
   "Open doors after 100 passes:"
   (apply str (interpose ", " (open-doors)))))</lang>

Unoptimized / functional <lang clojure>(defn doors []

 (reduce (fn [doors toggle-idx] (update-in doors [toggle-idx] not))
         (into [] (repeat 100 false))
         (for [pass   (range 1 101)
               i      (range (dec pass) 100 pass)
               :while (< i 100)]
           i)))

(defn open-doors [] (for [[d n] (map vector (doors) (iterate inc 1)) :when d] n))

(defn print-open-doors []

 (println 
   "Open doors after 100 passes:"
   (apply str (interpose ", " (open-doors)))))</lang>

Optimized / functional <lang clojure>(defn doors [] (reduce (fn [doors idx] (assoc doors idx true)) (into [] (repeat 100 false)) (map #(dec (* % %)) (range 1 11))))

(defn open-doors [] (for [[d n] (map vector (doors) (iterate inc 1)) :when d] n))

(defn print-open-doors []

 (println 
   "Open doors after 100 passes:"
   (apply str (interpose ", " (open-doors)))))</lang>

COBOL

<lang cobol> IDENTIFICATION DIVISION.

      PROGRAM-ID. 100Doors.
      DATA DIVISION.
      WORKING-STORAGE SECTION.
      01 Current        PIC 9(3)   VALUE ZEROES.
      01 StepSize       PIC 9(3)   VALUE ZEROES.
      01 DoorTable.
         02 Doors       PIC 9(1)   OCCURS 100 TIMES.
      01 Idx            PIC 9(3).
      PROCEDURE DIVISION.
      Begin.
          MOVE 1 TO StepSize
          PERFORM 100 TIMES
            MOVE StepSize TO Current
            PERFORM UNTIL Current > 100
              SUBTRACT Doors(Current) FROM 1 GIVING Doors(Current)
              ADD StepSize TO Current GIVING Current
            END-PERFORM
            ADD 1 TO StepSize GIVING StepSize
          END-PERFORM
          PERFORM VARYING Idx FROM 1 BY 1
                  UNTIL Idx > 100
            IF Doors(Idx) = 0
              DISPLAY Idx " is closed."
            ELSE
              DISPLAY Idx " is open."
            END-IF
          END-PERFORM
          STOP RUN.</lang>

CoffeeScript

unoptimized: <lang coffeescript>doors = []

for pass in [1..100]

 for i in [pass..100] by pass
   doors[i] = !doors[i]

console.log "Doors #{index for index, open of doors when open} are open"

  1. matrix output

console.log doors.map (open) -> +open </lang>

optimized:

<lang coffeescript>isInteger = (i) -> Math.floor(i) == i

console.log door for door in [1..100] when isInteger Math.sqrt door</lang>

ultra-optimized: <lang coffeescript>console.log Math.pow(i,2) for i in [1..10]</lang>

ColdFusion

Basic Solution: Returns List of 100 values: 1=open 0=closed <lang coldfusion> doorCount = 1; doorList = ""; // create all doors and set all doors to open while (doorCount LTE 100) { doorList = ListAppend(doorList,"1"); doorCount = doorCount + 1; } loopCount = 2; doorListLen = ListLen(doorList); while (loopCount LTE 100) { loopDoorListCount = 1; while (loopDoorListCount LTE 100) { testDoor = loopDoorListCount / loopCount; if (testDoor EQ Int(testDoor)) { checkOpen = ListGetAt(doorList,loopDoorListCount); if (checkOpen EQ 1) { doorList = ListSetAt(doorList,loopDoorListCount,"0"); } else { doorList = ListSetAt(doorList,loopDoorListCount,"1"); } } loopDoorListCount = loopDoorListCount + 1; } loopCount = loopCount + 1; } </lang>

Squares of Integers Solution: Returns List of 100 values: 1=open 0=closed <lang coldfusion> doorCount = 1; doorList = ""; loopCount = 1; while (loopCount LTE 100) { if (Sqr(loopCount) NEQ Int(Sqr(loopCount))) { doorList = ListAppend(doorList,0); } else { doorList = ListAppend(doorList,1); } loopCount = loopCount + 1; } </lang>

Display only <lang coldfusion>

   // Display all doors
   <cfloop from="1" to="100" index="x">
   	Door #x# Open: #YesNoFormat(ListGetAt(doorList,x))#
</cfloop>
   // Output only open doors
   <cfloop from="1" to="100" index="x">
   	<cfif ListGetAt(doorList,x) EQ 1>
       	#x#
</cfif> </cfloop>

</lang>

Common Lisp

Unoptimized / functional This is a very unoptimized version of the problem, using recursion and quite considerable list-copying. It emphasizes the functional way of solving this problem

<lang lisp>(defun visit-door (doors doornum value1 value2)

   "visits a door, swapping the value1 to value2 or vice-versa"
   (let ((d (copy-list doors))
         (n (- doornum 1)))
            (if (eq   (nth n d) value1)
                (setf (nth n d) value2)
                (setf (nth n d) value1))
            d))

(defun visit-every (doors num iter value1 value2)

   "visits every 'num' door in the list"
   (if (> (* iter num) (length doors))
       doors
       (visit-every (visit-door doors (* num iter) value1 value2)
                    num
                    (+ 1 iter)
                    value1
                    value2)))

(defun do-all-visits (doors cnt value1 value2)

   "Visits all doors changing the values accordingly"
   (if (< cnt 1)
       doors
       (do-all-visits (visit-every doors cnt 1 value1 value2)
                      (- cnt 1)
                      value1
                      value2)))

(defun print-doors (doors)

   "Pretty prints the doors list"
   (format T "~{~A ~A ~A ~A ~A ~A ~A ~A ~A ~A~%~}~%" doors))

(defun start (&optional (size 100))

   "Start the program"
   (let* ((open "_")
          (shut "#")
          (doors (make-list size :initial-element shut)))
              (print-doors (do-all-visits doors size open shut))))</lang>

Unoptimized / imperative This is a version that closely follows the problem description and is still quite short.

<lang lisp>(define-modify-macro toggle () not)

(defun 100-doors ()

 (let ((doors (make-array 100 :initial-element nil)))
   (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)))))</lang>

Optimized This is an optimized version of the above, using the perfect square algorithm (Note: This is non-functional as the state of the doors variable gets modified by a function call)

<lang lisp>(defun perfect-square-list (n)

   "Generates a list of perfect squares from 0 up to n"
   (loop for i from 1 to (sqrt n) collect (expt i 2))) 
                

(defun open-door (doors num open)

   "Sets door at num to open"
   (setf (nth (- num 1) doors) open)
   doors) 
                                 

(defun visit-all (doors vlist open)

   "Visits and opens all the doors indicated in vlist"
   (if (null vlist) 
       doors                     
       (visit-all (open-door doors (car vlist) open) 
                  (cdr vlist) 
                  open))) 
                  

(defun start2 (&optional (size 100))

   "Start the program"
   (print-doors (visit-all (make-list size :initial-element "#")
                           (perfect-square-list size) "_")))</lang>

Optimized (2) This version displays a much more functional solution through the use of MAPCAR (note however that this is imperative as it does variable mutation)

<lang lisp>(let ((i 0))

   (mapcar (lambda (x)
               (if (zerop (mod (sqrt (incf i)) 1))
                   "_" "#"))
           (make-list 100)))</lang>

D

<lang d>import std.stdio;

enum DoorState { Closed, Open } alias DoorState[] Doors;

Doors flipUnoptimized(Doors doors) {

   doors[] = DoorState.Closed;
   foreach (i; 0 .. doors.length)
       for (int j = i; j < doors.length; j += i+1)
           if (doors[j] == DoorState.Open)
               doors[j] = DoorState.Closed;
           else
               doors[j] = DoorState.Open;
   return doors;

}

Doors flipOptimized(Doors doors) {

   doors[] = DoorState.Closed;
   for (int i = 1; i*i <= doors.length; i++)
       doors[i*i - 1] = DoorState.Open;
   return doors;

}

// test program void main() {

   auto doors = new Doors(100);
   foreach (i, door; flipUnoptimized(doors))
       if (door == DoorState.Open)
           write(i+1, " ");
   writeln();
   foreach (i, door; flipOptimized(doors))
       if (door == DoorState.Open)
           write(i+1, " ");
   writeln();

}</lang>

Output:
1 4 9 16 25 36 49 64 81 100 
1 4 9 16 25 36 49 64 81 100 

Dart

unoptimized <lang dart>main() {

   for (var k = 1, x = new List(101); k <= 100; k++) {
       for (int i = k; i <= 100; i += k)
           x[i] = !x[i];
       if (x[k]) print("$k open");
   }

}</lang>

optimized version (including generating squares without multiplication) <lang dart>main() {

 for(int i=1,s=3;i<=100;i+=s,s+=2)
   print("door $i is open");

}</lang>

Delphi

See Pascal

DWScript

Unoptimized <lang delphi>var doors : array [1..100] of Boolean; var i, j : Integer;

for i := 1 to 100 do

  for j := i to 100 do
     if (j mod i) = 0 then
        doors[j] := not doors[j];

for i := 1 to 100 do

  if doors[i] then
     PrintLn('Door '+IntToStr(i)+' is open');</lang>

Dylan

Unoptimized <lang dylan>define method doors()

 let doors = make(<array>, fill: #f, size: 100);
 for (x from 0 below 100)
   for (y from x below 100 by x + 1)
     doors[y] := ~doors[y]
   end
 end;
 for (x from 1 to 100) 
   if (doors[x - 1]) 
     format-out("door %d open\n", x)
   end
 end

end</lang>

E

Graphical

Works with: E-on-Java

This version animates the changes of the doors (as checkboxes).

<lang e>#!/usr/bin/env rune

var toggles := [] var gets := []

  1. Set up GUI (and data model)

def frame := <swing:makeJFrame>("100 doors") frame.getContentPane().setLayout(<awt:makeGridLayout>(10, 10)) for i in 1..100 {

 def component := <import:javax.swing.makeJCheckBox>(E.toString(i))
 toggles with= fn { component.setSelected(!component.isSelected()) }
 gets with= fn { component.isSelected() }
 frame.getContentPane().add(component)

}

  1. Set up termination condition

def done frame.addWindowListener(def _ {

 to windowClosing(event) {
   bind done := true
 }
 match _ {}

})

  1. Open and close doors

def loop(step, i) {

 toggles[i] <- ()
 def next := i + step
 timer.whenPast(timer.now() + 10, fn {
   if (next >= 100) {
     if (step >= 100) {
       # Done.
     } else {
       loop <- (step + 1, step)
     }
   } else {
     loop <- (step, i + step)
   }    
 })

} loop(1, 0)

frame.pack() frame.show() interp.waitAtTop(done)</lang>


Eiffel

This is my first RosettaCode submission, as well as a foray into Eiffel for myself. I've tried to adhere to the description of the problem statement, as well as showcase a few Eiffelisms shown in the documentation.

file: application.e <lang eiffel>note description: "100 Doors problem" date: "07-AUG-2011" revision: "1.0"

class APPLICATION

create make

feature {NONE} -- Initialization

doors: LINKED_LIST [DOOR] -- A set of doors once Result := create {LINKED_LIST [DOOR]}.make end

make -- Run application. local count, i: INTEGER do --initialize doors count := 100 from i := 1 until i > count loop doors.extend (create {DOOR}.make (i, false)) i := i + 1 end

-- toggle doors from i := 1 until i > count loop across doors as this loop if this.item.address \\ i = 0 then this.item.open := not this.item.open end end -- across doors i := i + 1 end -- for i

-- print results doors.do_all (agent (door: DOOR) do if door.open then io.put_string ("Door " + door.address.out + " is open.") elseif not door.open then io.put_string ("Door " + door.address.out + " is closed.") end io.put_new_line end) end -- make

end -- APPLICATION</lang>

file: door.e <lang eiffel>note description: "A door with an address and an open or closed state." date: "07-AUG-2011" revision: "1.0"

class DOOR -- Represents a door

create make

feature -- initialization

make (addr: INTEGER; status: BOOLEAN) -- create door with address and status require valid_address: addr /= '%U' valid_status: status /= '%U' do address := addr open := status ensure address_set: address = addr status_set: open = status end

feature -- access

address: INTEGER

open: BOOLEAN assign set_open

feature -- mutators

set_open (status: BOOLEAN) require valid_status: status /= '%U' do open := status ensure open_updated: open = status end

end</lang>


Ela

Standard Approach

<lang ela>let gate (x::xs) (y::ys) | x == y = Open :: gate xs ys

   gate (x::xs) ys               = Closed :: gate xs ys
   gate []      _                = []

let run n = gate [1..n] [& k*k \\ k <- [1..]]</lang>

Alternate Approach <lang ela>open Core let run n = takeWhile (<n) [& k*k \\ k <- [1..]]</lang>


Emacs Lisp

Unoptimized

<lang lisp>(defun create-doors ()

 "Returns a list of closed doors

Each door only has two status: open or closed. If a door is closed it has the value 0, if it's open it has the value 1."

 (let ((return_value '(0))
        ;; There is already a door in the return_value, so k starts at 1
        ;; otherwise we would need to compare k against 99 and not 100 in
        ;; the while loop
        (k 1))
   (while (< k 100)
     (setq return_value (cons 0 return_value))
     (setq k (+ 1 k)))
   return_value))

(defun toggle-single-door (doors)

 "Toggle the stat of the door at the `car' position of the DOORS list

DOORS is a list of integers with either the value 0 or 1 and it represents a row of doors.

Returns a list where the `car' of the list has it's value toggled (if open it becomes closed, if closed it becomes open)."

 (if (= (car doors) 1)
   (cons 0 (cdr doors))
   (cons 1 (cdr doors))))

(defun toggle-doors (doors step original-step)

 "Step through all elements of the doors' list and toggle a door when step is 1

DOORS is a list of integers with either the value 0 or 1 and it represents a row of doors. STEP is the number of doors we still need to transverse before we arrive at a door that has to be toggled. ORIGINAL-STEP is the value of the argument step when this function is called for the first time.

Returns a list of doors"

 (cond ((null doors)
         '())
   ((= step 1)
     (cons (car (toggle-single-door doors))
       (toggle-doors (cdr doors) original-step original-step)))
   (t
     (cons (car doors)
       (toggle-doors (cdr doors) (- step 1) original-step)))))

(defun main-program ()

 "The main loop for the program"
 (let ((doors_list (create-doors))
        (k 1)
        ;; We need to define max-specpdl-size and max-specpdl-size to big
        ;; numbers otherwise the loop reaches the max recursion depth and
        ;; throws an error.
        ;; If you want more information about these variables, press Ctrl
        ;; and h at the same time and then press v and then type the name
        ;; of the variable that you want to read the documentation.
        (max-specpdl-size 5000)
        (max-lisp-eval-depth 2000))
   (while (< k 101)
     (setq doors_list (toggle-doors doors_list k k))
     (setq k (+ 1 k)))
   doors_list))

(defun print-doors (doors)

 "This function prints the values of the doors into the current buffer.

DOORS is a list of integers with either the value 0 or 1 and it represents a row of doors. "

 ;; As in the main-program function, we need to set the variable
 ;; max-lisp-eval-depth to a big number so it doesn't reach max recursion
 ;; depth.
 (let ((max-lisp-eval-depth 5000))
   (unless (null doors)
     (insert (int-to-string (car doors)))
     (print-doors (cdr doors)))))
Returns a list with the final solution

(main-program)

Print the final solution on the buffer

(print-doors (main-program))</lang>

Erlang

optimized <lang erlang>doors() ->

    F = fun(X) -> Root = math:pow(X,0.5), Root == trunc(Root) end,
    Out = fun(X, true) -> io:format("Door ~p: open~n",[X]);
             (X, false)-> io:format("Door ~p: close~n",[X]) end,
    [Out(X,F(X)) || X <- lists:seq(1,100)].</lang>

Euphoria

unoptimised <lang Euphoria>-- doors.ex include std/console.e sequence doors doors = repeat( 0, 100 ) -- 1 to 100, initialised to false

for pass = 1 to 100 do for door = pass to 100 by pass do --printf( 1, "%d", doors[door] ) --printf( 1, "%d", not doors[door] ) doors[door] = not doors[door] end for end for

sequence oc

for i = 1 to 100 do if doors[i] then oc = "open" else oc = "closed" end if

	printf( 1, "door %d is %s\n", { i, oc } )

end for </lang>

Euler Math Toolbox

<lang Euler Math Toolbox> function Doors $ doors:=zeros(1,100); $ for i=1 to 100 step 1 $ for j=i to 100 step i $ if doors[j]==0 then doors[j]:=1; $ else doors[j]:=0; $ endif; $ end; $ end; $ return doors $endfunction

A:=Doors; for i=1 to 100 step 1; if A[i]==1 then "door "|i|" is open" endif; end; </lang> Output <lang>

door 1 is open
door 4 is open
door 9 is open
door 16 is open
door 25 is open
door 36 is open
door 49 is open
door 64 is open
door 81 is open
door 100 is open

</lang>

Factor

<lang Factor>USING: bit-arrays formatting fry kernel math math.ranges sequences ; IN: rosetta.doors

CONSTANT: number-of-doors 100

multiples ( n -- range )
   0 number-of-doors rot <range> ;
toggle-multiples ( n doors -- )
   [ multiples ] dip '[ _ [ not ] change-nth ] each ;
toggle-all-multiples ( doors -- )
   [ number-of-doors [1,b] ] dip '[ _ toggle-multiples ] each ;
print-doors ( doors -- )
   [
       swap "open" "closed" ? "Door %d is %s\n" printf
   ] each-index ;
main ( -- )
   number-of-doors 1 + <bit-array>
   [ toggle-all-multiples ] [ print-doors ] bi ;</lang>

Falcon

Unoptimized code <lang falcon>doors = arrayBuffer( 101, false )

for pass in [ 0 : doors.len() ]

 for door in [ 0 : doors.len() : pass+1 ]
   doors[ door ] = not doors[ door ]
 end

end

for door in [ 1 : doors.len() ] // Show Output

 >  "Door ", $door, " is: ", ( doors[ door ] ) ? "open" : "closed"

end </lang> Optimized code <lang falcon> for door in [ 1 : 101 ]: > "Door ", $door, " is: ", fract( door ** 0.5 ) ? "closed" : "open"</lang>

Fantom

Unoptimized <lang fantom>

   states := (1..100).toList
   100.times |i| {
     states = states.map |state| { state % (i+1) == 0 ? -state : +state }
   }
   echo("Open doors are " + states.findAll { it < 0 }.map { -it })

</lang> Optimized <lang fantom>

   echo("Open doors are " + (1..100).toList.findAll { it.toFloat.pow(0.5f).toInt.pow(2) == it})

</lang>

Forth

Unoptimized <lang forth>: toggle ( c-addr -- ) \ toggle the byte at c-addr

   dup c@ 1 xor swap c! ;

100 1+ ( 1-based indexing ) constant ndoors create doors ndoors allot

init ( -- ) doors ndoors erase ; \ close all doors
pass ( n -- ) \ toggle every nth door
   ndoors over do
       doors i + toggle
   dup ( n ) +loop drop ;
run ( -- ) ndoors 1 do i pass loop ;
display ( -- ) \ display open doors
   ndoors 1 do  doors i + c@ if  i .  then loop cr ;

init run display</lang>

Optimized <lang forth>: squared ( n -- n' ) dup * ;

doors ( n -- )
   1 begin 2dup squared >= while
       dup squared .
   1+ repeat 2drop ;

100 doors</lang>

Fortran

Works with: Fortran version ISO 90 and later

unoptimized <lang fortran>PROGRAM DOORS

 INTEGER, PARAMETER :: n = 100    ! Number of doors
 INTEGER :: i, j
 LOGICAL :: door(n) = .TRUE.      ! Initially closed

 DO i = 1, n
   DO j = i, n, i
     door(j) = .NOT. door(j)
   END DO
 END DO 
 DO i = 1, n
   WRITE(*,"(A,I3,A)", ADVANCE="NO") "Door ", i, " is "
   IF (door(i)) THEN
     WRITE(*,"(A)") "closed"
   ELSE
     WRITE(*,"(A)") "open"
   END IF
 END DO

END PROGRAM DOORS</lang>

optimized <lang fortran>PROGRAM DOORS

 INTEGER, PARAMETER :: n = 100    ! Number of doors
 INTEGER :: i
 LOGICAL :: door(n) = .TRUE.      ! Initially closed

 DO i = 1, SQRT(REAL(n))
   door(i*i) = .FALSE.
 END DO  

 DO i = 1, n
   WRITE(*,"(A,I3,A)", ADVANCE="NO") "Door ", i, " is "
   IF (door(i)) THEN
     WRITE(*,"(A)") "closed"
   ELSE
     WRITE(*,"(A)") "open"
   END IF
 END DO

END PROGRAM DOORS</lang>

F#

Requires #light in versions of F# prior to 2010 beta. <lang fsharp>let answerDoors =

   let ToggleNth n (lst:bool array) =                  // Toggle every n'th door
       [(n-1) .. n .. 99]                              // For each appropriate door
       |> Seq.iter (fun i -> lst.[i] <- not lst.[i])   // toggle it
   let doors = Array.create 100 false                  // Initialize all doors to closed
   Seq.iter (fun n -> ToggleNth n doors) [1..100]      // toggle the appropriate doors for each pass
   doors                                               // Initialize all doors to closed

</lang> Following is the solution using perfect squares. The coercions in PerfectSquare are, I believe, slightly different in versions prior to 2010 beta and, again, #light is required in those versions. <lang fsharp>open System let answer2 =

   let PerfectSquare n =
       let sqrt = int(Math.Sqrt(float n))
       n = sqrt * sqrt
   [| for i in 1..100 do yield PerfectSquare i |]</lang>

GAP

<lang gap>doors := function(n)

 local a,j,s;
 a := [ ];
 for j in [1 .. n] do
   a[j] := 0;
 od;
 for s in [1 .. n] do
   j := s;
   while j <= n do
     a[j] := 1 - a[j];
     j := j + s;
   od;
 od;
 return Filtered([1 .. n], j -> a[j] = 1);

end;

doors(100);

  1. [ 1, 4, 9, 16, 25, 36, 49, 64, 81, 100 ]</lang>

GML

<lang gml>var doors,a,i; //Sets up the array for all of the doors. for (i=1;i<=100;i+=1)

   {
       doors[i]=0;
   }

//This first for loop goes through and passes the interval down to the next for loop. for (i=1;i<=100;i+=1)

   {
       //This for loop opens or closes the doors and uses the interval(if interval is 2 it only uses every other etc..)
       for (a=0;a<=100;a+=i;)
           {
               //Opens or closes a door.
               doors[a]=!doors[a];
           }
   }

open_doors=; //This for loop goes through the array and checks for open doors. //If the door is open it adds it to the string then displays the string. for (i=1;i<=100;i+=1)

   {
       if doors[i]=1
           {
               open_doors+="Door Number "+string(i)+" is open#";
           }
   }

show_message(open_doors); game_end();</lang>

Go

unoptimized <lang go>package main

import "fmt"

func main() {

   doors := make([]bool, 100)
   // the 100 passes called for in the task description
   for pass := 1; pass <= 100; pass++ {
       for door := pass-1; door < 100; door += pass {
           doors[door] = !doors[door]
       }
   }
   // one more pass to answer the question
   for i, v := range doors {
       if v {
           fmt.Print("1")
       } else {
           fmt.Print("0")
       }
       if i%10 == 9 {
           fmt.Print("\n")
       } else {
           fmt.Print(" ")
       }
   }

}</lang> Output:

1 0 0 1 0 0 0 0 1 0
0 0 0 0 0 1 0 0 0 0
0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 1

optimized <lang go>package main

import "fmt"

func main() {

   var door int = 1
   var incrementer = 0
   for current := 1; current <= 100; current++ {
       fmt.Printf("Door %d ", current)
       if current == door {
           fmt.Printf("Open\n")
           incrementer++
           door += 2*incrementer + 1
       } else {
           fmt.Printf("Closed\n")
       }
   }

}</lang>

Golfscript

<lang golfscript>100:c;[{0}c*]:d; c,{.c,>\)%{.d<\.d=1^\)d>++:d;}/}/ [c,{)"door "\+" is"+}%d{{"open"}{"closed"}if}%]zip {" "*puts}/</lang>

optimized with sqrt (Original version of GolfScript has no sqrt operator, but it can be added easily; the code was tested using a work-in-progress C interpreter for a language compatible enough with Golfscript) <lang golfscript>100,{)}% {:d.sqrt 2?= {"open"}{"close"}if"door "d+" is "+\+puts}/</lang>

optimized without sqrt <lang golfscript>[{"close"}100*]:d; 10,{)2?(.d<\["open"]\)d>++:d;}/ [100,{)"door "\+" is"+}%d]zip {" "*puts}/</lang>

Groovy

unoptimized <lang groovy>doors = [false] * 100 (0..99).each {

  it.step(100, it + 1) {
     doors[it] ^= true
  }

} (0..99).each {

  println("Door #${it + 1} is ${doors[it] ? 'open' : 'closed'}.")

}</lang>

optimized a Using square roots

<lang groovy>(1..100).each {

  println("Door #${it} is ${Math.sqrt(it).with{it==(int)it} ? 'open' : 'closed'}.")

}</lang>

optimized b Without using square roots <lang groovy>doors = ['closed'] * 100 (1..10).each { doors[it**2 - 1] = 'open' } (0..99).each {

  println("Door #${it + 1} is ${doors[it]}.")

}</lang>

Haskell

unoptimized <lang haskell>data Door = Open | Closed deriving Show

toggle Open = Closed toggle Closed = Open

toggleEvery :: [Door] -> Int -> [Door] toggleEvery xs k = zipWith ($) fs xs

   where fs = cycle $ (replicate (k-1) id) ++ [toggle]

run n = foldl toggleEvery (replicate n Closed) [0..n]</lang>

optimized (without using square roots) <lang haskell>gate :: Eq a => [a] -> [a] -> [Door] gate (x:xs) (y:ys) | x == y = Open  : gate xs ys gate (x:xs) ys = Closed : gate xs ys gate [] _ = []

run n = gate [1..n] [k*k | k <- [1..]]</lang>

alternatively, returning a list of all open gates, it's a one-liner:

<lang haskell>run n = takeWhile (< n) [k*k | k <- [1..]]</lang>

haXe

<lang haxe>class RosettaDemo {

   static public function main()
   {
       findOpenLockers(100);
   }
   static function findOpenLockers(n : Int)
   {
       var i = 1;
       while((i*i) <= n)
       {
           neko.Lib.print(i*i + "\n");
           i++;
       }
   }

}</lang>

HicEst

Unoptimized <lang hicest>REAL :: n=100, open=1, door(n)

door = 1 - open ! = closed DO i = 1, n

 DO j = i, n, i
   door(j) = open - door(j)
 ENDDO

ENDDO DLG(Text=door, TItle=SUM(door)//" doors open") </lang> Optimized <lang hicest>door = 1 - open ! = closed DO i = 1, n^0.5

 door(i*i) = open

ENDDO DLG(Text=door, TItle=SUM(door)//" doors open") </lang>

Icon and Unicon

Icon and Unicon don't have a boolean type because most often, logic is expressed in terms of success or failure, which affects flow at run time.

Unoptimized solution. <lang icon> procedure main()

   door := table(0)    # default value of entries is 0
   every pass := 1 to 100 do
       every door[i := pass to 100 by pass] := 1 - door[i]
   every write("Door ", i := 1 to 100, " is ", if door[i] = 1 then "open" else "closed")

end </lang>

Optimized solution. <lang icon> procedure main()

   every write("Door ", i := 1 to 100, " is ", if integer(sqrt(i)) = sqrt(i) then "open" else "closed")

end </lang>

or

<lang icon>procedure main(args)

   dMap := table("closed")
   every dMap[(1 to sqrt(100))^2] := "open"
   every write("Door ",i := 1 to 100," is ",dMap[i])

end</lang>

Inform 7

Works with: Z-machine version 8

<lang inform7>Hallway is a room.

A toggle door is a kind of thing. A toggle door can be open or closed. It is usually closed. A toggle door has a number called the door number. Understand the door number property as referring to a toggle door. Rule for printing the name of a toggle door: say "door #[door number]".

There are 100 toggle doors.

When play begins (this is the initialize doors rule): let the next door number be 1; repeat with D running through toggle doors: now the door number of D is the next door number; increment the next door number.

To toggle (D - open toggle door): now D is closed. To toggle (D - closed toggle door): now D is open.

When play begins (this is the solve puzzle rule): let the door list be the list of toggle doors; let the door count be the number of entries in the door list; repeat with iteration running from 1 to 100: let N be the iteration; while N is less than the door count: toggle entry N in the door list; increase N by the iteration; say "Doors left open: [list of open toggle doors]."; end the story.</lang>

Informix 4GL

<lang Informix 4GL> MAIN

   DEFINE
       i, pass SMALLINT,
       doors ARRAY[100] OF SMALLINT

   FOR i = 1 TO 100
       LET doors[i] = FALSE
   END FOR

   FOR pass = 1 TO 100
       FOR i = pass TO 100 STEP pass
           LET doors[i] = NOT doors[i]
       END FOR
   END FOR

   FOR i = 1 TO 100
       IF doors[i]
         THEN DISPLAY i USING "Door <<& is open"
         ELSE DISPLAY i USING "Door <<& is closed"
       END IF
   END FOR

END MAIN </lang>

Io

simple boolean list solution: <lang io> doors := List clone for(i,1,100, doors append(false)) for(i,1,100,

   for(x,i,100, i, doors atPut(x - 1, doors at(x - 1) not))

) doors foreach(i, x, if(x, "Door #{i + 1} is open" interpolate println)) </lang>

Ioke

Unoptimized Object Oriented solution. <lang ioke>NDoors = Origin mimic

NDoors Toggle = Origin mimic do(

 initialize = method(toggled?, @toggled? = toggled?)
 toggle! = method(@toggled? = !toggled?. self)

)

NDoors Doors = Origin mimic do(

 initialize = method(n,
   @n = n
   @doors = {} addKeysAndValues(1..n, (1..n) map(_, NDoors Toggle mimic(false)))
 )
 numsToToggle = method(n, for(x <- (1..@n), (x % n) zero?, x))
 toggleThese = method(nums, nums each(x, @doors[x] = @doors at(x) toggle))
 show = method(@doors filter:dict(value toggled?) keys sort println)

)

Test code

x = NDoors Doors mimic(100) (1..100) each(n, x toggleThese(x numsToToggle(n))) x show</lang>

J

unoptimized <lang j> ~:/ (100 $ - {. 1:)"0 >:i.100 1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 ...

  ~:/ 0=|/~ >:i.100  NB. alternative

1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 ...</lang> optimized <lang j> (e. *:) 1+i.100 1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 ...

  1 (<:*:i.10)} 100$0  NB. alternative

1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 ...</lang>

with formatting <lang j> 'these doors are open' ; >: I. (>:i.100) e. *: i.11 ┌────────────────────┬───────────────────────────┐ │these doors are open│1 4 9 16 25 36 49 64 81 100│ └────────────────────┴───────────────────────────┘

</lang>

Java

unoptimized <lang java> public class HundredDoors {

   public static void main(String[] args) {
       boolean[] doors = new boolean[101];
       for (int i = 1; i <= 100; i++) {
           for (int j = i; j <= 100; j++) {
               if(j % i == 0) doors[j] = !doors[j];
           }
       }
       for (int i = 1; i <= 100; i++) {
           System.out.printf("Door %d: %s%n", i, doors[i] ? "open" : "closed");
       }
   }

}</lang>

optimized <lang java>public class Doors {

public static void main(final String[] args)
{
 boolean[] doors = new boolean[100];
 for (int pass = 0; pass < 10; pass++)
  doors[(pass + 1) * (pass + 1) - 1] = true;
 for(int i = 0; i < 100; i++)
  System.out.println("Door #" + (i + 1) + " is " + (doors[i] ? "open." : "closed."));
}

}</lang> optimized 2 <lang java>public class Doors {

public static void main(final String[] args)
{
 StringBuilder sb = new StringBuilder();
 for (int i = 1; i <= 10; i++)
  sb.append("Door #").append(i*i).append(" is open\n");
 System.out.println(sb.toString());
}

}</lang>

optimized 3 <lang java>public class Doors{

  public static void main(String[] args){
     int i;		
     for(i = 1; i < 101; i++){
        double sqrt = Math.sqrt(i);
        if(sqrt != (int)sqrt){
           System.out.println("Door " + i + " is closed");
        }else{
           System.out.println("Door " + i + " is open");
        }
     }
  } 	

}</lang>

JavaScript

<lang javascript>var doors = [], n = 100, i, j;

for (i = 1; i <= n; i++) { for (j = i; j <= n; j += i) { doors[j] = !doors[j]; } }

for (i = 1 ; i <= n ; i++) { if (doors[i]) console.log("Door " + i + " is open"); }</lang> outputs

door 1 is open.
door 4 is open.
door 9 is open.
door 16 is open.
door 25 is open.
door 36 is open.
door 49 is open.
door 64 is open.
door 81 is open.
door 100 is open.

Using features of JavaScript 1.6, this

Works with: Firefox version 1.5

<lang javascript>var

n = 100,
doors = [n],
step,
idx;

// now, start opening and closing for (step = 1; step <= n; step += 1)

for (idx = step; idx <= n; idx += step)
// toggle state of door
doors[idx] = !doors[idx];

// find out which doors are open var open = doors.reduce(function(open, val, idx) {

   if (val) {
       open.push(idx);
   }
   return open;

}, []); document.write("These doors are open: " + open.join(', '));</lang> outputs

these doors are open: 1, 4, 9, 16, 25, 36, 49, 64, 81, 100

K

unoptimized / converted from Q . <lang k> `closed `open ![ ; 2 ] @ #:' 1 _ = ,/ &:' 0 = t !\:/: t : ! 101</lang>

optimized / 1 origin indices <lang k> ( 1 + ! 10 ) ^ 2</lang>

/ As parameterized function : <lang k> { ( 1 + ! _ x ^ % 2 ) ^ 2 } 100 </lang>

LabVIEW

This image is a VI Snippet, an executable image of LabVIEW code. The LabVIEW version is shown on the top-right hand corner. You can download it, then drag-and-drop it onto the LabVIEW block diagram from a file browser, and it will appear as runnable, editable code.

Optimized

This image is a VI Snippet, an executable image of LabVIEW code. The LabVIEW version is shown on the top-right hand corner. You can download it, then drag-and-drop it onto the LabVIEW block diagram from a file browser, and it will appear as runnable, editable code.

Liberty BASIC

<lang lb>dim doors(100) for pass = 1 to 100

   for door = pass to 100 step pass
       doors(door) = not(doors(door))
   next door

next pass print "open doors "; for door = 1 to 100

   if doors(door) then print door;"  ";

next door</lang>

<lang Logo>to doors

Problem 100 Doors
FMSLogo
lrcvs 2010

make "door (vector 100 1) for [p 1 100][setitem :p :door 0]

for [a 1 100 1][for [b :a 100 :a][make "x item :b :door ifelse :x = 0 [setitem :b :door 1][setitem :b :door 0] ] ]

for [c 1 100][make "y item :c :door ifelse :y = 0 [pr (list :c "Close)] [pr (list :c "Open)] ] end</lang>

Lhogho

This implementation defines 100 variables, named "1 through "100, rather than using a list. Thanks to Pavel Boytchev, the author of Lhogho, for help with the code.

<lang Logo>to doors ;Problem 100 Doors ;Lhogho

for "p [1 100] [ make :p "false ]

for "a [1 100 1] [ for "b [:a 100 :a] [ if :b < 101 [ make :b not thing :b ] ] ]

for "c [1 100] [ if thing :c [ (print "door :c "is "open) ] ] end

doors</lang>

Lua

<lang lua>is_open = {}

for door = 1,100 do is_open[door] = false end

for pass = 1,100 do

   for door = pass,100,pass do
       is_open[door] = not is_open[door]
   end

end

for i,v in next,is_open do

   if v then
       print ('Door '..i..':','open')
   else
       print ('Door '..i..':', 'close')
   end

end</lang>

M4

<lang m4>define(`_set', `define(`$1[$2]', `$3')')dnl define(`_get', `defn(`$1[$2]')')dnl define(`for',`ifelse($#,0,``$0,`ifelse(eval($2<=$3),1, `pushdef(`$1',$2)$5`'popdef(`$1')$0(`$1',eval($2+$4),$3,$4,`$5')')')')dnl define(`opposite',`_set(`door',$1,ifelse(_get(`door',$1),`closed',`open',`closed'))')dnl define(`upper',`100')dnl for(`x',`1',upper,`1',`_set(`door',x,`closed')')dnl for(`x',`1',upper,`1',`for(`y',x,upper,x,`opposite(y)')')dnl for(`x',`1',upper,`1',`door x is _get(`door',x) ')dnl</lang>

Mathematica

unoptimized 1 <lang mathematica>n=100; tmp=ConstantArray[-1,n]; Do[tmpi;;;;i*=-1;,{i,n}]; Do[Print["door ",i," is ",If[tmpi==-1,"closed","open"]],{i,1,Length[tmp]}]</lang>

unoptimized 2 <lang mathematica>f[n_] = "Closed"; Do[Do[If[f[n] == "Closed", f[n] = "Open", f[n] = "Closed"], {n, k, 100, k}], {k, 1, 100}]; Table[f[n], {n, 1, 100}]</lang>

optimized 1 <lang mathematica>Do[Print["door ",i," is ",If[IntegerQ[Sqrt[i]],"open","closed"]],{i,100}]</lang>

optimized 2 <lang mathematica>n=100; a=Range[1,Sqrt[n]]^2 Do[Print["door ",i," is ",If[MemberQ[a,i],"open","closed"]],{i,100}]</lang>

optimized 3 <lang mathematica>n=100 nn=1 a=0 For[i=1,i<=n,i++,

If[i==nn,
 Print["door ",i," is open"];
 a++;
 nn+=2a+1;
,
 Print["door ",i," is closed"];
];

]</lang>

These will only give the indices for the open doors: unoptimized 2 <lang mathematica>Pick[Range[100], Xor@@@Array[Divisible[#1,#2]&, {100,100}]]</lang>

optimized 4 <lang mathematica>Range[Sqrt[100]]^2</lang>

MATLAB

Iterative Method

Unoptimized <lang MATLAB> a=zeros(1,100); for b=1:100; for i=b:b:100;

   if a(i)==1
       a(i)=0;
   else 
       a(i)=1;
   end

end end a </lang> Optimized <lang MATLAB> for x=1:100;

 if sqrt(x) == floor(sqrt(x))
   a(i)=1;
 end

end a </lang> More Optimized <lang MATLAB> a = zeros(100,1); for counter = 1:sqrt(100);

 a(counter^2) = 1;

end a </lang>

Vectorized Method

<lang MATLAB>function [doors,opened,closed] = hundredDoors()

   %Initialize the doors, make them booleans for easy vectorization
   doors = logical( (1:1:100) );
   
   %Go through the flipping process, ignore the 1 case because the doors
   %array is already initialized to all open
   for initialPosition = (2:100)
       doors(initialPosition:initialPosition:100) = not( doors(initialPosition:initialPosition:100) );
   end
   
   opened = find(doors); %Stores the numbers of the open doors
   closed = find( not(doors) ); %Stores the numbers of the closed doors
   

end</lang>

Known-Result Method

<lang MATLAB> doors((1:10).^2) = 1;

doors </lang>

MAXScript

unoptimized <lang maxscript>doorsOpen = for i in 1 to 100 collect false

for pass in 1 to 100 do (

   for door in pass to 100 by pass do
   (
       doorsOpen[door] = not doorsOpen[door]
   )

)

for i in 1 to doorsOpen.count do (

   format ("Door % is open?: %\n") i doorsOpen[i]

)</lang> optimized <lang maxscript>for i in 1 to 100 do (

   root = pow i 0.5
   format ("Door % is open?: %\n") i (root == (root as integer))

)</lang>

Mercury

<lang Mercury>:- module doors.

- interface.
- import_module array, io, int.
- type door ---> open ; closed.
- type doors == array(door).
- func toggle(door) = door.
- pred walk(int::in, doors::in, doors::out) is semidet.
- pred walks(int::in, int::in, doors::in, doors::out) is det.
- pred main(io::di, io::uo) is det.
- implementation.

toggle(open) = closed. toggle(closed) = open.

walk(N, !D) :- walk(N, N, !D).

- pred walk(int::in, int::in, doors::in, doors::out) is semidet.

walk(At, By, !D) :-

       semidet_lookup(!.D, At - 1, Door),
       slow_set(!.D, At - 1, toggle(Door), !:D),
       ( walk(At + By, By, !D) -> true ; true ).

walks(N, End, !D) :-

       ( N =< End, walk(N, !D) -> walks(N + 1, End, !D) ; true ).

main(!IO) :-

       io.write(Doors1, !IO), io.nl(!IO),
       array.init(100, closed, Doors0),
       walks(1, 100, Doors0, Doors1).</lang>

Metafont

<lang metafont>boolean doors[]; for i = 1 upto 100: doors[i] := false; endfor for i = 1 upto 100:

 for j = 1 step i until 100:
   doors[j] := not doors[j];
 endfor

endfor for i = 1 upto 100:

 message decimal(i) & " " & if doors[i]: "open" else: "close" fi;

endfor end</lang>

Mirah

<lang Mirah>import java.util.ArrayList

class Door :state

def initialize @state=false end

def closed?; !@state; end def open?; @state; end

def close; @state=false; end def open; @state=true; end

def toggle if closed? open else close end end

def toString; Boolean.toString(@state); end end

doors=ArrayList.new 1.upto(100) do

   doors.add(Door.new)

end

1.upto(100) do |multiplier|

   index = 0
   doors.each do |door|
       Door(door).toggle if (index+1)%multiplier == 0
       index += 1
   end

end

i = 0 doors.each do |door|

   puts "Door #{i+1} is #{door}."
   i+=1

end </lang>

MIPS Assembly

<lang mips>.data

 doors:     .space 100
 num_str:   .asciiz "Number "
 comma_gap: .asciiz " is "
 newline:   .asciiz "\n"

.text main:

  1. Clear all the cells to zero
 li $t1, 100
 la $t2, doors

clear_loop:

 sb $0, ($t2)
 add $t2, $t2, 1
 sub $t1, $t1, 1
 bnez $t1, clear_loop
  1. Now start the loops
 li $t0, 1         # This will the the step size
 li $t4, 1         # just an arbitrary 1

loop1:

 move $t1, $t0      # Counter
 la $t2, doors      # Current pointer
 add $t2, $t2, $t0
 addi $t2, $t2, -1

loop2:

 lb $t3, ($t2)
 sub $t3, $t4, $t3
 sb $t3, ($t2)
 add $t1, $t1, $t0
 add $t2, $t2, $t0
 ble $t1, 100, loop2
 addi $t0, $t0, 1
 ble $t0, 100, loop1
 # Now display everything
 la $t0, doors
 li $t1, 1

loop3:

 li $v0, 4
 la $a0, num_str
 syscall
 
 li $v0, 1
 move $a0, $t1
 syscall
 li $v0, 4
 la $a0, comma_gap
 syscall
 li $v0, 1
 lb $a0, ($t0)
 syscall
 li $v0, 4,
 la $a0, newline
 syscall
 addi $t0, $t0, 1
 addi $t1, $t1, 1
 bne $t1, 101 loop3

</lang>

ML/I

<lang ML/I>MCSKIP "WITH" NL "" 100 doors MCINS %. MCSKIP MT,<> "" Doors represented by P1-P100, 0 is closed MCPVAR 100 "" Set P variables to 0 MCDEF ZEROPS WITHS NL AS <MCSET T1=1 %L1.MCSET PT1=0 MCSET T1=T1+1 MCGO L1 UNLESS T1 EN 101 > ZEROPS "" Generate door state MCDEF STATE WITHS () AS <MCSET T1=%A1. MCGO L1 UNLESS T1 EN 0 closed<>MCGO L0 %L1.open> "" Main macro - no arguments "" T1 is pass number "" T2 is door number MCDEF DOORS WITHS NL AS <MCSET T1=1 "" pass loop %L1.MCGO L4 IF T1 GR 100 "" door loop MCSET T2=T1 %L2.MCGO L3 IF T2 GR 100 MCSET PT2=1-PT2 MCSET T2=T2+T1 MCGO L2 %L3.MCSET T1=T1+1 MCGO L1 %L4."" now output the result MCSET T1=1 %L5.door %T1. is STATE(%PT1.) MCSET T1=T1+1 MCGO L5 UNLESS T1 GR 100 > "" Do it DOORS</lang>

MMIX

See 100 doors/MMIX

Modula-2

unoptimized <lang modula2>MODULE Doors; IMPORT InOut;

TYPE State = (Closed, Open); TYPE List = ARRAY [1 .. 100] OF State;

VAR

 Doors: List;
 I, J:  CARDINAL;

BEGIN

 FOR I := 1 TO 100 DO
   FOR J := 1 TO 100 DO
     IF J MOD I = 0 THEN
       IF Doors[J] = Closed THEN
         Doors[J] := Open
       ELSE
         Doors[J] := Closed
       END
     END
   END
 END;
 FOR I := 1 TO 100 DO
   InOut.WriteCard(I, 3);
   InOut.WriteString(' is ');
   IF Doors[I] = Closed THEN
     InOut.WriteString('Closed.')
   ELSE
     InOut.WriteString('Open.')
   END;
   InOut.WriteLn
 END

END Doors.</lang>

optimized <lang modula2>MODULE DoorsOpt; IMPORT InOut;

TYPE State = (Closed, Open); TYPE List = ARRAY [1 .. 100] OF State;

VAR

 Doors: List;
 I:  CARDINAL;

BEGIN

 FOR I := 1 TO 10 DO
   Doors[I*I] := Open
 END;
 FOR I := 1 TO 100 DO
   InOut.WriteCard(I, 3);
   InOut.WriteString(' is ');
   IF Doors[I] = Closed THEN
     InOut.WriteString('Closed.')
   ELSE
     InOut.WriteString('Open.')
   END;
   InOut.WriteLn
 END

END DoorsOpt.</lang>

Modula-3

unoptimized <lang modula3>MODULE Doors EXPORTS Main;

IMPORT IO, Fmt;

TYPE State = {Closed, Open}; TYPE List = ARRAY [1..100] OF State;

VAR doors := List{State.Closed, ..};

BEGIN

 FOR i := 1 TO 100 DO
   FOR j := FIRST(doors) TO LAST(doors) DO
     IF j MOD i = 0 THEN
       IF doors[j] = State.Closed THEN
         doors[j] := State.Open;
       ELSE
         doors[j] := State.Closed;
       END;
     END;
   END;
 END;
 FOR i := FIRST(doors) TO LAST(doors) DO
   IO.Put(Fmt.Int(i) & " is ");
   IF doors[i] = State.Closed THEN
     IO.Put("Closed.\n");
   ELSE
     IO.Put("Open.\n");
   END;
 END;

END Doors.</lang>

optimized

<lang modula3>MODULE DoorsOpt EXPORTS Main;

IMPORT IO, Fmt;

TYPE State = {Closed, Open}; TYPE List = ARRAY [1..100] OF State;

VAR doors := List{State.Closed, ..};

BEGIN

 FOR i := 1 TO 10 DO
   doors[i * i] := State.Open;
 END;
 FOR i := FIRST(doors) TO LAST(doors) DO
   IO.Put(Fmt.Int(i) & " is ");
   IF doors[i] = State.Closed THEN
     IO.Put("Closed.\n");
   ELSE
     IO.Put("Open.\n");
   END;
 END;

END DoorsOpt.</lang>

MOO

<lang moo>is_open = make(100); for pass in [1..100]

 for door in [pass..100]
   if (door % pass)
     continue;
   endif
   is_open[door] = !is_open[door];
 endfor

endfor

"output the result"; for door in [1..100]

 player:tell("door #", door, " is ", (is_open[door] ? "open" : "closed"), ".");

endfor</lang>


MUMPS

<lang MUMPS>doors new door,pass For door=1:1:100 Set door(door)=0 For pass=1:1:100 For door=pass:pass:100 Set door(door)='door(door) For door=1:1:100 If door(door) Write !,"Door",$j(door,4)," is open" Write !,"All other doors are closed." Quit Do doors Door 1 is open Door 4 is open Door 9 is open Door 16 is open Door 25 is open Door 36 is open Door 49 is open Door 64 is open Door 81 is open Door 100 is open All other doors are closed.</lang>

NetRexx

unoptimized <lang netrexx>/* NetRexx */ options replace format comments java crossref savelog symbols binary

True = Rexx(1 == 1) False = Rexx(\True)

doors = False

loop i_ = 1 to 100

 loop j_ = 1 to 100
   if 0 = (j_ // i_) then doors[j_] = \doors[j_]
   end j_
 end i_

loop d_ = 1 to 100

 if doors[d_] then  state = 'open'
 else  state = 'closed'
 say 'Door Nr.' Rexx(d_).right(4) 'is' state
 end d_

</lang>

optimized (Based on the Java 'optimized' version)

Translation of: Java

<lang netrexx>/* NetRexx */ options replace format comments java crossref savelog symbols binary

True = (1 == 1) False = \True

doors = boolean[100]

loop i_ = 0 to 9

 doors[(i_ + 1) * (i_ + 1) - 1] = True;
 end i_

loop i_ = 0 to 99

 if doors[i_] then  state = 'open'
 else  state = 'closed'
 say 'Door Nr.' Rexx(i_ + 1).right(4) 'is' state
 end i_

</lang>

optimized 2 (Based on the Java 'optimized 2' version)

Translation of: Java

<lang netrexx>/* NetRexx */ options replace format comments java crossref savelog symbols binary

resultstring =

loop i_ = 1 to 10

 resultstring = resultstring || 'Door Nr.' Rexx(i_ * i_).right(4) 'is open\n'
 end i_

say resultstring </lang>

optimized 3 <lang netrexx>/* NetRexx */

loop i = 1 to 10

  say 'Door Nr.' i * i 'is open.'
 end i

</lang>

Objeck

optimized <lang objeck> bundle Default {

 class Doors {
   function : Main(args : String[]) ~ Nil {
     doors := Bool->New[100];
     
     for(pass := 0; pass < 10; pass += 1;) {
       doors[(pass + 1) * (pass + 1) - 1] := true;
     };
     
     for(i := 0; i < 100; i += 1;) {    
       IO.Console->GetInstance()->Print("Door #")->Print(i + 1)->Print(" is ");
       if(doors[i]) {
         "open."->PrintLine();
       }
       else {
         "closed."->PrintLine();
       };
     };
   }
 }

} </lang>

OCaml

unoptimized <lang ocaml>let max_doors = 100

let show_doors =

 Array.iteri (fun i x -> Printf.printf "Door %d is %s\n" (i+1)
                                       (if x then "open" else "closed"))

let flip_doors doors =

 for i = 1 to max_doors do
   let rec flip idx =
     if idx < max_doors then begin
       doors.(idx) <- not doors.(idx);
       flip (idx + i)
     end
   in flip (i - 1)
 done;
 doors

let () =

 show_doors (flip_doors (Array.make max_doors false))</lang>

optimized <lang ocaml>let optimised_flip_doors doors =

 for i = 1 to int_of_float (sqrt (float_of_int max_doors)) do
   doors.(i*i - 1) <- true
 done;
 doors

let () =

 show_doors (optimised_flip_doors (Array.make max_doors false))</lang>

Octave

<lang octave>doors = false(100,1); for i = 1:100

 for j = i:i:100
   doors(j) = !doors(j);
 endfor

endfor for i = 1:100

 if ( doors(i) )
   s = "open";
 else
   s = "closed";
 endif
 printf("%d %s\n", i, s);

endfor</lang>

OpenEdge/Progress

<lang Progress (OpenEdge ABL)>DEFINE VARIABLE lopen AS LOGICAL NO-UNDO EXTENT 100. DEFINE VARIABLE idoor AS INTEGER NO-UNDO. DEFINE VARIABLE ipass AS INTEGER NO-UNDO. DEFINE VARIABLE cresult AS CHARACTER NO-UNDO.

DO ipass = 1 TO 100:

  idoor = 0.
  DO WHILE idoor <= 100:
     idoor = idoor + ipass.
     IF idoor <= 100 THEN
        lopen[ idoor ] = NOT lopen[ idoor ].
  END.

END.

DO idoor = 1 TO 100:

  cresult = cresult + STRING( lopen[ idoor ], "1  /0  " ).
  IF idoor MODULO 10 = 0 THEN
     cresult = cresult + "~r":U.

END.

MESSAGE cresult VIEW-AS ALERT-BOX. </lang>

Oz

<lang oz>declare

 NumDoors = 100
 NumPasses = 100
 fun {NewDoor} closed end
 fun {Toggle Door}
    case Door of closed then open
    [] open then closed
    end
 end
 fun {Pass Doors I}
    {List.mapInd Doors
     fun {$ Index Door}
        if Index mod I == 0 then {Toggle Door}
        else Door
        end
     end}
 end
 
 Doors0 = {MakeList NumDoors}
 {ForAll Doors0 NewDoor}
 DoorsN = {FoldL {List.number 1 NumPasses 1} Pass Doors0}

in

 %% print open doors
 {List.forAllInd DoorsN
  proc {$ Index Door}
     if Door == open then

{System.showInfo "Door "#Index#" is open."}

     end
  end
 }</lang>

Output:

Door 1 is open.
Door 4 is open.
Door 9 is open.
Door 16 is open.
Door 25 is open.
Door 36 is open.
Door 49 is open.
Door 64 is open.
Door 81 is open.
Door 100 is open.

PARI/GP

Unoptimized version. <lang parigp> v=vector(d=100);/*set 100 closed doors*/ for(i=1,d,forstep(j=i,d,i,v[j]=1-v[j])); for(i=1,d,if(v[i],print("Door ",i," is open."))) </lang> Optimized version. <lang parigp>for(n=1,10,print("Door ",n^2," is open."))</lang>

Pascal

<lang pascal>Program OneHundredDoors;

var

  doors : Array[1..100] of Boolean;
  i, j	 : Integer;
  

begin

  for i := 1 to 100 do
     doors[i] := False;
  for i := 1 to 100 do begin
     j := i;
     while j <= 100 do begin

doors[j] := not doors[j]; j := j + i

     end
  end;
  for i := 1 to 100 do begin
     Write(i, ' ');
     if doors[i] then

WriteLn('open')

     else

WriteLn('closed');

  end

end.</lang>

Optimized version.

<lang pascal>program OneHundredDoors;

{$APPTYPE CONSOLE}

uses

 math, sysutils;

var

  AOpendoors  : String;
  ACloseDoors : String;
  i	       : Integer;

begin

  for i := 1 to 100 do
  begin
     if (sqrt(i) = floor(sqrt(i))) then
       AOpenDoors := AOpenDoors + IntToStr(i) + ';'
     else
       ACloseDoors := ACloseDoors + IntToStr(i) +';';
  end;
  WriteLn('Open doors: ' + AOpenDoors);
  WriteLn('Close doors: ' + ACloseDoors);

end. </lang>

PHP

optimized <lang php><?php for ($i = 1; $i <= 100; $i++) { $root = sqrt($i); $state = ($root == ceil($root)) ? 'open' : 'closed'; echo "Door {$i}: {$state}\n"; } ?></lang>

unoptimized <lang php><?php $toggleState = array('open' => 'closed', 'closed' => 'open'); $doors = array_fill(1, 100, 'closed'); for ($pass = 1; $pass <= 100; ++$pass) { for ($nr = 1; $nr <= 100; ++$nr) { if ($nr % $pass == 0) { $doors[$nr] = $toggleState[$doors[$nr]]; } } } for ($nr = 1; $nr <= 100; ++$nr) printf("Door %d is %s\n", $nr, $doors[$nr]); ?></lang>

Perl

unoptimized

Works with: Perl version 5.x

<lang perl>my @doors; for my $pass (1 .. 100) {

   for (1 .. 100) {
       if (0 == $_ % $pass) {
           $doors[$_] = not $doors[$_];
       };
   };

};

print "Door $_ is ", $doors[$_] ? "open" : "closed", "\n" for 1 .. 100;</lang>

optimized

Works with: Perl version 5.x

<lang perl>print "Door $_ is open\n" for map { $_**2 } 1 .. 10;</lang> <lang perl>print "Door $_ is ", qw"closed open"[int sqrt == sqrt], "\n" for 1..100;</lang> <lang perl>while( ++$i <= 100 ) {

   $root = sqrt($i);
   if ( int( $root ) == $root )
   {
       print "Door $i is open\n";
   }
   else
   {
       print "Door $i is closed\n";
   }

}</lang>

Perl 6

unoptimized

Works with: Rakudo version 2010.07"

<lang perl6>my @doors = False xx 101;

($_ = !$_ for @doors[0, * + $_ ...^ * > 100]) for 1..100;

say "Door $_ is ", <closed open>[ @doors[$_] ] for 1..100;</lang>

optimized

<lang perl6>say "Door $_ is open" for map {$^n ** 2}, 1..10;</lang>

Here's a version using the cross meta-operator instead of a map:

<lang perl6> say "Door $_ is open" for 1..10 X** 2;</lang>

This one prints both opened and closed doors:

<lang perl6>say "Door $_ is ", <closed open>[.sqrt == .sqrt.floor] for 1..100;</lang>

PicoLisp

unoptimized <lang PicoLisp>(let Doors (need 100)

  (for I 100
     (for (D (nth Doors I)  D  (cdr (nth D I)))
        (set D (not (car D))) ) )
  (println Doors) )</lang>

optimized <lang PicoLisp>(let Doors (need 100)

  (for I (sqrt 100)
     (set (nth Doors (* I I)) T) )
  (println Doors) )</lang>

Output in both cases:

(T NIL NIL T NIL NIL NIL NIL T NIL NIL NIL NIL NIL NIL T NIL NIL NIL NIL NIL NIL
 NIL NIL T NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL T NIL NIL NIL NIL NIL NIL NIL
 NIL NIL NIL NIL NIL T NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL T
 NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL T NIL NIL NIL N
IL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL T)

With formatting: <lang PicoLisp>(let Doors (need 100)

  (for I (sqrt 100)
     (set (nth Doors (* I I)) T) )
  (make
     (for (N . D) Doors
        (when D (link N)) ) ) )</lang>

Output:

(1 4 9 16 25 36 49 64 81 100)

Piet

image

Pike

<lang pike>array onehundreddoors() {

   array doors = allocate(100);
   foreach(doors; int i;)
       for(int j=i; j<100; j+=i+1)
           doors[j] = !doors[j];
   return doors;

}</lang> optimized version: <lang pike>array doors = map(enumerate(100,1,1), lambda(int x)

                                     {  
                                         return sqrt((float)x)%1 == 0.0; 
                                     });</lang>

<lang pike>write("%{%d %d %d %d %d %d %d %d %d %d\n%}\n", doors/10)</lang> output:

1 0 0 1 0 0 0 0 1 0
0 0 0 0 0 1 0 0 0 0
0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 1

PL/I

<lang PL/I> declare door(100) bit (1) aligned; declare closed bit (1) static initial ('0'b),

       open   bit (1) static initial ('1'b);

declare (i, inc) fixed binary;

door = closed; inc = 1; do until (inc >= 100);

  do i = inc to 100 by inc;
     door(i) = ^door(i); /* close door if open; open it if closed. */
  end;
  inc = inc+1;

end;

do i = 1 to 100;

  put skip edit ('Door ', trim(i), ' is ') (a);
  if door(i) then put edit (' open.') (a);
  else put edit (' closed.') (a);

end; </lang>

Pop11

unoptimized <lang pop11>lvars i; lvars doors = {% for i from 1 to 100 do false endfor %}; for i from 1 to 100 do

  for j from i by i to 100 do
     not(doors(j)) -> doors(j);
  endfor;

endfor;

Print state

for i from 1 to 100 do

  printf('Door ' >< i >< ' is ' ><
           if doors(i) then 'open' else 'closed' endif, '%s\n');

endfor;</lang>

optimized <lang pop11>for i to 100 do

   lvars root = sqrt(i);
   i; if root = round(root) then ' open' ><; else ' closed' ><; endif; =>

endfor;</lang>

PostScript

Bruteforce:<lang PostScript>/doors [ 100 { false } repeat ] def

1 1 100 { dup 1 sub exch 99 {

       dup doors exch get not doors 3 1 roll put

} for } for doors pstack</lang>Shows: <lang>[true false false true false false false false true false ...<90 doors later>... true]</lang>

PowerShell

unoptimized

<lang powershell>$doors = @(0..99) for($i=0; $i -lt 100; $i++) {

 $doors[$i] = 0  # start with all doors closed

} for($i=0; $i -lt 100; $i++) {

 $step = $i + 1
 for($j=$i; $j -lt 100; $j = $j + $step) {
   $doors[$j] = $doors[$j] -bxor 1
 }

} foreach($doornum in 1..100) {

 if($doors[($doornum-1)] -eq $true) {"$doornum open"}
 else {"$doornum closed"}

}</lang>

unoptimized Pipeline

<lang powershell>$doors = 1..100 | ForEach-Object {0} 1..100 | ForEach-Object { $a=$_;1..100 | Where-Object { -not ( $_ % $a ) } | ForEach-Object { $doors[$_-1] = $doors[$_-1] -bxor 1 }; if ( $doors[$a-1] ) { "door opened" } else { "door closed" } } </lang>

unoptimized Pipeline 2

<lang powershell>$doors = 1..100 | ForEach-Object {0} $visited = 1..100 1..100 | ForEach-Object { $a=$_;$visited[0..([math]::floor(100/$a)-1)] | Where-Object { -not ( $_ % $a ) } | ForEach-Object { $doors[$_-1] = $doors[$_-1] -bxor 1;$visited[$_/$a-1]+=($_/$a) }; if ( $doors[$a-1] ) { "door opened" } else { "door closed" } } </lang>

ProDOS

Uses math module. <lang ProDOS>enableextensions enabledelayedexpansion editvar /newvar /value=0 /title=closed editvar /newvar /value=1 /title=open editvar /newvar /range=1-100 /increment=1 /from=2 editvar /newvar /value=2 /title=next

doors

for /alloccurrences (!next!-!102!) do editvar /modify /value=-open- editvar /modify /value=-next-=+1 if -next- /hasvalue=100 goto :cont else goto :doors

cont

printline !1!-!102! stoptask</lang>

Prolog

unoptimized

<lang Prolog>doors_unoptimized(N) :- length(L, N), maplist(init, L), doors(N, N, L, L1), affiche(N, L1).

init(close).

doors(Max, 1, L, L1) :- !,

      inverse(1, 1, Max, L, L1).

doors(Max, N, L, L1) :- N1 is N - 1, doors(Max, N1, L, L2), inverse(N, 1, Max, L2, L1).


inverse(N, Max, Max, [V], [V1]) :- !, 0 =:= Max mod N -> inverse(V, V1); V1 = V.

inverse(N, M, Max, [V|T], [V1|T1]) :- M1 is M+1, inverse(N, M1, Max, T, T1), ( 0 =:= M mod N -> inverse(V, V1); V1 = V).


inverse(open, close). inverse(close, open).

affiche(N, L) :- forall(between(1, N, I), ( nth1(I, L, open) -> format('Door ~w is open.~n', [I]); true)). </lang>

optimized

<lang Prolog>doors_optimized(N) :- Max is floor(sqrt(N)), forall(between(1, Max, I), ( J is I*I,format('Door ~w is open.~n',[J]))).

</lang>

PureBasic

unoptimized <lang purebasic>Dim doors.i(100)

For x = 1 To 100

 y = x
 While y <= 100
   doors(y) = 1 - doors(y)
   y + x
 Wend

Next

OpenConsole() PrintN("Following Doors are open:") For x = 1 To 100

 If doors(x)
   Print(Str(x) + ", ")
 EndIf

Next Input()</lang>

optimized <lang PureBasic>OpenConsole() PrintN("Following Doors are open:") For i = 1 To 100

   root.f = Sqr(i)
   If root = Int(root)
   	Print (Str(i) + ", ")
   EndIf

Next Input()</lang>


Output:

Following Doors are open:
1, 4, 9, 16, 25, 36, 49, 64, 81, 100,

Python

Works with: Python version 2.5+

unoptimized <lang python>close = 0 open = 1 doors = [close] * 100

for i in range(100):

   for j in range(i, 100, i+1):
       doors[j] = open if doors[j] is close else close
   print "Door %d:" % (i+1), 'open' if doors[i] else 'close'

</lang>

optimized

A version that only visits each door once:

<lang python>for i in xrange(1, 101):

   root = i ** 0.5
   print "Door %d:" % i, 'open' if root == int(root) else 'close'</lang>

One liner using a list comprehension, item lookup, and is_integer

<lang python>print '\n'.join(['Door %s is %s' % (i, ('closed', 'open')[(i**0.5).is_integer()]) for i in xrange(1, 101)])</lang>

One liner using a generator expression, ternary operator, and modulo

<lang python>print '\n'.join('Door %s is %s' % (i, 'closed' if i**0.5 % 1 else 'open') for i in range(1, 101))</lang>

Works with: Python version 3.x

<lang python> for i in list(range(1, 101)):

   if i**0.5 % 1: state='open'
   else: state='close'
   print ("Door {}:{}".format(i, state))

</lang>

Q

unoptimized <lang q>`closed`open mod[;2]count each 1 _ group raze where each 0=t mod\:/:t:til 101</lang>

optimized <lang q>`closed`open (1+til 100) in `int$xexp[;2] 1+til 10</lang>

R

unoptimized <lang r>doors_puzzle <- function(ndoors=100,passes=100) {

   doors <- rep(FALSE,ndoors)
   for (ii in seq(1,passes)) {
       mask <- seq(0,ndoors,ii)
       doors[mask] <- !doors[mask]	
   }
   return (which(doors == TRUE))

}

doors_puzzle()</lang>

optimized <lang r>## optimized version... we only have to to up to the square root of 100 seq(1,sqrt(100))**2</lang>

optimized <lang r>x <- rep(1, 100) for (i in 1:100-1) {

   x <- xor(x, rep(c(rep(0,i),1), length.out=100))

} which(!x)</lang>

REALbasic

<lang realbasic>//True=Open; False=Closed

 Dim doors(100) As Boolean   //Booleans default to false
 For j As Integer = 1 To 100
   For i As Integer = 1 to 100
     If i Mod j = 0 Then
       doors(i) = Not doors(i)
     End If
   Next
 Next</lang>

REBOL

Unoptimized

<lang rebol>doors: array/initial 100 'closed repeat i 100 [

   door: at doors i
   forskip door i [change door either 'open = first door ['closed] ['open]]

]</lang>

Optimized

<lang rebol>doors: array/initial 100 'closed repeat i 10 [doors/(i * i): 'open] </lang>

Retro

<lang Retro>: squared ( n-n ) dup * ;

doors ( n- ) [ 1 repeat 2over squared > 0; drop dup squared putn space 1+ again ] do 2drop ;

100 doors</lang>

REXX

<lang rexx>door. = 0 do inc = 1 to 100

 do d = inc to 100 by inc
   door.d = \door.d
 end

end say "The open doors after 100 passes:" do i = 1 to 100

 if door.i = 1 then say i

end </lang> Here is another version, solving it the hard way.

<lang rexx> /*REXX program to solve the 100 door puzzle, the hard-way version. */

parse arg doors . /*get the first argument (# of doors.) */ if doors== then doors=100 /*not specified? Then assume 100 doors*/

                                   /*   0 = closed.  */
                                   /*   1 = open.    */

door.=0 /*assume all that all doors are closed.*/

 do j=1 for doors           /*process a pass-through for all doors.*/
   do k=j by j to doors     /* ... every Jth door from this point. */
   door.k=\door.k           /*toggle the  "openness"  of the door. */
   end
 end

say say 'After' doors "passes, the following doors are open:" say

 do n=1 for doors
 if door.n then say right(n,20)
 end

say </lang> Output:


After 100 passes, the following doors are open:

                   1
                   4
                   9
                  16
                  25
                  36
                  49
                  64
                  81
                 100

Here is another version, solving it the easy way (version 1). <lang rexx> /*REXX program to solve the 100 door puzzle, the easy-way version. */

parse arg doors . /*get the first argument (# of doors.) */ if doors== then doors=100 /*not specified? Then assume 100 doors*/

                                   /*   0 = closed.  */
                                   /*   1 = open.    */

door.=0 /*assume all that all doors are closed.*/ say say 'For the' doors "doors problem, the following doors are open:" say

 do j=1 for doors           /*process an easy pass-through.        */
 p=j*j                      /*square the door number.              */
                            /*An alternative:     P=J**2           */
 if p>doors then leave      /*if too large, we're done.            */
 say right(p,20)
 end

say </lang> Output:


For the 100 doors problem, the following doors are open:

                   1
                   4
                   9
                  16
                  25
                  36
                  49
                  64
                  81
                 100

Here is another easy-way solution (version 2), but for 1,000 doors. <lang rexx> /*REXX program to solve the 100 door puzzle, the easy-way version 2.*/

parse arg doors . /*get the first argument (# of doors.) */ if doors== then doors=100 /*not specified? Then assume 100 doors*/

doors=1000

                                   /*   0 = closed.  */
                                   /*   1 = open.    */

door.=0 /*assume all that all doors are closed.*/ say say 'For the' doors "doors problem, the open doors are:" say

 do j=1 for doors while j*j<=doors  /*limit the pass-throughs.     */
 say right(j**2,20)
 end

say </lang> Output:


For the 1000 doors problem, the open doors are:

                   1
                   4
                   9
                  16
                  25
                  36
                  49
                  64
                  81
                 100
                 121
                 144
                 169
                 196
                 225
                 256
                 289
                 324
                 361
                 400
                 441
                 484
                 529
                 576
                 625
                 676
                 729
                 784
                 841
                 900
                 961

Ruby

unoptimized; Ruby-way
(I tried to show as much of Ruby syntax and conventions as possible. Of course, instead of a class you could just use generic true/false, but that's not the point, is it?) <lang ruby>class Door attr_reader :state def initialize @state=:closed end

def close; @state=:closed; end def open; @state=:open; end

def closed?; @state==:closed; end def open?; @state==:open; end

def toggle if closed? open else close end end

def to_s; @state.to_s; end end

doors=Array.new(100){Door.new} 1.upto(100) do |multiplier| doors.each_with_index do |door, i| door.toggle if (i+1)%multiplier==0 end end

doors.each_with_index{|door, i| puts "Door #{i+1} is #{door}."}</lang>

unoptimized <lang ruby>n = 100 Open = "open" Closed = "closed" def Open.f

   Closed

end def Closed.f

   Open

end doors = [Closed] * (n+1) for mul in 1..n

   for x in 1..n
       doors[mul*x] = (doors[mul*x] || break).f
   end

end doors.each_with_index {

   |b, i|
   puts "Door #{i} is #{b}" if i>0

}</lang>

optimized <lang ruby>n = 100 (1..n).each do |i|

   puts "Door #{i} is #{i**0.5 == (i**0.5).round ? "open" : "closed"}"

end </lang>

generic true/false, with another way of handling the inner loop demonstrating Range#step <lang ruby> doors = [false] * 100 100.times do |i|

 (i .. doors.length).step(i+1) do |j|
   doors[j] = !doors[j]
 end

end puts doors.inspect

</lang>

Run BASIC

<lang Runbasic>dim doors(100) print "Open doors "; for i = 1 to 100

   for door = i to 100 step i
       doors(door) = (doors(door) <> 1)
       if i = door and doors(door) = 1 then   print i;" ";
   next door

next i</lang>Output:

Open doors 1 4 9 16 25 36 49 64 81 100

S-lang

<lang s-lang>variable door,

   isOpen = Char_Type [101],
   pass;

for (door = 1; door <= 100; door++) {

   isOpen[door] = 0;

}

for (pass = 1; pass <= 100; pass++) {

   for (door = pass; door <= 100; door += pass) {
       isOpen[door] = not isOpen[door];
   }

}

for (door = 1; door <= 100; door++) {

   if (isOpen[door]) {
       print("Door " + string(door) + ":open");
   } else {
       print("Door " + string(door) + ":close");
   }

}</lang>

Salmon

Here's an unoptimized version: <lang Salmon>variable open := <<(* --> false)>>; for (pass; 1; pass <= 100)

   for (door_num; pass; door_num <= 100; pass)
       open[door_num] := !(open[door_num]);;;

iterate (door_num; [1...100])

   print("Door ", door_num, " is ",
         (open[door_num] ? "open.\n" : "closed.\n"));;</lang>

And here's an optimized one-line version:

<lang Salmon>iterate (x; [1...10]) { iterate (y; [(x-1)*(x-1)+1...x*x-1]) { print("Door ", y, " is closed.\n"); }; print("Door ", x*x, " is open.\n"); };</lang>

And a shorter optimized one-line version:

<lang Salmon>variable y:=1;for(x;1;x<101)"Door "~sprint(x)~" is "~(x==y*y?{++y;return"open";}:"closed")!;</lang>

Sather

<lang sather>class MAIN is

 main is
   pass, door :INT;
   doors :ARRAY{BOOL} := #(100);
   loop 
     doors[0.upto!(99)] := false;
   end;
   pass := 0;
   loop while!(pass < 100);
     door := pass;
     loop while! (door < 100);
       doors[door] := ~doors[door];

door := door + pass + 1

     end;
     pass := pass + 1;
   end;
   loop
     door := 0.upto!(99);
     #OUT + (door+1) + " " + doors[door] + "\n";
   end;
 end;

end;</lang>

SAS

<lang sas>data _null_;

  open=1;
  close=0;
  array Door{100};
  do Pass = 1 to 100;
     do Current = Pass to 100 by Pass;
        if Door{Current} ne open 
           then Door{Current} = open;
           else Door{Current} = close;
     end;
  end;
  NumberOfOpenDoors = sum(of Door{*});
  put "Number of Open Doors:  " NumberOfOpenDoors; 

run;</lang>

Scala

<lang scala>for { i <- 1 to 100

     r = 1 to 100 map (i % _ == 0) reduceLeft (_^_)                 
   } println (i +" "+ (if (r) "open" else "closed"))</lang>

The map operation maps each door (i) to a boolean sequence of toggles, one for each pass: true toggles, false leaves the same.

The reduceLeft method combines all the toggles sequentially, using the XOR operator.

And then we just need to output the result.

"Optimized" version: <lang scala>val o = 1 to 10 map (i => i * i) println("open: " + o) println("closed: " + (1 to 100 filterNot o.contains))</lang>

Scheme

unoptimized <lang scheme>(define *max-doors* 100)

(define (show-doors doors)

 (let door ((i 0)
            (l (vector-length doors)))
   (cond ((= i l) 
          (newline))
         (else 
          (printf "~nDoor ~a is ~a" 
                  (+ i 1) 
                  (if (vector-ref doors i) "open" "closed"))
          (door (+ i 1) l)))))

(define (flip-doors doors)

 (define (flip-all i)
   (cond ((> i *max-doors*) doors)
         (else 
          (let flip ((idx (- i 1)))
            (cond ((>= idx *max-doors*) 
                   (flip-all (+ i 1))) 
                  (else 
                   (vector-set! doors idx (not (vector-ref doors idx)))
                   (flip (+ idx i))))))))
 (flip-all 1))

(show-doors (flip-doors (make-vector *max-doors* #f)))</lang>

optimized <lang scheme>(define (optimised-flip-doors doors)

 (define (flip-all i)
   (cond ((> i (floor (sqrt *max-doors*))) doors)
         (else 
          (vector-set! doors (- (* i i) 1) #t)
          (flip-all (+ i 1)))))
 (flip-all 1))

(show-doors (optimised-flip-doors (make-vector *max-doors* #f)))</lang>

Works with: Racket

(moved from the Racket language entry, may be redundant)

<lang scheme>#lang racket

Like "map", but the proc must take an index as well as the element.

(define (map-index proc seq)

 (for/list ([(elt i) (in-indexed seq)])
   (proc elt i)))
Applies PROC to every STEPth element of SEQ, leaving the others
unchanged.

(define (map-step proc step seq)

 (map-index
  (lambda (elt i)
    ((if (zero? (remainder i step) )
         proc
         values) elt))
  seq))

(define (toggle-nth n seq)

 (map-step not n seq))

(define (solve seq)

 (for/fold ([result seq])
     ([(_ pass) (in-indexed  seq)])
     (toggle-nth (add1 pass) result)))

(for ([(door index) (in-indexed (solve (make-vector 100 #f)))])

 (when door
   (printf "~a is open~%" index)))</lang>

optimized:

<lang scheme>#lang racket

(for-each (lambda (x) (printf "~a is open\n" x))

           (filter (lambda (x)
                     (exact-integer? (sqrt x)))
                   (sequence->list (in-range 1 101))))</lang>


Seed7

unoptimized <lang seed7>$ include "seed7_05.s7i";

const proc: main is func

 local
   var array boolean: doorOpen is 100 times FALSE;
   var integer: pass is 0;
   var integer: index is 0;
   var array[boolean] string: closedOrOpen is [boolean] ("closed", "open");
 begin
   for pass range 1 to 100 do
     for key index range doorOpen do
       if index rem pass = 0 then
         doorOpen[index] := not doorOpen[index];
       end if;
     end for;
   end for;
   for key index range doorOpen do
     write(index lpad 3 <& " is " <& closedOrOpen[doorOpen[index]] rpad 7);
     if index rem 5 = 0 then
       writeln;
     end if;
   end for;
 end func;</lang>

optimized <lang seed7>$ include "seed7_05.s7i";

const proc: main is func

 local
   var integer: index is 0;
   var integer: number is 0;
   var array[boolean] string: closedOrOpen is [boolean] ("closed", "open");
 begin
   for index range 1 to 100 do
     number := sqrt(index);
     write(index lpad 3 <& " is " <& closedOrOpen[number**2 = index] rpad 7);
     if index rem 5 = 0 then
       writeln;
     end if;
   end for;
 end func;</lang>

Output of both programs:

  1 is open     2 is closed   3 is closed   4 is open     5 is closed 
  6 is closed   7 is closed   8 is closed   9 is open    10 is closed 
 11 is closed  12 is closed  13 is closed  14 is closed  15 is closed 
 16 is open    17 is closed  18 is closed  19 is closed  20 is closed 
 21 is closed  22 is closed  23 is closed  24 is closed  25 is open   
 26 is closed  27 is closed  28 is closed  29 is closed  30 is closed 
 31 is closed  32 is closed  33 is closed  34 is closed  35 is closed 
 36 is open    37 is closed  38 is closed  39 is closed  40 is closed 
 41 is closed  42 is closed  43 is closed  44 is closed  45 is closed 
 46 is closed  47 is closed  48 is closed  49 is open    50 is closed 
 51 is closed  52 is closed  53 is closed  54 is closed  55 is closed 
 56 is closed  57 is closed  58 is closed  59 is closed  60 is closed 
 61 is closed  62 is closed  63 is closed  64 is open    65 is closed 
 66 is closed  67 is closed  68 is closed  69 is closed  70 is closed 
 71 is closed  72 is closed  73 is closed  74 is closed  75 is closed 
 76 is closed  77 is closed  78 is closed  79 is closed  80 is closed 
 81 is open    82 is closed  83 is closed  84 is closed  85 is closed 
 86 is closed  87 is closed  88 is closed  89 is closed  90 is closed 
 91 is closed  92 is closed  93 is closed  94 is closed  95 is closed 
 96 is closed  97 is closed  98 is closed  99 is closed 100 is open   

Slate

Unoptimized <lang slate>define: #a -> (Array newSize: 100). a infect: [| :_ | False].

a keysDo: [| :pass |

 pass to: a indexLast by: pass do: [| :door |
   a at: door infect: #not `er]].

a keysAndValuesDo: [| :door :isOpen |

 inform: 'door #' ; door ; ' is ' ; (isOpen ifTrue: ['open'] ifFalse: ['closed'])].</lang>

Optimized <lang slate>define: #a -> (Array newSize: 100). a infect: [| :_ | False].

0 below: 10 do: [| :door | a at: door squared put: True]. a keysAndValuesDo: [| :door :isOpen |

 inform: 'door #' ; door ; ' is ' ; (isOpen ifTrue: ['open'] ifFalse: ['closed'])].</lang>

Smalltalk

Works with: GNU Smalltalk

Unoptimized <lang 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

]</lang> Optimized

<lang smalltalk>|a| a := (1 to: 100) collect: [ :x | false ]. 1 to: 10 do: [ :i | a at: (i squared) put: true ]. 1 to: 100 do: [ :i |

  ( 'door #%1 is %2' % { i . 
          (a at: i) ifTrue: [ 'open' ] 
                    ifFalse: [ 'closed' ] }
  ) displayNl

]</lang>

Works with: Squeak Smalltalk

Unoptimized, using Morphs <lang smalltalk> | m w h smh smw delay closedDoor border subMorphList |

closedDoor := Color black. border := Color veryLightGray. delay := Delay forMilliseconds: 50. w := World bounds corner x. h := (World bounds corner y) / 2. smw := w/100. smh := h/2.

m := BorderedMorph new position: 0@h. m height: smh; width: w; borderColor: border. m color: Color veryLightGray.

1 to: 100 do: [ :pos || sm | sm := BorderedMorph new height: smh ; width: smw ; borderColor: border; color: closedDoor; position: (smw*pos)@h. m addMorph: sm asElementNumber: pos].

m openInWorld. delay wait. subMorphList := m submorphs. "display every step" [1 to: 100 do: [ :step | step to: 100 by: step do: [ :pos | | subMorph | subMorph := subMorphList at: pos. subMorph color: subMorph color negated. delay wait]]] fork. </lang>

SETL

Unoptimized <lang setl>program hundred_doors;

const toggle := {['open', 'closed'], ['closed', 'open']};

doorStates := ['closed'] * 100;

(for interval in [1..100])

 doorStates := [if i mod interval = 0 then
                   toggle(prevState) else
                   prevState end:
                prevState = doorStates(i)];

end;

(for finalState = doorStates(i))

 print('door', i, 'is', finalState);

end;

end program;</lang> If 'open' weren't a reserved word, we could omit the single quotes around it.

Optimized Exploits the fact that squares are separated by successive odd numbers. Use array replication to insert the correct number of closed doors in between the open ones. <lang setl>program hundred_doors;

doorStates := (+/ [['closed'] * oddNum with 'open': oddNum in [1,3..17]]);

(for finalState = doorStates(i))

 print('door', i, 'is', finalState);

end;

end program;</lang>

SNOBOL4

unoptimized <lang snobol4> DEFINE('PASS(A,I),O') :(PASS.END) PASS O = 0 PASS.LOOP O = O + I EQ(A<O>,1) :S(PASS.1)F(PASS.0) PASS.0 A<O> = 1 :S(PASS.LOOP)F(RETURN) PASS.1 A<O> = 0 :S(PASS.LOOP)F(RETURN) PASS.END

MAIN D = ARRAY(100,0) I = 0

MAIN.LOOP I = LE(I,100) I + 1 :F(OUTPUT) PASS(D,I) :(MAIN.LOOP)

OUTPUT I = 1 ; OPEN = 'Opened doors are: ' OUTPUT.LOOP OPEN = OPEN EQ(D,1) " " I I = LE(I,100) I + 1 :S(OUTPUT.LOOP)F(OUTPUT.WRITE) OUTPUT.WRITE OUTPUT = OPEN

END </lang>

A run of this using CSNOBOL4 looks like this:

$ snobol4 100doors.sno 
The Macro Implementation of SNOBOL4 in C (CSNOBOL4) Version 1.3+
    by Philip L. Budne, January 23, 2011
SNOBOL4 (Version 3.11, May 19, 1975)
    Bell Telephone Laboratories, Incorporated

No errors detected in source program

Opened doors are:  1 4 9 16 25 36 49 64 81 100
Normal termination at level 0
100doors.sno:18: Last statement executed was 19

(There are command flags to remove the header and the summary, but these have been left in to keep the original SNOBOL4 experience intact.)

optimized <lang snobol4> MAIN D = ARRAY(100,0) I = 1

MAIN.LOOP LE(I, 10) :F(OUTPUT) D = 1 I = I + 1 :(MAIN.LOOP)

OUTPUT I = 1 ; O = 'Opened doors are: ' OUTPUT.LOOP O = O EQ(D,1) " " I I = LE(I,100) I + 1 :S(OUTPUT.LOOP)F(OUTPUT.WRITE) OUTPUT.WRITE OUTPUT = O END </lang>

The output of this version is almost identical to the above.

Tcl

unoptimized

<lang tcl>package require Tcl 8.5 set n 100 set doors [concat - [lrepeat $n 0]] for {set step 1} {$step <= $n} {incr step} {

   for {set i $step} {$i <= $n} {incr i $step} {
       lset doors $i [expr { ! [lindex $doors $i]}]
   }

} for {set i 1} {$i <= $n} {incr i} {

   puts [format "door %d is %s" $i [expr {[lindex $doors $i] ? "open" : "closed"}]]

}</lang>

optimized

<lang tcl>package require Tcl 8.5 set doors [lrepeat [expr {$n + 1}] closed] for {set i 1} {$i <= sqrt($n)} {incr i} {

   lset doors [expr {$i ** 2}] open

} for {set i 1} {$i <= $n} {incr i} {

   puts [format "door %d is %s" $i [lindex $doors $i]]

}</lang>

graphical

Library: Tk

Inspired by the E solution, here's a visual representation <lang tcl>package require Tcl 8.5 package require Tk

array set door_status {}

  1. create the gui

set doors [list x] for {set i 0} {$i < 10} {incr i} {

   for {set j 0} {$j < 10} {incr j} {
       set k [expr {1 + $j + 10*$i}]
       lappend doors [radiobutton .d_$k -text $k -variable door_status($k) \
                        -indicatoron no -offrelief flat -width 3 -value open]
       grid [lindex $doors $k] -column $j -row $i
   }

}

  1. create the controls

button .start -command go -text Start label .i_label -text " door:" entry .i -textvariable i -width 4 label .step_label -text " step:" entry .step -textvariable step -width 4 grid .start - .i_label - .i - .step_label - .step - -row $i grid configure .start -sticky ew grid configure .i_label .step_label -sticky e grid configure .i .step -sticky w

proc go {} {

   global doors door_status i step
   # initialize the door_status (all closed)
   for {set d 1} {$d <= 100} {incr d} {
       set door_status($d) closed
   }
   
   # now, begin opening and closing
   for {set step 1} {$step <= 100} {incr step} {
       for {set i 1} {$i <= 100} {incr i} {
           if {$i % $step == 0} {
               [lindex $doors $i] [expr {$door_status($i) eq "open" ? "deselect" : "select"}]
               update
               after 50
           }
       }
   }

}</lang>

TI-83 BASIC

Unoptimized

<lang ti83b>PROGRAM:DOORS100

ClrHome
Disp "SETTING UP LIST"
Disp "PLEASE WAIT..."
For(I,1,100,1)
0→L1(I)
End
ClrHome
Disp "Pass"
For(I,1,100,1)
For(J,I,100,I)
Output(2,1,I)
not(L1(J))→L1(J)
End
End
ClrHome

</lang>

Optimized

<lang ti83b>PROGRAM:DOORSOPT

For(I,1,100,1)
not(fPart(√(I)))→L1(I)
End

</lang>


TI-89 BASIC

<lang ti89b>Define doors(fast) = Func

 Local doors,i,j
 seq(false,x,1,100) → doors
 If fast Then
   For i,1,10,1
     true → doors[i^2]
   EndFor
 Else
   For i,1,100,1
     For j,i,100,i
       not doors[j] → doors[j]
     EndFor
   EndFor
 EndIf
 Return doors

EndFunc</lang>

TUSCRIPT

<lang tuscript> $$ MODE TUSCRIPT DICT doors create COMPILE LOOP door=1,100

LOOP pass=1,100
SET go=MOD (door,pass)
DICT doors lookup door,num,cnt,status
  IF (num==0) THEN
    SET status="open"
    DICT doors add  door,num,cnt,status
  ELSE
   IF (go==0) THEN
      IF (status=="closed") THEN
        SET status="open"
      ELSE
        SET status="closed"
      ENDIF
    DICT doors update door,num,cnt,status
    ENDIF
  ENDIF
ENDLOOP

ENDLOOP ENDCOMPILE DICT doors unload door,num,cnt,status </lang> Output (variable status):

 status       = *
           1 = open
           2 = closed
           3 = closed
           4 = open
           5 = closed
           6 = closed
           7 = closed
           8 = closed
           9 = open
          10 = closed
          11 = closed
          12 = closed
          13 = closed
          14 = closed
          15 = closed
          16 = open
          17 = closed
          18 = closed
          19 = closed
          20 = closed
          21 = closed
          22 = closed
          23 = closed
          24 = closed
          25 = open
          26 = closed
          27 = closed
          28 = closed
          29 = closed
          30 = closed
          31 = closed
          32 = closed
          33 = closed
          34 = closed
          35 = closed
          36 = open
          37 = closed
          38 = closed
          39 = closed
          40 = closed
          41 = closed
          42 = closed
          43 = closed
          44 = closed
          45 = closed
          46 = closed
          47 = closed
          48 = closed
          49 = open
          50 = closed
          51 = closed
          52 = closed
          53 = closed
          54 = closed
          55 = closed
          56 = closed
          57 = closed
          58 = closed
          59 = closed
          60 = closed
          61 = closed
          62 = closed
          63 = closed
          64 = open
          65 = closed
          66 = closed
          67 = closed
          68 = closed
          69 = closed
          70 = closed
          71 = closed
          72 = closed
          73 = closed
          74 = closed
          75 = closed
          76 = closed
          77 = closed
          78 = closed
          79 = closed
          80 = closed
          81 = open
          82 = closed
          83 = closed
          84 = closed
          85 = closed
          86 = closed
          87 = closed
          88 = closed
          89 = closed
          90 = closed
          91 = closed
          92 = closed
          93 = closed
          94 = closed
          95 = closed
          96 = closed
          97 = closed
          98 = closed
          99 = closed
         100 = open

TXR

<lang txr>@(do (defun 100-doors ()

      (let ((doors (vector 100)))
        (each ((i (range 0 99)))
          (for ((j i)) ((< j 100)) ((inc j (+ i 1)))
            (flip [doors j])))
        doors))
    (each ((counter (range 1))
           (door (list-vector (100-doors))))
       (format t "door ~a is ~a\n" counter (if door "open" "closed"))))</lang>

UNIX Shell

Works with: Bourne Again SHell

<lang bash>#! /bin/bash

declare -a doors for((i=1; i <= 100; i++)); do

   doors[$i]=0

done

for((i=1; i <= 100; i++)); do

   for((j=i; j <= 100; j += i)); do

echo $i $j doors[$j]=$(( doors[j] ^ 1 ))

   done

done

for((i=1; i <= 100; i++)); do

   if [[ ${doors[$i]} -eq 0 ]]; then

op="closed"

   else

op="open"

   fi
   echo $i $op

done</lang>

Optimised version <lang bash>#!/bin/bash

for i in {1..100}; do

 door[$i*$i]=1
 [ -z ${door[$i]} ] && echo "$i closed" || echo "$i open"

done</lang>

Ursala

The doors are represented as a list of 100 booleans initialized to false. The pass function takes a number and a door list to a door list with doors toggled at indices that are multiples of the number. The main program folds the pass function (to the right) over the list of pass numbers from 100 down to 1, numbers the result, and filters out the numbers of the open doors. <lang Ursala>#import std

  1. import nat

doors = 0!* iota 100

pass("n","d") = remainder\"n"?l(~&r,not ~&r)* num "d"

  1. cast %nL

main = ~&rFlS num pass=>doors nrange(100,1)</lang> optimized version: <lang Ursala>#import nat

  1. cast %nL

main = product*tiiXS iota10</lang> output:

<1,4,9,16,25,36,49,64,81>

VBScript

Works with: Windows Script Host version 5.7

Unoptimized <lang VBScript>Dim doorIsOpen(100), pass, currentDoor, text

For currentDoor = 0 To 99 doorIsOpen(currentDoor) = False Next

For pass = 0 To 99 For currentDoor = pass To 99 Step pass + 1 doorIsOpen(currentDoor) = Not doorIsOpen(currentDoor) Next Next

For currentDoor = 0 To 99 text = "Door #" & currentDoor + 1 & " is " If doorIsOpen(currentDoor) Then text = text & "open." Else text = text & "closed." End If WScript.Echo(text) Next</lang>


Vedit macro language

Unoptimized This implementation uses a free edit buffer as data array and for displaying the results.
A closed door is represented by a character '-' and an open door by character 'O'. <lang vedit>Buf_Switch(Buf_Free) Ins_Char('-', COUNT, 100) // All doors closed for (#1 = 1; #1 <= 100; #1++) {

   for (#2 = #1; #2 <= 100; #2 += #1) {
       Goto_Col(#2)
       Ins_Char((Cur_Char^0x62), OVERWRITE)   // Toggle between '-' and 'O'
   }

}</lang>

Optimized <lang vedit>Buf_Switch(Buf_Free) Ins_Char('-', COUNT, 100) for (#1=1; #1 <= 10; #1++) {

   Goto_Col(#1*#1)
   Ins_Char('O', OVERWRITE)

}</lang>

Output:

O--O----O------O--------O----------O------------O--------------O----------------O------------------O

VHDL

unoptimized <lang vhdl>library IEEE; use IEEE.STD_LOGIC_1164.ALL;

entity DOORS is port (CLK: in std_logic; OUTPUT: out std_logic_vector(1 to 100)); end DOORS;

architecture Behavioral of DOORS is begin process (CLK) variable TEMP: std_logic_vector(1 to 100); begin --setup closed doors TEMP := (others => '0');

--looping through for i in 1 to TEMP'length loop for j in i to TEMP'length loop if (j mod i) = 0 then TEMP(j) := not TEMP(j); end if; end loop; end loop;

--assign output OUTPUT <= TEMP; end process; end Behavioral; </lang>

Visual Basic .NET

Works with: Visual Basic .NET version 9.0+

unoptimized <lang vbnet>Module Module1

  Sub Main()
      Dim doors(100) As Boolean 'Door 1 is at index 0
      For pass = 1 To 100
          For door = pass - 1 To 99 Step pass
              doors(door) = Not doors(door)
          Next
      Next
      For door = 0 To 99
          Console.WriteLine("Door # " & (door + 1) & " is " & If(doors(door), "Open", "Closed"))
      Next
      Console.ReadLine()
  End Sub

End Module</lang> optimized <lang vbnet>Module Module1

  Sub Main()
      Dim doors(100) As Boolean 'Door 1 is at index 0
      For i = 1 To 10
          doors(i ^ 2 - 1) = True
      Next
      For door = 0 To 99
          Console.WriteLine("Door # " & (door + 1) & " is " & If(doors(door), "Open", "Closed"))
      Next
      Console.ReadLine()
  End Sub

End Module</lang>

Wrapl

Unoptimized <lang wrapl>MOD Doors;

IMP Agg.Table; IMP Std.String; IMP IO.Terminal USE Out;

VAR door <- {}; EVERY door[1:to(100), "closed"];

DEF toggle(num) door[num] <- door[num] = "open" => "closed" // "open";

EVERY WITH pass <- 1:to(100), num <- pass:to(100, pass) DO toggle(num);

Out:write('Doors {door @ String.T}.');

END Doors.</lang> Optimized <lang wrapl>MOD Doors;

IMP IO.Terminal USE Out;

DEF open <- ALL 1:to(100) ^ 2 \ $ <= 100; DEF closed <- ALL 1:to(100) \ NOT $ IN open;

Out:write('Doors {open} are open.\n'); Out:write('Doors {closed} are closed.\n');

END Doors.</lang>

XPL0

<lang XPL0>include c:\cxpl\codes; \intrinsic 'code' declarations int Door(100); \You have 100 doors in a row define Open, Closed; int D, Pass, Step;

[for D:= 0 to 100-1 do \that are all initially closed

       Door(D):= Closed;

Step:= 1; \The first time through, you visit every door for Pass:= 1 to 100 do \You make 100 passes by the doors

       [D:= Step-1;
       repeat  \if the door is closed, you open it; if it is open, you close it
               if Door(D)=Closed then Door(D):= Open else Door(D):= Closed;
               D:= D+Step;
       until   D>=100;
       Step:= Step+1;          \The second time you only visit every 2nd door
       ];                      \The third time, every 3rd door
                               \until you only visit the 100th door

\What state are the doors in after the last pass? Text(0, "Open: "); \Which are open? for D:= 0 to 100-1 do

       if Door(D)=Open then [IntOut(0, D+1); ChOut(0,^ )];

CrLf(0);

Text(0, "Closed: "); \Which are closed? for D:= 0 to 100-1 do

       if Door(D)=Closed then [IntOut(0, D+1); ChOut(0,^ )];

CrLf(0);

\Optimized: The only doors that remain open are those that are perfect squares Text(0, "Open: "); D:= 1; repeat IntOut(0, D*D); ChOut(0,^ );

       D:= D+1;

until D*D>100; CrLf(0); ]</lang>

XSLT

See: 100 doors/XSLT

Yorick

Unoptimized, iterative <lang yorick>doors = array(0, 100); for(i = 1; i <= 100; i++)

   for(j = i; j <= 100; j += i)
       doors(j) ~= 1;

print, where(doors);</lang>

Unoptimized, vectorized <lang yorick>doors = array(0, 100); for(i = 1; i <= 100; i++)

   doors(i::i) ~= 1;

print, where(doors);</lang>

Optimized <lang yorick>print, indgen(1:long(sqrt(100)))^2</lang>

All of the above output:

[1,4,9,16,25,36,49,64,81,100]