A visual 100 Door Problem solution in Python

A visual 100 Door Problem solution in Python
Photo by Marco Bianchetti / Unsplash

Last year, we did the 100 door problem on many platforms in BASIC and Assembly language.

The 100 door problem is:

  • There are 100 closed doors in a row.
  • You walk past the doors 100 times (100 passes)
  • The first time, visit every door. If the door is closed,  open it.   If it is open, close it. In programming, you'd probably call this toggling the door so let's call it that.
  • The second time, ONLY visit every 2nd door and toggle it. (door 2, 4, 6, etc)
  • The third time, ONLY visit every 3rd door and toggle it.  (door 3, 6, 9, etc)

Keep going through this loop over and over until you get to the loop where there's only the last door.

The vintage machine solutions:

We were not shooting for the fastest implementation at all. It was all about the cool visual representation.

The Color Maximite version was tricky since the screen locations aren't in order like the old 8 Bit machines. Python has the same issue. Sure there are graphics libraries, but there's something fun about this text-based visual.

Let's zoom in on the VIC-20:

Unexpanded VIC-20

This example is fun since it uses the screen memory locations to hold the data we're working on. Something that might be important on a system that only has 3583 Bytes of memory to work with.

Python version

In keeping with the ASCII codes spirit of the 8 Bit Machines (I know, I know, it's PETSCII on Commodore, calm down), let's do this effect in python the most straightforward way we can muster.

There is a neat Python library that is a bit help in creating ASCII screens called Asciimatics.

It does all kinds of fancy things, but we're most interested in positioning screen characters in specific locations over and over.

Let's look at the code:

from asciimatics.screen import Screen
from time import sleep

# Our ASCII Symbols for opened and closed
open = "O"
closed = "C"

def hundredDoors(screen):
    doors = [False] * 100
    for i in range(100):
        for j in range(i, 100, i+1):
            doors[j] = not doors[j]
            l=0
            p=j
            if j>=50:
                l = 1
                p=j-50
            if doors[j]:
                screen.print_at(open,p,l)
            else:
                screen.print_at(closed,p,l)
            screen.refresh()
            sleep(0.01) # Slow down there python
            
    # Print our open doors (all the perfect squares)
    j=3
    for i in range(100):
        if doors[i] == True:
            screen.print_at(i+1,0,j)
            j+=1
        screen.refresh()
    sleep(100) #don't close for 100 seconds

Screen.wrapper(hundredDoors)

Just like Cerberus and Maximite examples from the earlier article, we need to slow python down to see the visual well. It's for fun, not speed, right?

This example is straightforward and looks pretty close to the others. We create an array of closed doors (False) and loop through them, toggling each one when we get to it.

This code gets us on the correct line number to print the current state of the door:

l=0
p=j
if j>=50:
    l = 1
    p=j-50
Many ways to do this, just one example

The output is pretty neat and buttons up the "we missed the python implementation" problem.

You challenge

If you're up to it:


Instead of an array, use the values at screen locations as we did in the 8 Bit examples.

Let me know what you come up with, and have fun!