I'm working on modernizing Rosetta Code's infrastructure. Starting with communications. Please accept this time-limited open invite to RC's Slack.. --Michael Mol (talk) 20:59, 30 May 2020 (UTC)

# 100 doors

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

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

You make 100 passes by the doors.

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

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

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

Answer the question:   what state are the doors in after the last pass?   Which are open, which are closed?

Alternate: As noted in this page's   discussion page,   the only doors that remain open are those whose numbers are perfect squares.

Opening only those doors is an   optimization   that may also be expressed; however, as should be obvious, this defeats the intent of comparing implementations across programming languages.

## 11l

Translation of: Python
V doors = [0B] * 100L(i) 100   L(j) (i .< 100).step(i + 1)      doors[j] = !doors[j]   print(‘Door ’(i + 1)‘: ’(I doors[i] {‘open’} E ‘close’))

## 360 Assembly

*        100 doors                 13/08/2015HUNDOOR  CSECT         USING  HUNDOOR,R12         LR     R12,R15         LA     R6,0         LA     R8,1               step 1         LA     R9,100LOOPI    BXH    R6,R8,ELOOPI       do ipass=1 to 100 (R6)         LR     R7,R6         SR     R7,R6         LR     R10,R6             step ipass         LA     R11,100LOOPJ    BXH    R7,R10,ELOOPJ      do idoor=ipass to 100 by ipass (R7)         LA     R5,DOORS-1         AR     R5,R7         XI     0(R5),X'01'        doors(idoor)=not(doors(idoor))NEXTJ    B      LOOPJELOOPJ   B      LOOPIELOOPI   LA     R10,BUFFER         R10 address of the buffer         LA     R5,DOORS           R5 address of doors item         LA     R6,1               idoor=1 (R6)         LA     R9,100             loop counterLOOPN    CLI    0(R5),X'01'        if doors(idoor)=1         BNE    NEXTN         XDECO  R6,XDEC            idoor to decimal         MVC    0(4,R10),XDEC+8    move decimal to buffer         LA     R10,4(R10)NEXTN	 LA     R6,1(R6)           idoor=idoor+1         LA     R5,1(R5)         BCT    R9,LOOPN           loopELOOPN   XPRNT  BUFFER,80RETURN   XR     R15,R15         BR     R14DOORS    DC     100X'00'BUFFER   DC     CL80' 'XDEC     DS     CL12         YREGS         END    HUNDOOR
Output:
   1   4   9  16  25  36  49  64  81 100

## 4DOS Batch

 @echo offset 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]  enddoenddo

The SET line consists of three functions:

 %@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

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

## 6502 Assembly

Works with: [www.6502asm.com] version beta

unoptimized Based on BASIC QB64 unoptimized version

; 100 DOORS in  6502 assembly language for: http://www.6502asm.com/beta/index.html; Written for the original MOS Technology, Inc. NMOS version of the 6502, but should work with any version.; Based on BASIC QB64 unoptimized version: http://rosettacode.org/wiki/100_doors#BASIC;; Notes:;    Doors array[1..100] is at $0201..$0264. On the specified emulator, this is in video memory, so tbe results will ; be directly shown as pixels in the display.;    $0200 (door 0) is cleared for display purposes but is not involved in the open/close loops.; Y register holds Stride; X register holds Index; Zero Page address$01 used to add Stride to Index (via A) because there's no add-to-X or add-Y-to-A instruction.   ; First, zero door array    LDA #00    LDX #100Z_LOOP:    STA 200,X    DEX    BNE Z_LOOP    STA 200,X   ; Now do doors repeated open/close    LDY #01        ; Initial value of StrideS_LOOP:    CPY #101    BCS S_DONE    TYA            ; Initial value of IndexI_LOOP:    CMP #101    BCS I_DONE    TAX            ; Use as Door array index    INC $200,X ; Toggle bit 0 to reverse state of door STY 01 ; Add stride (Y) to index (X, via A) ADC 01 BCC I_LOOPI_DONE: INY BNE S_LOOPS_DONE: ; Finally, format array values for output: 0 for closed, 1 for open LDX #100C_LOOP: LDA$200,X    AND #$01 STA$200,X    DEX    BNE C_LOOP

48. bytes of code; the specified emulator does not report cycles.

Works with: [6502asm.com] version 1.2

optimized Largely inspired by the optimized C implementation - makes use of the fact that finally only the doors whose numbers are squares of integers are open, as well as the fact that

${\displaystyle n^{2}=1+3+5+\ldots +(2n-1)}$.

  ;assumes memory at $02xx is initially set to 0 and stack pointer is initialized ;the 1 to 100 door byte array will be at$0200-$0263 (decimal 512 to 611) ;Zero-page location$01 will hold delta  ;At end, closed doors = $00, open doors =$01 start:    ldx #0        ;initialize index - first door will be at $200 +$0          stx $1 inc$1        ;start out with a delta of 1 (0+1=1)openloop: inc $200,X ;open X'th door inc$1        ;add 2 to delta          inc $1 txa ;add delta to X by transferring X to A, adding delta to A, then transferring back to X clc ; clear carry before adding (6502 has no add-without-carry instruction) adc$1          tax          cpx #$64 ;check to see if we're at or past the 100th door (at$200 + $63) bmi openloop ;jump back to openloop if less than 100 22. bytes of code; the specified emulator does not report cycles. ## 68000 Assembly Works with: [EASy68K v5.13.00] Some of the macro code is derived from the examples included with EASy68K. *-----------------------------------------------------------* Title : 100Doors.X68* Written by : G. A. Tippery* Date : 2014-01-17* Description: Solves "100 Doors" problem, see: http://rosettacode.org/wiki/100_doors* Notes : Translated from C "Unoptimized" version, http://rosettacode.org/wiki/100_doors#unoptimized* : No optimizations done relative to C version; "for("-equivalent loops could be optimized.*----------------------------------------------------------- ** System-specific general console I/O macros (Sim68K, in this case)*PUTS MACRO ** Print a null-terminated string w/o CRLF ** ** Usage: PUTS stringaddress ** Returns with D0, A1 modified MOVEQ #14,D0 ; task number 14 (display null string) LEA \1,A1 ; address of string TRAP #15 ; display it ENDM*PRINTN MACRO ** Print decimal integer from number in register ** Usage: PRINTN register ** Returns with D0,D1 modified IFNC '\1','D1' ;if some register other than D1 MOVE.L \1,D1 ;put number to display in D1 ENDC MOVE.B #3,D0 TRAP #15 ;display number in D1** Generic constants*CR EQU 13 ;ASCII Carriage ReturnLF EQU 10 ;ASCII Line Feed ** Definitions specific to this program** Register usage:* D3 == pass (index)* D4 == door (index)* A2 == Doors array pointer*SIZE EQU 100 ;Define a symbolic constant for # of doors ORG$1000           ;Specify load address for program -- actual address system-specificSTART:                          ; Execution starts here        LEA     Doors,A2        ; make A2 point to Doors byte array        MOVEQ   #0,D3PassLoop:        CMP     #SIZE,D3        BCC     ExitPassLoop    ; Branch on Carry Clear - being used as Branch on Higher or Equal        MOVE    D3,D4DoorLoop:        CMP     #SIZE,D4        BCC     ExitDoorLoop        NOT.B   0(A2,D4)        ADD     D3,D4        ADDQ    #1,D4        BRA     DoorLoopExitDoorLoop:        ADDQ    #1,D3        BRA     PassLoopExitPassLoop:* $28 = 40. bytes of code to this point. 32626 cycles so far.* At this point, the result exists as the 100 bytes starting at address Doors.* To get output, we must use methods specific to the particular hardware, OS, or* emulator system that the code is running on. I use macros to "hide" some of the* system-specific details; equivalent macros would be written for another system. MOVEQ #0,D4PrintLoop: CMP #SIZE,D4 BCC ExitPrintLoop PUTS DoorMsg1 MOVE D4,D1 ADDQ #1,D1 ; Convert index to 1-based instead of 0-based PRINTN D1 PUTS DoorMsg2 TST.B 0(A2,D4) ; Is this door open (!= 0)? BNE ItsOpen PUTS DoorMsgC BRA NextItsOpen: PUTS DoorMsgONext: ADDQ #1,D4 BRA PrintLoopExitPrintLoop:* What to do at end of program is also system-specific SIMHALT ;Halt simulator**$78 = 120. bytes of code to this point, but this will depend on how the I/O macros are actually written.* Cycle count is nearly meaningless, as the I/O hardware and routines will dominate the timing. **   Data memory usage*        ORG     $2000Doors DCB.B SIZE,0 ;Reserve 100 bytes, prefilled with zeros DoorMsg1 DC.B 'Door ',0DoorMsg2 DC.B ' is ',0DoorMsgC DC.B 'closed',CR,LF,0DoorMsgO DC.B 'open',CR,LF,0 END START ;last line of source  ## 8080 Assembly page: equ 2 ; Store doors in page 2doors: equ 100 ; 100 doorsputs: equ 9 ; CP/M string output org 100h xra a ; Set all doors to zero lxi h,256*page mvi c,doorszero: mov m,a inx h dcr c jnz zero mvi m,'$'	; CP/M string terminator (for easier output later)	mov	d,a	; D=0 so that DE=E=pass counter	mov	e,a	; E=0, first pass	mvi	a,doors-1	; Last pass and doorpass:	mov	l,e	; L=door counter, start at first door in passdoor:	inr	m	; Incrementing always toggles the low bit	dad	d	; Go to next door in pass	inr	l	cmp	l	; Was this the last door?	jnc	door	; If not, do the next door	inr	e	; Next pass	cmp	e	; Was this the last pass?	jnc	pass	; If not, do the next pass	lxi	h,256*page	mvi	c,doors	; Door counter	lxi	d,130h	; D=1 (low bit), E=30h (ascii 0)char:	mov	a,m	; Get door		ana	d	; Low bit gives door status	ora	e	; ASCII 0 or 1	mov	m,a	; Write character back	inx	h	; Next door	dcr	c	; Any doors left?	jnz	char	; If so, next door	lxi	d,256*page	mvi	c,puts	; CP/M system call to print the string	jmp	5
Output:
1001000010000001000000001000000000010000000000001000000000000001000000000000000010000000000000000001

## 8th

 \ Array of doors; init to empty; accessing a non-extant member will return\ 'null', which is treated as 'false', so we don't need to initialize it:[] var, doors     \ given a door number, get the value and toggle it:: toggle-door \ n --	doors @ over a:@	not rot swap a:! drop ; \ print which doors are open:: .doors	( 		doors @ over a:@ nip		if . space else drop then	) 1 100 loop ; \ iterate over the doors, skipping 'n':: main-pass \ n --	0	true	repeat		drop		dup toggle-door		over n:+		dup 101 <	while 2drop drop ; \ calculate the first 100 doors:' main-pass 1 100 loop\ print the results:.doors cr bye
Output:

1 4 9 16 25 36 49 64 81 100

## AArch64 Assembly

Works with: as version Raspberry Pi 3B version Buster 64 bits

unoptimized

 /* ARM assembly AARCH64 Raspberry PI 3B *//*  program 100doors64.s   */ /*******************************************//* Constantes file                         *//*******************************************//* for this file see task include a file in language AArch64 assembly*/.include "../includeConstantesARM64.inc" .equ NBDOORS,   100/*********************************//* Initialized data              *//*********************************/.datasMessResult:       .asciz "The door @ is open.\n" /*********************************//* UnInitialized data            *//*********************************/.bss  stTableDoors:    .skip   8 * NBDOORSsZoneConv:       .skip 24/*********************************//*  code section                 *//*********************************/.text.global main main:                             // entry of program     // display first line    ldr x3,qAdrstTableDoors       // table address    mov x5,1             1:    mov x4,x52:                               // begin loop    ldr x2,[x3,x4,lsl #3]        // read doors index x4    cmp x2,#0    cset x2,eq    //moveq x2,#1                // if x2 = 0   1 -> x2    //movne x2,#0                // if x2 = 1   0 -> x2    str x2,[x3,x4,lsl #3]        // store value of doors    add x4,x4,x5                 // increment x4 with  x5 value    cmp x4,NBDOORS               // number of doors ?    ble 2b                       // no -> loop    add x5,x5,#1                 // increment the increment !!    cmp x5,NBDOORS               // number of doors ?    ble 1b                       // no -> loop                                  // loop display state doors    mov x4,#0              3:    ldr x2,[x3,x4,lsl #3]        // read state doors x4 index    cmp x2,#0    beq 4f    mov x0,x4                    // open -> display message    ldr x1,qAdrsZoneConv          // display value index    bl conversion10              // call function    ldr x0,qAdrsMessResult    ldr x1,qAdrsZoneConv     bl strInsertAtCharInc        // insert result at first @ character    bl affichageMess             // display message4:    add x4,x4,1    cmp x4,NBDOORS    ble 3b                       // loop  100:                             // standard end of the program     mov x0,0                     // return code    mov x8,EXIT                  // request to exit program    svc 0                        // perform the system call qAdrstTableDoors:        .quad stTableDoorsqAdrsMessResult:         .quad sMessResultqAdrsZoneConv:           .quad sZoneConv/***********************************************//*        File Include fonctions                        *//********************************************************//* for this file see task include a file in language AArch64 assembly */.include "../includeARM64.inc"

optimized

 /* ARM assembly AARCH64 Raspberry PI 3B *//*  program 100doors64_1.s   */ /*******************************************//* Constantes file                         *//*******************************************//* for this file see task include a file in language AArch64 assembly*/.include "../includeConstantesARM64.inc" .equ NBDOORS,   100/*********************************//* Initialized data              *//*********************************/.datasMessResult:       .asciz "The door @ is open.\n" /*********************************//* UnInitialized data            *//*********************************/.bss  sZoneConv:        .skip 24/*********************************//*  code section                 *//*********************************/.text.global main main:                             // entry of program      mov x5,3    mov x4,11:    mov x0,x4    ldr x1,qAdrsZoneConv          // display value index    bl conversion10              // call function    ldr x0,qAdrsMessResult    ldr x1,qAdrsZoneConv     bl strInsertAtCharInc        // insert result at first @ character    bl affichageMess             // display message    add x4,x4,x5    add x5,x5,2    cmp x4,NBDOORS    ble 1b                       // loop  100:                             // standard end of the program     mov x0,0                     // return code    mov x8,EXIT                  // request to exit program    svc 0                        // perform the system call qAdrsMessResult:         .quad sMessResultqAdrsZoneConv:           .quad sZoneConv/***********************************************//*        File Include fonctions                        *//********************************************************//* for this file see task include a file in language AArch64 assembly */.include "../includeARM64.inc"

## ABAP

unoptimized

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.

unoptimized / functional

 cl_demo_output=>display( REDUCE stringtab( INIT list TYPE stringtab                                              aux TYPE i                                          FOR door = 1 WHILE door <= 100                                          FOR pass = 1 WHILE pass <= 100                                         NEXT aux   = COND #( WHEN pass = 1 THEN 1                                                              WHEN door MOD pass = 0 THEN aux + 1 ELSE aux  )                                              list  = COND #( WHEN pass = 100                                                                THEN COND #( WHEN aux MOD 2 <> 0 THEN VALUE #( BASE list ( CONV #( door ) ) )                                                                              ELSE list ) ELSE list ) ) ).

optimized

Using ${\displaystyle \sum _{i=1}^{n}(2i-1)=n^{2}}$

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.

ultra-optimized / imperative

 DO 10 TIMES.  DATA(val) = sy-index * sy-index.  WRITE: / val.ENDDO.

ultra-optimized / functional

 cl_demo_output=>display( REDUCE stringtab( INIT list TYPE stringtab                                          FOR i = 1 WHILE i <= 10                                         NEXT list = VALUE #( BASE list ( i * i ) ) ) ).

## ACL2

(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))))

## ActionScript

Works with: ActionScript version 3.0

unoptimized

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);        }    }}

## Acurity Architect

Using #HASH-OFF, OPTION OICC ="^" , CICC ="^"

 VAR sStatus: SHORTVAR sArray: SHORTVAR sCount: SHORTVAR sDoor: SHORTVAR sPass: SHORTVAR zIndex: STRINGVAR zState: STRING//SET sStatus = GET_UNUSED_ARRAY_HANDLE(sArray)SET sStatus = INIT_SORTED_ARRAY(sArray, 0, 0, 1)//DO sCount = 1 TO 100  DO sPass = 1 TO 100    SET sDoor = sCount * sPass    IF sDoor <= 100      SET zIndex = REPEAT("0", 3 - LENGTH(STR(sDoor))) + STR(sDoor)      SET sStatus = READ_ARRAY_REC("=", sArray, zIndex)      SET zState = "OPEN"      IF GET_STRING_SAY(sArray, 1) = "OPEN"        SET zState = "CLOSE"      ENDIF      //      SET sStatus = ADD_ARRAY_REC(sArray, zIndex)      SET sStatus = PUT_STRING_SAY(sArray, 1, zState)    ELSE      BREAK    ENDIF  ENDDOENDDO//SET zIndex = ""SET sStatus = READ_ARRAY_REC(">=", sArray, zIndex)DO WHILE sStatus = 0  >>Door:  ^zIndex^  State: ^GET_STRING_SAY(sArray, 1)^  SET sStatus = READ_ARRAY_REC("+", sArray, zIndex)ENDDO
Output:
Door:  001  State: OPEN
Door:  002  State: CLOSE
Door:  003  State: CLOSE
Door:  004  State: OPEN
Door:  005  State: CLOSE
Door:  006  State: CLOSE
Door:  007  State: CLOSE
Door:  008  State: CLOSE
Door:  009  State: OPEN
Door:  010  State: CLOSE
Door:  011  State: CLOSE
Door:  012  State: CLOSE
Door:  013  State: CLOSE
Door:  014  State: CLOSE
Door:  015  State: CLOSE
Door:  016  State: OPEN
Door:  017  State: CLOSE
Door:  018  State: CLOSE
Door:  019  State: CLOSE
Door:  020  State: CLOSE
Door:  021  State: CLOSE
Door:  022  State: CLOSE
Door:  023  State: CLOSE
Door:  024  State: CLOSE
Door:  025  State: OPEN
Door:  026  State: CLOSE
Door:  027  State: CLOSE
Door:  028  State: CLOSE
Door:  029  State: CLOSE
Door:  030  State: CLOSE
Door:  031  State: CLOSE
Door:  032  State: CLOSE
Door:  033  State: CLOSE
Door:  034  State: CLOSE
Door:  035  State: CLOSE
Door:  036  State: OPEN
Door:  037  State: CLOSE
Door:  038  State: CLOSE
Door:  039  State: CLOSE
Door:  040  State: CLOSE
Door:  041  State: CLOSE
Door:  042  State: CLOSE
Door:  043  State: CLOSE
Door:  044  State: CLOSE
Door:  045  State: CLOSE
Door:  046  State: CLOSE
Door:  047  State: CLOSE
Door:  048  State: CLOSE
Door:  049  State: OPEN
Door:  050  State: CLOSE
Door:  051  State: CLOSE
Door:  052  State: CLOSE
Door:  053  State: CLOSE
Door:  054  State: CLOSE
Door:  055  State: CLOSE
Door:  056  State: CLOSE
Door:  057  State: CLOSE
Door:  058  State: CLOSE
Door:  059  State: CLOSE
Door:  060  State: CLOSE
Door:  061  State: CLOSE
Door:  062  State: CLOSE
Door:  063  State: CLOSE
Door:  064  State: OPEN
Door:  065  State: CLOSE
Door:  066  State: CLOSE
Door:  067  State: CLOSE
Door:  068  State: CLOSE
Door:  069  State: CLOSE
Door:  070  State: CLOSE
Door:  071  State: CLOSE
Door:  072  State: CLOSE
Door:  073  State: CLOSE
Door:  074  State: CLOSE
Door:  075  State: CLOSE
Door:  076  State: CLOSE
Door:  077  State: CLOSE
Door:  078  State: CLOSE
Door:  079  State: CLOSE
Door:  080  State: CLOSE
Door:  081  State: OPEN
Door:  082  State: CLOSE
Door:  083  State: CLOSE
Door:  084  State: CLOSE
Door:  085  State: CLOSE
Door:  086  State: CLOSE
Door:  087  State: CLOSE
Door:  088  State: CLOSE
Door:  089  State: CLOSE
Door:  090  State: CLOSE
Door:  091  State: CLOSE
Door:  092  State: CLOSE
Door:  093  State: CLOSE
Door:  094  State: CLOSE
Door:  095  State: CLOSE
Door:  096  State: CLOSE
Door:  097  State: CLOSE
Door:  098  State: CLOSE
Door:  099  State: CLOSE
Door:  100  State: OPEN


unoptimized

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;

optimized

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;

## Agena

Translation of Algol W. Tested with Agena 2.9.5 Win32

# find the first few squares via the unoptimised door flipping methodscope     local doorMax := 100;    local door;    create register door( doorMax );     # set all doors to closed    for i to doorMax do door[ i ] := false od;     # repeatedly flip the doors    for i to doorMax do        for j from i to doorMax by i do door[ j ] := not door[ j ] od    od;     # display the results    for i to doorMax do if door[ i ] then write( " ", i ) fi od; print() epocs

## Aikido

 var doors = new int [100] foreach pass 100 {    for (var door = pass ; door < 100 ; door += pass+1) {        doors[door] = !doors[door]    }} var d = 1foreach door doors {    println ("door " + d++ + " is " + (door ? "open" : "closed")) }

## ALGOL 60

Works with: A60
 begin comment - 100 doors problem in ALGOL-60; boolean array doors[1:100];integer i, j;boolean open, closed; open := true;closed := not true; outstring(1,"100 Doors Problem\n"); comment - all doors are initially closed;for i := 1 step 1 until 100 do  doors[i] := closed; comment  cycle through at increasing intervals  and flip each door encountered;for i := 1 step 1 until 100 do  for j := i step i until 100 do    doors[j] := not doors[j]; comment - show which doors are open; outstring(1,"The open doors are:");for i := 1 step 1 until 100 do  if doors[i] then     outinteger(1,i); end
Output:
100 Doors Problem
The open doors are: 1  4  9  16  25  36  49  64  81  100


## ALGOL 68

unoptimized

# 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;

optimized

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)

## ALGOL W

begin    % find the first few squares via the unoptimised door flipping method   %     integer doorMax;    doorMax := 100;     begin        % need to start a new block so the array can have variable bounds   %         % array of doors - door( i ) is true if open, false if closed       %        logical array door( 1 :: doorMax );         % set all doors to closed                                           %        for i := 1 until doorMax do door( i ) := false;         % repeatedly flip the doors                                         %        for i := 1 until doorMax        do begin            for j := i step i until doorMax            do begin                door( j ) := not door( j )            end        end;         % display the results                                               %        i_w := 1; % set integer field width                                 %        s_w := 1; % and separator width                                     %        for i := 1 until doorMax do if door( i ) then writeon( i )     end end.
Output:
 1 4 9 16 25 36 49 64 81 100


## ALGOL-M

 BEGIN INTEGER ARRAY DOORS[1:100];INTEGER I, J, OPEN, CLOSED; OPEN := 1;CLOSED := 0; % ALL DOORS ARE INITIALLY CLOSED %FOR I := 1 STEP 1 UNTIL 100 DO  BEGIN    DOORS[I] := CLOSED;  END; % PASS THROUGH AND FLIP %FOR I := 1 STEP 1 UNTIL 100 DO  BEGIN     FOR J := I STEP I UNTIL 100 DO       BEGIN         DOORS[J] := 1 - DOORS[J];       END;  END; % SHOW RESULTS %WRITE("THE OPEN DOORS ARE:");WRITE("");FOR I := 1 STEP 1 UNTIL 100 DO  BEGIN    IF DOORS[I] = OPEN THEN      WRITEON(I);  END; END
Output:
THE OPEN DOORS ARE:
1     4     9    16    25    36    49    64    81   100


## 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

## APL

Works with: GNU APL
doors←{100⍴((⍵-1)⍴0),1}≠⌿⊃doors¨ ⍳100
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 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.

Works with: Dyalog APL
⍸≠⌿0=(⍳100)∘.|⍳100
Output:
1 4 9 16 25 36 49 64 81 100


## AppleScript

### Iteration

set is_open to {}repeat 100 times   set end of is_open to falseendrepeat 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  endendset open_doors to {}repeat with door from 1 to 100   if item door of is_open then     set end of open_doors to door   endendset text item delimiters to ", "display dialog "Open doors: " & open_doors

### Functional composition

-- FINAL DOOR STATES --------------------------------------------------------- -- finalDoors :: Int -> [(Int, Bool)]on finalDoors(n)     -- toggledCorridor :: [(Int, Bool)] -> (Int, Bool) -> Int -> [(Int, Bool)]    script toggledCorridor        on |λ|(a, _, k)             -- perhapsToggled :: Bool -> Int -> Bool            script perhapsToggled                on |λ|(x, i)                    if i mod k = 0 then                        {i, not item 2 of x}                    else                        {i, item 2 of x}                    end if                end |λ|            end script             map(perhapsToggled, a)        end |λ|    end script     set xs to enumFromTo(1, n)     foldl(toggledCorridor, ¬        zip(xs, replicate(n, {false})), xs)end finalDoors -- TEST ----------------------------------------------------------------------on run    -- isOpenAtEnd :: (Int, Bool) -> Bool    script isOpenAtEnd        on |λ|(door)            (item 2 of door)        end |λ|    end script     -- doorNumber :: (Int, Bool) -> Int    script doorNumber        on |λ|(door)            (item 1 of door)        end |λ|    end script     map(doorNumber, filter(isOpenAtEnd, finalDoors(100)))     --> {1, 4, 9, 16, 25, 36, 49, 64, 81, 100}end run  -- GENERIC FUNCTIONS --------------------------------------------------------- -- enumFromTo :: Int -> Int -> [Int]on enumFromTo(m, n)    if n < m then        set d to -1    else        set d to 1    end if    set lst to {}    repeat with i from m to n by d        set end of lst to i    end repeat    return lstend enumFromTo -- filter :: (a -> Bool) -> [a] -> [a]on filter(f, xs)    tell mReturn(f)        set lst to {}        set lng to length of xs        repeat with i from 1 to lng            set v to item i of xs            if |λ|(v, i, xs) then set end of lst to v        end repeat        return lst    end tellend filter -- foldl :: (a -> b -> a) -> a -> [b] -> aon foldl(f, startValue, xs)    tell mReturn(f)        set v to startValue        set lng to length of xs        repeat with i from 1 to lng            set v to |λ|(v, item i of xs, i, xs)        end repeat        return v    end tellend foldl -- map :: (a -> b) -> [a] -> [b]on map(f, xs)    tell mReturn(f)        set lng to length of xs        set lst to {}        repeat with i from 1 to lng            set end of lst to |λ|(item i of xs, i, xs)        end repeat        return lst    end tellend map -- min :: Ord a => a -> a -> aon min(x, y)    if y < x then        y    else        x    end ifend min -- Lift 2nd class handler function into 1st class script wrapper -- mReturn :: Handler -> Scripton mReturn(f)    if class of f is script then        f    else        script            property |λ| : f        end script    end ifend mReturn -- replicate :: Int -> a -> [a]on replicate(n, a)    set out to {}    if n < 1 then return out    set dbl to {a}     repeat while (n > 1)        if (n mod 2) > 0 then set out to out & dbl        set n to (n div 2)        set dbl to (dbl & dbl)    end repeat    return out & dblend replicate -- zip :: [a] -> [b] -> [(a, b)]on zip(xs, ys)    set lng to min(length of xs, length of ys)    set lst to {}    repeat with i from 1 to lng        set end of lst to {item i of xs, item i of ys}    end repeat    return lstend zip
Output:
{1, 4, 9, 16, 25, 36, 49, 64, 81, 100}

### Odd numbers of integer factors

The question of which doors are flipped an odd number of times reduces to the question of which numbers in the range have an odd number of integer factors (for an AppleScript implementation of integerFactors(n) see Factors of An Integer). Using map from the functional composition example above:

map(factorCountMod2, enumFromTo(1, 100)) on factorCountMod2(n)    {n, (length of integerFactors(n)) mod 2 = 1}end factorCountMod2

This, on inspection, and further reflection, then collapses to the even simpler question of which numbers are perfect squares, since all other numbers have an even number of integer factors (n factors below the square root, plus n paired cofactors above the square root). Using map and enumFromTo from the functional composition example above:

-- perfectSquaresUpTo :: Int -> [Int]on perfectSquaresUpTo(n)    script squared        -- (Int -> Int)        on |λ|(x)            x * x        end |λ|    end script     set realRoot to n ^ (1 / 2)    set intRoot to realRoot as integer    set blnNotPerfectSquare to not (intRoot = realRoot)     map(squared, enumFromTo(1, intRoot - (blnNotPerfectSquare as integer)))end perfectSquaresUpTo on run     perfectSquaresUpTo(100) end run
Output:
{1, 4, 9, 16, 25, 36, 49, 64, 81, 100}

## 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

## Argile

use std, array close all doorsfor 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]"

## ARM Assembly

Works with: as version Raspberry Pi

unoptimized

  /* ARM assembly Raspberry PI  *//*  program 100doors.s   */ /************************************//* Constantes                       *//************************************/.equ STDOUT, 1                                 @ Linux output console.equ EXIT,   1                                 @ Linux syscall.equ WRITE,  4                                 @ Linux syscall.equ NBDOORS,   100/*********************************//* Initialized data              *//*********************************/.datasMessResult:       .ascii "The door "sMessValeur:       .fill 11, 1, ' '            @ size => 11                      .asciz "is open.\n" /*********************************//* UnInitialized data            *//*********************************/.bss  stTableDoors:	.skip   4 * NBDOORS/*********************************//*  code section                 *//*********************************/.text.global main main:                                         @ entry of program     push {fp,lr}                              @ saves 2 registers     @ display first line    ldr r3,iAdrstTableDoors                   @ table address    mov r5,#1            1:    mov r4,r52:                                            @ begin loop    ldr r2,[r3,r4,lsl #2]                     @ read doors index r4    cmp r2,#0    moveq r2,#1                               @ if r2 = 0   1 -> r2    movne r2,#0                               @ if r2 = 1   0 -> r2    str r2,[r3,r4,lsl #2]                     @ store value of doors    add r4,r5                                 @ increment r4 with  r5 value    cmp r4,#NBDOORS                           @ number of doors ?    ble 2b                                    @ no -> loop    add r5,#1                                 @ increment the increment !!    cmp r5,#NBDOORS                           @ number of doors ?    ble 1b                                    @ no -> loop                                               @ loop display state doors    mov r4,#0              3:    ldr r2,[r3,r4,lsl #2]                     @ read state doors r4 index    cmp r2,#0    beq 4f    mov r0,r4                                 @ open -> display message    ldr r1,iAdrsMessValeur                    @ display value index    bl conversion10                           @ call function    ldr r0,iAdrsMessResult    bl affichageMess                          @ display message4:    add r4,#1    cmp r4,#NBDOORS    ble 3b                                    @ loop  100:                                          @ standard end of the program     mov r0, #0                                @ return code    pop {fp,lr}                               @restaur 2 registers    mov r7, #EXIT                             @ request to exit program    svc #0                                    @ perform the system call iAdrsMessValeur:                .int sMessValeuriAdrstTableDoors:		.int stTableDoorsiAdrsMessResult:		.int sMessResult /******************************************************************//*     display text with size calculation                         */ /******************************************************************//* r0 contains the address of the message */affichageMess:    push {r0,r1,r2,r7,lr}                     @ save  registres    mov r2,#0                                 @ counter length 1:                                            @ loop length calculation     ldrb r1,[r0,r2]                           @ read octet start position + index     cmp r1,#0                                 @ if 0 its over     addne r2,r2,#1                            @ else add 1 in the length     bne 1b                                    @ and loop                                               @ so here r2 contains the length of the message     mov r1,r0        			      @ address message in r1     mov r0,#STDOUT      		      @ code to write to the standard output Linux     mov r7, #WRITE                            @ code call system "write"     svc #0                                    @ call systeme     pop {r0,r1,r2,r7,lr}                      @ restaur des  2 registres */     bx lr                                     @ return  /******************************************************************//*     Converting a register to a decimal unsigned                */ /******************************************************************//* r0 contains value and r1 address area   *//* r0 return size of result (no zero final in area) *//* area size => 11 bytes          */.equ LGZONECAL,   10conversion10:    push {r1-r4,lr}                            @ save registers     mov r3,r1    mov r2,#LGZONECAL 1:	                                       @ start loop    bl divisionpar10U                          @unsigned  r0 <- dividende. quotient ->r0 reste -> r1    add r1,#48                                 @ digit	    strb r1,[r3,r2]                            @ store digit on area    cmp r0,#0                                  @ stop if quotient = 0     subne r2,#1                                @ else previous position    bne 1b	                               @ and loop    // and move digit from left of area    mov r4,#02:    ldrb r1,[r3,r2]    strb r1,[r3,r4]    add r2,#1    add r4,#1    cmp r2,#LGZONECAL    ble 2b    // and move spaces in end on area    mov r0,r4                                 @ result length     mov r1,#' '                               @ space	3:    strb r1,[r3,r4]                           @ store space in area    add r4,#1                                 @ next position    cmp r4,#LGZONECAL    ble 3b                                    @ loop if r4 <= area size 100:    pop {r1-r4,lr}                            @ restaur registres     bx lr                                     @return /***************************************************//*   division par 10   unsigned                    *//***************************************************//* r0 dividende   *//* r0 quotient */	/* r1 remainder  */divisionpar10U:    push {r2,r3,r4, lr}    mov r4,r0                                        @ save value    //mov r3,#0xCCCD                                 @ r3 <- magic_number  lower   @ for Raspberry pi 3    //movt r3,#0xCCCC                                @ r3 <- magic_number  upper   @ for Raspberry pi 3    ldr r3,iMagicNumber                              @ for Raspberry pi 1 2    umull r1, r2, r3, r0                             @ r1<- Lower32Bits(r1*r0) r2<- Upper32Bits(r1*r0)     mov r0, r2, LSR #3                               @ r2 <- r2 >> shift 3    add r2,r0,r0, lsl #2                             @ r2 <- r0 * 5     sub r1,r4,r2, lsl #1                             @ r1 <- r4 - (r2 * 2)  = r4 - (r0 * 10)    pop {r2,r3,r4,lr}    bx lr                                            @ leave function iMagicNumber:            .int 0xCCCCCCCD

optimized

 /*********************************************//* optimized version                         *//*********************************************//* ARM assembly Raspberry PI  *//*  program 100doors.s   */ /************************************//* Constantes                       *//************************************/.equ STDOUT, 1     @ Linux output console.equ EXIT,   1     @ Linux syscall.equ WRITE,  4     @ Linux syscall.equ NBDOORS,   100/*********************************//* Initialized data              *//*********************************/.datasMessResult:       .ascii "The door "sMessValeur:       .fill 11, 1, ' '                 @ size => 11                   .asciz "is open.\n" /*********************************//* UnInitialized data            *//*********************************/.bss  /*********************************//*  code section                 *//*********************************/.text.global main main:                                               @ entry of program     push {fp,lr}                                    @ saves 2 registers                                                     @ display first line    mov r5,#3                                       @ start value of increment    mov r4,#1                                       @ start doors                                                    @ loop display state doors1:    mov r0,r4                                       @ open -> display message    ldr r1,iAdrsMessValeur                          @ display value index    bl conversion10                                 @ call function    ldr r0,iAdrsMessResult    bl affichageMess                                @ display message    add r4,r5                                       @ add increment    add r5,#2                                       @ new increment    cmp r4,#NBDOORS    ble 1b                                          @ loop  100:   @ standard end of the program     mov r0, #0                                      @ return code    pop {fp,lr}                                     @ restaur 2 registers    mov r7, #EXIT                                   @ request to exit program    svc #0                                          @ perform the system call iAdrsMessValeur:                .int sMessValeuriAdrsMessResult:		.int sMessResult /******************************************************************//*     display text with size calculation                         */ /******************************************************************//* r0 contains the address of the message */affichageMess:    push {r0,r1,r2,r7,lr}                           @ save  registres    mov r2,#0                                       @ counter length 1:                                                  @ loop length calculation     ldrb r1,[r0,r2]                                 @ read octet start position + index     cmp r1,#0                                       @ if 0 its over     addne r2,r2,#1                                  @ else add 1 in the length     bne 1b                                          @ and loop                                                     @ so here r2 contains the length of the message     mov r1,r0        			            @ address message in r1     mov r0,#STDOUT      		            @ code to write to the standard output Linux     mov r7, #WRITE                                  @ code call system "write"     svc #0                                          @ call systeme     pop {r0,r1,r2,r7,lr}                            @ restaur des  2 registres */     bx lr                                           @ return  /******************************************************************//*     Converting a register to a decimal unsigned                */ /******************************************************************//* r0 contains value and r1 address area   *//* r0 return size of result (no zero final in area) *//* area size => 11 bytes          */.equ LGZONECAL,   10conversion10:    push {r1-r4,lr}                                 @ save registers     mov r3,r1    mov r2,#LGZONECAL 1:	                                            @ start loop    bl divisionpar10U                               @ unsigned  r0 <- dividende. quotient ->r0 reste -> r1    add r1,#48                                      @ digit	    strb r1,[r3,r2]                                 @ store digit on area    cmp r0,#0                                       @ stop if quotient = 0     subne r2,#1                                     @ else previous position    bne 1b	                                    @ and loop                                                    @ and move digit from left of area    mov r4,#02:    ldrb r1,[r3,r2]    strb r1,[r3,r4]    add r2,#1    add r4,#1    cmp r2,#LGZONECAL    ble 2b                                                    @ and move spaces in end on area    mov r0,r4                                       @ result length     mov r1,#' '                                     @ space	3:    strb r1,[r3,r4]                                 @ store space in area    add r4,#1                                       @ next position    cmp r4,#LGZONECAL    ble 3b                                          @ loop if r4 <= area size 100:    pop {r1-r4,lr}                                  @ restaur registres     bx lr                                           @return /***************************************************//*   division par 10   unsigned                    *//***************************************************//* r0 dividende   *//* r0 quotient */	/* r1 remainder  */divisionpar10U:    push {r2,r3,r4, lr}    mov r4,r0                                       @ save value    //mov r3,#0xCCCD                                @ r3 <- magic_number  lower   @ for raspberry 3    //movt r3,#0xCCCC                               @ r3 <- magic_number  upper   @ for raspberry 3    ldr r3,iMagicNumber                             @ for raspberry 1 2    umull r1, r2, r3, r0                            @ r1<- Lower32Bits(r1*r0) r2<- Upper32Bits(r1*r0)     mov r0, r2, LSR #3                              @ r2 <- r2 >> shift 3    add r2,r0,r0, lsl #2                            @ r2 <- r0 * 5     sub r1,r4,r2, lsl #1                            @ r1 <- r4 - (r2 * 2)  = r4 - (r0 * 10)    pop {r2,r3,r4,lr}    bx lr                                           @ leave function iMagicNumber:            .int 0xCCCCCCCD

## Arturo

isOpen: map 1..101 => false loop 1..100 'pass ->	loop (range.step:pass pass 100) 'door [		isOpen\[door]: not? isOpen\[door]	] loop 1..100 'x ->	if isOpen\[x] [		print ["Door" x "is open."]	]
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.

## Astro

var doors = falses(100) for a in 1..100: for b in a..a..100:    doors[b] = not doors[b] for a in 1..100:    print "Door $a is${(doors[a]) ? 'open.': 'closed.'}"

## BlitzMax

Works with: BlitzMax version 1.37

optimized

Graphics 640,480i=1While ((i*i)<=100)	a$=i*i DrawText a$,10,20*i	Print i*i	i=i+1 WendFlip WaitKey 

## BlooP

The currently available BlooP interpreters don't really allow iterating over cells with any level of ease, so instead I loop over each door in turn, running it through all 100 cycles and toggling it when it is a multiple of the step number.

 DEFINE PROCEDURE ''DIVIDE'' [A,B]:BLOCK 0: BEGIN  IF A < B, THEN:    QUIT BLOCK 0;  CELL(0) <= 1;  OUTPUT <= 1;  LOOP AT MOST A TIMES:  BLOCK 2: BEGIN    IF OUTPUT * B = A, THEN:    QUIT BLOCK 0;    OUTPUT <= OUTPUT + 1;    IF OUTPUT * B > A, THEN:    BLOCK 3: BEGIN      OUTPUT <= CELL(0);      QUIT BLOCK 0;    BLOCK 3: END;    CELL(0) <= OUTPUT;  BLOCK 2: END;BLOCK 0: END. DEFINE PROCEDURE ''MINUS'' [A,B]:BLOCK 0: BEGIN  IF A < B, THEN:    QUIT BLOCK 0;  LOOP AT MOST A TIMES:  BLOCK 1: BEGIN    IF OUTPUT + B = A, THEN:      QUIT BLOCK 0;    OUTPUT <= OUTPUT + 1;  BLOCK 1: END;BLOCK 0: END. DEFINE PROCEDURE ''MODULUS'' [A,B]:BLOCK 0: BEGIN  CELL(0) <= DIVIDE[A,B];  OUTPUT <= MINUS[A,CELL(0) * B];BLOCK 0: END.   DEFINE PROCEDURE ''TOGGLE'' [DOOR]:BLOCK 0: BEGIN  IF DOOR = 1, THEN:    QUIT BLOCK 0;  OUTPUT <= 1;BLOCK 0: END. DEFINE PROCEDURE ''NUMBERS'' [DOOR, COUNT]:BLOCK 0: BEGIN  CELL(0) <= 1; /*each number*/  OUTPUT <= 0; /*current door state*/   LOOP COUNT TIMES:  BLOCK 1: BEGIN     IF MODULUS[DOOR, CELL(0)] = 0, THEN:      OUTPUT <= TOGGLE[OUTPUT];     CELL(0) <= CELL(0) + 1;   BLOCK 1: END; BLOCK 0: END. DEFINE PROCEDURE ''DOORS'' [COUNT]:BLOCK 0: BEGIN   CELL(0) <= 1; /*each door*/  LOOP COUNT TIMES:  BLOCK 1: BEGIN     CELL(1) <= NUMBERS[CELL(0), COUNT];  /*iterate over the states of this door to get its final state*/    IF CELL(1) = 1, THEN: /*door state = open*/      PRINT[CELL(0), '   '];     CELL(0) <= CELL(0) + 1;   BLOCK 1: END;BLOCK 0: END. DOORS[100]; 
Output:
 > 1
> 4
> 9
> 16
> 25
> 36
> 49
> 64
> 81
> 100


## 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.

( 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 })

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.

( 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 }        ))

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.

## 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.

(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 (eql  (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))))

Unoptimized, imperative This is a version that closely follows the problem description and is still quite short. Of all the presented solutions it might be closest to "idiomatic Common Lisp".

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

Unoptimized, n-doors.

(defun doors (z &optional (w (make-list z)) (n 1))  (if (> n z) w (doors z (toggle w n z) (1+ n)))) (defun toggle (w m z)  (loop for a in w for n from 1 to z        collect (if (zerop (mod n m)) (not a) a))) > (doors 100)(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 NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL T)

Optimized, n-doors.

(defun doors (n)  (loop for a from 1 to n collect        (zerop (mod (sqrt a) 1)))) > (doors 100)(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 NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL T)

Optimized This is an optimized version, using the perfect square algorithm.

(defun 100-doors ()  (let ((doors (make-array 100)))    (dotimes (i 10)      (setf (svref doors (* i i)) t))    (dotimes (i 100)      (format t "door ~a: ~:[closed~;open~]~%" (1+ i) (svref doors i)))))

Optimized 2 Another optimized version, with finer granular separation of functionality (might be a bit excessive).

(defun perfect-square-list (n)                         "Generates a list of perfect squares from 0 up to n"  (loop for i from 1 to (isqrt n) collect (expt i 2)))  (defun print-doors (doors)  "Pretty prints the doors list"  (format T "~{~A ~A ~A ~A ~A ~A ~A ~A ~A ~A~%~}~%" doors)) (defun open-door (doors num open)  "Sets door at num to open"  (setf (nth (- num 1) doors) open))  (defun visit-all (doors vlist open)  "Visits and opens all the doors indicated in vlist"  (dolist (dn vlist doors)    (open-door doors dn open))) (defun start2 (&optional (size 100))                          "Start the program"  (print-doors   (visit-all (make-list size :initial-element '\#)              (perfect-square-list size)              '_)))

Optimized (2) This version displays a much more functional solution through the use of MAPCAR.

(let  ((i 0))    (mapcar (lambda (x)                (if (zerop (mod (sqrt (incf i)) 1))                    "_" "#"))            (make-list 100)))

## Component Pascal

BlackBox Component Builder

 MODULE Doors100;IMPORT StdLog; PROCEDURE Do*;VAR	i,j: INTEGER;	closed: ARRAY 101 OF BOOLEAN;BEGIN	(* initialization of closed to true *)	FOR i := 0 TO LEN(closed) - 1 DO closed[i] := TRUE END;	(* process *)	FOR i := 1 TO LEN(closed)  DO;		j := 1;		WHILE j < LEN(closed) DO			IF j MOD i = 0 THEN closed[j] := ~closed[j] END;INC(j)		END	END;	(* print results *)	i := 1;	WHILE  i < LEN(closed)  DO		IF (i - 1) MOD 10 = 0 THEN StdLog.Ln END;		IF closed[i] THEN StdLog.String("C ") ELSE StdLog.String("O ") END;		INC(i) 	END;END Do;END Doors100.  

Execute: ^Q Doors100.Do

Output:
O C C O C C C C O C
C C C C C O C C C C
C C C C O C C C C C
C C C C C O C C C C
C C C C C C C C O C
C C C C C C C C C C
C C C O C C C C C C
C C C C C C C C C C
O C C C C C C C C C
C C C C C C C C C O


## Coq

Basic solution:

Require Import List. Fixpoint rep {A} (a : A) n :=  match n with    | O => nil    | S n' => a::(rep a n')  end. Fixpoint flip (l : list bool) (n k : nat) : list bool :=  match l with    | nil => nil    | cons h t => match k with                | O => (negb h) :: (flip t n n)                | S k' => h :: (flip t n k')              end  end. Definition flipeach l n := flip l n n. Fixpoint flipwhile l n :=  match n with    | O => flipeach l 0    | S n' => flipwhile (flipeach l (S n')) n'  end. Definition prison cells := flipwhile (rep false cells) cells.

Optimized version ((n+1)^2 = n^2 + 2n + 1):

Require Import List. Fixpoint prisoo' nd n k accu :=  match nd with    | O => rev accu    | S nd' => let ra := match k with                 | O => (true, S n, (n + n))                 | S k' => (false, n, k')               end in               prisoo' nd' (snd (fst ra)) (snd ra) ((fst (fst ra))::accu)  end. Definition prisoo cells := prisoo' cells 1 0 nil.

Unit test:

Goal prison 100 = prisoo 100. compute. reflexivity. Qed.

Full proof at github:

Goal forall n, prison n = prisoo n. Abort.

## Cowgol

include "cowgol.coh"; var doors: uint8[101];  # one extra so we can start at 1var pass: @indexof doors;var door: @indexof doors; MemZero(&doors as [uint8], @bytesof doors); pass := 1;while pass <= 100 loop    door := pass;    while door <= 100 loop        doors[door] := 1-doors[door];        door := door + pass;    end loop;    pass := pass + 1;end loop; door := 1;while door <= 100 loop    if doors[door] == 1 then        print_i8(door);        print(" is open\n");    end if;    door := door + 1;end loop;
Output:
1 is open
4 is open
9 is open
16 is open
25 is open
36 is open
49 is open
64 is open
81 is open
100 is open

## Crystal

doors = Array.new(100, false) 1.upto(100) do |i|  i.step(by: i, to: 100) do |j|    doors[j - 1] = !doors[j - 1]  endend doors.each_with_index do |open, i|  puts "Door #{i + 1} is #{open ? "open" : "closed"}"end

## D

import std.stdio, std.algorithm, std.range; enum DoorState : bool { closed, open }alias Doors = DoorState[]; Doors flipUnoptimized(Doors doors) pure nothrow {    doors[] = DoorState.closed;     foreach (immutable i; 0 .. doors.length)        for (ulong 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) pure nothrow {    doors[] = DoorState.closed;    for (int i = 1; i ^^ 2 <= doors.length; i++)        doors[i ^^ 2 - 1] = DoorState.open;    return doors;} void main() {    auto doors = new Doors(100);     foreach (const open; [doors.dup.flipUnoptimized,                          doors.dup.flipOptimized])        iota(1, open.length + 1).filter!(i => open[i - 1]).writeln;}
Output:
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

Unoptimized. Demonstrates very basic language syntax/features. Program output allows to see what the code is doing:

 import std.stdio; void printAllDoors(bool[] doors){   // Prints the state of all the doors   foreach(i, door; doors)   {      writeln("#: ", i + 1, (door) ? " open" : " closed");      }}void main(){   bool[100] doors = false;   //Create 100 closed doors   for(int a = 0; a < 100; ++a) {      writefln("Pass #%s; visiting every %s door.", a + 1, a + 1);  // Optional	 for(int i = a; i < 100; i += (a + 1)) {	 writefln("Visited door %s", i + 1);  //Optional	 doors[i] = !doors[i];	 }      writeln();  // Optional      }   printAllDoors(doors);   // Prints the state of each door} 

## Dafny

The InitializeDoors function demonstrates some of Dafny's advanced features.

 datatype Door = Closed | Open method InitializeDoors(n:int) returns (doors:array<Door>)  // Precondition: n must be a valid array size.  requires n >= 0  // Postcondition: doors is an array, which is not an alias for any other  // object, with a length of n, all of whose elements are Closed. The "fresh"  // (non-alias) condition is needed to allow doors to be modified by the  // remaining code.  ensures doors != null && fresh(doors) && doors.Length == n  ensures forall j :: 0 <= j < doors.Length ==> doors[j] == Closed;{  doors := new Door[n];  var i := 0;  // Invariant: i is always a valid index inside the loop, and all doors less  // than i are Closed. These invariants are needed to ensure the second  // postcondition.  while i < doors.Length    invariant i <= doors.Length    invariant forall j :: 0 <= j < i ==> doors[j] == Closed;  {    doors[i] := Closed;    i := i + 1;  }} method Main (){  var doors := InitializeDoors(100);   var pass := 1;  while pass <= doors.Length  {    var door := pass;    while door < doors.Length    {      doors[door] := if doors[door] == Closed then Open else Closed;      door := door + pass;    }    pass := pass + 1;  }  var i := 0;  while i < doors.Length  {    print i, " is ", if doors[i] == Closed then "closed\n" else "open\n";    i := i + 1;  }} 

## Dart

unoptimized

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"); }} optimized version (including generating squares without multiplication) main() { for(int i=1,s=3;i<=100;i+=s,s+=2) print("door$i is open");}

comprehensible (not "code golf") version for a pedestrian language

## Hy

Translation of: Coco
(def doors (* [False] 100)) (for [pass (range (len doors))]  (for [i (range pass (len doors) (inc pass))]    (assoc doors i (not (get doors i))))) (for [i (range (len doors))]  (print (.format "Door {} is {}."    (inc i)    (if (get doors i) "open" "closed"))))

## I

software {	var doors = len(100) 	for pass over [1, 100]		var door = pass - 1		loop door < len(doors) {			doors[door] = doors[door]/0			door += pass		}	end 	for door,isopen in doors		if isopen			print("Door ",door+1,": open")		end	end	print("All other doors are closed")}

## 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.

 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

Optimized solution.

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

or

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

import Data.Vect -- Creates list from 0 to n (not including n) upTo : (m : Nat) -> Vect m (Fin m)upTo Z = []upTo (S n) = 0 :: (map FS (upTo n)) data DoorState = DoorOpen | DoorClosed toggleDoor : DoorState -> DoorStatetoggleDoor DoorOpen = DoorClosedtoggleDoor DoorClosed = DoorOpen isOpen : DoorState -> BoolisOpen DoorOpen = TrueisOpen DoorClosed = False initialDoors : Vect 100 DoorStateinitialDoors = fromList $map (\_ => DoorClosed) [1..100] iterate : (n : Fin m) -> Vect m DoorState -> Vect m DoorStateiterate n doors {m} = map (\(idx, doorState) => if ((S (finToNat idx)) mod (S (finToNat n))) == Z then toggleDoor doorState else doorState) (zip (upTo m) doors) -- Returns all doors left open at the endsolveDoors : List (Fin 100)solveDoors = findIndices isOpen$ foldl (\doors,val => iterate val doors) initialDoors (upTo 100) main : IO ()main = print $map (\n => S (finToNat n)) solveDoors ## Inform 7 Works with: Z-machine version 8 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. ## 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 FOREND MAIN  ## Io simple boolean list solution: doors := List clone100 repeat(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)) Optimized solution: (Range 1 to(10) asList) foreach(v, "Door #{v ** 2} is open." interpolate println) Sample 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. ## Ioke Unoptimized Object Oriented solution. 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 <- ([email protected]), (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 codex = NDoors Doors mimic(100)(1..100) each(n, x toggleThese(x numsToToggle(n)))x show ## Isabelle theory Scratch imports Mainbegin section‹100 Doors› datatype doorstate = Open | Closed fun toggle :: "doorstate ⇒ doorstate" where "toggle Open = Closed" | "toggle Closed = Open" fun walk :: "('a ⇒ 'a) ⇒ nat ⇒ nat ⇒ 'a list ⇒ 'a list" where "walk f _ _ [] = []" | "walk f every 0 (x#xs) = (f x) # walk f every every xs" | "walk f every (Suc n) (x#xs) = x # walk f every n xs" text‹Example: \<^const>‹toggle› every second door. (second = 1, because of 0 indexing)› lemma "walk toggle 1 1 [Open, Open, Open, Open, Open, Open] = [Open, Closed, Open, Closed, Open, Closed]" by code_simp text‹Example: \<^const>‹toggle› every third door.› lemma "walk toggle 2 2 [Open, Open, Open, Open, Open, Open] = [Open, Open, Closed, Open, Open, Closed]" by code_simp text‹Walking each door is essentially the same as the common \<^const>‹map› function.› lemma "walk f 0 0 xs = map f xs" by(induction xs) (simp)+ lemma walk_beginning: "walk f every n xs = (walk f every n (take (Suc n) xs)) @ (walk f every every (drop (Suc n) xs))" by(induction f every n xs rule:walk.induct) (simp)+ text‹A convenience definition to take the off-by-one into account and setting the starting position.› definition visit_every :: "('a ⇒ 'a) ⇒ nat ⇒ 'a list ⇒ 'a list" where "visit_every f every xs ≡ walk f (every - 1) (every - 1) xs" fun iterate :: "nat ⇒ (nat ⇒ 'a ⇒ 'a) ⇒ nat ⇒ 'a ⇒ 'a" where "iterate 0 _ _ a = a" | "iterate (Suc i) f n a = iterate i f (Suc n) (f n a)" text‹The 100 doors problem.› definition "onehundred_doors ≡ iterate 100 (visit_every toggle) 1 (replicate 100 Closed)" lemma "onehundred_doors = [Open, Closed, Closed, Open, Closed, Closed, Closed, Closed, Open, Closed, Closed, Closed, Closed, Closed, Closed, Open, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Open, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Open, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Open, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Open, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Open, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Open]" by code_simp text‹Filtering for the open doors, we get the same result as the Haskell implementation.› lemma "[(i, door) ← enumerate 1 onehundred_doors. door = Open] = [(1,Open),(4,Open),(9,Open),(16,Open),(25,Open),(36,Open),(49,Open),(64,Open),(81,Open),(100,Open)]" by code_simp section‹Equivalence to Haskell Implementation›text‹We will now present an alternative implementation, which is similar to the Haskell implementationon 🌐‹https://rosettacode.org/wiki/100_doors#Haskell›. We will prove, that the two behave the same;in general, not just for a fixed set of 100 doors.› definition map_every_start :: "('a ⇒ 'a) ⇒ nat ⇒ nat ⇒ 'a list ⇒ 'a list" where "map_every_start f every start xs ≡ map (λ(i, x). if i mod every = 0 then f x else x) (enumerate start xs)" definition visit_every_alt :: "('a ⇒ 'a) ⇒ nat ⇒ 'a list ⇒ 'a list" where "visit_every_alt f every xs ≡ map_every_start f every 1 xs" text‹Essentially, \<^term>‹start› and \<^term>‹start mod every› behave the same.› lemma map_every_start_cycle: "map_every_start f every (start + k*every) xs = map_every_start f every start xs" proof(induction xs arbitrary: start) case Nil show "map_every_start f every (start + k * every) [] = map_every_start f every start []" by(simp add: map_every_start_def) next case (Cons x xs) from Cons.IH[of "Suc start"] show "map_every_start f every (start + k * every) (x # xs) = map_every_start f every start (x # xs)" by(simp add: map_every_start_def) qed corollary map_every_start_cycle_zero: "map_every_start f every every xs = map_every_start f every 0 xs" using map_every_start_cycle[where k=1 and start=0, simplified] by blast lemma map_every_start_fst_zero: "map_every_start f every 0 (x # xs) = f x # map_every_start f every (Suc 0) xs" by(simp add: map_every_start_def) text‹ The first \<^term>‹n› elements are not processed by \<^term>‹f›, as long as \<^term>‹n› is less than the \<^term>‹every› cycle. › lemma map_every_start_skip_first: "Suc n < every ⟹ map_every_start f every (every - (Suc n)) (x # xs) = x # map_every_start f every (every - n) xs" by(simp add: map_every_start_def Suc_diff_Suc) lemma map_every_start_append: "map_every_start f n s (ds1 @ ds2) = map_every_start f n s ds1 @ map_every_start f n (s + length ds1) ds2" by(simp add: map_every_start_def enumerate_append_eq) text‹ The \<^const>‹walk› function and \<^const>‹map_every_start› behave the same, as long as the starting \<^term>‹n› is less than the \<^term>‹every› cycle, because \<^const>‹walk› allows pushing the start arbitrarily far and \<^const>‹map_every_start› only allows deferring the start within the \<^term>‹every› cycle. This generalization is needed to strengthen the induction hypothesis for the proof. › lemma walk_eq_map_every_start: "n ≤ every ⟹ walk f every n xs = map_every_start f (Suc every) (Suc every - n) xs" proof(induction xs arbitrary: n) case Nil show "walk f every n [] = map_every_start f (Suc every) (Suc every - n) []" by(simp add: map_every_start_def) next case (Cons x xs) then show "walk f every n (x # xs) = map_every_start f (Suc every) (Suc every - n) (x # xs)" proof(cases n) case 0 with Cons.IH show ?thesis by(simp add: map_every_start_cycle_zero map_every_start_fst_zero) next case (Suc n2) with Cons.prems map_every_start_skip_first[of n2 "Suc every"] have "map_every_start f (Suc every) (Suc every - Suc n2) (x # xs) = x # map_every_start f (Suc every) (Suc every - n2) xs" by fastforce with Suc Cons show ?thesis by(simp) qed qed corollary walk_eq_visit_every_alt: "walk f every every xs = visit_every_alt f (Suc every) xs" unfolding visit_every_alt_def using walk_eq_map_every_start by fastforce text‹ Despite their very different implementations, our alternative visit function behaves the same as our original visit function. Text the theorem includes \<^term>‹Suc every› to express that we exclude \<^term>‹every = 0›. › theorem visit_every_eq_visit_every_alt: "visit_every f (Suc every) xs = visit_every_alt f (Suc every) xs" unfolding visit_every_def using walk_eq_visit_every_alt by fastforce text‹Also, the \<^const>‹iterate› function we implemented above can be implemented by a simple \<^const>‹fold›.› lemma fold_upt_helper: assumes n_geq_1: "Suc 0 ≤ n" shows "fold f [Suc s..<n + s] (f s xs) = fold f [s..<n + s] xs" proof - from n_geq_1 have "[s..<n + s] = s#[Suc s..<n + s]" by (simp add: Suc_le_lessD upt_rec) from this have "fold f [s..<n + s] xs = fold f (s#[Suc s..<n + s]) xs" by simp also have "fold f (s#[Suc s..<n + s]) xs = fold f [Suc s..<n + s] (f s xs)" by(simp) ultimately show ?thesis by simp qed theorem iterate_eq_fold: "iterate n f s xs = fold f [s ..< n+s] xs" proof(induction n arbitrary: s xs) case 0 then show "iterate 0 f s xs = fold f [s..<0 + s] xs" by simp next case (Suc n) from Suc show "iterate (Suc n) f s xs = fold f [s..<Suc n + s] xs" by(simp add: fold_upt_helper not_less_eq_eq) qed section‹Efficient Implementation›text ‹As noted on this page, the only doors that remain open are those whose numbers are perfect squares.Yet, rosettacode does not want us to take this shortcut, since we want to compare implementationsacross programming languages. But we can prove that our code computes the same result as reportingall doors with a perfect square number as open:› theorem "[(i, door) ← enumerate 1 onehundred_doors. door = Open] = [(i*i, Open). i ← [1..<11]]" by code_simpend ## J unoptimized  ~:/ (100$ - {. 1:)"0 >:i.1001 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. alternative1 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 ...

optimized

   (e. *:) 1+i.1001 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. alternative1 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 ... with formatting  'these doors are open' ; >: I. (>:i.100) e. *: i.11+------------------------------------------------+¦these doors are open¦1 4 9 16 25 36 49 64 81 100¦+------------------------------------------------+  ## Janet  (def doors (seq [_ :range [0 100]] false)) (loop [pass :range [0 100] door :range [pass 100 (inc pass)]] (put doors door (not (doors door)))) (print "open doors: " ;(seq [i :range [0 100] :when (doors i)] (string (inc i) " ")))  Output: open doors: 1 4 9 16 25 36 49 64 81 100  ## Java ### With an array of boolean class HundredDoors { public static void main(String[] args) { boolean[] doors = new boolean[101]; for (int i = 1; i < doors.length; i++) { for (int j = i; j < doors.length; j += i) { doors[j] = !doors[j]; } } for (int i = 1; i < doors.length; i++) { if (doors[i]) { System.out.printf("Door %d is open.%n", i); } } }} ### With a BitSet import java.util.BitSet; public class HundredDoors { public static void main(String[] args) { final int n = 100; var a = new BitSet(n); for (int i = 1; i <= n; i++) { for (int j = i - 1; j < n; j += i) { a.flip(j); } } a.stream().map(i -> i + 1).forEachOrdered(System.out::println); }} ### Only print the result class HundredDoors { public static void main(String[] args) { for (int i = 1; i <= 10; i++) System.out.printf("Door %d is open.%n", i * i); }} 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. If only printing the result is required, using streams. import java.util.stream.Collectors;import java.util.stream.IntStream; class HundredDoors { public static void main(String args[]) { String openDoors = IntStream.rangeClosed(1, 100) .filter(i -> Math.pow((int) Math.sqrt(i), 2) == i) .mapToObj(Integer::toString) .collect(Collectors.joining(", ")); System.out.printf("Open doors: %s%n", openDoors); }}  Output: Open doors: 1, 4, 9, 16, 25, 36, 49, 64, 81, 100  ## JavaScript ### ES5 #### Iterative var doors=[];for (var i=0;i<100;i++) doors[i]=false;for (var i=1;i<=100;i++) for (var i2=i-1,g;i2<100;i2+=i) doors[i2]=!doors[i2];for (var i=1;i<=100;i++) console.log("Door %d is %s",i,doors[i-1]?"open":"closed") #### Functional Composition Naive search (function (n) { "use strict"; function finalDoors(n) { var lstRange = range(1, n); return lstRange .reduce(function (a, _, k) { var m = k + 1; return a.map(function (x, i) { var j = i + 1; return [j, j % m ? x[1] : !x[1]]; }); }, zip( lstRange, replicate(n, false) )); }; function zip(xs, ys) { return xs.length === ys.length ? ( xs.map(function (x, i) { return [x, ys[i]]; }) ) : undefined; } function replicate(n, a) { var v = [a], o = []; if (n < 1) return o; while (n > 1) { if (n & 1) o = o.concat(v); n >>= 1; v = v.concat(v); } return o.concat(v); } function range(m, n, delta) { var d = delta || 1, blnUp = n > m, lng = Math.floor((blnUp ? n - m : m - n) / d) + 1, a = Array(lng), i = lng; if (blnUp) while (i--) a[i] = (d * i) + m; else while (i--) a[i] = m - (d * i); return a; } return finalDoors(n) .filter(function (tuple) { return tuple[1]; }) .map(function (tuple) { return { door: tuple[0], open: tuple[1] }; }); })(100); #### Optimized (iterative) for (var door = 1; door <= 100; door++) { var sqrt = Math.sqrt(door); if (sqrt === (sqrt | 0)) { console.log("Door %d is open", door); }} Simple for loop. Optimizing the optimized? for(var door=1;i<10/*Math.sqrt(100)*/;i++){ console.log("Door %d is open",i*i);} #### Optimized (functional) The question of which doors are flipped an odd number of times reduces to the question of which numbers have an odd number of integer factors. We can simply search for these: (function (n) { "use strict"; return range(1, 100) .filter(function (x) { return integerFactors(x) .length % 2; }); function integerFactors(n) { var rRoot = Math.sqrt(n), intRoot = Math.floor(rRoot), lows = range(1, intRoot) .filter(function (x) { return (n % x) === 0; }); return lows.concat(lows.map(function (x) { return n / x; }) .reverse() .slice((rRoot === intRoot) | 0)); } function range(m, n, delta) { var d = delta || 1, blnUp = n > m, lng = Math.floor((blnUp ? n - m : m - n) / d) + 1, a = Array(lng), i = lng; if (blnUp) while (i--) a[i] = (d * i) + m; else while (i--) a[i] = m - (d * i); return a; }})(100); Or we can note, on inspection and further reflection, that only perfect squares have odd numbers of integer factors - all other numbers have only matched pairs of factors - low factors below the non-integer square root, and the corresponding quotients above the square root. In the case of perfect squares, the additional integer square root (not paired with any other factor than itself) makes the total number of distinct factors odd. (function (n) { "use strict"; return perfectSquaresUpTo(100); function perfectSquaresUpTo(n) { return range(1, Math.floor(Math.sqrt(n))) .map(function (x) { return x * x; }); } function range(m, n, delta) { var d = delta || 1, blnUp = n > m, lng = Math.floor((blnUp ? n - m : m - n) / d) + 1, a = Array(lng), i = lng; if (blnUp) while (i--) a[i] = (d * i) + m; else while (i--) a[i] = m - (d * i); return a; }})(100); ### ES6  Array.apply(null, { length: 100 }) .map((v, i) => i + 1) .forEach(door => { var sqrt = Math.sqrt(door); if (sqrt === (sqrt | 0)) { console.log("Door %d is open", door); } }); // Array comprehension style[ for (i of Array.apply(null, { length: 100 })) i ].forEach((_, i) => { var door = i + 1 var sqrt = Math.sqrt(door); if (sqrt === (sqrt | 0)) { console.log("Door %d is open", door); } }); The result is always: 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 Or using a more general function for listing perfect squares: (function (n) { // ONLY PERFECT SQUARES HAVE AN ODD NUMBER OF INTEGER FACTORS // (Leaving the door open at the end of the process) return perfectSquaresUpTo(n); // perfectSquaresUpTo :: Int -> [Int] function perfectSquaresUpTo(n) { return range(1, Math.floor(Math.sqrt(n))) .map(x => x * x); } // GENERIC // range(intFrom, intTo, optional intStep) // Int -> Int -> Maybe Int -> [Int] function range(m, n, step) { let d = (step || 1) * (n >= m ? 1 : -1); return Array.from({ length: Math.floor((n - m) / d) + 1 }, (_, i) => m + (i * d)); } })(100); Output: [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] ## jq jq arrays have 0 as their index origin, but in the following, the 100 doors are numbered from 1 to 100. Solution by simulation # Solution for n doors:def doors(n): def print: . as$doors    | range(1; length+1)    | if $doors[.] then "Door \(.) is open" else empty end; [range(n+1)|null] as$doors  | reduce range(1; n+1) as $run ($doors; reduce range($run; n+1;$run ) as $door ( .; .[$door] = (.[$door] | not) ) ) | print ;  Analytical solution # Solution for 100 doors:def solution: range(1;11) | "Door \(. * .) is open";  ## Julia Simple: • falses(100) creates a 100-element Bool array filled with false values, • 'b in a:a:100' translates to 'start:step:end', • string concatenation by '*'. doors = falses(100)for a in 1:100, b in a:a:100 doors[b] = !doors[b]endfor a = 1:100 println("Door$a is " * (doors[a] ? "open." : "closed.")) end

Gimmicky-optimized:

## Klong

### unoptimized

 flip::{,/{(1-*x),1_x}'x:#y}i::0;(100{i::i+1;flip(i;x)}:*100:^0)?1

### optimized

 (1+!9)^2

## Kotlin

fun oneHundredDoors(): List<Int> {    val doors = BooleanArray(100, { false })    for (i in 0..99) {        for (j in i..99 step (i + 1)) {            doors[j] = !doors[j]        }    }    return doors        .mapIndexed { i, b -> i to b }        .filter { it.second }        .map { it.first + 1 }}

## KQL

range InitialDoor from 1 to 100 step 1| extend DoorsVisited=range(InitialDoor, 100, InitialDoor)| mvexpand DoorVisited=DoorsVisited to typeof(int)| summarize VisitCount=count() by DoorVisited| project Door=DoorVisited, IsOpen=(VisitCount % 2) == 1

## 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.

## langur

### not optimized

Works with: langur version 0.8.11
var .doors = arr 100, false for .i of .doors {    for .j = .i; .j <= len(.doors); .j += .i {        .doors[.j] = not .doors[.j]    }} writeln wherekeys .doors

We could also use a for loop value to produce the output (instead of the wherekeys function), as in the following example.

Works with: langur version 0.8.1
writeln for[=[]] .i of .doors { if(.doors[.i]: _for ~= [.i]) }

Or, we could use the foldfrom() function to produce the output.

writeln foldfrom(f if(.b: .a~[.c]; .a), [], .doors, series 1..len .doors)

### optimized

writeln map(f .x ^ 2, series 1..10)
Works with: langur version 0.8.11
writeln map f{^2}, 1..10
Output:
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

## lambdatalk

Translation from Python

 1) unoptimized version {def doors {A.new  {S.map {lambda {} false} {S.serie 1 100}}}}-> doors {def toggle {lambda {:i :a}  {let { {_ {A.set! :i {not {A.get :i :a}} :a} }}}}}-> toggle {S.map {lambda {:b}  {S.map {lambda {:i} {toggle :i {doors}}}   {S.serie :b 99 {+ :b 1}}}}   {S.serie 0 99}} -> {S.replace \s by space in  {S.map {lambda {:i} {if {A.get :i {doors}} then {+ :i 1} else}}   {S.serie 0 99}}} -> 1 4 9 16 25 36 49 64 81 100 2.2) optimized version {S.replace \s by space in  {S.map {lambda {:i}         {let { {:root {sqrt :i}} }               {if {= :root {round :root}}                then {* :root :root}               else}}}        {S.serie 1 100}}} -> 1 4 9 16 25 36 49 64 81 100

## Lasso

### Loop

loop(100) => {^	local(root = math_sqrt(loop_count))	local(state = (#root == math_ceil(#root) ? '<strong>open</strong>' | 'closed'))	#state != 'closed' ? 'Door ' + loop_count + ': ' + #state + '<br>'^}
Output:
Door 1: open
Door 4: open
Door 9: open
Door 16: open
Door 25: open
Door 36: open
Door 49: open
Door 64: open
Door 81: open
Door 100: open

## Latitude

use 'format importAllSigils. doors := Object clone.doors missing := { False. }.doors check := {  self slot ($1 ordinal).}.doors toggle := { self slot ($1 ordinal) = self slot ($1 ordinal) not.}.1 upto 101 do { takes '[i]. local 'j = i. while { j <= 100. } do { doors toggle (j). j = j + i. }.}.$stdout printf: ~fmt "The open doors are: ~A", 1 upto 101 filter { doors check. } to (Array).

## 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.

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

## Liberty BASIC

dim doors(100)for pass = 1 to 100    for door = pass to 100 step pass        doors(door) = not(doors(door))    next doornext passprint "open doors ";for door = 1 to 100    if doors(door) then print door;"  ";next door

## Mirah

import java.util.ArrayList class Door	:state 	def initialize		@state=false	end 	def closed?; [email protected]; 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); endend doors=ArrayList.new1.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    endend i = 0doors.each do |door|     puts "Door #{i+1} is #{door}."    i+=1end

## Myrddin

 use std const main = {	var isopen	: bool[100] 	std.slfill(isopen[:], false)	for var i = 0; i < isopen.len; i++		for var j = i; j < isopen.len; j += i + 1			isopen[j] = !isopen[j]		;;	;; 	for var i = 0; i < isopen.len; i++		if isopen[i]			std.put("door {} is open\n", i + 1)		;;	;;}
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


## MySQL

 DROP PROCEDURE IF EXISTS one_hundred_doors; DELIMITER | CREATE PROCEDURE one_hundred_doors (n INT)BEGIN  DROP TEMPORARY TABLE IF EXISTS doors;   CREATE TEMPORARY TABLE doors (    id INTEGER NOT NULL,    open BOOLEAN DEFAULT FALSE,    PRIMARY KEY (id)  );   SET @i = 1;  create_doors: LOOP    INSERT INTO doors (id, open) values (@i, FALSE);    SET @i = @i + 1;    IF @i > n THEN      LEAVE create_doors;    END IF;  END LOOP create_doors;   SET @i = 1;  toggle_doors: LOOP    UPDATE doors SET open = NOT open WHERE MOD(id, @i) = 0;    SET @i = @i + 1;    IF @i > n THEN      LEAVE toggle_doors;    END IF;  END LOOP toggle_doors;   SELECT id FROM doors WHERE open;END| DELIMITER ; CALL one_hundred_doors(100);
Output:
+-----+
| id  |
+-----+
|   1 |
|   4 |
|   9 |
|  16 |
|  25 |
|  36 |
|  49 |
|  64 |
|  81 |
| 100 |
+-----+
10 rows in set (0.02 sec)


## Nanoquery

// allocate a boolean array with all closed doors (false)// we need 101 since there will technically be a door 0doors = {false} * 101 // loop through all the step lengths (1-100)for step in range(1, 100)	// loop through all the doors, stepping by step	for door in range(0, len(doors) - 1, step)		// change the state of the current door		doors[door] = !doors[door]	end forend for // loop through and print the doors that are open, skipping door 0for i in range(1, len(doors) - 1)	// if the door is open, display it	if doors[i]		println "Door " + i + " is open."	end ifend for

## NetRexx

unoptimized

/* NetRexx */options replace format comments java crossref 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_

optimized (Based on the Java 'optimized' version)

Translation of: Java
/* NetRexx */options replace format comments java crossref 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_

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

Translation of: Java
/* 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

optimized 3

/* NetRexx */ loop i = 1 to 10   say 'Door Nr.' i * i 'is open.'  end i

## newLISP

(define (status door-num)    (let ((x (int (sqrt door-num))))     (if       (= (* x x) door-num) (string "Door " door-num " Open")       (string "Door " door-num " Closed")))) (dolist (n (map status (sequence 1 100)))  (println n))

Not optimized:

 (set 'Doors (array 100))  ;; Default value: nil (Closed) (for (x 0 99)    (for (y x 99 (+ 1 x))        (setf (Doors y) (not (Doors y))))) (for (x 0 99)  ;; Display open doors    (if (Doors x)        (println (+ x 1) " : Open")))

Output:

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


## Nial

unoptimized solution (works with Q'Nial7):

Output of the boolean array showing the status of the doors. Truth values in Nial arrays are shown as l(true) and o(false):

     n:=100;reduce xor (count n eachright mod count n eachall<1)looloooolooooooloooooooolooooooooooloooooooooooolooooooooooooooloooooooooooooooo looooooooooooooooool

Indices of the open doors:

     true findall (n:=100;reduce xor (count n eachright mod count n eachall<1))+11 4 9 16 25 36 49 64 81 100

optimized solution:

     count 10 power 21 4 9 16 25 36 49 64 81 100

## Nim

unoptimized:

from strutils import % const numDoors = 100var doors: array[1..numDoors, bool] for pass in 1..numDoors:  for door in countup(pass, numDoors, pass):    doors[door] = not doors[door] for door in 1..numDoors:  echo "Door $1 is$2." % [$door, if doors[door]: "open" else: "closed"] Challenging C++'s compile time computation: https://rosettacode.org/wiki/100_doors#C.2B.2B outputString is evaluated at compile time. Check the resulting binary in case of doubt. from strutils import % const numDoors = 100var doors {.compileTime.}: array[1..numDoors, bool] proc calcDoors(): string = for pass in 1..numDoors: for door in countup(pass, numDoors, pass): doors[door] = not doors[door] for door in 1..numDoors: result.add("Door$1 is $2.\n" % [$door, if doors[door]: "open" else: "closed"]) const outputString: string = calcDoors() echo outputString

## Oberon

MODULE Doors;  IMPORT Out;   PROCEDURE Do*;  (* In Oberon an asterisk after an identifier is an export mark *)    CONST N = 100; len = N + 1;    VAR i, j: INTEGER;      closed: ARRAY len OF BOOLEAN;  (* Arrays in Oberon always start with index 0; closed[0] is not used *)  BEGIN    FOR i := 1 TO N DO closed[i] := TRUE END;    FOR i := 1 TO N DO      j := 1;      WHILE j < len DO        IF j MOD i = 0 THEN closed[j] := ~closed[j] END; INC(j)  (* ~ = NOT *)      END    END;    (* Print a state diagram of all doors *)    FOR i := 1 TO N DO       IF (i - 1) MOD 10 = 0 THEN Out.Ln END;      IF closed[i] THEN Out.String("- ") ELSE Out.String("+ ") END    END;  Out.Ln;    (* Print the numbers of the open doors *)    FOR i := 1 TO N DO       IF ~closed[i] THEN Out.Int(i, 0); Out.Char(" ") END    END;  Out.Ln  END Do; END Doors.

Execute: Doors.Do

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


## Objeck

optimized

 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();        };      };    }  }}

## Objective-C

A basic implementation in Objective-C:

This is a very basic Objective-C sample that shows the usage of standard types and classes such as NSInteger and NSMutableArray.

It uses modern Objective-C syntax such as literals, blocks, and a compiler module import statement.

 @import Foundation; int main(int argc, const char * argv[]) {    @autoreleasepool {         // Create a mutable array        NSMutableArray *doorArray = [@[] mutableCopy];         // Fill the doorArray with 100 closed doors        for (NSInteger i = 0; i < 100; ++i) {            doorArray[i] = @NO;        }         // Do the 100 passes        for (NSInteger pass = 0; pass < 100; ++pass) {            for (NSInteger door = pass; door < 100; door += pass+1) {                doorArray[door] = [doorArray[door]  isEqual: @YES] ? @NO : @YES;            }        }         // Print the results        [doorArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {            if ([obj isEqual: @YES]) {                NSLog(@"Door number %lu is open", idx + 1);            }        }];    }}

A more typical implementation in Objective-C:

This example is more along the lines of what typical Objective-C program would look like.

Language features used include:

• MVC design pattern with separate classes for the data model, user interface, and controller (Here, main steps in to represent the controller class.)
• Class category to extend the standard NSMutableArray class to add doors without a subclass
• Class inheritance in the DoorViewClass when subclassing NSObject
• Pragma mark statements for IDE navigation in Xcode

In a real world program classes are normally separated into different files.

 @import Foundation; #pragma mark - Classes////////////////////////////////////////////////////// Model class header - A we are using a category to add a method to MSMutableArray@interface NSMutableArray (DoorModelExtension) - (void)setNumberOfDoors:(NSUInteger)doors; @end // Model class implementation@implementation NSMutableArray (DoorModelExtension) - (void)setNumberOfDoors:(NSUInteger)doors {    // Fill the doorArray with 100 closed doors    for (NSInteger i = 0; i < doors; ++i) {        self[i] = @NO;    }}@end//////////////////////////////////////////////////// // View class header - A simple class to handle printing our values@interface DoorViewClass : NSObject - (void)printResultsOfDoorTask:(NSMutableArray *)doors; @end // View class implementation@implementation DoorViewClass - (void)printResultsOfDoorTask:(NSMutableArray *)doors {     // Print the results, using an enumeration block for easy index tracking    [doors enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {        if ([obj isEqual: @YES]) {            NSLog(@"Door number %lu is open", idx + 1);        }    }];} @end//////////////////////////////////////////////////// #pragma mark - main// With our classes set we can use them from our controller, in this case mainint main(int argc, const char * argv[]) {     // Init our classes    NSMutableArray *doorArray = [NSMutableArray array];    DoorViewClass *doorView = [DoorViewClass new];     // Use our class category to add the doors    [doorArray setNumberOfDoors:100];     // Do the 100 passes    for (NSUInteger pass = 0; pass < 100; ++pass) {        for (NSUInteger door = pass; door < 100; door += pass+1) {            doorArray[door] = [doorArray[door]  isEqual: @YES] ? @NO : @YES;        }    }     // Print the results    [doorView printResultsOfDoorTask:doorArray]; }

## OCaml

unoptimized

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))

optimized

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))

This variant is more functional style (loops are recursions), unoptimized, and we do rather 100 passes on first element, then 100 * second, to avoid mutable data structures and many intermediate lists.

type door = Open | Closed    (* human readable code *) let flipdoor = function Open -> Closed | Closed -> Open let string_of_door =         function Open -> "is open." | Closed -> "is closed." let printdoors ls =  let f i d = Printf.printf "Door %i %s\n" (i + 1) (string_of_door d)  in List.iteri f ls let outerlim = 100let innerlim = 100 let rec outer cnt accu =  let rec inner i door = match i > innerlim with (* define inner loop *)    | true  -> door                             | false -> inner (i + 1) (if (cnt mod i) = 0 then flipdoor door else door)  in (* define and do outer loop *)  match cnt > outerlim with  | true  -> List.rev accu  | false -> outer  (cnt + 1)  (inner 1 Closed :: accu) (* generate new entries with inner *) let () = printdoors (outer 1 [])

## Octave

doors = false(100,1);for i = 1:100  for j = i:i:100    doors(j) = !doors(j);  endforendforfor i = 1:100  if ( doors(i) )    s = "open";  else    s = "closed";  endif  printf("%d %s\n", i, s);endfor

See also the solutions in Matlab. They will work in Octave, too.

## Oforth

: doors| i j l |   100 false Array newWith dup ->l   100 loop: i [       i 100 i step: j [ l put ( j , j l at not ) ]       ] ;

## Ol

 (define (flip doors every)   (map (lambda (door num)            (mod (+ door (if (eq? (mod num every) 0) 1 0)) 2))      doors      (iota (length doors) 1))) (define doors   (let loop ((doors (repeat 0 100)) (n 1))      (if (eq? n 100)         doors         (loop (flip doors n) (+ n 1))))) (print "100th doors: " doors)

Output:

100th doors: (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 0)


## OpenEdge/Progress

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.

## OxygenBasic

def    doors 100
int    door[doors],i ,j, c
string cr,tab,pr
'
for i=1 to doors
for j=i to doors step i
door[j]=1-door[j]
if door[j] then c++ else c--
next
next
'
cr=chr(13) chr(10)
pr="Doors Open: " c cr cr
'
for i=1 to doors
if door[i] then pr+=i cr
next
print pr


## 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  }

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.

 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.")))

Optimized version.

for(n=1,sqrt(100),print("Door ",n^2," is open."))

Unoptimized version.

 doors =vector(100);print("open doors are : ");for(i=1,100,for(j=i,100,doors[j]=!doors[j];j +=i-1))for(k=1,100,if(doors[k]==1,print1(" ",k)))

Output:

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

## 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');   endend.

Optimized version.

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.  ## Perl unoptimized Works with: Perl version 5.x 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; semi-optimized Works with: Perl version 5.x This version flips doors, but doesn't visit (iterate over) doors that aren't toggled. Note: I represent open doors as 0 and closed as 1 just for preference. (When I print it as a bit vector, 0 looks more like an open door to me.)  #!/usr/bin/perluse strict;use warnings; my @doors = (1) x 100;for my$N (1 .. 100) {   $doors[$_]=1-$doors[$_] for map { $_*$N - 1 } 1 .. int(100/$N);}print join("\n", map { "Door$_ is Open" } grep { ! $doors[$_-1] } 1 .. 100), "\n";print "The rest are closed\n";

optimized

Works with: Perl version 5.x
print "Door $_ is open\n" for map$_**2, 1 .. 10;
print "Door $_ is ", qw"closed open"[int sqrt == sqrt], "\n" for 1..100; while( ++$i <= 100 ){    $root = sqrt($i);    if ( int( $root ) ==$root )    {        print "Door $i is open\n"; } else { print "Door$i is closed\n";    }}

## Perl5i

 use perl5i::2; package doors {   use perl5i::2;  use Const::Fast;   const my $OPEN => 1; const my$CLOSED => 0;   # ----------------------------------------  # Constructor: door->new( @args );  # input: N - how many doors?  # returns: door object  #  method new($class: @args ) { my$self = bless {}, $class;$self->_init( @args );    return $self; } # ---------------------------------------- # class initializer. # input: how many doors? # sets N, creates N+1 doors ( door zero is not used ). # method _init($N ) {    $self->{N} =$N;    $self->{doors} = [ ($CLOSED) x ($N+1) ]; } # ---------------------------------------- #$self->toggle( $door_number ); # input: number of door to toggle. # OPEN a CLOSED door; CLOSE an OPEN door. # method toggle($which ) {    $self->{doors}[$which] = ( $self->{doors}[$which] == $OPEN ?$CLOSED                               : $OPEN ); } # ---------------------------------------- #$self->toggle_n( $cycle ); # input: number. # Toggle doors 0,$cycle, 2 * $cycle, 3 *$cycle, .. $self->{N} # method toggle_n($n ) {    $self->toggle($_)      for map { $n *$_ }          ( 1 .. int( $self->{N} /$n) );   }   # ----------------------------------------  # $self->toggle_all(); # Toggle every door, then every other door, every third door, ... # method toggle_all() {$self->toggle_n( $_ ) for ( 1 ..$self->{N} );  }    # ----------------------------------------  # $self->print_open(); # Print list of which doors are open. # method print_open() { say join ', ', grep {$self->{doors}[$_] ==$OPEN } ( 1 ... $self->{N} ); }} # ----------------------------------------------------------------------# Main Thread#my$doors = doors->new(100);$doors->toggle_all();$doors->print_open();

## Phix

### unoptimised

sequence doors = repeat(false,100)

for i=1 to 100 do
for j=i to 100 by i do
doors[j] = not doors[j]
end for
end for

for i=1 to 100 do
if doors[i] == true then
printf(1,"Door #%d is open.\n", i)
end if
end for

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.


### optimised

function doors(integer n)
-- returns the perfect squares<=n
integer door = 1, step = 1
sequence res = {}
while door<=n do
res &= door
step += 2
door += step
end while
return res
end function

?doors(100)

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


## Phixmonti

101 var l                           0 l repeat                       l for    var s    s l s 3 tolist    for        var i        i get not i set    endforendfor l for    var i    i get    if        i print " " print    endifendfor

Another way

100 var n   /# Number of doors #/0 n repeat  /# Make the doors #/ n for    dup    sqrt int    dup * over == if 1 swap set else drop endifendfor n for    "The door " print dup print " is " print    get if "OPEN." else "closed." endif print nlendfor "Time elapsed: " print msec print " seconds" print nl

## PHL

### unoptimized

module doors; extern printf; @Integer main [	@Array<@Boolean> doors = new @Array<@Boolean>.init(100);	var i = 1;	while (i <= 100) {		var j = i-1;		while (j < 100) {			doors.set(j, doors.get(j)::not);			j = j + i;		}		i = i::inc;	}	i = 0;	while (i < 100) {		printf("%i %s\n", i+1, iif(doors.get(i), "open", "closed"));		i = i::inc;	}	return 0;]

### optimized

Translation of: C#
module var; extern printf; @Integer main [	var door = 1;	var incrementer = 0;	var current = 1;        while (current <= 100)        {		printf("Door %i ", current);		if (current == door)		{			printf("open\n");			incrementer = incrementer::inc;			door = door + 2 * incrementer + 1;		}		else			printf("closed\n"); 		current = current + 1;         } 	return 0;]

## PHP

See: Demo optimized

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

unoptimized

<?php$doors = array_fill(1, 100, false);for ($pass = 1; $pass <= 100; ++$pass) {	for ($nr = 1;$nr <= 100; ++$nr) { if ($nr % $pass == 0) {$doors[$nr] = !$doors[$nr]; } }}for ($nr = 1; $nr <= 100; ++$nr)	printf("Door %d: %s\n", $nr, ($doors[nr])?'open':'closed');?> ## Picat Non-optimized: doors(N) => Doors = new_array(N), foreach(I in 1..N) Doors[I] := 0 end, foreach(I in 1..N) foreach(J in I..I..N) Doors[J] := 1^Doors[J] end, if N <= 10 then print_open(Doors) end end, println(Doors), print_open(Doors), nl. print_open(Doors) => println([I : I in 1..Doors.length, Doors[I] == 1]).  optimized version 1: doors_opt(N) => foreach(I in 1..N) Root = sqrt(I), println([I, cond(Root == 1.0*round(Root), open, closed)]) end, nl.  optimized version 2: doors_opt2(N) => println([I**2 : I in 1..N, I**2 <= N]).  ## PicoLisp unoptimized (let Doors (need 100) (for I 100 (for (D (nth Doors I) D (cdr (nth D I))) (set D (not (car D))) ) ) (println Doors) ) optimized (let Doors (need 100) (for I (sqrt 100) (set (nth Doors (* I I)) T) ) (println Doors) ) 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: (let Doors (need 100) (for I (sqrt 100) (set (nth Doors (* I I)) T) ) (make (for (N . D) Doors (when D (link N)) ) ) ) Output: (1 4 9 16 25 36 49 64 81 100) ## Piet ## 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;} optimized version: array doors = map(enumerate(100,1,1), lambda(int x) { return sqrt((float)x)%1 == 0.0; }); write("%{%d %d %d %d %d %d %d %d %d %d\n%}\n", doors/10) 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  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;  ## PL/M Translation of: ALGOL W 100H: /* FIND THE FIRST FEW SQUARES VIA THE UNOPTIMISED DOOR FLIPPING METHOD */ /* BDOS SYSTEM CALL */ BDOS: PROCEDURE( FN, ARG ); DECLARE FN BYTE, ARG ADDRESS; GO TO 5; END BDOS; /* PRINTS A BYTE AS A CHARACTER */ PRINTCHAR: PROCEDURE( CH );        DECLARE CH BYTE;        CALL BDOS( 2, CH );    END PRINT$CHAR; /* PRINTS A BYTE AS A NUMBER */ PRINT$BYTE: PROCEDURE( N );        DECLARE N BYTE;        DECLARE ( V, D3, D2 ) BYTE;        V  = N;        D3 = V MOD 10;        IF ( V := V / 10 ) <> 0 THEN DO;            D2 = V MOD 10;            IF ( V := V / 10 ) <> 0 THEN CALL PRINT$CHAR( '0' + V ); CALL PRINT$CHAR( '0' + D2 );        END;        CALL PRINT$CHAR( '0' + D3 ); END PRINT$BYTE;     DECLARE DOOR$DCL LITERALLY '101'; DECLARE FALSE LITERALLY '0'; DECLARE CR LITERALLY '0DH'; DECLARE LF LITERALLY '0AH'; /* ARRAY OF DOORS - DOOR( I ) IS TRUE IF OPEN, FALSE IF CLOSED */ DECLARE DOOR( DOOR$DCL ) BYTE;    DECLARE ( I, J )         BYTE;     /* SET ALL DOORS TO CLOSED */    DO I = 0 TO LAST( DOOR ); DOOR( I ) = FALSE; END;    /* REPEATEDLY FLIP THE DOORS */    DO I = 1 TO LAST( DOOR );       DO J = I TO LAST( DOOR ) BY I;          DOOR( J ) = NOT DOOR( J );       END;    END;    /* DISPLAY THE RESULTS */    DO I = 1 TO LAST( DOOR );       IF DOOR( I ) THEN DO;          CALL PRINT$CHAR( ' ' ); CALL PRINT$BYTE( I );       END;    END;    CALL PRINT$CHAR( CR ); CALL PRINT$CHAR( LF );EOF
Output:
 1 4 9 16 25 36 49 64 81 100


## PL/SQL

Unoptimized

 DECLARE  TYPE doorsarray IS VARRAY(100) OF BOOLEAN;  doors doorsarray := doorsarray();BEGIN doors.EXTEND(100);  --ACCOMMODATE 100 DOORS FOR i IN 1 .. doors.COUNT  --MAKE ALL 100 DOORS FALSE TO INITIALISE  LOOP     doors(i) := FALSE;                      END LOOP; FOR j IN 1 .. 100 --ITERATE THRU USING MOD LOGIC AND FLIP THE DOOR RIGHT OPEN OR CLOSE LOOP      FOR k IN 1 .. 100        LOOP                  IF MOD(k,j)=0 THEN                      doors(k) := NOT doors(k);                   END IF;        END LOOP; END LOOP; FOR l IN 1 .. doors.COUNT  --PRINT THE STATUS IF ALL 100 DOORS AFTER ALL ITERATION  LOOP       DBMS_OUTPUT.PUT_LINE('DOOR '||l||' IS -->> '||CASE WHEN SYS.DBMS_SQLTCB_INTERNAL.I_CONVERT_FROM_BOOLEAN(doors(l)) = 'TRUE'                                                                 THEN 'OPEN'                                                               ELSE 'CLOSED'                                                         END);  END LOOP; END;

## Pointless

output =  range(1, 100)  |> map(visit(100))  |> println ---------------------------------------------------------- toggle(state) =  if state == Closed then Open else Closed ------------------------------------------------------------ Door state on iteration i is recursively-- defined in terms of previous door state visit(i, index) = cond {  case (i == 0) Closed  case (index % i == 0) toggle(lastState)  else lastState} where lastState = visit(i - 1, index)
Output:
[Open, Closed, Closed, Open, Closed, Closed, Closed, Closed, Open, Closed, Closed, Closed, Closed, Closed, Closed, Open, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Open, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Open, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Open, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Open, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Open, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Closed, Open]

## Pony

Combined Optimized and Unoptimized

Probably also rather pointless in its use of actors, but, after all, they're cheap.

 actor Toggler    let doors:Array[Bool]    let env: Env    new create(count:USize,_env:Env) =>        var i:USize=0        doors=Array[Bool](count)        env=_env        while doors.size() < count do            doors.push(false)        end    be togglin(interval : USize)=>        var i:USize=0        try            while i < doors.size() do                doors.update(i,not doors(i)?)?                i=i+interval            end        else            env.out.print("Errored while togglin'!")        end    be printn(onlyOpen:Bool)=>        try            for i in doors.keys() do                if onlyOpen and not doors(i)? then                    continue                end                env.out.print("Door " + i.string() + " is " +                    if doors(i)? then                        "Open"                    else                        "closed"                    end)            end        else            env.out.print("Error!")        end        true actor OptimizedToggler    let doors:Array[Bool]    let env:Env    new create(count:USize,_env:Env)=>        env=_env        doors=Array[Bool](count)        while doors.size()<count do            doors.push(false)        end    be togglin()=>        var i:USize=0        if alreadydone then            return        end        try            doors.update(0,true)?            doors.update(1,true)?            while i < doors.size() do                i=i+1                let z=i*i                let x=z*z                if z > doors.size() then                    break                else                    doors.update(z,true)?                end                if x < doors.size() then                    doors.update(x,true)?                end            end        end    be printn(onlyOpen:Bool)=>        try            for i in doors.keys() do                if onlyOpen and not doors(i)? then                    continue                end                env.out.print("Door " + i.string() + " is " +                    if doors(i)? then                        "Open"                    else                        "closed"                    end)            end        else            env.out.print("Error!")        end        trueactor Main    new create(env:Env)=>        var count: USize =100        try            let index=env.args.find("-n",0,0,{(l,r)=>l==r})?            try            match env.args(index+1)?.read_int[USize]()?                | (let x:USize, _)=>count=x                end            else                env.out.print("You either neglected to provide an argument after -n or that argument was not an integer greater than zero.")                return            end        end        if env.args.contains("optimized",{(l,r)=>r==l}) then            let toggler=OptimizedToggler(count,env)            var i:USize = 1            toggler.togglin()            toggler.printn(env.args.contains("onlyopen", {(l,r)=>l==r}))        else            let toggler=Toggler(count,env)            var i:USize = 1            while i < count do                toggler.togglin(i)                i=i+1            end            toggler.printn(env.args.contains("onlyopen", {(l,r)=>l==r}))        end

## Pop11

unoptimized

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 statefor i from 1 to 100 do   printf('Door ' >< i >< ' is ' ><            if doors(i) then 'open' else 'closed' endif, '%s\n');endfor;

optimized

for i to 100 do    lvars root = sqrt(i);    i; if root = round(root) then ' open' ><; else ' closed' ><; endif; =>endfor;

## PostScript

Bruteforce:
/doors [ 100 { false } repeat ] def 1 1 100 { dup 1 sub exch 99 {        dup doors exch get not doors 3 1 roll put} for } fordoors pstack
Shows:
[true false false true false false false false true false ...<90 doors later>... true]

## Potion

square=1, i=31 to 100(door):  if (door == square):    ("door", door, "is open") say    square += i    i += 2..

## PowerShell

### optimized

 1..10|%{"Door "+ $_*$_ + " is open"}

## Processing

Unoptimized:

boolean[] doors = new boolean[100]; void setup() {  for (int i = 0; i < 100; i++) {    doors[i] = false;  }  for (int i = 1; i < 100; i++) {    for (int j = 0; j < 100; j += i) {      doors[j] = !doors[j];    }  }  println("Open:");  for (int i = 1; i < 100; i++) {    if (doors[i]) {      println(i);    }  }  exit();}
Output:
Open:
1
4
9
16
25
36
49
64
81

Unoptimized:

### optimized

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

say 'Door $_ is open' for (1..10)»²; ### Here's a version using the cross meta-operator instead of a map:  say "Door$_ is open" for 1..10 X** 2;

This one prints both opened and closed doors:

say "Door $_ is ", <closed open>[.sqrt == .sqrt.floor] for 1..100; ### verbose version, but uses ordinary components Works with: Rakudo version 2016.07 Tom Legrady  sub output( @arr,$max ) {    my $output = 1; for 1..^$max -> $index { if @arr[$index] {	    printf "%4d", $index; say '' if$output++ %%  10;	}    }    say '';} sub MAIN ( Int :$doors = 100 ) { my$doorcount = $doors + 1; my @door[$doorcount] = 0 xx ($doorcount); INDEX: for 1...^$doorcount -> $index { # flip door$index & its multiples, up to last door.        #	for ($index, * +$index ... *)[^$doors] ->$multiple {	    next INDEX if $multiple >$doors;	    @door[$multiple] = @door[$multiple] ?? 0 !! 1;	}    }    output @door, $doors+1;}  Output: $ ./100_doors.pl6 -doors=100
1   4   9  16  25  36  49  64  81


## RapidQ

 dim x as integer, y as integerdim door(1 to 100) as byte 'initialize arrayfor x = 1 to 100 : door(x) = 0 : next 'set door valuesfor y = 1 to 100    for x = y to 100 step y        door(x) = not door(x)    next xnext y 'print resultfor x = 1 to 100    if door(x) then print "Door " + str$(x) + " = open"next while inkey$="":wendend

Output

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

## REBOL

### Unoptimized

doors: array/initial 100 'closedrepeat i 100 [    door: at doors i    forskip door i [change door either 'open = first door ['closed] ['open]]]

### Optimized

doors: array/initial 100 'closedrepeat i 10 [doors/(i * i): 'open]

## Red

### Unoptimized

Red [  Purpose: "100 Doors Problem (Perfect Squares)"  Author: "Barry Arthur"  Date: "07-Oct-2016"]doors: make vector! [char! 8 100]repeat i 100 [change at doors i #"."] repeat i 100 [    j: i    while [j <= 100] [      door: at doors j      change door either #"O" = first door [#"."] [#"O"]      j: j + i    ]] repeat i 10 [  print copy/part at doors (i - 1 * 10 + 1) 10]

### Using bitset! type

Red ["Doors"] doors: make bitset! len: 100repeat step len [	repeat n to-integer len / step [		m: step * n 		doors/:m: not doors/:m	]]repeat n len [if doors/:n [print n]]

## Relation

 relation door, stateset i = 1while i <= 100insert i, 1set i = i+1end whileset i = 2while i <= 100update state = 1-state where not (door mod i)set i = i+1end whileupdate state = "open" where stateupdate state = "closed" where state !== "open"print
door state
1 open
2 closed
3 closed
4 open
5 closed
6 closed
7 closed
8 closed
9 open...

## Retro

:doors (n-) [ #1 repeat dup-pair n:square gt? 0; drop dup n:square n:put sp n:inc again ] do drop-pair ;#100 doors

## REXX

### the idiomatic way

/*REXX pgm solves the  100 doors puzzle, doing it the hard way by opening/closing doors.*/parse arg doors .                                /*obtain the optional argument from CL.*/if doors=='' | doors==","  then doors=100        /*not specified?  Then assume 100 doors*/                                                 /*        0 =  the door is  closed.    */                                                 /*        1 =   "    "   "  open.      */door.=0                                          /*assume all doors are closed at start.*/                do #=1  for doors                /*process a pass─through for all doors.*/                    do j=#  by #  to doors       /*  ··· every Jth door from this point.*/                    door.j= \door.j              /*toggle the  "openness"  of the door. */                    end   /*j*/                end       /*#*/ say 'After '                doors          " passes, the following doors are open:"say                do k=1  for doors                if door.k  then say right(k, 20) /*add some indentation for the output. */                end    /*k*/                     /*stick a fork in it,  we're all done. */
output   when using the default input:
After  100  passes, the following doors are open:

1
4
9
16
25
36
49
64
81
100


### the shortcut way

/*REXX pgm solves the  100 doors  puzzle,  doing it the easy way by calculating squares.*/parse arg doors .                                /*obtain the optional argument from CL.*/if doors=='' | doors==","  then doors=100        /*not specified?  Then assume 100 doors*/say 'After '          doors          " passes, the following doors are open:"say          do #=1  while  #**2 <= doors           /*process easy pass─through  (squares).*/          say right(#**2, 20)                    /*add some indentation for the output. */          end   /*#*/                            /*stick a fork in it,  we're all done. */
output   is identical to the 1st REXX version.

## Ring

Unoptimized

doors = list(100)for i = 1 to 100doors[i] = falsenext For pass = 1 To 100         For door = pass To 100             if doors[door] doors[door] = false else doors[door] = true ok         door += pass-1         NextNext For door = 1 To 100     see "Door (" + door + ") is "     If doors[door] see "Open" else see "Closed" ok     see nlNext

Optimized

doors = list(100)for i = 1 to 100doors[i] = falsenext For p = 1 To 10        doors[pow(p,2)] = TrueNext For door = 1 To 100     see "Door (" + door + ") is "     If doors[door] see "Open" else see "Closed" ok     see nlNext

## Ruby

doors = Array.new(101,0)print "Open doors "(1..100).step(){ |i|(i..100).step(i) { |d|    doors[d] = doors[d]^= 1    if i == d and doors[d] == 1 then      print "#{i} "    end  }}
Output:
Open doors 1 4 9 16 25 36 49 64 81 100

unoptimized; Ruby-way

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? then open else close end  end   def to_s    @state.to_s  endend 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  endend doors.each_with_index { |door, i| puts "Door #{i+1} is #{door}." }

unoptimized

n = 100Open = "open"Closed = "closed"def Open.toggle  Closedenddef Closed.toggle  Openenddoors = [Closed] * (n + 1)for mul in 1..n  for x in (mul..n).step(mul)    doors[x] = doors[x].toggle  endenddoors.each_with_index do |b, i|  puts "Door #{i} is #{b}" if i > 0end

optimized

n = 100(1..n).each do |i|   puts "Door #{i} is #{i**0.5 == (i**0.5).round ? "open" : "closed"}"end

generic true/false, with another way of handling the inner loop demonstrating Range#step

doors = [false] * 100100.times do |i|  (i ... doors.length).step(i + 1) do |j|    doors[j] = !doors[j]  endendputs doors.map.with_index(1){|d,i| "Door #{i} is #{d ? 'open' : 'closed'}."}
Output:
Door 1 is open
Door 2 is closed
Door 3 is closed
Door 4 is open
Door 5 is closed
Door 6 is closed
Door 7 is closed
Door 8 is closed
Door 9 is open
Door 10 is closed
Door 11 is closed
Door 12 is closed
Door 13 is closed
Door 14 is closed
Door 15 is closed
Door 16 is open
Door 17 is closed
Door 18 is closed
Door 19 is closed
Door 20 is closed
Door 21 is closed
Door 22 is closed
Door 23 is closed
Door 24 is closed
Door 25 is open
Door 26 is closed
Door 27 is closed
Door 28 is closed
Door 29 is closed
Door 30 is closed
Door 31 is closed
Door 32 is closed
Door 33 is closed
Door 34 is closed
Door 35 is closed
Door 36 is open
Door 37 is closed
Door 38 is closed
Door 39 is closed
Door 40 is closed
Door 41 is closed
Door 42 is closed
Door 43 is closed
Door 44 is closed
Door 45 is closed
Door 46 is closed
Door 47 is closed
Door 48 is closed
Door 49 is open
Door 50 is closed
Door 51 is closed
Door 52 is closed
Door 53 is closed
Door 54 is closed
Door 55 is closed
Door 56 is closed
Door 57 is closed
Door 58 is closed
Door 59 is closed
Door 60 is closed
Door 61 is closed
Door 62 is closed
Door 63 is closed
Door 64 is open
Door 65 is closed
Door 66 is closed
Door 67 is closed
Door 68 is closed
Door 69 is closed
Door 70 is closed
Door 71 is closed
Door 72 is closed
Door 73 is closed
Door 74 is closed
Door 75 is closed
Door 76 is closed
Door 77 is closed
Door 78 is closed
Door 79 is closed
Door 80 is closed
Door 81 is open
Door 82 is closed
Door 83 is closed
Door 84 is closed
Door 85 is closed
Door 86 is closed
Door 87 is closed
Door 88 is closed
Door 89 is closed
Door 90 is closed
Door 91 is closed
Door 92 is closed
Door 93 is closed
Door 94 is closed
Door 95 is closed
Door 96 is closed
Door 97 is closed
Door 98 is closed
Door 99 is closed
Door 100 is open


## Run BASIC

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 doornext i
Output:
Open doors 1 4 9 16 25 36 49 64 81 100

## Rust

fn main() {    let mut door_open = [false; 100];    for pass in 1..101 {        let mut door = pass;        while door <= 100 {            door_open[door - 1] = !door_open[door - 1];            door += pass;        }    }    for (i, &is_open) in door_open.iter().enumerate() {        println!("Door {} is {}.", i + 1, if is_open {"open"} else {"closed"});    }}

Declarative version of above:

fn main() {    let doors = vec![false; 100].iter_mut().enumerate()                                .map(|(door, door_state)| (1..100).into_iter()                                                                   .filter(|pass| (door + 1) % pass == 0)                                                                   .map(|_| { *door_state = !*door_state; *door_state })                                                                   .last().unwrap()).collect::<Vec<_>>();     println!("{:?}", doors);}

Optimized version:
(In this case the printing is the bottleneck so this version is not faster than the above one.)

fn main() {    let squares: Vec<_> = (1..11).map(|n| n*n).collect();    let is_square = |num| squares.binary_search(&num).is_ok();     for i in 1..101 {        let state = if is_square(i) {"open"} else {"closed"};        println!("Door {} is {}", i, state);    }}

ultra-optimized: ported from Julia version

fn main() {    for i in 1u32..11u32{        println!("Door {} is open", i.pow(2));    }}