# The Locker Problem¶

There are lots of ways to explore this problem, and we encourage you to spend some time thinking about it on your own. Below, we are going to give you some tools to explore this problem with programming.

We've created a Locker object that will let you simulate this problem. Each locker has 4 properties:

• id: the locker number)
• isOpen: a boolean indicating whether the locker is open
• flipCount: an integer for keeping track of the numebr of times the locker was openened
• students: a list of all of the students who open or closed the locker
In [12]:
from Locker import Locker


Let's create a locker. When we create a locker, it will be initialized with an id of 1, flipCount of 0, and closed.

In [13]:
locker1 = Locker()


We can "flip" the state of the locker with the flip() funciton. This function requires you also pass it a number indicitating the number of the studnet who "flipped" the locker. In this case, we will assume student 1 flips the locker.

In [14]:
locker1.flip(1)


We can see the status of the locker using the status() function.

In [15]:
print(locker1.status())

11: open: 1 [1]


The status function outputs the number of the locker, followed by its open status, followed by the number of times it has been openend and the list of students who opened it.

Let's delete the locker we created. Python automatically numbers each new locker sequentially, so if we want to create a new locker starting with 1, we need to call the reset function.

To create an entire set of lockers, we can use a for loop. This command would create 10 lockers, for example.

In [27]:
locker1.reset() #re-initialize counter to start at 1
Lockers=[]  #create an empty array to store our lockers
for i in range(10): #repeat 10 times
l = Locker() #create a locker
Lockers.append(l) #add l to our list of lockers


We can use a similar loop to print the status of our collection of locekrs:

In [28]:
for l in Lockers:
print(l.status())

1: closed: 0 []
2: closed: 0 []
3: closed: 0 []
4: closed: 0 []
5: closed: 0 []
6: closed: 0 []
7: closed: 0 []
8: closed: 0 []
9: closed: 0 []
10: closed: 0 []


Now you have a set of lockers that you can begin to experiment with. Using your knowledge of iteration (for loops) and conditionals (if statements), let's see how you can model this problem.

Let's start by just trying to open every locker, using our first student. You'll need a loop to loop over every locker. When we are done, we can go ahead and print the status of the lockers, too.

In [18]:
for l in Lockers:
l.flip(1) #student 1 flips locker l

In [19]:
for l in Lockers:
print(l.status())

1: open: 1 [1]
2: open: 1 [1]
3: open: 1 [1]
4: open: 1 [1]
5: open: 1 [1]
6: open: 1 [1]
7: open: 1 [1]
8: open: 1 [1]
9: open: 1 [1]
10: open: 1 [1]


Later students should not flip every single locker, they should only flip lockers that have numbers that are multiples of that student's number. This will require you to use a conditional statement. One easy way to test if a number is a multiple of another number is to use the mod operator, %, which gives you the remainder when the first argument is divided by the second argument. See this example.

In [21]:
print (9 % 3) #9 is a multiple of 3
print (9 % 2) #9 is not a multiple of 2
print (137 % 40) #140 is not a multiple of 40

0
1
17


How can you use this argument to build a test for a conditional (if statement) that will be true when the first argument is a multiple of the second? Here's a small example get you started—here's a way to have the computer test if 2+4 is equal to 5.

In [24]:
print 2 + 4 == 5

False


### Build the algorithm¶

Use the ideas above to build an algorithm that will simulate the first 10 students flipping the first 10 lockers as described in the problem above.

Here's an example of what successful output might look like:

In [ ]:
1: open: 1 [1]
2: closed: 2 [1, 2]
3: closed: 2 [1, 3]
4: open: 3 [1, 2, 4]
5: closed: 2 [1, 5]
6: closed: 4 [1, 2, 3, 6]
7: closed: 2 [1, 7]
8: closed: 4 [1, 2, 4, 8]
9: open: 3 [1, 3, 9]
10: closed: 4 [1, 2, 5, 10]