HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaModerate

Locker Puzzle in Java

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
lockerpuzzlejava

Problem

The author of my book does not release odd-numbered solutions to students, so I can't check my solutions. I was wondering if there was a better way to solve this problem without simply printing out the square roots.

Here is the question:


(Game: locker puzzle) A school has 100 lockers and 100 students. All
lockers are closed on the first day of school. As the students enter,
the first student, denoted S1, opens every locker. Then the second
student, S2, begins with the second locker, denoted L2, and closes
every other locker. Student S3 begins with the third locker and
changes every third locker (closes it if it was open, and opens it if
it was closed). Student S4 begins with locker L4 and changes every
fourth locker. Student S5 starts with L5 and changes every fifth
locker, and so on, until student S100 changes L100.


After all the students have passed through the building and changed
the lockers, which lockers are open? Write a program to find your
answer.


(Hint: Use an array of 100 Boolean elements, each of which indicates
whether a locker is open (true) or closed (false). Initially, all
lockers are closed.)

Here is my solution:

public class Main {
    public static void main(String[] args) {
        boolean[] lockers = new boolean[101];
        //Open all multiples of 1 before moving on to 2
        for (int i = 1; i < lockers.length; i++) {
            lockers[i] = true;
        }

        //open every locker for every multiple of i
        for (int i = 2; i <= 100; i++) {
            for (int j = 1; i * j <= 100; j++) {
                lockers[i * j] = (lockers[i * j] == true) ? false : true;
            }
        }

        //Display the indices of the open lockers
        for (int i = 0; i < lockers.length; i++) {
            if (lockers[i] == true)
                System.out.println("locker " + i + " is open.");
        }
    }
}

Solution

You are using i = 1 as a special case, when in fact that can be handled by your other code already:

for (int i = 1; i <= 100; i++) {
    for (int j = 1; i * j <= 100; j++) {
        lockers[i * j] = !lockers[i * j];
    }
}


However, to be more readable, I suggest changing the inner loop:

for (int i = 1; i <= 100; i++) {
    for (int j = i; j <= 100; j += i) {
        lockers[j] = !lockers[j];
    }
}


Now it reads as "Start j at i, repeat as long as j is less than or equal to 100, increase j by the value of i"

Code Snippets

for (int i = 1; i <= 100; i++) {
    for (int j = 1; i * j <= 100; j++) {
        lockers[i * j] = !lockers[i * j];
    }
}
for (int i = 1; i <= 100; i++) {
    for (int j = i; j <= 100; j += i) {
        lockers[j] = !lockers[j];
    }
}

Context

StackExchange Code Review Q#86665, answer score: 17

Revisions (0)

No revisions yet.