100 doors: Difference between revisions

From Rosetta Code
Content added Content deleted
m ((pre) is done with leading spaces in wikicode.)
(→‎{{header|Perl}}: added optimized Perl example)
Line 91: Line 91:
print "$_\t$doors[$_]\n" for 1..100;
print "$_\t$doors[$_]\n" for 1..100;

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


=={{header|Python}}==
=={{header|Python}}==

Revision as of 02:21, 21 October 2007

100 doors is a programming puzzle. It lays out a problem which Rosetta Code users are encouraged to solve, using languages and techniques they know. Multiple approaches are not discouraged, so long as the puzzle guidelines are followed. For other Puzzles, see Category:Puzzles.

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

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

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

Ada

unoptimized

with Ada.Text_Io; use Ada.Text_Io;

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

optimized

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

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

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

Perl

unoptimized

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

print "$_\t$doors[$_]\n" for 1..100;

optimized

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

Python

unoptimized

Note: this version requires Python 2.5 for the ternary syntax.

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

A version that only visits each door once:

for i in range(1, 101):
    root = i**0.5
    print "Door %d:" % i, ['close', 'open'][root == int(root)]