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] * 100
L(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/2015
HUNDOOR CSECT
USING HUNDOOR,R12
LR R12,R15
LA R6,0
LA R8,1 step 1
LA R9,100
LOOPI BXH R6,R8,ELOOPI do ipass=1 to 100 (R6)
LR R7,R6
SR R7,R6
LR R10,R6 step ipass
LA R11,100
LOOPJ 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 LOOPJ
ELOOPJ B LOOPI
ELOOPI 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 counter
LOOPN 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 loop
ELOOPN XPRNT BUFFER,80
RETURN XR R15,R15
BR R14
DOORS 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 off
set doors=%@repeat[C,100]
do step = 1 to 100
do door = %step to 100 by %step
set doors=%@left[%@eval[%door-1],%doors]%@if[%@instr[%@eval[%door-1],1,%doors]==C,O,C]%@right[%@eval[100-%door],%doors]
enddo
enddo

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 #100
Z_LOOP:
STA 200,X
DEX
BNE Z_LOOP
STA 200,X

; Now do doors repeated open/close
LDY #01  ; Initial value of Stride
S_LOOP:
CPY #101
BCS S_DONE
TYA  ; Initial value of Index
I_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_LOOP I_DONE: INY BNE S_LOOP S_DONE: ; Finally, format array values for output: 0 for closed, 1 for open LDX #100 C_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

$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 Return LF 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-specific
START: ; Execution starts here
LEA Doors,A2 ; make A2 point to Doors byte array
MOVEQ #0,D3
PassLoop:
CMP #SIZE,D3
BCC ExitPassLoop ; Branch on Carry Clear - being used as Branch on Higher or Equal
MOVE D3,D4
DoorLoop:
CMP #SIZE,D4
BCC ExitDoorLoop
NOT.B 0(A2,D4)
BRA DoorLoop
ExitDoorLoop:
BRA PassLoop
ExitPassLoop:

* $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,D4 PrintLoop: 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 Next ItsOpen: PUTS DoorMsgO Next: ADDQ #1,D4 BRA PrintLoop ExitPrintLoop: * 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 $2000 Doors DCB.B SIZE,0 ;Reserve 100 bytes, prefilled with zeros DoorMsg1 DC.B 'Door ',0 DoorMsg2 DC.B ' is ',0 DoorMsgC DC.B 'closed',CR,LF,0 DoorMsgO DC.B 'open',CR,LF,0 END START ;last line of source 8080 Assembly page: equ 2 ; Store doors in page 2 doors: equ 100 ; 100 doors puts: equ 9 ; CP/M string output org 100h xra a ; Set all doors to zero lxi h,256*page mvi c,doors zero: 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 door
pass: mov l,e ; L=door counter, start at first door in pass
door: inr m ; Incrementing always toggles the low bit
dad d ; Go to next door in pass
inr l
jnc door ; If not, do the next door
inr e ; Next 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 */
/*********************************/
.data
sMessResult: .asciz "The door @ is open.\n"

/*********************************/
/* UnInitialized data */
/*********************************/
.bss
stTableDoors: .skip 8 * NBDOORS
sZoneConv: .skip 24
/*********************************/
/* code section */
/*********************************/
.text
.global main
main: // entry of program
// display first line
mov x5,1
1:
mov x4,x5
2: // 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
bl strInsertAtCharInc // insert result at first @ character
bl affichageMess // display message
4:
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

/***********************************************/
/* 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 */
/*********************************/
.data
sMessResult: .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,1
1:
mov x0,x4
ldr x1,qAdrsZoneConv // display value index
bl conversion10 // call function
bl strInsertAtCharInc // insert result at first @ character
bl affichageMess // display message
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

/***********************************************/
/* 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.
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 $\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))))

Action!

DEFINE COUNT="100"

PROC Main()
BYTE ARRAY doors(COUNT+1)
BYTE door,pass

FOR door=1 TO COUNT
DO
doors(door)=0
OD

PrintE("Following doors are open:")
FOR pass=1 TO COUNT
DO
FOR door=pass TO COUNT STEP pass
DO
doors(door)==!$FF OD IF doors(pass)=$FF THEN
PrintB(pass) Put(32)
FI
OD
RETURN
Output:
Following doors are open:
1 4 9 16 25 36 49 64 81 100

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: SHORT
VAR sArray: SHORT
VAR sCount: SHORT
VAR sDoor: SHORT
VAR sPass: SHORT
VAR zIndex: STRING
VAR 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 = PUT_STRING_SAY(sArray, 1, zState)
ELSE
BREAK
ENDIF
ENDDO
ENDDO
//
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

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

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 method
scope

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 

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

var d = 1
foreach door doors {
println ("door " + d++ + " is " + (door ? "open" : "closed"))

}

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: 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|+/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

⍝⍝ Also works with GNU APL after introduction of
⍝⍝ the ⍸ function with SVN r1368, Dec 03 2020
⍸≠⌿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 false
end
repeat with pass from 1 to 100
repeat with door from pass to 100 by pass
set item door of is_open to not item door of is_open
end
end
set open_doors to {}
repeat with door from 1 to 100
if item door of is_open then
set end of open_doors to door
end
end
set text item delimiters to ", "
display dialog "Open doors: " & open_doors

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 lst
end 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 tell
end filter

-- foldl :: (a -> b -> a) -> a -> [b] -> a
on 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 tell
end 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 tell
end map

-- min :: Ord a => a -> a -> a
on min(x, y)
if y < x then
y
else
x
end if
end min

-- Lift 2nd class handler function into 1st class script wrapper
-- mReturn :: Handler -> Script
on mReturn(f)
if class of f is script then
f
else
script
property |λ| : f
end script
end if
end 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 & dbl
end 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 lst
end 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 doors
for each pass from 1 to 100
for (door = pass) (door <= 100) (door += pass)
toggle door

let int pass, door.

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

let doors be an array of 100 bool

for each door from 1 to 100
printf "#%.3d %s\n" door (doors[door - 1]) ? "[ ]", "[X]"

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 */
/*********************************/
.data
sMessResult: .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
mov r5,#1
1:
mov r4,r5
2: @ 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
bl affichageMess @ display message
4:
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

/******************************************************************/
/* 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
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, 10
conversion10:
push {r1-r4,lr} @ save registers
mov r3,r1
mov r2,#LGZONECAL

1: @ start loop
bl divisionpar10U @unsigned r0 <- dividende. quotient ->r0 reste -> r1
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,#0
2:
ldrb r1,[r3,r2]
strb r1,[r3,r4]
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
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 */
/*********************************/
.data
sMessResult: .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 doors
1:
mov r0,r4 @ open -> display message
ldr r1,iAdrsMessValeur @ display value index
bl conversion10 @ call function
bl affichageMess @ display message
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

/******************************************************************/
/* 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
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, 10
conversion10:
push {r1-r4,lr} @ save registers
mov r3,r1
mov r2,#LGZONECAL

1: @ start loop
bl divisionpar10U @ unsigned r0 <- dividende. quotient ->r0 reste -> r1
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,#0
2:
ldrb r1,[r3,r2]
strb r1,[r3,r4]
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
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.'}"

ATS

implement
main0((*void*)) = let
//
var A = @[bool](false)
val A = $UNSAFE.cast{arrayref(bool,100)}([email protected]) // fnx loop ( pass: intGte(0) ) : void = if pass < 100 then loop2 (pass, pass) // end of [if] and loop2 ( pass: natLt(100), door: intGte(0) ) : void = if door < 100 then (A[door] := ~A[door]; loop2(pass, door+pass+1)) else loop(pass+1) // end of [if] // fun loop3 ( door: intGte(0) ) : void = if door < 100 then ( println!("door #", door+1, " is ", (if A[door] then "open" else "closed"): string, "."); loop3(door+1) ) (* end of [then] *) // end of [if] // in loop(0); loop3 (0) end // end of [main0] AutoHotkey Standard Approach Loop, 100 Door%A_Index% := "closed" Loop, 100 { x := A_Index, y := A_Index While (x <= 100) { CurrentDoor := Door%x% If CurrentDoor contains closed { Door%x% := "open" x += y } else if CurrentDoor contains open { Door%x% := "closed" x += y } } } Loop, 100 { CurrentDoor := Door%A_Index% If CurrentDoor contains open Res .= "Door " A_Index " is openn" } MsgBox % Res Alternative Approach Making use of the identity: $\sum _{i=1}^{n}(2i-1)=n^{2}$ increment := 3, square := 1 Loop, 100 If (A_Index = square) outstring .= "nDoor " A_Index " is open" ,square += increment, increment += 2 MsgBox,, Succesfull, % SubStr(outstring, 2) Optimized While (Door := A_Index ** 2) <= 100 Result .= "Door " Door " is openn" MsgBox, %Result% AutoIt #include <array.au3>$doors = 100

;door array, 0 = closed, 1 = open
Local $door[$doors +1]

For $ii = 1 To$doors
For $i =$ii To $doors Step$ii
$door[$i] = Not $door[$i]
next
Next

;display to screen
For $i = 1 To$doors
ConsoleWrite (Number($door[$i])& " ")
If Mod($i,10) = 0 Then ConsoleWrite(@CRLF) Next AWK unoptimized BEGIN { for(i=1; i <= 100; i++) { doors[i] = 0 # close the doors } for(i=1; i <= 100; i++) { for(j=i; j <= 100; j += i) { doors[j] = (doors[j]+1) % 2 } } for(i=1; i <= 100; i++) { print i, doors[i] ? "open" : "close" } } optimized BEGIN { for(i=1; i <= 100; i++) { doors[i] = 0 # close the doors } for(i=1; i <= 100; i++) { if ( int(sqrt(i)) == sqrt(i) ) { doors[i] = 1 } } for(i=1; i <= 100; i++) { print i, doors[i] ? "open" : "close" } } Axiom Unoptimized: (open,closed,change,open?) := (true,false,not,test); doors := bits(100,closed); for i in 1..#doors repeat for j in i..#doors by i repeat doors.j := change doors.j [i for i in 1..#doors | open? doors.i] Optimized: [i for i in 1..100 | perfectSquare? i] -- or [i^2 for i in 1..sqrt(100)::Integer] B Works with: The Amsterdam Compiler Kit - B version V6.1pre1 main() { auto doors; /* != 0 means open */ auto pass, door; door = 0; while( door<100 ) doors[door++] = 0; pass = 0; while( pass<100 ) { door = pass; while( door<100 ) { doors[door] = !doors[door]; door =+ pass+1; } ++pass; } door = 0; while( door<100 ) { printf("door #%d is %s.*n", door+1, doors[door] ? "open" : "closed"); ++door; } return(0); } BaCon OPTION BASE 1 DECLARE doors FOR size = 1 TO 100 FOR pass = 0 TO 100 STEP size doors[pass] = NOT(doors[pass]) NEXT NEXT FOR which = 1 TO 100 IF doors[which] THEN PRINT which NEXT Output: 1 4 9 16 25 36 49 64 81 100 BASIC Applesoft BASIC Based on the Sinclair ZX81 BASIC implementation. 100 : 110 REM 100 DOORS PROBLEM 120 : 130 DIM D(100) 140 FOR P = 1 TO 100 150 FOR T = P TO 100 STEP P 160 D(T) = NOT D(T): NEXT T 170 NEXT P 180 FOR I = 1 TO 100 190 IF D(I) THEN PRINT I;" "; 200 NEXT I Output: ]RUN 1 4 9 16 25 36 49 64 81 100 BASIC256 # 100 doors problem dim d(100) # simple solution print "simple solution" gosub initialize for t = 1 to 100 for j = t to 100 step t d[j-1] = not d[j-1] next j next t gosub showopen # more optimized solution print "more optimized solution" gosub initialize for t = 1 to 10 d[t^2-1] = true next t gosub showopen end initialize: for t = 1 to d[?] d[t-1] = false # closed next t return showopen: for t = 1 to d[?] print d[t-1]+ " "; if t%10 = 0 then print next t return ultra optimizado: portado desde la versión Julia for i = 1 to 10 : if i % i^2 < 11 then print "La puerta "; int(i^2); " esta abierta" : end if : next i : end Commodore BASIC Based on the Sinclair ZX81 BASIC implementation. 10 DIM D(100) 20 FOR I=1 TO 100 30 FOR J=I TO 100 STEP I 40 D(J) = NOT D(J) 50 NEXT J 60 NEXT I 70 FOR I=1 TO 100 80 IF D(I) THEN PRINT I, 90 NEXT I IS-BASIC 100 PROGRAM "100doors.bas" 110 NUMERIC D(1 TO 100) 120 FOR I=1 TO 100 130 LET D(I)=0 140 NEXT 150 FOR I=1 TO 100 160 FOR J=I TO 100 STEP I 170 LET D(J)=NOT D(J) 180 NEXT 190 NEXT 200 FOR I=1 TO 100 210 IF D(I) THEN PRINT I 220 NEXT Optimized: 100 PROGRAM "100doors.bas" 110 LET NR=1:LET D=3 120 DO 130 PRINT NR 140 LET NR=NR+D:LET D=D+2 150 LOOP WHILE NR<=100 QBasic Works with: QBASIC, QB64 unoptimized REM "100 Doors" program FOR QB64 BASIC (http://www.qb64.net/), a QuickBASIC-like compiler. REM Author: G. A. Tippery REM Date: 12-Feb-2014 REM REM Unoptimized (naive) version, per specifications at http://rosettacode.org/wiki/100_doors DEFINT A-Z CONST N = 100 DIM door(N) FOR stride = 1 TO N FOR index = stride TO N STEP stride LET door(index) = NOT (door(index)) NEXT index NEXT stride PRINT "Open doors:" FOR index = 1 TO N IF door(index) THEN PRINT index NEXT index END Works with: QuickBasic version 4.5 unoptimized DIM doors(0 TO 99) FOR pass = 0 TO 99 FOR door = pass TO 99 STEP pass + 1 PRINT doors(door) PRINT NOT doors(door) doors(door) = NOT doors(door) NEXT door NEXT pass FOR i = 0 TO 99 PRINT "Door #"; i + 1; " is "; IF NOT doors(i) THEN PRINT "closed" ELSE PRINT "open" END IF NEXT i optimized DIM doors(0 TO 99) FOR door = 0 TO 99 IF INT(SQR(door)) = SQR(door) THEN doors(door) = -1 NEXT door FOR i = 0 TO 99 PRINT "Door #"; i + 1; " is "; IF NOT doors(i) THEN PRINT "closed" ELSE PRINT "open" END IF NEXT i Sinclair ZX81 BASIC Works with only 1k of RAM, although it doesn't leave too much to play with. 10 DIM D(100) 20 FOR I=1 TO 100 30 FOR J=I TO 100 STEP I 40 LET D(J)=NOT D(J) 50 NEXT J 60 NEXT I 70 FOR I=1 TO 100 80 IF D(I) THEN PRINT I, 90 NEXT I Batch File unoptimized @echo off setlocal enableDelayedExpansion :: 0 = closed :: 1 = open :: SET /A treats undefined variable as 0 :: Negation operator ! must be escaped because delayed expansion is enabled for /l %%p in (1 1 100) do for /l %%d in (%%p %%p 100) do set /a "door%%d=^!door%%d" for /l %%d in (1 1 100) do if !door%%d!==1 ( echo door %%d is open ) else echo door %%d is closed optimized @echo off setlocal enableDelayedExpansion set /a square=1, incr=3 for /l %%d in (1 1 100) do ( if %%d neq !square! (echo door %%d is closed) else ( echo door %%d is open set /a square+=incr, incr+=2 ) ) BBC BASIC DIM doors%(100) FOR pass% = 1 TO 100 FOR door% = pass% TO 100 STEP pass% doors%(door%) = NOT doors%(door%) NEXT door% NEXT pass% FOR door% = 1 TO 100 IF doors%(door%) PRINT "Door " ; door% " is open" NEXT door% bc /* 0 means door is closed, 1 means door is open */ for (i = 0; i < 100; i++) { for (j = i; j < 100; j += (i + 1)) { d[j] = 1 - d[j] /* Toggle door */ } } "Open doors: " for (i = 0; i < 100; i++) { if (d[i] == 1) (i + 1) } BCPL get "libhdr" let start() be$( let doors = vec 100

// close all doors
for n = 1 to 100 do doors!n := 0

// make 100 passes
for pass = 1 to 100 do
$( let n = pass while n <= 100 do$( doors!n := ~doors!n
n := n + pass
$)$)

// report which doors are open
for n = 1 to 100 do
if doors!n then
writef("Door %N is open.*N", n)
::<[email protected]#$:\*:+55:+1p27g1g+9/9\%9 Optimized Just calculates the first 10 perfect squares. 1+:::*.9#@_ Befunge-98 Works with: CCBI version 2.1 108p0>:18p;;>:9g!18g9p08g] *!0\|+relet|-1*aap81::+] ;::+1<r]!g9;>$08g1+:08paa[
*#@_^._aa

BlitzMax

Works with: BlitzMax version 1.37

optimized

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

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;

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.

( 100doors-list
= doors door doorIndex step
.  :?doors
& 0:?door
& whl
' ( 1+!door:~>100:?door
& closed !doors:?doors
)
& 0:?skip
& whl
' ( :?ndoors
& whl
' ( !doors:?skipped [!skip %?door ?doors { the [<number> pattern only succeeds when the scanning cursor is at position <number> }
&  !ndoors
!skipped
( !door:open&closed
| open
)
: ?ndoors
)
& !ndoors !doors:?doors
& 1+!skip:<100:?skip
)
& out$!doors ) Solution 4. Use a list of objects. Each object can be changed without the need to re-create the whole list. ( 100doors-obj = doors door doorIndex step . :?doors & 0:?door & whl ' ( 1+!door:~>100:?door & new$(=closed) !doors:?doors
)
& 0:?skip
& whl
' ( !doors:?tododoors
& whl
' ( !tododoors:? [!skip %?door ?tododoors
& ( !(door.):open&closed
| open
)
: ?(door.)
)
& 1+!skip:<100:?skip
)
& out$!doors ) These four functions are called in the following way: 100doors-tbl$
& 100doors-var$& 100doors-list$
& 100doors-obj$; Burlesque Version using square numbers: blsq ) 10ro2?^ {1 4 9 16 25 36 49 64 81 100} BQN swch ← ≠´{100⥊1«𝕩⥊0}¨1+↕100 ¯1↓∾{𝕩∾@+10}¨•Fmt¨⟨swch,/swch⟩ "⟨ 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 ⟩ ⟨ 0 3 8 15 24 35 48 63 80 99 ⟩" swch uses an idea similar to the GNU APL solution to generate a boolean array of the correct switches. The second line then formats the boolean array and the truthy indices into a string for display. C unoptimized Uses: C Runtime (Components:printf,) #include <stdio.h> int main() { char is_open = { 0 }; int pass, door; /* do the 100 passes */ for (pass = 0; pass < 100; ++pass) for (door = pass; door < 100; door += pass+1) is_open[door] = !is_open[door]; /* output the result */ for (door = 0; door < 100; ++door) printf("door #%d is %s.\n", door+1, (is_open[door]? "open" : "closed")); return 0; } Using defensive programming, pointers, sentinel values and some other standard programming practices, Uses: C Runtime (Components:printf,) #include <stdio.h> #define NUM_DOORS 100 int main(int argc, char *argv[]) { int is_open[NUM_DOORS] = { 0 } ; int * doorptr, * doorlimit = is_open + NUM_DOORS ; int pass ; /* do the N passes, go backwards because the order is not important */ for ( pass= NUM_DOORS ; ( pass ) ; -- pass ) { for ( doorptr= is_open + ( pass-1 ); ( doorptr < doorlimit ) ; doorptr += pass ) { ( * doorptr ) ^= 1 ; } } /* output results */ for ( doorptr= is_open ; ( doorptr != doorlimit ) ; ++ doorptr ) { printf("door #%lld is %s\n", ( doorptr - is_open ) + 1, ( * doorptr ) ? "open" : "closed" ) ; } } optimized This optimized version makes use of the fact that finally only the doors with square index are open, as well as the fact that $n^{2}=1+3+5+\ldots +(2n-1)$. Uses: C Runtime (Components:printf,) #include <stdio.h> int main() { int square = 1, increment = 3, door; for (door = 1; door <= 100; ++door) { printf("door #%d", door); if (door == square) { printf(" is open.\n"); square += increment; increment += 2; } else printf(" is closed.\n"); } return 0; } The following ultra-short optimized version demonstrates the flexibility of C loops, but isn't really considered good C style: #include <stdio.h> int main() { int door, square, increment; for (door = 1, square = 1, increment = 1; door <= 100; door++ == square && (square += increment += 2)) printf("door #%d is %s.\n", door, (door == square? "open" : "closed")); return 0; } Or really optimize it -- square of an integer is, well, computable: #include <stdio.h> int main() { int i; for (i = 1; i * i <= 100; i++) printf("door %d open\n", i * i); return 0; } C# Unoptimized with Modulus % Operator namespace ConsoleApplication1 { using System; class Program { static void Main(string[] args) { bool[] doors = new bool; //Close all doors to start. for (int d = 0; d < 100; d++) doors[d] = false; //For each pass... for (int p = 0; p < 100; p++)//number of passes { //For each door to toggle... for (int d = 0; d < 100; d++)//door number { if ((d + 1) % (p + 1) == 0) { doors[d] = !doors[d]; } } } //Output the results. Console.WriteLine("Passes Completed!!! Here are the results: \r\n"); for (int d = 0; d < 100; d++) { if (doors[d]) { Console.WriteLine(String.Format("Door #{0}: Open", d + 1)); } else { Console.WriteLine(String.Format("Door #{0}: Closed", d + 1)); } } Console.ReadKey(true); } } } Optimized for Orthogonality (This version demonstrates a different thought pattern during development, where operation and presentation are separated. It could easily be refactored so that the operations to determine which doors are opened and to display the list of doors would be in separate methods, at which point it would become simple to extract them to separate classes and employ a DI pattern to switch the algorithm or display mechanism being used. It also keeps the calculation clear and concise.) namespace ConsoleApplication1 { using System; class Program { static void Main(string[] args) { //Perform the operation. bool[] doors = new bool; int n = 0; int d; while ((d = (++n * n)) <= 100) doors[d - 1] = true; //Perform the presentation. for (d = 0; d < doors.Length; d++) Console.WriteLine("Door #{0}: {1}", d + 1, doors[d] ? "Open" : "Closed"); Console.ReadKey(true); } } } Unoptimized but Concise namespace ConsoleApplication1 { using System; class Program { static void Main() { bool[] doors = new bool; //The number of passes can be 1-based, but the number of doors must be 0-based. for (int p = 1; p <= 100; p++) for (int d = p - 1; d < 100; d += p) doors[d] = !doors[d]; for (int d = 0; d < 100; d++) Console.WriteLine("Door #{0}: {1}", d + 1, doors[d] ? "Open" : "Closed"); Console.ReadKey(true); } } } Optimized for brevity namespace ConsoleApplication1 { using System; class Program { static void Main() { double n; //If the current door number is the perfect square of an integer, say it is open, else say it is closed. for (int d = 1; d <= 100; d++) Console.WriteLine("Door #{0}: {1}", d, (n = Math.Sqrt(d)) == (int)n ? "Open" : "Closed"); Console.ReadKey(true); } } } Optimized for Flexibility This version supports altering the number of doors through console commands. Its main intent is to be flexible and easy to use. using System; using System.IO; using System.Collections.Generic; class Program { static void Main() { Console.Clear(); Console.WriteLine("Input a number of doors to calculate, then press enter"); StartCalculator(); } static void StartCalculator() { //The number to calculate is input here string input = Console.ReadLine(); Console.Clear(); try { //The program attempts to convert the string to an int //Exceptions will be caught on this line int numberOfDoors = Convert.ToInt32(input); //Will call method recursively if input number is less than 1 if (numberOfDoors <= 0) { Console.WriteLine("Please use a number greater than 0"); StartCalculator(); } //The program then starts the calculation process Calculate(numberOfDoors); //After calculation process is finished, restart method is called RestartCalculator(); } catch(FormatException) { //Code will be executed if the number has a decimal or has an unrecognizable symbol Console.WriteLine("Unable to read. Please use a real number without a decimal"); StartCalculator(); } catch (OverflowException) { //Code will be executed if number is too long Console.WriteLine("You number is too long"); StartCalculator(); } } static void Calculate(int numberOfDoors) { //Increases numberOfDoors by 1 since array starts at 0 numberOfDoors++; //Dictionary key represents door number, value represents if the door is open //if value == true, the door is open Dictionary<int, bool> doors = new Dictionary<int, bool>(); //Creates Dictionary size of numberOfDoors, all initialized at false for(int i = 0; i < numberOfDoors; i++) { doors.Add(i, false); } //Creates interval between doors, starting at 0, while less than numberOfDoors for (int doorInterval = 0; doorInterval < numberOfDoors; doorInterval++) { //Will alter every cubby at doorInterval //1 needs to be added since doorInterval will start at 0 and end when equal to numberOfDoors for(int i = 0; i < numberOfDoors; i += doorInterval + 1) { //Changes a false value to true and vice versa doors[i] = doors[i] ? false: true; } } //Writes each door and whether it is open or closed for(int i = 0; i < numberOfDoors; i++) { //Skips over door 0 if (i == 0) continue; //Writes open if door value is true, writes closed if door value is false Console.WriteLine("Door " + (i) + " is " + (doors[i] ? "open" : "closed")); } } static void RestartCalculator() { Console.WriteLine("Press any key to restart"); Console.ReadKey(true); Main(); } } C++ Works with: GCC version 4.1.2 20061115 (prerelease) (SUSE Linux) unoptimized #include <iostream> int main() { bool is_open = { false }; // do the 100 passes for (int pass = 0; pass < 100; ++pass) for (int door = pass; door < 100; door += pass+1) is_open[door] = !is_open[door]; // output the result for (int door = 0; door < 100; ++door) std::cout << "door #" << door+1 << (is_open[door]? " is open." : " is closed.") << std::endl; return 0; } optimized This optimized version makes use of the fact that finally only the doors with square index are open, as well as the fact that $(n+1)^{2}=1+3+5+\ldots +(2n+1)$. #include <iostream> int main() { int square = 1, increment = 3; for (int door = 1; door <= 100; ++door) { std::cout << "door #" << door; if (door == square) { std::cout << " is open." << std::endl; square += increment; increment += 2; } else std::cout << " is closed." << std::endl; } return 0; } The only calculation that's really needed: #include <iostream> //compiled with "Dev-C++" , from RaptorOne int main() { for(int i=1; i*i<=100; i++) std::cout<<"Door "<<i*i<<" is open!"<<std::endl; } Compile time computation using C++17 to produce fastest runtime. #include <iostream> // compiled with clang (tags/RELEASE_600/final) #include <type_traits> // or g++ (GCC) 7.3.1 20180406 -- from hare1039 namespace functional_list // basic building block for template meta programming { struct NIL { using head = NIL; using tail = NIL; friend std::ostream& operator << (std::ostream& os, NIL const) { return os; } }; template <typename H, typename T = NIL> struct list { using head = H; using tail = T; }; template <int i> struct integer { static constexpr int value = i; friend std::ostream& operator << (std::ostream& os, integer<i> const) { os << integer<i>::value; return os;} }; template <typename L, int nTH> constexpr auto at() { if constexpr (nTH == 0) return (typename L::head){}; else if constexpr (not std::is_same_v<typename L::tail, NIL>) return at<typename L::tail, nTH - 1>(); else return NIL{}; } template <typename L, int nTH> using at_t = decltype(at<L, nTH>()); template <typename L, typename elem> constexpr auto prepend() { return list<elem, L>{}; } template <typename L, typename elem> using prepend_t = decltype(prepend<L, elem>()); template <int Size, typename Dat = integer<0>> constexpr auto gen_list() { if constexpr (Size == 0) return NIL{}; else { using next = decltype(gen_list<Size - 1, Dat>()); return prepend<next, Dat>(); } } template <int Size, typename Dat = integer<0>> using gen_list_t = decltype(gen_list<Size, Dat>()); } namespace fl = functional_list; constexpr int door_amount = 101; // index from 1 to 100 template <typename L, int current, int moder> constexpr auto construct_loop() { using val_t = fl::at_t<L, current>; if constexpr (std::is_same_v<val_t, fl::NIL>) return fl::NIL{}; else { constexpr int val = val_t::value; using val_add_t = fl::integer<val + 1>; using val_old_t = fl::integer<val>; if constexpr (current == door_amount) { if constexpr(current % moder == 0) return fl::list<val_add_t>{}; else return fl::list<val_old_t>{}; } else { using sub_list = decltype(construct_loop<L, current + 1, moder>()); if constexpr(current % moder == 0) return fl::prepend<sub_list, val_add_t>(); else return fl::prepend<sub_list, val_old_t>(); } } } template <int iteration> constexpr auto construct() { if constexpr (iteration == 1) // door index = 1 { using l = fl::gen_list_t<door_amount>; return construct_loop<l, 0, iteration>(); } else { using prev_iter_list = decltype(construct<iteration - 1>()); return construct_loop<prev_iter_list, 0, iteration>(); } } template <typename L, int pos> constexpr void show_ans() { if constexpr (std::is_same_v<typename L::head, fl::NIL>) return; else { if constexpr (L::head::value % 2 == 1) std::cout << "Door " << pos << " is opened.\n"; show_ans<typename L::tail, pos + 1>(); } } int main() { using result = decltype(construct<100>()); show_ans<result, 0>(); } C1R 100_doors Caché ObjectScript for i=1:1:100 { set doors(i) = 0 } for i=1:1:100 { for door=i:i:100 { Set doors(door)='doors(door) } } for i = 1:1:100 { if doors(i)=1 write i_": open",! } Output: 1: open 4: open 9: open 16: open 25: open 36: open 49: open 64: open 81: open 100: open Ceylon shared void run() { print("Open doors (naive): naive() Open doors (optimized): optimized()"); } shared {Integer*} naive(Integer count = 100) { variable value doors = [ for (_ in 1..count) closed ]; for (step in 1..count) { doors = [for (i->door in doors.indexed) let (index = i+1) if (step == 1 || step.divides(index)) then door.toggle() else door ]; } return doors.indexesWhere((door) => door == opened).map(1.plusInteger); } shared {Integer*} optimized(Integer count = 100) => { for (i in 1..count) i*i }.takeWhile(count.notSmallerThan); shared abstract class Door(shared actual String string) of opened | closed { shared formal Door toggle(); } object opened extends Door("opened") { toggle() => closed; } object closed extends Door("closed") { toggle() => opened; } Output: Open doors (naive): { 1, 4, 9, 16, 25, 36, 49, 64, 81, 100 } Open doors (optimized): { 1, 4, 9, 16, 25, 36, 49, 64, 81, 100 } Clarion program map end MAX_DOOR_NUMBER equate(100) CRLF equate('<13,10>') Doors byte,dim(MAX_DOOR_NUMBER) Pass byte DoorNumber byte DisplayString cstring(2000) ResultWindow window('Result'),at(,,133,291),center,double,auto prompt('Door states:'),at(8,4),use(?PromptTitle) text,at(8,16,116,266),use(DisplayString),boxed,vscroll,font('Courier New',,,,CHARSET:ANSI),readonly end code Doors :=: false loop Pass = 1 to MAX_DOOR_NUMBER loop DoorNumber = Pass to MAX_DOOR_NUMBER by Pass Doors[DoorNumber] = choose(Doors[DoorNumber], false, true) end end clear(DisplayString) loop DoorNumber = 1 to MAX_DOOR_NUMBER DisplayString = DisplayString & format(DoorNumber, @n3) & ' is ' & choose(Doors[DoorNumber], 'opened', 'closed') & CRLF end open(ResultWindow) accept end close(ResultWindow) return Clio Unoptimized fn visit-doors doors step: if step > 100: doors else: [1:100] -> * fn index: if index % step: doors[(index - 1)] else: not doors[(index - 1)] -> visit-doors (step + 1) [1:100] -> * n: false -> visit-doors 1 => doors [1:100] -> * (@eager) fn i: doors[(i - 1)] -> if = true: #open else: #closed -> print #Door i #is @ Optimized [1:100] -> * (@eager) fn i: i ^ 0.5 -> eq @ (transform i: floor) -> if = true: #open else: #closed -> print #Door i #is @ CLIPS Unoptimized (deffacts initial-state (door-count 100) ) (deffunction toggle (?state) (switch ?state (case "open" then "closed") (case "closed" then "open") ) ) (defrule create-doors-and-visits (door-count ?count) => (loop-for-count (?num 1 ?count) do (assert (door ?num "closed")) (assert (visit-from ?num ?num)) ) (assert (doors initialized)) ) (defrule visit (door-count ?max) ?visit <- (visit-from ?num ?step) ?door <- (door ?num ?state) => (retract ?visit) (retract ?door) (assert (door ?num (toggle ?state))) (if (<= (+ ?num ?step) ?max) then (assert (visit-from (+ ?num ?step) ?step)) ) ) (defrule start-printing (doors initialized) (not (visit-from ? ?)) => (printout t "These doors are open:" crlf) (assert (print-from 1)) ) (defrule print-door (door-count ?max) ?pf <- (print-from ?num) (door ?num ?state) => (retract ?pf) (if (= 0 (str-compare "open" ?state)) then (printout t ?num " ") ) (if (< ?num ?max) then (assert (print-from (+ ?num 1))) else (printout t crlf "All other doors are closed." crlf) ) ) Optimized (deffacts initial-state (door-count 100) ) (deffunction is-square (?num) (= (sqrt ?num) (integer (sqrt ?num))) ) (defrule check-doors (door-count ?count) => (printout t "These doors are open:" crlf) (loop-for-count (?num 1 ?count) do (if (is-square ?num) then (printout t ?num " ") ) ) (printout t crlf "All other doors are closed." crlf) ) Clojure Unoptimized / mutable array (defn doors [] (let [doors (into-array (repeat 100 false))] (doseq [pass (range 1 101) i (range (dec pass) 100 pass) ] (aset doors i (not (aget doors i)))) doors)) (defn open-doors [] (for [[d n] (map vector (doors) (iterate inc 1)) :when d] n)) (defn print-open-doors [] (println "Open doors after 100 passes:" (apply str (interpose ", " (open-doors))))) Unoptimized / functional (defn doors [] (reduce (fn [doors toggle-idx] (update-in doors [toggle-idx] not)) (into [] (repeat 100 false)) (for [pass (range 1 101) i (range (dec pass) 100 pass) ] i))) (defn open-doors [] (for [[d n] (map vector (doors) (iterate inc 1)) :when d] n)) (defn print-open-doors [] (println "Open doors after 100 passes:" (apply str (interpose ", " (open-doors))))) Alternative Unoptimized / functional (defn open-doors [] (->> (for [step (range 1 101), occ (range step 101 step)] occ) frequencies (filter (comp odd? val)) keys sort)) (defn print-open-doors [] (println "Open doors after 100 passes:" (apply str (interpose ", " (open-doors))))) Optimized / functional (defn doors [] (reduce (fn [doors idx] (assoc doors idx true)) (into [] (repeat 100 false)) (map #(dec (* % %)) (range 1 11)))) (defn open-doors [] (for [[d n] (map vector (doors) (iterate inc 1)) :when d] n)) (defn print-open-doors [] (println "Open doors after 100 passes:" (apply str (interpose ", " (open-doors))))) Alternative Optimized / functional (defn open-doors [] (->> (iterate inc 1) (map #(* % %)) (take-while #(<= % 100)))) (defn print-open-doors [] (println "Open doors after 100 passes:" (apply str (interpose ", " (open-doors))))) CLU start_up = proc () max = 100 po: stream := stream$primary_output()
open: array[bool] := array[bool]$fill(1, max, false) for pass: int in int$from_to(1, max) do
for door: int in int$from_to_by(pass, max, pass) do open[door] := ~open[door] end end for door: int in array[bool]$indexes(open) do
if open[door] then
stream$putl(po, "Door " || int$unparse(door) || " is open.")
end
end
end start_up
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.

COBOL

IDENTIFICATION DIVISION.
PROGRAM-ID. 100Doors.

DATA DIVISION.
WORKING-STORAGE SECTION.
01 Current-n PIC 9(3).
01 StepSize PIC 9(3).
01 DoorTable.
02 Doors PIC 9(1) OCCURS 100 TIMES.
88 ClosedDoor VALUE ZERO.
01 Idx PIC 9(3).

PROCEDURE DIVISION.
Begin.
INITIALIZE DoorTable
PERFORM VARYING StepSize FROM 1 BY 1 UNTIL StepSize > 100
PERFORM VARYING Current-n FROM StepSize BY StepSize
UNTIL Current-n > 100
SUBTRACT Doors (Current-n) FROM 1 GIVING Doors (Current-n)
END-PERFORM
END-PERFORM

PERFORM VARYING Idx FROM 1 BY 1
UNTIL Idx > 100
IF ClosedDoor (Idx)
DISPLAY Idx " is closed."
ELSE
DISPLAY Idx " is open."
END-IF
END-PERFORM

STOP RUN
.

Coco

We use the naive algorithm.

doors = [false] * 100

for pass til doors.length
for i from pass til doors.length by pass + 1
! = doors[i]

for i til doors.length
console.log 'Door %d is %s.', i + 1, if doors[i] then 'open' else 'closed'

CoffeeScript

unoptimized:

doors = []

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

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

# matrix output
console.log doors.map (open) -> +open

optimized:

isInteger = (i) -> Math.floor(i) == i

console.log door for door in [1..100] when isInteger Math.sqrt door

ultra-optimized:

console.log Math.pow(i,2) for i in [1..10]

ColdFusion

Basic Solution: Returns List of 100 values: 1=open 0=closed

doorCount = 1;
doorList = "";
// create all doors and set all doors to open
while (doorCount LTE 100) {
doorList = ListAppend(doorList,"1");
doorCount = doorCount + 1;
}
loopCount = 2;
doorListLen = ListLen(doorList);
while (loopCount LTE 100) {
loopDoorListCount = 1;
while (loopDoorListCount LTE 100) {
testDoor = loopDoorListCount / loopCount;
if (testDoor EQ Int(testDoor)) {
checkOpen = ListGetAt(doorList,loopDoorListCount);
if (checkOpen EQ 1) {
doorList = ListSetAt(doorList,loopDoorListCount,"0");
} else {
doorList = ListSetAt(doorList,loopDoorListCount,"1");
}
}
loopDoorListCount = loopDoorListCount + 1;
}
loopCount = loopCount + 1;
}

Squares of Integers Solution: Returns List of 100 values: 1=open 0=closed

doorCount = 1;
doorList = "";
loopCount = 1;
while (loopCount LTE 100) {
if (Sqr(loopCount) NEQ Int(Sqr(loopCount))) {
doorList = ListAppend(doorList,0);
} else {
doorList = ListAppend(doorList,1);
}
loopCount = loopCount + 1;
}

Display only

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

// Output only open doors
<cfloop from="1" to="100" index="x">
<cfif ListGetAt(doorList,x) EQ 1>
#x#<br />
</cfif>
</cfloop>

Another Route

<Cfparam name="doorlist" default="">
<cfloop from="1" to="100" index="i">
<Cfset doorlist = doorlist & 'c,'>
</cfloop>
<cfloop from="1" to="100" index="i">
<Cfloop from="1" to="100" index="door" step="#i#">
<Cfif listgetat(doorlist, door) eq 'c'>
<Cfset doorlist = listsetat(doorlist, door, 'O')>
<Cfelse>
<Cfset doorlist = listsetat(doorlist, door, 'c')>
</Cfif>
</Cfloop>
</cfloop>
<Cfoutput>#doorlist#</Cfoutput>

Commodore BASIC

10 D=100: DIMD(D): P=1
20 PRINT CHR$(147);"PASS: ";P 22 FOR I=P TO D STEP P: D(I)=NOTD(I): NEXT 30 IF P=100 THEN 40 32 P=P+1: GOTO20 40 PRINT: PRINT"THE FOLLOWING DOORS ARE OPEN: " 42 FOR I=1 TO D: IF D(I)=-1 THEN PRINTI; 44 NEXT 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; # one extra so we can start at 1 var 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] end end doors.each_with_index do |open, i| puts "Door #{i + 1} is #{open ? "open" : "closed"}" end D Unoptimized import std.stdio; const N = 101; // #doors + 1 void main() { bool[N] doors = false; for(auto door=1; door<N; door++ ) { for(auto i=door; i<N; i+=door ) doors[i] = !doors[i]; if (doors[door]) write(door, " "); } } Output: 1 4 9 16 25 36 49 64 81 100 Optimized The problem of the 100 doors is an algorithm to find the squares between 1 and 100. This optimized version prints these squares using an alternative algorithm based on $\sum _{i=1}^{n}(2i-1)=n^{2}$ import std.stdio; const N = 101; // #doors + 1 void main() { for( auto door=1,s=3; door<N; door+=s, s+=2 ) write(door, " "); } Output: 1 4 9 16 25 36 49 64 81 100 Other proposals 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 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 import 'dart:io'; final numDoors = 100; final List<bool> doorClosed = List(numDoors); String stateToString(String message) { var res = ''; for (var i = 0; i < numDoors; i++) { res += (doorClosed[i] ? 'X' : '\u2610'); } return res + " " + message; } main() { for (var i = 0; i < numDoors; i++) { doorClosed[i] = true; } stdout.writeln(stateToString("after initialization")); for (var step = 1; step <= numDoors; step++) { final start = step - 1; for (var i = start; i < numDoors; i += step) { doorClosed[i] = !doorClosed[i]; } stdout.writeln(stateToString("after toggling with step =$step"));
}
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX after initialization
☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐ after toggling with step = 1
☐X☐X☐X☐X☐X☐X☐X☐X☐X☐X☐X☐X☐X☐X☐X☐X☐X☐X☐X☐X☐X☐X☐X☐X☐X☐X☐X☐X☐X☐X☐X☐X☐X☐X☐X☐X☐X☐X☐X☐X☐X☐X☐X☐X☐X☐X☐X☐X☐X☐X after toggling with step = 2
☐XXX☐☐☐XXX☐☐☐XXX☐☐☐XXX☐☐☐XXX☐☐☐XXX☐☐☐XXX☐☐☐XXX☐☐☐XXX☐☐☐XXX☐☐☐XXX☐☐☐XXX☐☐☐XXX☐☐☐XXX☐☐☐XXX☐☐☐XXX☐☐☐XXX after toggling with step = 3
☐XX☐☐☐☐☐XX☐X☐XX☐☐☐☐☐XX☐X☐XX☐☐☐☐☐XX☐X☐XX☐☐☐☐☐XX☐X☐XX☐☐☐☐☐XX☐X☐XX☐☐☐☐☐XX☐X☐XX☐☐☐☐☐XX☐X☐XX☐☐☐☐☐XX☐X☐XX☐ after toggling with step = 4
☐XX☐X☐☐☐X☐☐X☐X☐☐☐☐☐XXX☐XXXX☐☐X☐☐XXXX☐XXX☐☐☐☐☐X☐X☐☐X☐☐☐X☐XX☐☐☐XX☐X☐☐☐X☐☐X☐X☐☐☐☐☐XXX☐XXXX☐☐X☐☐XXXX☐XXX after toggling with step = 5
☐XX☐XX☐☐X☐☐☐☐X☐☐☐X☐XXX☐☐XXX☐☐☐☐☐XXX☐☐XXX☐X☐☐☐X☐☐☐☐X☐☐XX☐XX☐X☐XX☐XX☐☐X☐☐☐☐X☐☐☐X☐XXX☐☐XXX☐☐☐☐☐XXX☐☐XXX after toggling with step = 6
☐XX☐XXX☐X☐☐☐☐☐☐☐☐X☐X☐X☐☐XXXX☐☐☐☐XX☐☐☐XXX☐☐☐☐☐X☐☐X☐X☐☐XXXXX☐X☐X☐☐XX☐☐XX☐☐☐X☐☐XX☐XXX☐XXXX☐☐☐X☐XXX☐☐☐XX after toggling with step = 7
☐XX☐XXXXX☐☐☐☐☐☐X☐X☐X☐X☐XXXXX☐☐☐XXX☐☐☐XX☐☐☐☐☐☐X☐XX☐X☐☐XX☐XX☐X☐X☐XXX☐☐XX☐X☐X☐☐XX☐☐XX☐XXXXX☐☐X☐XXXX☐☐XX after toggling with step = 8
☐XX☐XXXX☐☐☐☐☐☐☐X☐☐☐X☐X☐XXX☐X☐☐☐XXX☐X☐XX☐☐☐☐☐XX☐XX☐X☐☐☐X☐XX☐X☐XXXXX☐☐XX☐☐☐X☐☐XX☐☐☐X☐XXXXX☐XX☐XXXX☐☐☐X after toggling with step = 9
☐XX☐XXXX☐X☐☐☐☐☐X☐☐☐☐☐X☐XXX☐X☐X☐XXX☐X☐XXX☐☐☐☐XX☐XXXX☐☐☐X☐XX☐☐☐XXXXX☐☐X☐☐☐☐X☐☐XX☐X☐X☐XXXXX☐☐X☐XXXX☐☐☐☐ after toggling with step = 10
☐XX☐XXXX☐XX☐☐☐☐X☐☐☐☐☐☐☐XXX☐X☐X☐X☐X☐X☐XXX☐☐☐XXX☐XXXX☐☐☐☐☐XX☐☐☐XXXX☐☐☐X☐☐☐☐X☐☐☐X☐X☐X☐XXXX☐☐☐X☐XXXX☐☐X☐ after toggling with step = 11
☐XX☐XXXX☐XXX☐☐☐X☐☐☐☐☐☐☐☐XX☐X☐X☐X☐X☐☐☐XXX☐☐☐XXX☐☐XXX☐☐☐☐☐XX☐X☐XXXX☐☐☐X☐☐X☐X☐☐☐X☐X☐X☐☐XXX☐☐☐X☐XXX☐☐☐X☐ after toggling with step = 12
☐XX☐XXXX☐XXXX☐☐X☐☐☐☐☐☐☐☐X☐☐X☐X☐X☐X☐☐☐X☐X☐☐☐XXX☐☐XXXX☐☐☐☐XX☐X☐XXX☐☐☐☐X☐☐X☐X☐☐☐☐☐X☐X☐☐XXX☐☐☐☐☐XXX☐☐☐X☐ after toggling with step = 13
☐XX☐XXXX☐XXXXX☐X☐☐☐☐☐☐☐☐X☐☐☐☐X☐X☐X☐☐☐X☐X☐X☐XXX☐☐XXXX☐☐☐XXX☐X☐XXX☐☐☐☐XX☐X☐X☐☐☐☐☐X☐X☐XXXX☐☐☐☐☐XXX☐☐XX☐ after toggling with step = 14
☐XX☐XXXX☐XXXXXXX☐☐☐☐☐☐☐☐X☐☐☐☐☐☐X☐X☐☐☐X☐X☐X☐X☐X☐☐XXXX☐☐☐XXX☐☐☐XXX☐☐☐☐XX☐X☐XX☐☐☐☐X☐X☐XXXX☐☐X☐☐XXX☐☐XX☐ after toggling with step = 15
☐XX☐XXXX☐XXXXXX☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐X☐☐☐X☐X☐X☐X☐X☐XXXXX☐☐☐XXX☐☐☐XX☐☐☐☐☐XX☐X☐XX☐☐☐☐☐☐X☐XXXX☐☐X☐☐XXXX☐XX☐ after toggling with step = 16
☐XX☐XXXX☐XXXXXX☐X☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐X☐X☐X☐X☐X☐XXX☐X☐☐☐XXX☐☐☐XX☐☐☐☐XXX☐X☐XX☐☐☐☐☐☐X☐X☐XX☐☐X☐☐XXXX☐XX☐ after toggling with step = 17
☐XX☐XXXX☐XXXXXX☐XX☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐X☐X☐X☐X☐X☐X☐XXX☐X☐X☐XXX☐☐☐XX☐☐☐☐XXX☐☐☐XX☐☐☐☐☐☐X☐X☐XX☐☐☐☐☐XXXX☐XX☐ after toggling with step = 18
☐XX☐XXXX☐XXXXXX☐XXX☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐X☐☐☐X☐X☐X☐X☐XXX☐X☐X☐X☐X☐☐☐XX☐☐☐☐XXX☐☐☐XXX☐☐☐☐☐X☐X☐XX☐☐☐☐☐XX☐X☐XX☐ after toggling with step = 19
☐XX☐XXXX☐XXXXXX☐XXXX☐☐☐☐X☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐X☐X☐X☐XXX☐X☐X☐X☐X☐X☐XX☐☐☐☐XXX☐☐☐XXX☐☐☐X☐X☐X☐XX☐☐☐☐☐XX☐X☐XXX after toggling with step = 20
☐XX☐XXXX☐XXXXXX☐XXXXX☐☐☐X☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐X☐X☐XXX☐X☐X☐X☐X☐X☐X☐☐☐☐☐XXX☐☐☐XXX☐☐☐X☐X☐☐☐XX☐☐☐☐☐XX☐X☐XXX after toggling with step = 21
☐XX☐XXXX☐XXXXXX☐XXXXXX☐☐X☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐X☐XXX☐X☐X☐X☐X☐X☐X☐☐☐X☐XXX☐☐☐XXX☐☐☐X☐X☐☐☐XXX☐☐☐☐XX☐X☐XXX after toggling with step = 22
☐XX☐XXXX☐XXXXXX☐XXXXXXX☐X☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐XXX☐X☐X☐X☐X☐X☐X☐☐☐X☐X☐X☐☐☐XXX☐☐☐X☐X☐☐☐XXX☐☐☐XXX☐X☐XXX after toggling with step = 23
☐XX☐XXXX☐XXXXXX☐XXXXXXXXX☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐XX☐X☐X☐X☐X☐X☐X☐☐☐X☐X☐X☐X☐XXX☐☐☐X☐X☐☐☐XXX☐☐☐XXX☐☐☐XXX after toggling with step = 24
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐X☐☐X☐X☐X☐X☐X☐X☐☐☐X☐X☐X☐X☐X☐X☐☐☐X☐X☐☐☐XXX☐☐☐XXX☐☐☐XX☐ after toggling with step = 25
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐X☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐X☐X☐X☐X☐X☐☐☐X☐X☐X☐X☐X☐X☐X☐X☐X☐☐☐XXX☐☐☐XXX☐☐☐XX☐ after toggling with step = 26
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XX☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐X☐X☐X☐X☐☐☐X☐X☐X☐X☐X☐X☐X☐XXX☐☐☐XXX☐☐☐XXX☐☐☐XX☐ after toggling with step = 27
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXX☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐X☐X☐X☐☐☐X☐X☐X☐X☐X☐X☐X☐XXX☐X☐XXX☐☐☐XXX☐☐☐XX☐ after toggling with step = 28
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXX☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐X☐X☐☐☐X☐X☐X☐X☐X☐X☐X☐XXX☐X☐X☐X☐☐☐XXX☐☐☐XX☐ after toggling with step = 29
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXX☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐X☐X☐X☐X☐X☐X☐X☐XXX☐X☐X☐X☐X☐XXX☐☐☐XX☐ after toggling with step = 30
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXX☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X☐X☐X☐X☐X☐X☐X☐XXX☐X☐X☐X☐X☐X☐X☐☐☐XX☐ after toggling with step = 31
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXX☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐X☐X☐X☐X☐X☐X☐X☐X☐XXX☐X☐X☐X☐X☐X☐X☐X☐XX☐ after toggling with step = 32
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXX☐☐X☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐X☐X☐X☐X☐X☐X☐XXX☐X☐X☐X☐X☐X☐X☐X☐X☐☐ after toggling with step = 33
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXX☐X☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐X☐X☐X☐X☐X☐XXX☐X☐X☐X☐X☐X☐X☐X☐X☐☐ after toggling with step = 34
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXXX☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐X☐X☐X☐X☐XXX☐X☐X☐X☐X☐X☐X☐X☐X☐☐ after toggling with step = 35
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐X☐X☐X☐XXX☐X☐X☐X☐X☐X☐X☐X☐X☐☐ after toggling with step = 36
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐X☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐X☐X☐XXX☐X☐X☐X☐X☐X☐X☐X☐X☐☐ after toggling with step = 37
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XX☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐X☐XXX☐X☐X☐X☐X☐X☐X☐X☐X☐☐ after toggling with step = 38
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXX☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐XXX☐X☐X☐X☐X☐X☐X☐X☐X☐☐ after toggling with step = 39
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXX☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐XX☐X☐X☐X☐X☐X☐X☐X☐X☐☐ after toggling with step = 40
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXX☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X☐☐X☐X☐X☐X☐X☐X☐X☐X☐☐ after toggling with step = 41
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXX☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐X☐X☐X☐X☐X☐X☐X☐☐ after toggling with step = 42
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXX☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐X☐X☐X☐X☐X☐X☐☐ after toggling with step = 43
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXX☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐X☐X☐X☐X☐X☐☐ after toggling with step = 44
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXX☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐X☐X☐X☐X☐☐ after toggling with step = 45
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXX☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐X☐X☐X☐☐ after toggling with step = 46
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXX☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐X☐X☐☐ after toggling with step = 47
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXXX☐☐☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X☐☐ after toggling with step = 48
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐ after toggling with step = 49
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐X☐☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X after toggling with step = 50
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐XX☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X after toggling with step = 51
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐XXX☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X after toggling with step = 52
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐XXXX☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X after toggling with step = 53
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐XXXXX☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X after toggling with step = 54
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐XXXXXX☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X after toggling with step = 55
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐XXXXXXX☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X after toggling with step = 56
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐XXXXXXXX☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X after toggling with step = 57
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐XXXXXXXXX☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X after toggling with step = 58
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐XXXXXXXXXX☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X after toggling with step = 59
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐XXXXXXXXXXX☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X after toggling with step = 60
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐XXXXXXXXXXXX☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X after toggling with step = 61
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐XXXXXXXXXXXXX☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X after toggling with step = 62
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐XXXXXXXXXXXXXXX☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X after toggling with step = 63
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐XXXXXXXXXXXXXX☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X after toggling with step = 64
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐XXXXXXXXXXXXXX☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X after toggling with step = 65
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐XXXXXXXXXXXXXX☐XX☐☐☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X after toggling with step = 66
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐XXXXXXXXXXXXXX☐XXX☐☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X after toggling with step = 67
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐XXXXXXXXXXXXXX☐XXXX☐☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X after toggling with step = 68
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐XXXXXXXXXXXXXX☐XXXXX☐☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X after toggling with step = 69
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐XXXXXXXXXXXXXX☐XXXXXX☐☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X after toggling with step = 70
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐XXXXXXXXXXXXXX☐XXXXXXX☐☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X after toggling with step = 71
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐XXXXXXXXXXXXXX☐XXXXXXXX☐☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X after toggling with step = 72
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐XXXXXXXXXXXXXX☐XXXXXXXXX☐☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X after toggling with step = 73
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐XXXXXXXXXXXXXX☐XXXXXXXXXX☐☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X after toggling with step = 74
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐XXXXXXXXXXXXXX☐XXXXXXXXXXX☐☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X after toggling with step = 75
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐XXXXXXXXXXXXXX☐XXXXXXXXXXXX☐☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X after toggling with step = 76
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐XXXXXXXXXXXXXX☐XXXXXXXXXXXXX☐☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X after toggling with step = 77
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐XXXXXXXXXXXXXX☐XXXXXXXXXXXXXX☐☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X after toggling with step = 78
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐XXXXXXXXXXXXXX☐XXXXXXXXXXXXXXX☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X after toggling with step = 79
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐XXXXXXXXXXXXXX☐XXXXXXXXXXXXXXXXX☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X after toggling with step = 80
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐XXXXXXXXXXXXXX☐XXXXXXXXXXXXXXXX☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X after toggling with step = 81
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐XXXXXXXXXXXXXX☐XXXXXXXXXXXXXXXX☐X☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X after toggling with step = 82
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐XXXXXXXXXXXXXX☐XXXXXXXXXXXXXXXX☐XX☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X after toggling with step = 83
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐XXXXXXXXXXXXXX☐XXXXXXXXXXXXXXXX☐XXX☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐X after toggling with step = 84
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐XXXXXXXXXXXXXX☐XXXXXXXXXXXXXXXX☐XXXX☐☐☐☐☐☐☐☐☐☐☐☐☐☐X after toggling with step = 85
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐XXXXXXXXXXXXXX☐XXXXXXXXXXXXXXXX☐XXXXX☐☐☐☐☐☐☐☐☐☐☐☐☐X after toggling with step = 86
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐XXXXXXXXXXXXXX☐XXXXXXXXXXXXXXXX☐XXXXXX☐☐☐☐☐☐☐☐☐☐☐☐X after toggling with step = 87
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐XXXXXXXXXXXXXX☐XXXXXXXXXXXXXXXX☐XXXXXXX☐☐☐☐☐☐☐☐☐☐☐X after toggling with step = 88
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐XXXXXXXXXXXXXX☐XXXXXXXXXXXXXXXX☐XXXXXXXX☐☐☐☐☐☐☐☐☐☐X after toggling with step = 89
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐XXXXXXXXXXXXXX☐XXXXXXXXXXXXXXXX☐XXXXXXXXX☐☐☐☐☐☐☐☐☐X after toggling with step = 90
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐XXXXXXXXXXXXXX☐XXXXXXXXXXXXXXXX☐XXXXXXXXXX☐☐☐☐☐☐☐☐X after toggling with step = 91
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐XXXXXXXXXXXXXX☐XXXXXXXXXXXXXXXX☐XXXXXXXXXXX☐☐☐☐☐☐☐X after toggling with step = 92
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐XXXXXXXXXXXXXX☐XXXXXXXXXXXXXXXX☐XXXXXXXXXXXX☐☐☐☐☐☐X after toggling with step = 93
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐XXXXXXXXXXXXXX☐XXXXXXXXXXXXXXXX☐XXXXXXXXXXXXX☐☐☐☐☐X after toggling with step = 94
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐XXXXXXXXXXXXXX☐XXXXXXXXXXXXXXXX☐XXXXXXXXXXXXXX☐☐☐☐X after toggling with step = 95
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐XXXXXXXXXXXXXX☐XXXXXXXXXXXXXXXX☐XXXXXXXXXXXXXXX☐☐☐X after toggling with step = 96
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐XXXXXXXXXXXXXX☐XXXXXXXXXXXXXXXX☐XXXXXXXXXXXXXXXX☐☐X after toggling with step = 97
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐XXXXXXXXXXXXXX☐XXXXXXXXXXXXXXXX☐XXXXXXXXXXXXXXXXX☐X after toggling with step = 98
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐XXXXXXXXXXXXXX☐XXXXXXXXXXXXXXXX☐XXXXXXXXXXXXXXXXXXX after toggling with step = 99
☐XX☐XXXX☐XXXXXX☐XXXXXXXX☐XXXXXXXXXX☐XXXXXXXXXXXX☐XXXXXXXXXXXXXX☐XXXXXXXXXXXXXXXX☐XXXXXXXXXXXXXXXXXX☐ after toggling with step = 100

Dc

Unoptimized:

Works with: GNU dc version 1.3.95

## NB: This code uses the dc command "r" via register "r".
## You may comment out the unwanted version.
[SxSyLxLy]sr # this should work with every "dc"
[r]sr # GNU dc can exchange top 2 stack values by "r"
## Now use "lrx" instead of "r" ...

0k # we work without decimal places
[q]sq # useful e.g. as loop termination

## (x)(y)>R == if (y)>(x) eval R
## isle x y --> (x <= y)
[
[1q]S. [ !<. 0 ]x s.L.
]sl
## l: isle

[
100 llx
]sL
## L: isle100

## for initcode condcode incrcode body
##    
[
[q]S. 4:. 3:. 2:. 1:. 1;.x [2;.x 0=. 4;.x 3;.x 0;.x]d0:.x Os.L.o
]sf
## f: for
##----------------------------------------------------------------------------

## for( i=1 ; i<=100 ; ++i ) {
## door[i] = 0;
## }
#[init ...]P []ps-
[1si] [li lLx] [li1+si] [
li 0:d
]lfx

## for( s=1 ; s<=100 ; ++s ) {
## for( i=s ; i<=100 ; i+=s ) {
## door[i] = 1 - door[i]
## }
## }
[1ss] [ls lLx] [ls1+ss] [
#[step ]P lsn [ ...]ps-
[lssi] [li lLx] [lils+si] [
1 li;d - li:d
]lfx
]lfx

## long output:
## for( i=1 ; i<=100 ; ++i ) {
## print "door #", i, " is ", (door[i] ? "open" : "closed")), NL
## }
[
[1si] [li lLx] [li1+si] [
[door #]P
li n
[ is ]P
[closed]
[open]
li;d 0=r lrx s- n
[.]ps-
]lfx
]

## terse output:
## for( i=1 ; i<=100 ; ++i ) {
## if( door[i] ) {
## print i
## }
## print NL
## }
[
[1si] [li lLx] [li1+si] [
[] [ [ ]n lin ]
li;d 0=r lrx s- x
]lfx
[]ps-
]

lrx # comment out for the long output version
s- x
#[stack rest...]P []ps- f

Output:

1 4 9 16 25 36 49 64 81 100

DCL

$! doors.com$! Excecute by running @doors at prompt.
$square = 1$ incr = 3
$count2 = 0$ d = 1
$LOOP2:$ count2 = count2 + 1
$IF (d .NE. square)$ THEN WRITE SYS$OUTPUT "door ''d' is closed"$ ELSE WRITE SYS$OUTPUT "door ''d' is open"$ square = incr + square
$incr = incr + 2$ ENDIF
$d = d + 1$ IF (count2 .LT. 100) THEN GOTO LOOP2

See Pascal

Draco

proc nonrec main() void:
byte DOORS = 100;
[DOORS+1] bool door_open;
unsigned DOORS i, j;

/* make sure all doors are closed */
for i from 1 upto DOORS do door_open[i] := false od;

/* pass through the doors */
for i from 1 upto DOORS do
for j from i by i upto DOORS do
door_open[j] := not door_open[j]
od
od;

/* show the open doors */
for i from 1 upto DOORS do
if door_open[i] then
writeln("Door ", i, " is open.")
fi
od
corp
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.

DUP

100[$][0^:1-]# {initialize doors} % [s;[$101<][$$;~\:s;+]#%]d: {function d, switch door state function} 1s:[s;101<][d;!s;1+s:]# {increment step width from 1 to 100, execute function d each time} 1[101<][$$.' ,;['o,'p,'e,'n,10,]['c,'l,'o,'s,'e,'d,10,]?1+]# {loop through doors, print door number and state}

Result:

1 open
2 closed
3 closed
4 open
5 closed
6 closed
7 closed
8 closed
9 open
10 closed
11 closed
12 closed
...
94 closed
95 closed
96 closed
97 closed
98 closed
99 closed
100 open

Compare this solution to the FALSE solution of this problem.

DWScript

Unoptimized

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

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

for i := 1 to 100 do
if doors[i] then
PrintLn('Door '+IntToStr(i)+' is open');

Dyalect

Outputs only open doors to save up space:

var doors = Array.empty(100, false)

for p in 0..99 {
for d in 0..99 {
if (d + 1) % (p + 1) == 0 {
doors[d] = !doors[d];
}
}
}

for d in doors.indices() when doors[d] {
print("Door $$d+1): Open") } 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 Dylan Unoptimized define method doors() let doors = make(<array>, fill: #f, size: 100); for (x from 0 below 100) for (y from x below 100 by x + 1) doors[y] := ~doors[y] end end; for (x from 1 to 100) if (doors[x - 1]) format-out("door %d open\n", x) end end end Déjà Vu local :open-doors [ rep 101 false ] for i range 1 100: local :j i while <= j 100: set-to open-doors j not open-doors! j set :j + j i !print\ "Open doors: " for i range 1 100: if open-doors! i: !print\( to-str i " " ) Output: Open doors: 1 4 9 16 25 36 49 64 81 100 E Graphical Works with: E-on-Java This version animates the changes of the doors (as checkboxes). #!/usr/bin/env rune var toggles := [] var gets := [] # Set up GUI (and data model) def frame := <swing:makeJFrame>("100 doors") frame.getContentPane().setLayout(<awt:makeGridLayout>(10, 10)) for i in 1..100 { def component := <import:javax.swing.makeJCheckBox>(E.toString(i)) toggles with= fn { component.setSelected(!component.isSelected()) } gets with= fn { component.isSelected() } frame.getContentPane().add(component) } # Set up termination condition def done frame.addWindowListener(def _ { to windowClosing(event) { bind done := true } match _ {} }) # Open and close doors def loop(step, i) { toggles[i] <- () def next := i + step timer.whenPast(timer.now() + 10, fn { if (next >= 100) { if (step >= 100) { # Done. } else { loop <- (step + 1, step) } } else { loop <- (step, i + step) } }) } loop(1, 0) frame.pack() frame.show() interp.waitAtTop(done) EasyLang len d[] 101 for p = 1 to 100 i = p while i <= 100 d[i] = 1 - d[i] i += p . . for i = 1 to 100 if d[i] = 1 print i . . EchoLisp The result is obviously the same in we run the process backwards. So, we check the state of each door during the 100-th step (opening/closing every door) ; initial state = closed = #f (define doors (make-vector 101 #f)) ; run pass 100 to 1 (for* ((pass (in-range 100 0 -1)) (door (in-range 0 101 pass))) (when (and (vector-set! doors door (not (vector-ref doors door))) (= pass 1)) (writeln door "is open"))) 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" ECL optimized version Doors := RECORD UNSIGNED1 DoorNumber; STRING6 State; END; AllDoors := DATASET([{0,0}],Doors); Doors OpenThem(AllDoors L,INTEGER Cnt) := TRANSFORM SELF.DoorNumber := Cnt; SELF.State := IF((CNT * 10) % (SQRT(CNT)*10)<>0,'Closed','Opened'); END; OpenDoors := NORMALIZE(AllDoors,100,OpenThem(LEFT,COUNTER)); OpenDoors; unoptimized version - demonstrating LOOP Doors := RECORD UNSIGNED1 DoorNumber; STRING6 State; END; AllDoors := DATASET([{0,'0'}],Doors); //first build the 100 doors Doors OpenThem(AllDoors L,INTEGER Cnt) := TRANSFORM SELF.DoorNumber := Cnt; SELF.State := 'Closed'; END; ClosedDoors := NORMALIZE(AllDoors,100,OpenThem(LEFT,COUNTER)); //now iterate through them and use door logic loopBody(DATASET(Doors) ds, UNSIGNED4 c) := PROJECT(ds, //ds=original input TRANSFORM(Doors, SELF.State := CASE((COUNTER % c) * 100, 0 => IF(LEFT.STATE = 'Opened','Closed','Opened') ,LEFT.STATE); SELF.DoorNumber := COUNTER; //PROJECT COUNTER )); g1 := LOOP(ClosedDoors,100,loopBody(ROWS(LEFT),COUNTER)); OUTPUT(g1); unoptimized version - using ITERATE This is a bit more efficient than the LOOP version DoorSet := DATASET(100,TRANSFORM({UNSIGNED1 DoorState},SELF.DoorState := 1)); SetDoors := SET(DoorSet,DoorState); Doors := RECORD UNSIGNED1 Pass; SET OF UNSIGNED1 DoorSet; END; StartDoors := DATASET(100,TRANSFORM(Doors,SELF.Pass := COUNTER,SELF.DoorSet := SetDoors)); Doors XF(Doors L, Doors R) := TRANSFORM ds := DATASET(L.DoorSet,{UNSIGNED1 DoorState}); NextDoorSet := PROJECT(ds, TRANSFORM({UNSIGNED1 DoorState}, SELF.DoorState := CASE((COUNTER % R.Pass) * 100, 0 => IF(LEFT.DoorState = 1,0,1), LEFT.DoorState))); SELF.DoorSet := IF(L.Pass=0,R.DoorSet,SET(NextDoorSet,DoorState)); SELF.Pass := R.Pass END; Res := DATASET(ITERATE(StartDoors,XF(LEFT,RIGHT)).DoorSet,{UNSIGNED1 DoorState}); PROJECT(Res,TRANSFORM({STRING20 txt},SELF.Txt := 'Door ' + COUNTER + ' is ' + IF(LEFT.DoorState=1,'Open','Closed'))); EDSAC order code Since there are only 100 doors, we'll keep things simple and use a whole EDSAC location for each door. A single bit would be enough, but that would make the code much longer. The program works through the array of doors by modifying its own orders (instructions). This would be considered bad practice today, but was quite usual on the EDSAC. [Hundred doors problem from Rosetta Code website] [EDSAC program, Initial Orders 2] [Library subroutine M3. Prints header and is then overwritten. Here, the last character sets the teleprinter to figures.] [email protected]@E8FEZPF @&*[email protected]&# ..PZ [blank tape, needed to mark end of header text] [Library subroutine P6. Prints strictly positive integer. 32 locations; working locations 1, 4, 5] T56K [define load address for subroutine] [email protected]@[email protected]@[email protected] [email protected] [email protected]@[email protected]@J995FJF!F T88K [define load address for main program] GK [set @ (theta) for relative addresses] [The 100 doors are at locations 200..299. Doors are numbered 0..99 internally, and 1..100 for output. The base address and the number of doors can be varied. The value of a door is 0 if open, negative if closed.] [Constants. Program also uses order 'P 1 F' which is permanently at absolute address 2.]  P200F [address of door #0]  P100F [number of doors, as an address]  UF [makes S order from T, since 'S' = 'T' + 'U']  MF [makes A order from T, since 'A' = 'T' + 'M']  V2047D [all 1's for "closed" (any negative value will do)]  &F [line feed]  @F [carriage return]  K4096F [teleprinter null[ [Variables]  PF [pass number; step when toggling doors]  PF [door number, as address, 0-based]  PF [order referring to door 0] [Enter with acc = 0] [Part 1 : close all the doors]  [email protected] [pass := 0 (used in part 2)] [email protected] [door number := 0] [email protected] [load 'T F' order] [email protected] [add base address] [email protected] [store T order for door #0]  TF [clear acc; also serves as constant] [email protected] [load door number] [email protected] [make T order] [email protected] [plant in code] [email protected] [load value for "closed"]  TF [store in current door] [email protected] [load door number] A2F [add 1] [email protected] [update door number] [email protected] [done all doors yet?] [email protected] [if not, loop back] [Part 2 : 100 passes, toggling the doors]  TF [clear acc] [email protected] [load pass number] A2F [add 1] [email protected] [save updated pass number] S2F [make -1] [email protected] [door number := -1] [email protected] [add pass number to get first door toggled on this pass] [email protected] [gone beyond end?] [email protected] [if so, move on to part 3]  [email protected] [restore acc after test] [email protected] [store current door number] [email protected] [make T order to load status] [email protected] [plant T order for first door in pass] [email protected] [convert to S order] [email protected] [plant S order] [email protected] [load value for "closed"]  SF [subtract status; toggles status]  TF [update status] [email protected] [load door number just toggled] [email protected] [add pass number to get next door in pass] [email protected] [gone beyond end?] [email protected] [no, loop to do next door] [email protected] [yes, loop to do next pass] [Part 3 : Print list of open doors. Header has set teleprinter to figures.]  TF [clear acc] [email protected] [door nr := 0] [email protected] [T order for door 0] [email protected] [convert to A order] [email protected]  TF [email protected] [load door number] [email protected] [make A order to load value] [email protected] [plant in next order]  AF [acc := 0 if open, < 0 if closed] [email protected] [skip if closed] [email protected] [door number as address] A2F [add 1 for 1-based output] RD [shift 1 right, address --> integer] TF [store integer at 0 for printing]  [email protected] [for return from subroutine] G56F [call subroutine to print door number] [email protected] [followed by CRLF] [email protected]  TF [clear acc] [email protected] [load door number] A2F [add 1] [email protected] [update door number] [email protected] [done all doors yet?] [email protected] [if not, loop back]  [email protected] [output null to flush teleprinter buffer] ZF [stop] E11Z [define relative start address] PF Output: THE OPEN DOORS ARE 1 4 9 16 25 36 49 64 81 100 Eero #import <Foundation/Foundation.h> int main() square := 1, increment = 3 for int door in 1 .. 100 printf("door #%d", door) if door == square puts(" is open.") square += increment increment += 2 else puts(" is closed.") return 0 Egel import "prelude.eg" using System using List data open, closed def toggle = [ open N -> closed N | closed N -> open N ] def doors = [ N -> map [ N -> closed N ] (fromto 1 N) ] def toggleK = [ K nil -> nil | K (cons (D N) DD) -> let DOOR = if (N%K) == 0 then toggle (D N) else D N in cons DOOR (toggleK K DD) ] def toggleEvery = [ nil DOORS -> DOORS | (cons K KK) DOORS -> toggleEvery KK (toggleK K DOORS) ] def run = [ N -> toggleEvery (fromto 1 N) (doors N) ] def main = run 100 EGL program OneHundredDoors function main() doors boolean[] = new boolean; n int = 100; for (i int from 1 to n) for (j int from i to n by i) doors[j] = !doors[j]; end end for (i int from 1 to n) if (doors[i]) SysLib.writeStdout( "Door " + i + " is open" ); end end end end Eiffel This is my first RosettaCode submission, as well as a foray into Eiffel for myself. I've tried to adhere to the description of the problem statement, as well as showcase a few Eiffelisms shown in the documentation. The replacement code below took the original code and has made improvements in some ways, such as: 1. Removal of "magic" many magic numbers and strings. 2. Refactor of various code blocks to routines (commands and queries with good CQS). 3. Utilization/Demonstration of full, secret, and selective feature exporting. 4. Utilization/Demonstration of constants as expanded type constants and once-functions. 5. Utilization/Demonstration of static-references (e.g. {APPLICATION}.min_door_count). 6. Utilization/Demonstration of "like" keyword type anchoring (e.g. a_index_address: like {DOOR}.address). 7. Utilization/Demonstration of semi-strict logical implication (e.g. consistency: is_open implies not Is_closed). 8. Utilization/Demonstration of contracts, including require, ensure, and class invariant. 9. Utilization/Demonstration of agent and do_all' call on ITERABLE type. 10. Utilization/Demonstration of various forms of across including "loop" and "all". ... as well as other Eiffel-ism's and some coding standards/best-practices. file: application.e note description: "100 Doors problem" date: "08-JUL-2015" revision: "1.1" class APPLICATION create make feature {NONE} -- Initialization make -- Main application routine. do initialize_closed_doors toggle_doors output_door_states end feature -- Access doors: ARRAYED_LIST [DOOR] -- A set of doors (self-initialized to capacity of max_door_count'). attribute create Result.make (max_door_count) end feature -- Basic Operations initialize_closed_doors -- Initialize all doors'. do across min_door_count |..| max_door_count as ic_address_list loop doors.extend (create {DOOR}.make_closed (ic_address_list.item)) end ensure has_all_closed_doors: across doors as ic_doors_list all not ic_doors_list.item.is_open end end toggle_doors -- Toggle all doors'. do across min_door_count |..| max_door_count as ic_addresses_list loop across doors as ic_doors_list loop if is_door_to_toggle (ic_doors_list.item.address, ic_addresses_list.item) then ic_doors_list.item.toggle_door end end end end output_door_states -- Output the state of all doors'. do doors.do_all (agent door_state_out) end feature -- Status Report is_door_to_toggle (a_door_address, a_index_address: like {DOOR}.address): BOOLEAN -- Is the door at a_door_address' needing to be toggled, when compared to a_index_address'? do Result := a_door_address \\ a_index_address = 0 ensure only_modulus_zero: Result = (a_door_address \\ a_index_address = 0) end feature -- Outputs door_state_out (a_door: DOOR) -- Output the state of a_door'. do print ("Door " + a_door.address.out + " is ") if a_door.is_open then print ("open.") else print ("closed.") end io.new_line end feature {DOOR} -- Constants min_door_count: INTEGER = 1 -- Minimum number of doors. max_door_count: INTEGER = 100 -- Maximum number of doors. end file: door.e note description: "A door with an address and an open or closed state." date: "08-JUL-2015" revision: "1.1" class DOOR create make_closed, make feature {NONE} -- initialization make_closed (a_address: INTEGER) -- Initialize Current {DOOR} at a_address' and state of Is_closed'. require positive: a_address >= {APPLICATION}.min_door_count and a_address >= Min_door_count do make (a_address, Is_closed) ensure closed: is_open = Is_closed end make (a_address: INTEGER; a_status: BOOLEAN) -- Initialize Current {DOOR} with a_address' and a_status', denoting position and is_open' or Is_closed'. require positive: a_address >= {APPLICATION}.min_door_count and a_address >= Min_door_count do address := a_address is_open := a_status ensure address_set: address = a_address status_set: is_open = a_status end feature -- access address: INTEGER -- address' of Current {DOOR}. is_open: BOOLEAN assign set_open -- is_open' (or not) status of Current {DOOR}. feature -- Setters set_open (a_status: BOOLEAN) -- Set status' with a_status' do is_open := a_status ensure open_updated: is_open = a_status end feature {APPLICATION} -- Basic Operations toggle_door -- Toggle Current {DOOR} from is_open' to not is_open'. do is_open := not is_open ensure toggled: is_open /= old is_open end feature {NONE} -- Implementation: Constants Is_closed: BOOLEAN = False -- State of being not is_open'. Min_door_count: INTEGER = 1 -- Minimum door count. invariant one_or_more: address >= 1 consistency: is_open implies not Is_closed end Ela Standard Approach open generic type Door = Open | Closed deriving Show gate [] _ = [] gate (x::xs) (y::ys) | x == y = Open :: gate xs ys | else = Closed :: gate xs ys run n = gate [1..n] [& k*k \\ k <- [1..]] Alternate Approach open list run n = takeWhile (<n) [& k*k \\ k <- [1..]] Elena ELENA 4.0 : import system'routines; import extensions; public program() { var Doors := Array.allocate(100).populate:(n=>false); for(int i := 0, i < 100, i := i + 1) { for(int j := i, j < 100, j := j + i + 1) { Doors[j] := Doors[j].Inverted } }; for(int i := 0, i < 100, i := i + 1) { console.printLine("Door #",i + 1," :",Doors[i].iif("Open","Closed")) }; console.readChar() } Elixir defmodule HundredDoors do def doors(n \\ 100) do List.duplicate(false, n) end def toggle(doors, n) do List.update_at(doors, n, &(!&1)) end def toggle_every(doors, n) do Enum.reduce( Enum.take_every((n-1)..99, n), doors, fn(n, acc) -> toggle(acc, n) end ) end end # unoptimized final_state = Enum.reduce(1..100, HundredDoors.doors, fn(n, acc) -> HundredDoors.toggle_every(acc, n) end) open_doors = Enum.with_index(final_state) |> Enum.filter_map(fn {door,_} -> door end, fn {_,index} -> index+1 end) IO.puts "All doors are closed except these: #{inspect open_doors}" # optimized final_state = Enum.reduce(1..10, HundredDoors.doors, fn(n, acc) -> HundredDoors.toggle(acc, n*n-1) end) open_doors = Enum.with_index(final_state) |> Enum.filter_map(fn {door,_} -> door end, fn {_,index} -> index+1 end) IO.puts "All doors are closed except these: #{inspect open_doors}" Output: All doors are closed except these: [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] Elm -- Unoptimized import List exposing (indexedMap, foldl, repeat, range) import Html exposing (text) import Debug exposing (toString) type Door = Open | Closed toggle d = if d == Open then Closed else Open toggleEvery : Int -> List Door -> List Door toggleEvery k doors = indexedMap (\i door -> if modBy k (i+1) == 0 then toggle door else door) doors n = 100 main = text (toString (foldl toggleEvery (repeat n Closed) (range 1 n))) Emacs Lisp Unoptimized (defun create-doors () "Returns a list of closed doors Each door only has two status: open or closed. If a door is closed it has the value 0, if it's open it has the value 1." (let ((return_value '(0)) ;; There is already a door in the return_value, so k starts at 1 ;; otherwise we would need to compare k against 99 and not 100 in ;; the while loop (k 1)) (while (< k 100) (setq return_value (cons 0 return_value)) (setq k (+ 1 k))) return_value)) (defun toggle-single-door (doors) "Toggle the stat of the door at the car' position of the DOORS list DOORS is a list of integers with either the value 0 or 1 and it represents a row of doors. Returns a list where the car' of the list has it's value toggled (if open it becomes closed, if closed it becomes open)." (if (= (car doors) 1) (cons 0 (cdr doors)) (cons 1 (cdr doors)))) (defun toggle-doors (doors step original-step) "Step through all elements of the doors' list and toggle a door when step is 1 DOORS is a list of integers with either the value 0 or 1 and it represents a row of doors. STEP is the number of doors we still need to transverse before we arrive at a door that has to be toggled. ORIGINAL-STEP is the value of the argument step when this function is called for the first time. Returns a list of doors" (cond ((null doors) '()) ((= step 1) (cons (car (toggle-single-door doors)) (toggle-doors (cdr doors) original-step original-step))) (t (cons (car doors) (toggle-doors (cdr doors) (- step 1) original-step))))) (defun main-program () "The main loop for the program" (let ((doors_list (create-doors)) (k 1) ;; We need to define max-specpdl-size and max-specpdl-size to big ;; numbers otherwise the loop reaches the max recursion depth and ;; throws an error. ;; If you want more information about these variables, press Ctrl ;; and h at the same time and then press v and then type the name ;; of the variable that you want to read the documentation. (max-specpdl-size 5000) (max-lisp-eval-depth 2000)) (while (< k 101) (setq doors_list (toggle-doors doors_list k k)) (setq k (+ 1 k))) doors_list)) (defun print-doors (doors) "This function prints the values of the doors into the current buffer. DOORS is a list of integers with either the value 0 or 1 and it represents a row of doors. " ;; As in the main-program function, we need to set the variable ;; max-lisp-eval-depth to a big number so it doesn't reach max recursion ;; depth. (let ((max-lisp-eval-depth 5000)) (unless (null doors) (insert (int-to-string (car doors))) (print-doors (cdr doors))))) ;; Returns a list with the final solution (main-program) ;; Print the final solution on the buffer (print-doors (main-program)) Erlang non-optimized -module(hundoors). -export([go/0]). toggle(closed) -> open; toggle(open) -> closed. go() -> go([closed || _ <- lists:seq(1, 100)],[], 1, 1). go([], L, N, _I) when N =:= 101 -> lists:reverse(L); go([], L, N, _I) -> go(lists:reverse(L), [], N + 1, 1); go([H|T], L, N, I) -> H2 = case I rem N of 0 -> toggle(H); _ -> H end, go(T, [H2|L], N, I + 1). optimized doors() -> F = fun(X) -> Root = math:pow(X,0.5), Root == trunc(Root) end, Out = fun(X, true) -> io:format("Door ~p: open~n",[X]); (X, false)-> io:format("Door ~p: close~n",[X]) end, [Out(X,F(X)) || X <- lists:seq(1,100)]. ERRE ! "100 Doors" program for ERRE LANGUAGE ! Author: Claudio Larini ! Date: 21-Nov-2014 ! ! PC Unoptimized version translated from a QB version PROGRAM 100DOORS !INTEGER CONST N=100 DIM DOOR[N] BEGIN FOR STRIDE=1 TO N DO FOR INDEX=STRIDE TO N STEP STRIDE DO DOOR[INDEX]=NOT(DOOR[INDEX]) END FOR END FOR PRINT("Open doors:";) FOR INDEX=1 TO N DO IF DOOR[INDEX] THEN PRINT(INDEX;) END IF END FOR PRINT END PROGRAM Euler Math Toolbox >function Doors () ...  doors:=zeros(1,100);  for i=1 to 100  for j=i to 100 step i  doors[j]=!doors[j];  end;  end;  return doors endfunction >nonzeros(Doors()) [ 1 4 9 16 25 36 49 64 81 100 ] Euphoria unoptimised -- doors.ex include std/console.e sequence doors doors = repeat( 0, 100 ) -- 1 to 100, initialised to false for pass = 1 to 100 do for door = pass to 100 by pass do --printf( 1, "%d", doors[door] ) --printf( 1, "%d", not doors[door] ) doors[door] = not doors[door] end for end for sequence oc for i = 1 to 100 do if doors[i] then oc = "open" else oc = "closed" end if printf( 1, "door %d is %s\n", { i, oc } ) end for Excel Note: The use of Auto Fill saves a lot of time when entering this code. One can refer to Excel help pages to learn about Auto Fill features. Create a labelling column (A) and row (1) labelling the number of the door (column A, labelling starts in row 2 with a "1" and continues counting up to "100" in row 101) and the number of the pass (row 1, labelling starts in column B with a "0" and continues counting up to "100" in column CX). Additonally, you can label cell A1 as "Door/Pass" or so. Closed doors are represented by zeroes ("0"), open doors are represented by ones ("1"). To represent the initial condition fill rows 2 to 101 in column B (pass "0") with zeroes. Starting in column C, row 2, you enter code as shown in the examples below. The examples show the code to be entered in cells C2, C3, and D2. Continue to write code for the rest of the 4245 data cells, accordingly. Excel Auto Fill feature is best used for this. Cell C2: =IF(A2/C1=INT(A2/C1),IF(B2=0,1,IF(B2=1,0)),B2) Cell C3: =IF(A3/C1=INT(A3/C1),IF(B3=0,1,IF(B3=1,0)),B3) Cell D2: =IF(A2/D1=INT(A2/D1),IF(C2=0,1,IF(C2=1,0)),C2) The last column (column CX, labelled "100") shows a "1" for each door (labelled by the rows in column A) that is open after the 100th pass. It shows a "1" for the following doors: 1, 4, 9, 16, 25, 36, 49, 64, 81, 100. F# Requires #light in versions of F# prior to 2010 beta. let answerDoors = let ToggleNth n (lst:bool array) = // Toggle every n'th door [(n-1) .. n .. 99] // For each appropriate door |> Seq.iter (fun i -> lst.[i] <- not lst.[i]) // toggle it let doors = Array.create 100 false // Initialize all doors to closed Seq.iter (fun n -> ToggleNth n doors) [1..100] // toggle the appropriate doors for each pass doors // Initialize all doors to closed Unoptimized / functional let modifier doors skip = let rec modifierInner doors skip counter = match doors with | [] -> [] //base case: end of hall | first::rest when counter >= skip -> //case: reached door marked for change not first::(modifierInner rest skip 0) // open or close that door | first::rest -> //case: reached door to skip first::(modifierInner rest skip (counter+1)) // skip it modifierInner doors skip 0 //Initial state for walkthrough let answerDoors doors = let rec modifyDoors skipRange doors modifier = //fold each door result to the next with List.fold modifier doors skipRange //with an increasing skip modifyDoors [0..99] doors modifier //Initial starting state let initDoors = Array.create 100 false |> Array.toList //Initialize all doors to closed (false) answerDoors initDoors |> printfn "%A" //print answer (false is closed door) Tail-Recursive Optimized/Functional let modifier doors skip = let rec modifier' doors skip counter result = match doors with | [] -> result |> List.rev //base case: end of hall | first::rest when counter >= skip -> //case: reached door marked for change modifier' rest skip 0 ((not first)::result) // open or close that door | first::rest -> //case: reached door to skip modifier' rest skip (counter+1) (first::result) // skip it modifier' doors skip 0 [] //Initial state for walkthrough Following is the solution using perfect squares. The coercions in PerfectSquare are, I believe, slightly different in versions prior to 2010 beta and, again, #light is required in those versions. open System let answer2 = let PerfectSquare n = let sqrt = int(Math.Sqrt(float n)) n = sqrt * sqrt [| for i in 1..100 do yield PerfectSquare i |] Simple single line solution using nothing but List [1..100] |> List.fold (fun doors pass->List.mapi (fun i x->if ((i + 1) % pass)=0 then not x else x) doors) (List.init 100 (fun _->false)) Factor Unoptimized USING: bit-arrays formatting fry kernel math math.ranges sequences ; IN: rosetta.doors CONSTANT: number-of-doors 100 : multiples ( n -- range ) 0 number-of-doors rot <range> ; : toggle-multiples ( n doors -- ) [ multiples ] dip '[ _ [ not ] change-nth ] each ; : toggle-all-multiples ( doors -- ) [ number-of-doors [1,b] ] dip '[ _ toggle-multiples ] each ; : print-doors ( doors -- ) [ swap "open" "closed" ? "Door %d is %s\n" printf ] each-index ; : main ( -- ) number-of-doors 1 + <bit-array> [ toggle-all-multiples ] [ print-doors ] bi ; main Optimized USING: formatting math math.primes.factors math.ranges sequences ; IN: rosetta-doors2 : main ( -- ) 100 [1,b] [ divisors length odd? ] filter "Open %[%d, %]\n" printf ; Falcon Unoptimized code doors = arrayBuffer( 101, false ) for pass in [ 0 : doors.len() ] for door in [ 0 : doors.len() : pass+1 ] doors[ door ] = not doors[ door ] end end for door in [ 1 : doors.len() ] // Show Output > "Door ", door, " is: ", ( doors[ door ] ) ? "open" : "closed" end Optimized code for door in [ 1 : 101 ]: > "Door ", door, " is: ", fract( door ** 0.5 ) ? "closed" : "open" FALSE 100[][0 1ø:1-]# {initialize doors} % [s;[101\>][;~\:s;+]#%]d: {function d, switch door state function} 1s:[s;101\>][d;!s;1+s:]# {increment step width from 1 to 100, execute function d each time} 1[101\>][." ";["open "]?~["closed "]?1+]# {loop through doors, print door number and state} Result: 1 open 2 closed 3 closed 4 open 5 closed 6 closed 7 closed 8 closed 9 open 10 closed ... 98 closed 99 closed 100 open Compare this solution to the DUP solution of this problem. Fantom Unoptimized states := (1..100).toList 100.times |i| { states = states.map |state| { state % (i+1) == 0 ? -state : +state } } echo("Open doors are " + states.findAll { it < 0 }.map { -it }) Optimized echo("Open doors are " + (1..100).toList.findAll { it.toFloat.pow(0.5f).toInt.pow(2) == it}) FBSL Unoptimised #AppType Console DIM doors[], n AS INTEGER = 100 FOR DIM i = 1 TO n FOR DIM j = i TO n STEP i doors[j] = NOT doors[j] NEXT NEXT FOR i = 1 TO n IF doors[i] THEN PRINT "Door ", i, " is open" NEXT Pause Optimised (by ML) #APPTYPE CONSOLE DIM i = 0, j = 0, door = 1 WHILE INCR(i) < 101 IF i = door THEN PRINT "Door ", door, " open" INCR(door, INCR((INCR(j) << 1))) END IF WEND PAUSE Fhidwfe unoptomized doors = malloc 100u for uint [0u, sizeof doors) with l1 { put_byte + doors l1 as false byte } function void pass(step:uint) { location = step while <= location sizeof doors { ac = - + doors location 1u put_byte ac ~ deref_byte ac// true is represented as 255 (0xff) location = + location step } } for uint (0u, sizeof doors] with l2 {//range exclusive of 0, inclusive of 100 pass l2 } count = 1u for ubyte as doors listubyte with isopen {// list for-each if as isopen bool {// cast byte to bool puts "door " putui count puts " is open\n" } ; count = + count 1u } free doors Fish Unoptimized 1001-p01. >0101-p02. >101-g001-g+:::aa*)?v101-p03. >02-g?v1}02-p02. >05. >0}02-p02. >~~~0101-p001-g:1+001-paa*)?v02. >07. >0101-p08. >101-g::02-g?v >1+:101-paa*=?; >n" "o^ FOCAL 1.1 F N=1,100;S D(N)=0 1.2 F M=1,100;F N=M,M,100;S D(N)=1-D(N) 1.3 F N=1,100;D 2.0 1.4 Q 2.1 I (D(N)),,2.2;R 2.2 T "OPEN DOOR ",%3.0,N,! Output: OPEN 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 Forth Unoptimized : toggle ( c-addr -- ) \ toggle the byte at c-addr dup [email protected] 1 xor swap c! ; 100 1+ ( 1-based indexing ) constant ndoors create doors ndoors allot : init ( -- ) doors ndoors erase ; \ close all doors : pass ( n -- ) \ toggle every nth door ndoors over do doors i + toggle dup ( n ) +loop drop ; : run ( -- ) ndoors 1 do i pass loop ; : display ( -- ) \ display open doors ndoors 1 do doors i + [email protected] if i . then loop cr ; init run display Optimized : squared ( n -- n' ) dup * ; : doors ( n -- ) 1 begin 2dup squared >= while dup squared . 1+ repeat 2drop ; 100 doors Fortran Works with: Fortran 90 unoptimized program doors implicit none integer, allocatable :: door(:) character(6), parameter :: s(0:1) = [character(6) :: "closed", "open"] integer :: i, n print "(A)", "Number of doors?" read *, n allocate (door(n)) door = 1 do i = 1, n door(i:n:i) = 1 - door(i:n:i) print "(A,G0,2A)", "door ", i, " is ", s(door(i)) end do end program optimized PROGRAM DOORS INTEGER, PARAMETER :: n = 100 ! Number of doors INTEGER :: i LOGICAL :: door(n) = .TRUE. ! Initially closed DO i = 1, SQRT(REAL(n)) door(i*i) = .FALSE. END DO DO i = 1, n WRITE(*,"(A,I3,A)", ADVANCE="NO") "Door ", i, " is " IF (door(i)) THEN WRITE(*,"(A)") "closed" ELSE WRITE(*,"(A)") "open" END IF END DO END PROGRAM DOORS Free Pascal program OneHundredIsOpen; const DoorCount = 100; var IsOpen: array[1..DoorCount] of boolean; Door, Jump: integer; begin // Close all doors for Door := 1 to DoorCount do IsOpen[Door] := False; // Iterations for Jump := 1 to DoorCount do begin Door := Jump; repeat IsOpen[Door] := not IsOpen[Door]; Door := Door + Jump; until Door > DoorCount; end; // Show final status for Door := 1 to DoorCount do begin Write(Door, ' '); if IsOpen[Door] then WriteLn('open') else WriteLn('closed'); end; // Wait for <enter> Readln; end. FreeBASIC Toggle ' version 27-10-2016 ' compile with: fbc -s console #Define max_doors 100 Dim As ULong c, n, n1, door(1 To max_doors) ' toggle, at start all doors are closed (0) ' 0 = door closed, 1 = door open For n = 1 To max_doors For n1 = n To max_doors Step n door(n1) = 1 - door(n1) Next Next ' count the doors that are open (1) Print "doors that are open nr: "; For n = 1 To max_doors If door(n) = 1 Then Print n; " "; c = c + 1 End If Next Print : Print Print "There are " + Str(c) + " doors open" ' empty keyboard buffer While InKey <> "" : Wend Print : Print "hit any key to end program" Sleep End Output: doors that are open nr: 1 4 9 16 25 36 49 64 81 100 There are 10 doors open Count ' version 27-10-2016 ' compile with: fbc -s console #Define max_doors 100 Dim As ULong c, n, n1, door(1 To max_doors) ' at start all doors are closed ' simple add 1 each time we open or close a door ' doors with odd numbers are open ' doors with even numbers are closed For n = 1 To max_doors For n1 = n To max_doors Step n door(n1) += 1 Next Next Print "doors that are open nr: "; For n = 1 To max_doors If door(n) And 1 Then Print n; " "; c = c + 1 End If Next Print : Print Print "There are " + Str(c) + " doors open" ' empty keyboard buffer While InKey <> "" : Wend Print : Print "hit any key to end program" Sleep End Output is the same as the first version. Optimized ' version 27-10-2016 ' compile with: fbc -s console #Define max_doors 100 Dim As ULong c, n Print "doors that are open nr: "; For n = 1 To 10 Print n * n; " "; c = c + 1 Next Print : Print Print "There are " + Str(c) + " doors open" ' empty keyboard buffer While InKey <> "" : Wend Print : Print "hit any key to end program" Sleep End Output is the same as the first version. Ultra optimizado ' version 16-06-2021 ' portado desde Julia For i As Integer = 1 To 10 If (i Mod i^2) < 11 Then Print "La puerta"; i^2; " esta abierta" Next i Sleep friendly interactive shell Unoptimized # Set doors to empty list set doors # Initialize doors arrays for i in (seq 100) set doors[i] 0 end for i in (seq 100) set j i while test j -le 100 # Logical not on doors set doors[j] (math !doors[j]) set j (math j + i) end end # Print every door for i in (seq (count doors)) echo -n "i " if test doors[i] -eq 0 echo closed else echo open end end Optimized # Set doors to empty list set doors for i in (seq 100) set doors[(math "i * i")] 1 echo -n "i " if test doors[i] -eq 1 echo open else echo closed end end Frink doors = new array[, false] for pass=1 to 100 for door=pass to 100 step pass [email protected] = ! [email protected] print["Open doors: "] for door=1 to 100 if [email protected] print["door "] FunL Unoptimized for i <- 1..100 r = foldl1( \a, b -> a xor b, [(a|i) | a <- 1..100] ) println( i + ' ' + (if r then 'open' else 'closed') ) Optimized import math.sqrt for i <- 1..100 println( i + ' ' + (if sqrt(i) is Integer then 'open' else 'closed') ) Futhark let main(n: i32): [n]bool = loop is_open = replicate n false for i < n do let js = map (*i+1) (iota n) let flips = map (\j -> if j < n then unsafe !is_open[j] else true -- Doesn't matter. ) js in scatter is_open js flips FutureBasic include "NSLog.incl" NSInteger door, square = 1, increment = 3 for door = 1 to 100 if ( door == square ) NSLog( @"Door %ld is open.", door ) square += increment : increment += 2 else NSLog( @"Door %ld is closed.", door ) end if next HandleEvents 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. FUZE BASIC READ x,y,z PRINT "Open doors: ";x;" "; CYCLE z=x+y PRINT z;" "; x=z y=y+2 REPEAT UNTIL z>=100 DATA 1,3,0 END Fōrmulæ Fōrmulæ programs are not textual, visualization/edition of programs is done showing/manipulating structures but not text. Moreover, there can be multiple visual representations of the same program. Even though it is possible to have textual representation —i.e. XML, JSON— they are intended for storage and transfer purposes more than visualization and edition. Programs in Fōrmulæ are created/edited online in its website, However they run on execution servers. By default remote servers are used, but they are limited in memory and processing power, since they are intended for demonstration and casual use. A local server can be downloaded and installed, it has no limitations (it runs in your own computer). Because of that, example programs can be fully visualized and edited, but some of them will not run if they require a moderate or heavy computation/memory resources, and no local server is being used. In this page you can see the program(s) related to this task and their results. Gambas Public Sub Main() Dim bDoor As New Boolean Dim siCount1, siCount2, siStart As Short For siCount1 = 1 To 100 Inc siStart For siCount2 = siStart To 100 Step siCount1 bDoor[siCount2] = Not bDoor[siCount2] Next Next For siCount1 = 1 To 100 If bDoor[siCount1] Then Print siCount1;; Next End Output: 1 4 9 16 25 36 49 64 81 100 GAP doors := function(n) local a,j,s; a := [ ]; for j in [1 .. n] do a[j] := 0; od; for s in [1 .. n] do j := s; while j <= n do a[j] := 1 - a[j]; j := j + s; od; od; return Filtered([1 .. n], j -> a[j] = 1); end; doors(100); # [ 1, 4, 9, 16, 25, 36, 49, 64, 81, 100 ] Genie // 100 doors problem // Author: Sinuhe masan (2019) init // 100 elements array of boolean type doors:bool for var i = 1 to 100 doors[i] = false // set all doors closed for var i = 1 to 100 j:int = i while j <= 100 do doors[j] = not doors[j] j = j + i print("Doors open: ") for var i = 1 to 100 if doors[i] stdout.printf ("%d ", i) Glee 100 *=0=>d  create vector 1..100, create bit pattern d, marking all equal to 0 :for (1..100[.s]){  loop s from 1 to 100 d^(100 %s *=0 )=>d;}  d = d xor (bit pattern of vector 1..100 % s) d  output d The resulting output is the bit pattern showing the state of the 100 doors: Result: 10010000 10000001 00000000 10000000 00010000 00000000 10000000 00000001 00000000 00000000 10000000 00000000 0001 GML var doors,a,i; //Sets up the array for all of the doors. for (i = 1; i<=100; i += 1) { doors[i]=0; } //This first for loop goes through and passes the interval down to the next for loop. for (i = 1; i <= 100; i += 1;) { //This for loop opens or closes the doors and uses the interval(if interval is 2 it only uses every other etc..) for (a = 0; a <= 100; a += i;) { //Opens or closes a door. doors[a] = !doors[a]; } } open_doors = ''; //This for loop goes through the array and checks for open doors. //If the door is open it adds it to the string then displays the string. for (i = 1; i <= 100; i += 1;) { if (doors[i] == 1) { open_doors += "Door Number "+string(i)+" is open#"; } } show_message(open_doors); game_end(); Go unoptimized package main import "fmt" func main() { doors := bool{} // the 100 passes called for in the task description for pass := 1; pass <= 100; pass++ { for door := pass-1; door < 100; door += pass { doors[door] = !doors[door] } } // one more pass to answer the question for i, v := range doors { if v { fmt.Print("1") } else { fmt.Print("0") } if i%10 == 9 { fmt.Print("\n") } else { fmt.Print(" ") } } } 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 package main import "fmt" func main() { var door int = 1 var incrementer = 0 for current := 1; current <= 100; current++ { fmt.Printf("Door %d ", current) if current == door { fmt.Printf("Open\n") incrementer++ door += 2*incrementer + 1 } else { fmt.Printf("Closed\n") } } } optimized 2 // 100 (optimized) doors in Go package main import ( "fmt" "math" ) func main() { for i := 1; i <= 100; i++ { f := math.Sqrt(float64(i)) if math.Mod(f, 1) == 0 { fmt.Print("O") } else { fmt.Print("-") } } fmt.Println() } Output: O--O----O------O--------O----------O------------O--------------O----------------O------------------O Golfscript 100:c;[{0}c*]:d; c,{.c,>$$%{.d<\.d=1^\)d>++:d;}/}/
[c,{)"door "\+" is"+}%d{{"open"}{"closed"}if}%]zip
{" "*puts}/

optimized with sqrt (Original version of GolfScript has no sqrt operator, but it can be added easily; the code was tested using a work-in-progress C interpreter for a language compatible enough with Golfscript)

100,{)}%
{:d.sqrt 2?=
{"open"}{"close"}if"door "d+" is "+\+puts}/

optimized without sqrt

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

Gosu

unoptimized

uses java.util.Arrays

var doors = new boolean
Arrays.fill( doors, false )

for( pass in 1..100 ) {
var counter = pass-1
while( counter < 100 ) {
doors[counter] = !doors[counter]
counter += pass
}
}

for( door in doors index i ) {
print( "door ${i+1} is${door ? 'open' : 'closed'}" )
}

optimized

var door = 1
var delta = 0

for( i in 1..100 ) {
if( i == door ) {
print( "door ${i} is open" ) delta++ door += 2*delta + 1 } else { print( "door${i} is closed" )
}
}

Groovy

unoptimized

doors = [false] * 100
(0..99).each {
it.step(100, it + 1) {
doors[it] ^= true
}
}
(0..99).each {
println("Door #${it + 1} is${doors[it] ? 'open' : 'closed'}.")
}

optimized a Using square roots

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

optimized b Without using square roots

doors = ['closed'] * 100
(1..10).each { doors[it**2 - 1] = 'open' }
(0..99).each {
println("Door #${it + 1} is${doors[it]}.")
}

GW-BASIC

10 DIM A(100)
20 FOR OFFSET = 1 TO 100
30 FOR I = 0 TO 100 STEP OFFSET
40 A(I) = A(I) + 1
50 NEXT I
60 NEXT OFFSET
70 ' Print "opened" doors
80 FOR I = 1 TO 100
90 IF A(I) MOD 2 = 1 THEN PRINT I
100 NEXT I

Output:

1
4
9
16
25
36
49
64
81
100

Harbour

Unoptimized code:

#define ARRAY_ELEMENTS 100
PROCEDURE Main()
LOCAL aDoors := Array( ARRAY_ELEMENTS )
LOCAL i, j

FOR i := 1 TO ARRAY_ELEMENTS
FOR j := i TO ARRAY_ELEMENTS STEP i
NEXT
NEXT
AEval( aDoors, {|e, n| QQout( Padl(n,3) + " is " + Iif(aDoors[n], "*open*", "closed" ) + "|" ), Iif( n%5 == 0, Qout(), e:=NIL) } )
RETURN

Optimized code

#define ARRAY_ELEMENTS 100
PROCEDURE Main()
LOCAL aDoors := Array( ARRAY_ELEMENTS )

AEval( aDoors, {|e, n| aDoors[n] := e := Iif( Int(Sqrt(n))==Sqrt(n), .T., .F. ) } )
AEval( aDoors, {|e, n| QQout( Padl(n,3) + " is " + Iif(aDoors[n], "*open*", "closed" ) + "|" ), Iif( n%5 == 0, Qout(), e:=NIL )} )
RETURN

Output:

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

unoptimized

data Door
= Open
| Closed
deriving (Eq, Show)

toggle :: Door -> Door
toggle Open = Closed
toggle Closed = Open

toggleEvery :: Int -> [Door] -> [Door]
toggleEvery k = zipWith toggleK [1 ..]
where
toggleK n door
| n mod k == 0 = toggle door
| otherwise = door

run :: Int -> [Door]
run n = foldr toggleEvery (replicate n Closed) [1 .. n]

main :: IO ()
main = print $filter ((== Open) . snd)$ zip [1 ..] (run 100)
Output:
[(1,Open),(4,Open),(9,Open),(16,Open),(25,Open),(36,Open),(49,Open),(64,Open),(81,Open),(100,Open)]

optimized (without using square roots)

gate :: Eq a => [a] -> [a] -> [Door]
gate (x:xs) (y:ys) | x == y = Open  : gate xs ys
gate (x:xs) ys = Closed : gate xs ys
gate [] _ = []

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

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

run n = takeWhile (< n) [k*k | k <- [1..]]

Haxe

{
static public function main()
{
findOpenLockers(100);
}

static function findOpenLockers(n : Int)
{
var i = 1;

while((i*i) <= n)
{
Sys.print(i*i + "\n");
i++;
}
}
}

HicEst

Unoptimized

REAL :: n=100, open=1, door(n)

door = 1 - open ! = closed
DO i = 1, n
DO j = i, n, i
door(j) = open - door(j)
ENDDO
ENDDO
DLG(Text=door, TItle=SUM(door)//" doors open")

Optimized

door = 1 - open ! = closed
DO i = 1, n^0.5
door(i*i) = open
ENDDO
DLG(Text=door, TItle=SUM(door)//" doors open")

HolyC

Translation of: C
U8 is_open;
U8 pass = 0, door = 0;

/* do the 100 passes */
for (pass = 0; pass < 100; ++pass)
for (door = pass; door < 100; door += pass + 1)
is_open[door] = !is_open[door];

/* output the result */
for (door = 0; door < 100; ++door)
if (is_open[door])
Print("Door #%d is open.\n", door + 1);
else
Print("Door #%d is closed.\n", door + 1);

Hoon

|^
=/ doors=(list ?) (reap 100 %.n)
=/ passes=(list (list ?)) (turn (gulf 1 100) pass-n)
|-
?~ passes doors
$(doors (toggle doors i.passes), passes t.passes) ++ pass-n |= [email protected] (turn (gulf 1 100) |=([email protected] =((mod k n) 0))) ++ toggle |= [a=(list ?) b=(list ?)] =| c=(list ?) |- ?: |(?=(~ a) ?=(~ b)) (flop c)$(a t.a, b t.b, c [=((mix i.a i.b) 1) c])
--

#! /bin/sh
exec huginn --no-argv -E "${0}" #! huginn import Algorithms as algo; main() { doorCount = 100; doors = [].resize( doorCount, false ); for ( pass : algo.range( doorCount ) ) { i = 0; step = pass + 1; while ( i < doorCount ) { doors[i] = ! doors[i]; i += step; } } for ( i : algo.range( doorCount ) ) { if ( doors[i] ) { print( "door {} is open\n".format( i ) ); } } return ( 0 ); } 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 Idris 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 -> DoorState toggleDoor DoorOpen = DoorClosed toggleDoor DoorClosed = DoorOpen isOpen : DoorState -> Bool isOpen DoorOpen = True isOpen DoorClosed = False initialDoors : Vect 100 DoorState initialDoors = fromList$ map (\_ => DoorClosed) [1..100]

iterate : (n : Fin m) -> Vect m DoorState -> Vect m DoorState
iterate 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 end
solveDoors : 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 OF SMALLINT

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

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

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

Io

simple boolean list solution:

doors := List clone
100 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 code
x = NDoors Doors mimic(100)
(1..100) each(n, x toggleThese(x numsToToggle(n)))
x show

Isabelle

theory Scratch
imports Main
begin

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

text‹
We will now present an alternative implementation, which is similar to the Haskell implementation
on 🌐‹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 []"
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)"
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"

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"

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"

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
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) []"
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
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"
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 implementations
across programming languages. But we can prove that our code computes the same result as reporting
all 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_simp
end

J

unoptimized

~:/ (100 $- {. 1:)"0 >:i.100 1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 ... ~:/ 0=|/~ >:i.100 NB. alternative 1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 ... optimized (e. *:) 1+i.100 1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 ... 1 (<:*:i.10)} 100$0 NB. alternative
1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 ...

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;

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 : !x];
});
}, 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;
})
.map(function (tuple) {
return {
door: tuple,
open: tuple
};
});

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

School example

Works with: JavaScript version Node.js 16.13.0 (LTS)
"use strict";

// Doors can be open or closed.
const open = "O";
const closed = "C";

// There are 100 doors in a row that are all initially closed.
const doorsCount = 100;
const doors = [];
for (let i = 0; i < doorsCount; doors[i] = closed, i++);

// You make 100 passes by the doors, visiting every door and toggle the door (if
// the door is closed, open it; if it is open, close it), according to the rules
for (let pass = 1; pass <= doorsCount; pass++)
for (let i = pass - 1; i < doorsCount; i += pass)
doors[i] = doors[i] == open ? closed : open;

// Answer the question: what state are the doors in after the last pass?
doors.forEach((v, i) =>
console.log(Doors ${i + 1} are${v == open ? 'opened' : 'closed'}.));

// Which are open, which are closed?
let openKeyList = [];
let closedKeyList = [];
for (let door of doors.entries())
if (door == open)
openKeyList.push(door + 1);
else
closedKeyList.push(door + 1);
console.log("These are open doors: " + openKeyList.join(", ") + ".");
console.log("These are closed doors: " + closedKeyList.join(", ") + ".");

// Assert:
const expected = [];
for (let i = 1; i * i <= doorsCount; expected.push(i * i), i++);
if (openKeyList.every((v, i) => v === expected[i]))
else
throw "These aren't the doors you're looking for.";

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]
end
for a = 1:100
println("Door $a is " * (doors[a] ? "open." : "closed.")) end Gimmicky-optimized: for i in 1:10 println("Door$(i^2) is open.") end

K

unoptimized / converted from Q .

closed open ![ ; 2 ] @ #:' 1 _ = ,/ &:' 0 = t !\:/: t : ! 101

optimized / 1 origin indices

( 1 + ! 10 ) ^ 2

/ As parameterized function :

{ ( 1 + ! _ x ^ % 2 ) ^ 2 } 100

Klingphix

include ..\Utilitys.tlhy

%n 100 !n
0 $n repeat$n [dup sqrt int dup * over
== ( [1 swap set] [drop] ) if] for

$n [ ( "The door " over " is " ) lprint get ( ["OPEN"] ["closed"] ) if print nl] for ( "Time elapsed: " msec " seconds" ) lprint nl pstack " " input 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 door next pass print "open doors "; for door = 1 to 100 if doors(door) then print door;" "; next door Lily var doors = List.fill(100, false) for i in 0...99: for j in i...99 by i + 1: doors[j] = !doors[j] # The type must be specified since the list starts off empty. var open_doors: List[Integer] = [] doors.each_index{|i| if doors[i]: open_doors.push(i + 1) } print($"Open doors: ^(open_doors)")
Output:
Open doors: [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

xTalk

Works with: HyperCard
Works with: LiveCode

on mouseUp
repeat with tStep = 1 to 100
repeat with tDoor = tStep to 100 step tStep
put not tDoors[tDoor] into tDoors[tDoor]
end repeat
if tDoors[tStep] then put "Door " & tStep & " is open" & cr after tList
end repeat
set the text of field "Doors" to tList
end mouseUp

Logo

to doors
;Problem 100 Doors
;FMSLogo
;lrcvs 2010

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

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

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

LOLCODE

HAI 1.3

I HAS A doors ITZ A BUKKIT
IM IN YR hallway UPPIN YR door TIL BOTH SAEM door AN 100
doors HAS A SRS door ITZ FAIL BTW, INISHULIZE ALL TEH DOORZ AS CLOZD
IM OUTTA YR hallway

IM IN YR hallway UPPIN YR pass TIL BOTH SAEM pass AN 100
I HAS A door ITZ pass
IM IN YR passer
doors'Z SRS door R NOT doors'Z SRS door
door R SUM OF door AN SUM OF pass AN 1
DIFFRINT door AN SMALLR OF door AN 99, O RLY?
YA RLY, GTFO
OIC
IM OUTTA YR passer
IM OUTTA YR hallway

IM IN YR printer UPPIN YR door TIL BOTH SAEM door AN 100
VISIBLE "Door #" SUM OF door AN 1 " is "!
doors'Z SRS door, O RLY?
YA RLY, VISIBLE "open."
NO WAI, VISIBLE "closed."
OIC
IM OUTTA YR printer

KTHXBYE

Lua

local is_open = {}

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

for i,v in next,is_open do
print ('Door '..i..':',v and 'open' or 'close')
end

M2000 Interpreter

Second dim preserve values except explicit assign a value for each item using = or a different value using << and a lambda function as generator.

Here we use =false to make all items false (which is a double value of 0).

M2000 use True and False as -1 and 0 (type of double), but from comparisons return Boolean True and False, which used as -1 and 0 also. Using =1=1 we get Boolean True and =1=0 we get Boolean False. We can check type from a variable using Type$(), so x=1=1 : Print Type$(x)="Boolean". We can chack type of an expression using a function: Def ExpressionType$(x)=Type$(x)

Module Doors100 {
Dim Doors(1 to 100)
For i=1 to 100
For j=i to 100 step i
Doors(j)~
Next j
Next i
DispAll()
' optimization
Dim Doors(1 to 100)=False
For i=1 to 10
Doors(i**2)=True
Next i
Print
DispAll()
Sub DispAll()
Local i
For i=1 to 100
if Doors(i) then print i,
Next i
Print
End Sub
}
Doors100

M4

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

NORMAL MODE IS INTEGER
DIMENSION OPEN(100)
PRINT COMMENT 

R MAKE SURE ALL DOORS ARE CLOSED AT BEGINNING
THROUGH CLOSE, FOR DOOR=1, 1, DOOR.G.100
CLOSE OPEN(DOOR) = 0

R MAKE 100 PASSES
THROUGH TOGGLE, FOR PASS=1, 1, PASS.G.100
THROUGH TOGGLE, FOR DOOR=PASS, PASS, DOOR.G.100
TOGGLE OPEN(DOOR) = 1 - OPEN(DOOR)

R PRINT THE DOORS THAT ARE OPEN
THROUGH SHOW, FOR DOOR=1, 1, DOOR.G.100
SHOW WHENEVER OPEN(DOOR).E.1, PRINT FORMAT ISOPEN, DOOR

VECTOR VALUES ISOPEN = $5HDOOR ,I3,S1,8HIS OPEN.*$
END OF PROGRAM
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.

Maple

NDoors := proc( N :: posint )
# Initialise, using 0 to represent "closed"
local pass, door, doors := Array( 1 .. N, 'datatype' = 'integer'[ 1 ] );
# Now do N passes
for pass from 1 to N do
for door from pass by pass while door <= N do
doors[ door ] := 1 - doors[ door ]
end do
end do;
# Output
for door from 1 to N do
printf( "Door %d is %s.\n", door, if( doors[ door ] = 0, "closed", "open" ) )
end do;
# Since this is a printing routine, return nothing.
NULL
end proc:

To solve the problem, call it with 100 as argument (output not shown here).

> NDoors( 100 );

Here is the optimised version, which outputs only the open doors.

> seq( i^2, i = 1 .. isqrt( 100 ) );
1, 4, 9, 16, 25, 36, 49, 64, 81, 100

Alternatively,

> [seq]( 1 .. 10 )^~2;
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

Mathematica/Wolfram Language

unoptimized 1

n=100;
tmp=ConstantArray[-1,n];
Do[tmp[[i;;;;i]]*=-1;,{i,n}];
Do[Print["door ",i," is ",If[tmp[[i]]==-1,"closed","open"]],{i,1,Length[tmp]}]

unoptimized 2

f[n_] = "Closed";
Do[Do[If[f[n] == "Closed", f[n] = "Open", f[n] = "Closed"], {n, k, 100, k}], {k, 1, 100}];
Table[f[n], {n, 1, 100}]

unoptimized 3

Mathematica also supports immutable data paradigms, like so:

Fold[
ReplacePart[#1, (i_ /; Mod[i, #2] == 0) :> (-#1[[i]])] &,
ConstantArray[-1, {100}],
Range
] /. {1 -> "Open", -1 -> "Closed"}

optimized 1

Do[Print["door ",i," is ",If[IntegerQ[Sqrt[i]],"open","closed"]],{i,100}]

optimized 2

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

optimized 3

n=100
nn=1
a=0
For[i=1,i<=n,i++,
If[i==nn,
Print["door ",i," is open"];
a++;
nn+=2a+1;
,
Print["door ",i," is closed"];
];
]

These will only give the indices for the open doors: unoptimized 2

Pick[Range, [email protected]@@Array[Divisible[#1,#2]&, {100,100}]]

optimized 4

Range[Sqrt]^2

MATLAB / Octave

Iterative Method

Unoptimized

a = false(1,100);
for b=1:100
for i = b:b:100
a(i) = ~a(i);
end
end
a

Optimized

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

More Optimized

a = zeros(100,1);
for counter = 1:sqrt(100);
a(counter^2) = 1;
end
a

Vectorized Method

function [doors,opened,closed] = hundredDoors()

%Initialize the doors, make them booleans for easy vectorization
doors = logical( (1:1:100) );

%Go through the flipping process, ignore the 1 case because the doors
%array is already initialized to all open
for initialPosition = (2:100)
doors(initialPosition:initialPosition:100) = not( doors(initialPosition:initialPosition:100) );
end

opened = find(doors); %Stores the numbers of the open doors
closed = find( not(doors) ); %Stores the numbers of the closed doors

end

Known-Result Method

doors((1:10).^2) = 1;

doors

Maxima

doors(n) := block([v], local(v),
v: makelist(true, n),
for i: 2 thru n do
for j: i step i thru n do v[j]: not v[j],
sublist_indices(v, 'identity));

Usage:

doors(100);
/* [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] */

MAXScript

unoptimized

doorsOpen = for i in 1 to 100 collect false

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

for i in 1 to doorsOpen.count do
(
format ("Door % is open?: %\n") i doorsOpen[i]
)

optimized

for i in 1 to 100 do
(
root = pow i 0.5
format ("Door % is open?: %\n") i (root == (root as integer))
)

Mercury

:- module doors.
:- interface.
:- import_module io.
:- pred main(io::di, io::uo) is det.
:- implementation.
:- import_module bitmap, bool, list, string, int.

:- func doors = bitmap.
doors = bitmap.init(100, no).

:- pred walk(int, bitmap, bitmap).
:- mode walk(in, bitmap_di, bitmap_uo) is det.
walk(Pass, !Doors) :-
walk(Pass, Pass, !Doors).

:- pred walk(int, int, bitmap, bitmap).
:- mode walk(in, in, bitmap_di, bitmap_uo) is det.
walk(At, By, !Doors) :-
( if bitmap.in_range(!.Doors, At - 1) then
bitmap.unsafe_flip(At - 1, !Doors),
walk(At + By, By, !Doors)
else
true
).

:- pred report(bitmap, int, io, io).
:- mode report(bitmap_di, in, di, uo) is det.
report(Doors, N, !IO) :-
( if is_set(Doors, N - 1) then
State = "open"
else
State = "closed"
),
io.format("door #%d is %s\n",
[i(N), s(State)], !IO).

main(!IO) :-
list.foldl(walk, 1 .. 100, doors, Doors),
list.foldl(report(Doors), 1 .. 100, !IO).

Metafont

boolean doors[];
for i = 1 upto 100: doors[i] := false; endfor
for i = 1 upto 100:
for j = 1 step i until 100:
doors[j] := not doors[j];
endfor
endfor
for i = 1 upto 100:
message decimal(i) & " " & if doors[i]: "open" else: "close" fi;
endfor
end

Microsoft Small Basic

Translation of: GW-BASIC

For offset = 1 To 100
For i = 0 To 100 Step offset
a[i] = a[i] + 1
EndFor
EndFor
' Print "opened" doors
For i = 1 To 100
If math.Remainder(a[i], 2) = 1 Then
TextWindow.WriteLine(i)
EndIf
EndFor

Output:

1
4
9
16
25
36
49
64
81
100

MiniScript

Using a map to hold the set of open doors:

d = {}
for p in range(1, 100)
for t in range(p, 100, p)
if d.hasIndex(t) then d.remove t else d.push t
end for
end for

print d.indexes.sort
Output:
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

Using an array of boolean values to keep track of door state, and a separate list of indexes of the open doors:

d = [false] * 101
open = []
for p in range(1, 100)
for t in range(p, 100, p)
d[t] = not d[t]
end for
if d[p] then open.push p
end for

print open

(Output same as above.)

MIPS Assembly

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

.text
main:
# Clear all the cells to zero
li $t1, 100 la$t2, doors
clear_loop:
sb $0, ($t2)
add $t2,$t2, 1
sub $t1,$t1, 1
bnez $t1, clear_loop # Now start the loops li$t0, 1 # This will the the step size
li $t4, 1 # just an arbitrary 1 loop1: move$t1, $t0 # Counter la$t2, doors # Current pointer
add $t2,$t2, $t0 addi$t2, $t2, -1 loop2: lb$t3, ($t2) sub$t3, $t4,$t3
sb $t3, ($t2)
add $t1,$t1, $t0 add$t2, $t2,$t0
ble $t1, 100, loop2 addi$t0, $t0, 1 ble$t0, 100, loop1

# Now display everything
la $t0, doors li$t1, 1
loop3:
li $v0, 4 la$a0, num_str
syscall

li $v0, 1 move$a0, $t1 syscall li$v0, 4
la $a0, comma_gap syscall li$v0, 1
lb $a0, ($t0)
syscall

li $v0, 4, la$a0, newline
syscall

addi $t0,$t0, 1
addi $t1,$t1, 1
bne $t1, 101 loop3 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); end end doors=ArrayList.new 1.upto(100) do doors.add(Door.new) end 1.upto(100) do |multiplier| index = 0 doors.each do |door| Door(door).toggle if (index+1)%multiplier == 0 index += 1 end end i = 0 doors.each do |door| puts "Door #{i+1} is #{door}." i+=1 end mIRC Scripting Language var %d =$str(0 $+$chr(32),100), %m = 1
while (%m <= 100) {
var %n = 1
while ($calc(%n * %m) <= 100) { var %d =$puttok(%d,$iif($gettok(%d,$calc(%n * %m),32),0,1),$calc(%n * %m),32)
inc %n
}
inc %m
}
echo -ag All Doors (Boolean): %d
var %n = 1
while (%n <= $findtok(%d,1,0,32)) { var %t = %t$findtok(%d,1,%n,32)
inc %n
}
echo -ag Open Door Numbers: %t

ML/I

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

Modula-2

unoptimized

MODULE Doors;
IMPORT InOut;

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

VAR
Doors: List;
I, J: CARDINAL;

BEGIN
FOR I := 1 TO 100 DO
FOR J := 1 TO 100 DO
IF J MOD I = 0 THEN
IF Doors[J] = Closed THEN
Doors[J] := Open
ELSE
Doors[J] := Closed
END
END
END
END;

FOR I := 1 TO 100 DO
InOut.WriteCard(I, 3);
InOut.WriteString(' is ');

IF Doors[I] = Closed THEN
InOut.WriteString('Closed.')
ELSE
InOut.WriteString('Open.')
END;

InOut.WriteLn
END
END Doors.

optimized

MODULE DoorsOpt;
IMPORT InOut;

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

VAR
Doors: List;
I: CARDINAL;

BEGIN
FOR I := 1 TO 10 DO
Doors[I*I] := Open
END;

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

Modula-3

unoptimized

MODULE Doors EXPORTS Main;

IMPORT IO, Fmt;

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

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

BEGIN
FOR i := 1 TO 100 DO
FOR j := FIRST(doors) TO LAST(doors) DO
IF j MOD i = 0 THEN
IF doors[j] = State.Closed THEN
doors[j] := State.Open;
ELSE
doors[j] := State.Closed;
END;
END;
END;
END;

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

optimized

MODULE DoorsOpt EXPORTS Main;

IMPORT IO, Fmt;

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

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

BEGIN
FOR i := 1 TO 10 DO
doors[i * i] := State.Open;
END;

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

MontiLang

101 var l .

for l 0 endfor
arr

0 var i .
for l
i 1 + var i var j .
j l < var pass .
while pass
get j not insert j .
j i + var j
l < var pass .
endwhile
endfor
print /# show all doors #/

/# show only open doors #/
|| print .
0 var i .
for l
get i
if : i out | | out . . endif .
i 1 + var i .
endfor

input . /# pause until ENTER key pressed #/

MOO

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

"output the result";
for door in [1..100]
player:tell("door #", door, " is ", (is_open[door] ? "open" : "closed"), ".");
endfor

MoonScript

is_open = [false for door = 1,100]

for pass = 1,100
for door = pass,100,pass
is_open[door] = not is_open[door]

for i,v in ipairs is_open
print "Door #{i}: " .. if v then 'open' else 'closed'

MUMPS

doors	new door,pass
For door=1:1:100 Set door(door)=0
For pass=1:1:100 For door=pass:pass:100 Set door(door)='door(door)
For door=1:1:100 If door(door) Write !,"Door",$j(door,4)," is open" Write !,"All other doors are closed." Quit Do doors Door 1 is open Door 4 is open Door 9 is open Door 16 is open Door 25 is open Door 36 is open Door 49 is open Door 64 is open Door 81 is open Door 100 is open All other doors are closed. Myrddin use std const main = { var isopen : bool 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 0 doors = {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 for end for // loop through and print the doors that are open, skipping door 0 for i in range(1, len(doors) - 1) // if the door is open, display it if doors[i] println "Door " + i + " is open." end if end 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 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))+1 1 4 9 16 25 36 49 64 81 100 optimized solution: count 10 power 2 1 4 9 16 25 36 49 64 81 100 Nim unoptimized: from strutils import % const numDoors = 100 var 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 = 100
var 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 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; 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 main int 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 = 100 let 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); endfor endfor for 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) Onyx$Door dict def
1 1 100 {Door exch false put} for
$Toggle {dup Door exch get not Door up put} def$EveryNthDoor {dup 100 {Toggle} for} def
$Run {1 1 100 {EveryNthDoor} for} def$ShowDoor {dup Door no. ' exch cvs cat  is ' cat
exch Door exch get {open.\n'}{shut.\n'} ifelse cat
print flush} def
Run 1 1 100 {ShowDoor} for
Output:
Door no. 1 is open.
Door no. 2 is shut.
Door no. 3 is shut.
Door no. 4 is open.
Door no. 5 is shut.
Door no. 6 is shut.
Door no. 7 is shut.
Door no. 8 is shut.
Door no. 9 is open.
Door no. 10 is shut.
Door no. 11 is shut.
Door no. 12 is shut.
Door no. 13 is shut.
Door no. 14 is shut.
Door no. 15 is shut.
Door no. 16 is open.
Door no. 17 is shut.
Door no. 18 is shut.
Door no. 19 is shut.
Door no. 20 is shut.
Door no. 21 is shut.
Door no. 22 is shut.
Door no. 23 is shut.
Door no. 24 is shut.
Door no. 25 is open.
Door no. 26 is shut.
Door no. 27 is shut.
Door no. 28 is shut.
Door no. 29 is shut.
Door no. 30 is shut.
Door no. 31 is shut.
Door no. 32 is shut.
Door no. 33 is shut.
Door no. 34 is shut.
Door no. 35 is shut.
Door no. 36 is open.
Door no. 37 is shut.
Door no. 38 is shut.
Door no. 39 is shut.
Door no. 40 is shut.
Door no. 41 is shut.
Door no. 42 is shut.
Door no. 43 is shut.
Door no. 44 is shut.
Door no. 45 is shut.
Door no. 46 is shut.
Door no. 47 is shut.
Door no. 48 is shut.
Door no. 49 is open.
Door no. 50 is shut.
Door no. 51 is shut.
Door no. 52 is shut.
Door no. 53 is shut.
Door no. 54 is shut.
Door no. 55 is shut.
Door no. 56 is shut.
Door no. 57 is shut.
Door no. 58 is shut.
Door no. 59 is shut.
Door no. 60 is shut.
Door no. 61 is shut.
Door no. 62 is shut.
Door no. 63 is shut.
Door no. 64 is open.
Door no. 65 is shut.
Door no. 66 is shut.
Door no. 67 is shut.
Door no. 68 is shut.
Door no. 69 is shut.
Door no. 70 is shut.
Door no. 71 is shut.
Door no. 72 is shut.
Door no. 73 is shut.
Door no. 74 is shut.
Door no. 75 is shut.
Door no. 76 is shut.
Door no. 77 is shut.
Door no. 78 is shut.
Door no. 79 is shut.
Door no. 80 is shut.
Door no. 81 is open.
Door no. 82 is shut.
Door no. 83 is shut.
Door no. 84 is shut.
Door no. 85 is shut.
Door no. 86 is shut.
Door no. 87 is shut.
Door no. 88 is shut.
Door no. 89 is shut.
Door no. 90 is shut.
Door no. 91 is shut.
Door no. 92 is shut.
Door no. 93 is shut.
Door no. 94 is shut.
Door no. 95 is shut.
Door no. 96 is shut.
Door no. 97 is shut.
Door no. 98 is shut.
Door no. 99 is shut.
Door no. 100 is open.

ooRexx

doors = .array~new(100)    -- array containing all of the doors
do i = 1 to doors~size -- initialize with a collection of closed doors
doors[i] = .door~new(i)
end

do inc = 1 to doors~size
do d = inc to doors~size by inc
doors[d]~toggle
end
end
say "The open doors after 100 passes:"
do door over doors
if door~isopen then say door
end

::class door -- simple class to represent a door
::method init -- initialize an instance of a door
expose id state -- instance variables of a door
use strict arg id -- set the id
state = .false -- initial state is closed

::method toggle -- toggle the state of the door
expose state
state = \state

::method isopen -- test if the door is open
expose state
return state

::method string -- return a string value for a door
expose state id
if state then return "Door" id "is open"
else return "Door" id "is closed"

::method state -- return door state as a descriptive string
expose state
if state then return "open"
else return "closed"

The two programs in the Rexx section run under ooRexx when '#' is replaced by, e.g., 'dd'.
'#' is not supported by ooRexx as part of or as a symbol. Neither are @ and $. 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'); end end. 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/perl
use 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} );
}
}

# ----------------------------------------------------------------------
#
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 endfor endfor l for var i i get if i print " " print endif endfor 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 endif endfor n for "The door " print dup print " is " print get if "OPEN." else "closed." endif print nl endfor "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 <?php for ($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)

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/I-80

/* Solution to the 100 doors problem in PLI-80 */

hundred_doors:
procedure options (main);

%replace
open_door by '1'b,
closed_door by '0'b,
numdoors by 100;

dcl
doors(1:numdoors) bit(1),
(i, j) fixed bin(15);

/* all doors are initially closed */
do i = 1 to numdoors;
doors(i) = closed_door;
end;

/* cycle through at increasing intervals and flip doors */
do i = 1 to numdoors;
j = i;
do while (j <= numdoors);
doors(j) = ^doors(j);
j = j + i;
end;
end;

/* show results - open doors should all be perfect squares */
put skip list ('The open doors are:');
do i = 1 to numdoors;
if doors(i) = open_door then
put edit (i) (F(4));
end;

end hundred_doors;
Output:
The open doors are:   1   4   9  16  25  36  49  64  81 100

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 );
GO TO 5;
END BDOS;

/* PRINTS A BYTE AS A CHARACTER */
PRINT$CHAR: 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 See Also #Polyglot:PL/I and PL/M 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] Polyglot:PL/I and PL/M Works with: 8080 PL/M Compiler ... under CP/M (or an emulator) Should work with many PL/I implementations. The PL/I include file "pg.inc" can be found on the Polyglot:PL/I and PL/M page. Note the use of text in column 81 onwards to hide the PL/I specifics from the PL/M compiler. /* FIND THE FIRST FEW SQUARES VIA THE UNOPTIMISED DOOR FLIPPING METHOD */ doors_100H: procedure options (main); /* PROGRAM-SPECIFIC %REPLACE STATEMENTS MUST APPEAR BEFORE THE %INCLUDE AS */ /* E.G. THE CP/M PL/I COMPILER DOESN'T LIKE THEM TO FOLLOW PROCEDURES */ /* PL/I */ %replace dcldoors by 100; /* PL/M */ /* DECLARE DCLDOORS LITERALLY '101'; /* */ /* PL/I DEFINITIONS */ %include 'pg.inc'; /* PL/M DEFINITIONS: CP/M BDOS SYSTEM CALL AND CONSOLE I/O ROUTINES, ETC. */ /* DECLARE BINARY LITERALLY 'ADDRESS', CHARACTER LITERALLY 'BYTE'; DECLARE FIXED LITERALLY ' ', BIT LITERALLY 'BYTE'; DECLARE STATIC LITERALLY ' ', RETURNS LITERALLY ' '; DECLARE FALSE LITERALLY '0', TRUE LITERALLY '1'; DECLARE HBOUND LITERALLY 'LAST', SADDR LITERALLY '.'; BDOSF: PROCEDURE( FN, ARG )BYTE; DECLARE FN BYTE, ARG ADDRESS; GOTO 5; END; BDOS: PROCEDURE( FN, ARG ); DECLARE FN BYTE, ARG ADDRESS; GOTO 5; END; PRCHAR: PROCEDURE( C ); DECLARE C BYTE; CALL BDOS( 2, C ); END; PRSTRING: PROCEDURE( S ); DECLARE S ADDRESS; CALL BDOS( 9, S ); END; PRNL: PROCEDURE; CALL PRCHAR( 0DH ); CALL PRCHAR( 0AH ); END; PRNUMBER: PROCEDURE( N ); DECLARE N ADDRESS; DECLARE V ADDRESS, N$STR( 6 ) BYTE, W BYTE;
N$STR( W := LAST( N$STR ) ) = '$'; N$STR( W := W - 1 ) = '0' + ( ( V := N ) MOD 10 );
DO WHILE( ( V := V / 10 ) > 0 );
N$STR( W := W - 1 ) = '0' + ( V MOD 10 ); END; CALL BDOS( 9, .N$STR( W ) );
END PRNUMBER;
DECLARE ( A, B ) ADDRESS;
RETURN A MOD B;
END MODF;
/* END LANGUAGE DEFINITIONS */

/* ARRAY OF DOORS - DOOR( I ) IS TRUE IF OPEN, FALSE IF CLOSED */
DECLARE DOOR( DCLDOORS ) BIT;
DECLARE ( I, J, MAXDOOR ) FIXED BINARY;

MAXDOOR = HBOUND( DOOR ,1
);

/* SET ALL DOORS TO CLOSED */
DO I = 0 TO MAXDOOR; DOOR( I ) = FALSE; END;
/* REPEATEDLY FLIP THE DOORS */
DO I = 1 TO MAXDOOR;
DO J = I TO MAXDOOR BY I;
DOOR( J ) = NOT( DOOR( J ) );
END;
END;
/* DISPLAY THE RESULTS */
DO I = 1 TO MAXDOOR;
IF DOOR( I ) THEN DO;
CALL PRCHAR( ' ' );
CALL PRNUMBER( I );
END;
END;
CALL PRNL;

EOF: end doors_100H;
Output:
1 4 9 16 25 36 49 64 81 100

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
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
true
actor Main
new create(env:Env)=>
var count: USize =100
try
let index=env.args.find("-n",0,0,{(l,r)=>l==r})?
try
| (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 state
for 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 } for
doors pstack
Shows:
[true false false true false false false false true false ...<90 doors later>... true]

Potion

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

PowerShell

unoptimized

$doors = @(0..99) for($i=0; $i -lt 100;$i++) {
$doors[$i] = 0 # start with all doors closed
}
for($i=0;$i -lt 100; $i++) {$step = $i + 1 for($j=$i;$j -lt 100; $j =$j + $step) {$doors[$j] =$doors[$j] -bxor 1 } } foreach($doornum in 1..100) {
if($doors[($doornum-1)] -eq $true) {"$doornum open"}
else {"$doornum closed"} } Alternative Method function Get-DoorState($NumberOfDoors)
{
begin
{
$Doors = @()$Multiple = 1
}

process
{
for ($i = 1;$i -le $NumberOfDoors;$i++)
{
$Door = [pscustomobject]@{ Name =$i
Open = $false }$Doors += $Door } While ($Multiple -le $NumberOfDoors) { Foreach ($Door in $Doors) { if ($Door.name % $Multiple -eq 0) { If ($Door.open -eq $False){$Door.open = $True} Else {$Door.open = $False} } }$Multiple++
}
}

end {$Doors} } unoptimized Pipeline$doors = 1..100 | ForEach-Object {0}
1..100 | ForEach-Object { $a=$_;1..100 | Where-Object { -not ( $_ %$a ) } | ForEach-Object { $doors[$_-1] = $doors[$_-1] -bxor 1 }; if ( $doors[$a-1] ) { "door opened" } else { "door closed" } }

unoptimized Pipeline 2

$doors = 1..100 | ForEach-Object {0}$visited = 1..100
1..100 | ForEach-Object { $a=$_;$visited[0..([math]::floor(100/$a)-1)] | Where-Object { -not ( $_ %$a ) } | ForEach-Object { $doors[$_-1] = $doors[$_-1] -bxor 1;$visited[$_/$a-1]+=($_/$a) }; if ($doors[$a-1] ) { "door opened" } else { "door closed" } } unoptimized Pipeline 3 (dynamically build pipeline) 1..100|foreach-object {$pipe += "toggle $_ |"} -begin {$pipe=""}
filter toggle($pass) {$_.door = $_.door -xor !($_.index % $pass);$_}
invoke-expression "1..100| foreach-object {@{index=$_;door=$false}} | $pipe out-host" Using Powershell Workflow for Parallelism Workflow Calc-Doors { Foreach –parallel ($number in 1..100) {
"Door " + $number.ToString("0000") + ": " + @{$true="Closed";$false="Open"}[([Math]::pow($number, 0.5)%1) -ne 0]
}
}
Calc-Doors | sort

optimized

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

Processing

Unoptimized:

boolean[] doors = new boolean;

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

Processing.R

Unoptimized:

setup <- function() {
for(door in doors(100, 100)) {
stdout$print(paste(door, "")) } } doors <- function(ndoors=100,passes=100) { doors <- rep(FALSE,ndoors) for (ii in seq(1,passes)) { mask <- seq(0,ndoors,ii) doors[mask] <- !doors[mask] } return (which(doors == TRUE)) } Output: 1 4 9 16 25 36 49 64 81 100 ProDOS Uses math module. enableextensions enabledelayedexpansion editvar /newvar /value=0 /title=closed editvar /newvar /value=1 /title=open editvar /newvar /range=1-100 /increment=1 /from=2 editvar /newvar /value=2 /title=next :doors for /alloccurrences (!next!-!102!) do editvar /modify /value=-open- editvar /modify /value=-next-=+1 if -next- /hasvalue=100 goto :cont else goto :doors :cont printline !1!-!102! stoptask Prolog unoptimized Declarative: main :- forall(between(1,100,Door), ignore(display(Door))). % show output if door is open after the 100th pass display(Door) :- status(Door, 100, open), format("Door ~d is open~n", [Door]). % true if Door has Status after Pass is done status(Door, Pass, Status) :- Pass > 0, Remainder is Door mod Pass, toggle(Remainder, OldStatus, Status), OldPass is Pass - 1, status(Door, OldPass, OldStatus). status(_Door, 0, closed). toggle(Remainder, Status, Status) :- Remainder > 0. toggle(0, open, closed). toggle(0, closed, open). Doors as a list: doors_unoptimized(N) :- length(L, N), maplist(init, L), doors(N, N, L, L1), affiche(N, L1). init(close). doors(Max, 1, L, L1) :- !, inverse(1, 1, Max, L, L1). doors(Max, N, L, L1) :- N1 is N - 1, doors(Max, N1, L, L2), inverse(N, 1, Max, L2, L1). inverse(N, Max, Max, [V], [V1]) :- !, 0 =:= Max mod N -> inverse(V, V1); V1 = V. inverse(N, M, Max, [V|T], [V1|T1]) :- M1 is M+1, inverse(N, M1, Max, T, T1), ( 0 =:= M mod N -> inverse(V, V1); V1 = V). inverse(open, close). inverse(close, open). affiche(N, L) :- forall(between(1, N, I), ( nth1(I, L, open) -> format('Door ~w is open.~n', [I]); true)). Using dynamic-rules. Tried to be ISO: doors(Num, Passes) :- forall(( everyNth(1,Passes,1,Pass) , forall((everyNth(Pass,Num,Pass,Door), toggle(Door))) )) , show(Num) . toggle(Door) :- Opened = opened(Door) , ( clause(Opened,_) -> retract(Opened) ; asserta(Opened) ). show(Num) :- forall(( between(1,Num,Door) , (opened(Door) -> State = opened ; State = closed) , write(Door), write(' '), write(State), nl )). % utils forall(X) :- findall(_, X, _). everyNth(From,To,Step,X) :- From =< To , ( X = From ; From1 is From + Step, everyNth(From1,To,Step,X) ) . main :- doors(100,100), halt. optimized doors_optimized(N) :- Max is floor(sqrt(N)), forall(between(1, Max, I), ( J is I*I,format('Door ~w is open.~n',[J]))). Pure using system; // initialize doors as pairs: number, status where 0 means open let doors = zip (1..100) (repeat 1); toogle (x,y) = x,~y; toogleEvery n d = map (tooglep n) d with tooglep n [email protected]((x,_)) = toogle d if ~(x mod n); = d otherwise; end; // show description of given doors status (n,x) = (str n) + (case x of 1 = " close"; 0 = " open"; end); let result = foldl (\a n -> toogleEvery n a) doors (1..100); // pretty print the result (only open doors) showResult = do (puts.status) final when final = filter open result with open (_,x) = ~x; end; end; Output: > showResult; 1 open 4 open 9 open 16 open 25 open ... Pure Data 100Doors.pd #N canvas 241 375 414 447 10; #X obj 63 256 expr doors[$f1] = doors[$f1] ^ 1; #X msg 83 118 \; doors const 0; #X msg 44 66 bang; #X obj 44 92 t b b b; #X obj 43 28 table doors 101; #X obj 44 360 sel 0; #X obj 44 336 expr if (doors[$f1] == 1 \, $f1 \, 0); #X obj 63 204 t b f f; #X text 81 66 run; #X obj 71 384 print -n; #X text 132 310 print results (open doors); #X obj 63 179 loop 1 100 1; #X obj 63 231 loop 1 100 1; #X obj 44 310 loop 1 100 1; #X text 148 28 create array; #X text 151 180 100 passes; #X text 179 123 set values to 0; #X connect 2 0 3 0; #X connect 3 0 13 0; #X connect 3 1 11 0; #X connect 3 2 1 0; #X connect 5 1 9 0; #X connect 6 0 5 0; #X connect 7 0 12 0; #X connect 7 1 12 1; #X connect 7 2 12 3; #X connect 11 0 7 0; #X connect 12 0 0 0; #X connect 13 0 6 0; loop.pd #N canvas 656 375 427 447 10; #X obj 62 179 until; #X obj 102 200 f; #X obj 62 89 inlet; #X obj 303 158 f \$3;
#X obj 270 339 outlet;
#X obj 223 89 inlet;
#X obj 138 89 inlet;
#X obj 324 89 inlet;
#X obj 117 158 f \$1; #X text 323 68 step; #X obj 202 158 f \$2;
#X obj 62 118 t b b b b;
#X obj 270 315 spigot;
#X obj 89 314 sel 0;
#X obj 137 206 +;
#X obj 102 237 expr $f1 \; if ($f3 > 0 \, if ($f1 >$f2 \, 0 \, 1)
\, if ($f3 < 0 \, if ($f1 < $f2 \, 0 \, 1) \, 0)), f 34; #X text 63 68 run; #X text 136 68 start; #X text 227 68 end; #X text 58 31 loop (abstraction); #X connect 0 0 1 0; #X connect 1 0 14 0; #X connect 1 0 15 0; #X connect 2 0 11 0; #X connect 3 0 14 1; #X connect 3 0 15 2; #X connect 5 0 10 1; #X connect 6 0 8 1; #X connect 7 0 3 1; #X connect 8 0 1 1; #X connect 10 0 15 1; #X connect 11 0 0 0; #X connect 11 1 8 0; #X connect 11 2 10 0; #X connect 11 3 3 0; #X connect 12 0 4 0; #X connect 13 0 0 1; #X connect 14 0 1 1; #X connect 15 0 12 0; #X connect 15 1 12 1; #X connect 15 1 13 0; PureBasic unoptimized Dim doors.i(100) For x = 1 To 100 y = x While y <= 100 doors(y) = 1 - doors(y) y + x Wend Next OpenConsole() PrintN("Following Doors are open:") For x = 1 To 100 If doors(x) Print(Str(x) + ", ") EndIf Next Input() optimized OpenConsole() PrintN("Following Doors are open:") For i = 1 To 100 root.f = Sqr(i) If root = Int(root) Print (Str(i) + ", ") EndIf Next Input() Output: Following Doors are open: 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, Pyret data Door: | open | closed end fun flip-door(d :: Door) -> Door: cases(Door) d: | open => closed | closed => open end end fun flip-doors(doors :: List<Door>) -> List<Door>: doc:Given a list of door positions, repeatedly switch the positions of every nth door for every nth pass, and return the final list of door positions for fold(flipped-doors from doors, n from range(1, doors.length() + 1)): for map_n(m from 1, d from flipped-doors): if num-modulo(m, n) == 0: flip-door(d) else: d end end end where: flip-doors([list: closed, closed, closed]) is [list: open, closed, closed] flip-doors([list: closed, closed, closed, closed]) is [list: open, closed, closed, open] flip-doors([list: closed, closed, closed, closed, closed, closed]) is [list: open, closed, closed, open, closed, closed] closed-100 = for map(_ from range(1, 101)): closed end answer-100 = for map(n from range(1, 101)): if num-is-integer(num-sqrt(n)): open else: closed end end flip-doors(closed-100) is answer-100 end fun find-indices<A>(pred :: (A -> Boolean), xs :: List<A>) -> List<Number>: doc:Given a list and a predicate function, produce a list of index positions where there's a match on the predicate ps = map_n(lam(n,e): if pred(e): n else: -1 end end, 1, xs) ps.filter(lam(x): x >= 0 end) where: find-indices((lam(i): i == true end), [list: true,false,true]) is [list:1,3] end fun run(n): doc:Given a list of doors that are closed, make repeated passes over the list, switching the positions of every nth door for each nth pass. Return a list of positions in the list where the door is Open. doors = repeat(n, closed) ys = flip-doors(doors) find-indices((lam(y): y == open end), ys) where: run(4) is [list: 1,4] end run(100) Python Works with: Python version 2.5+ unoptimized doors = [False] * 100 for i in range(100): for j in range(i, 100, i+1): doors[j] = not doors[j] print("Door %d:" % (i+1), 'open' if doors[i] else 'close') optimized A version that only visits each door once: for i in xrange(1, 101): root = i ** 0.5 print "Door %d:" % i, 'open' if root == int(root) else 'close' One liner using a list comprehension, item lookup, and is_integer print '\n'.join(['Door %s is %s' % (i, ('closed', 'open')[(i**0.5).is_integer()]) for i in xrange(1, 101)]) One liner using a generator expression, ternary operator, and modulo print '\n'.join('Door %s is %s' % (i, 'closed' if i**0.5 % 1 else 'open') for i in range(1, 101)) Works with: Python version 3.x for i in range(1, 101): if i**0.5 % 1: state='closed' else: state='open' print("Door {}:{}".format(i, state)) ultra-optimized: ported from Julia version for i in range(1,101): print("Door %s is open" % i**2) Q unoptimized closedopen (<>)over 0=t mod\:/:t:1+til 100 optimized closedopen (1+til 100) in {x*x} 1+til 10 alternative @[100#closed; -1+{x*x}1+til 10; :; open] Quackery unoptimized /O> [ bit ^ ] is toggle ( f n --> f ) ... ... [ 0 ... 100 times ... [ i^ 1+ swap ... 101 times ... [ i^ toggle over step ] ... nip ] ] is toggledoors ( --> f ) ... ... [ 100 times ... [ 1 >> dup 1 & ... if [ i^ 1+ echo sp ] ] ... drop ] is echodoors ( f --> ) ... ... toggledoors ... say " These doors are open: " echodoors cr ... say " The rest are closed." cr ... These doors are open: 1 4 9 16 25 36 49 64 81 100 The rest are closed. Stack empty. R Using a loop doors_puzzle <- function(ndoors=100,passes=100) { doors <- rep(FALSE,ndoors) for (ii in seq(1,passes)) { mask <- seq(0,ndoors,ii) doors[mask] <- !doors[mask] } return (which(doors == TRUE)) } doors_puzzle() optimized x <- rep(1, 100) for (i in 1:100-1) { x <- xor(x, rep(c(rep(0,i),1), length.out=100)) } which(!x) Using a **ply function doors_puzzle <- function(ndoors=100,passes=100) { names(which(table(unlist(sapply(1:passes, function(X) seq(0, ndoors, by=X)))) %% 2 == 1)) } doors_puzzle() Using Reduce H=100 f=rep(F,H) which(Reduce(function(d,n) xor(replace(f,seq(n,H,n),T),d), 1:H, f)) Output: 1 4 9 16 25 36 49 64 81 100 Racket #lang racket ;; Applies fun to every step-th element of seq, leaving the others unchanged. (define (map-step fun step seq) (for/list ([elt seq] [i (in-naturals)]) ((if (zero? (modulo i step)) fun values) elt))) (define (toggle-nth n seq) (map-step not n seq)) (define (solve seq) (for/fold ([result seq]) ([_ seq] [pass (in-naturals 1)]) (toggle-nth pass result))) (for ([door (solve (make-vector 101 #f))] [index (in-naturals)] #:when (and door (> index 0))) (printf "~a is open~%" index)) Optimized: #lang racket (for ([x (in-range 1 101)] #:when (exact-integer? (sqrt x))) (printf "~a is open\n" x)) Unoptimized imperative, with graphic rendering: #lang slideshow (define-syntax-rule (vector-neg! vec pos) (vector-set! vec pos (not (vector-ref vec pos)))) (define (make-doors) (define doors (make-vector 100 #f)) (for* ([i 100] [j (in-range i 100 (add1 i))]) (vector-neg! doors j)) doors) (displayln (list->string (for/list ([d (make-doors)]) (if d #\o #\-)))) (define closed-door (inset (filled-rectangle 4 20) 2)) (define open-door (inset (rectangle 4 20) 2)) (for/fold ([doors (rectangle 0 0)]) ([open? (make-doors)]) (hc-append doors (if open? open-door closed-door))) Output: Raku (formerly Perl 6) unoptimized Works with: Rakudo version 2015.09" my @doors = False xx 101; (.=not for @doors[0,$_ ... 100]) for 1..100;

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

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 integer
dim door(1 to 100) as byte

'initialize array
for x = 1 to 100 : door(x) = 0 : next

'set door values
for y = 1 to 100
for x = y to 100 step y
door(x) = not door(x)
next x
next y

'print result
for x = 1 to 100
if door(x) then print "Door " + str$(x) + " = open" next while inkey$="":wend
end

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 'closed
repeat i 100 [
door: at doors i
forskip door i [change door either 'open = first door ['closed] ['open]]
]

Optimized

doors: array/initial 100 'closed
repeat 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: 100
repeat 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, state
set i = 1
while i <= 100
insert i, 1
set i = i+1
end while
set i = 2
while i <= 100
update state = 1-state where not (door mod i)
set i = i+1
end while
update state = "open" where state
update 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 100
doors[i] = false
next

For pass = 1 To 100
For door = pass To 100
if doors[door] doors[door] = false else doors[door] = true ok
door += pass-1
Next
Next

For door = 1 To 100
see "Door (" + door + ") is "
If doors[door] see "Open" else see "Closed" ok
see nl
Next

Optimized

doors = list(100)
for i = 1 to 100
doors[i] = false
next

For p = 1 To 10
doors[pow(p,2)] = True
Next

For door = 1 To 100
see "Door (" + door + ") is "
If doors[door] see "Open" else see "Closed" ok
see nl
Next

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

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

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

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

unoptimized

n = 100
Open = "open"
Closed = "closed"
def Open.toggle
Closed
end
def Closed.toggle
Open
end
doors = [Closed] * (n + 1)
for mul in 1..n
for x in (mul..n).step(mul)
doors[<