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.



Task

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.




/* 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;
   MODF:     PROCEDURE( A, B )ADDRESS;
      DECLARE ( A, B ) ADDRESS;
      RETURN A MOD B;
   END MODF;
/* END LANGUAGE DEFINITIONS */
 
   /* TASK */
 
   /* 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;