"Open and closed doors" riddle Riddle Description:


  \$N\$ doors are closed. In the first pass, I open all of them. In the
  second pass, I toggle every second door. In the third pass, I toggle
  every third door. I continue this until I have completed the \$N\$th
  pass. Find all the doors that will remain open after \$N\$ passes.


public static void printDoorsOpened(int passes)
{
        HashMap&lt;Integer, Boolean&gt; doors=new HashMap&lt;Integer, Boolean&gt;();
        int i = 0;
        //Close all doors as default in the start
        while(i &lt; passes)
        {
            doors.put(i, false);
            i++;
        }

        for(int j = 1; j &lt;= passes; j++)
        {
            for(int k = j - 1; k &lt; passes; k += j)
                doors.put(k, !(doors.get(k)));
        }

        for(int l = 0; l &lt; passes; l++)
        {
            System.out.println("The door number "+(l + 1)+" is "+(doors.get(l) == true ? "Opened" : "Closed"));
        }
}


Please feel free to review it based on best practices, style and any other efficient solution, but please refrain from solely style-based reviews.
This looks like something that can get optimized to a mathematical function.

Let's run it pass by pass and try to interpret the result.


  N = 12
  
  Doors #1 through #12

Pass 1:  1 1 1  1 1 1  1 1 1  1 1 1 //All opened
Pass 2:  1 0 1  0 1 0  1 0 1  0 1 0 //2, 4, 6, 8, 10, 12 closed
Pass 3:  1 0 0  0 1 1  1 0 0  0 1 1 //3 and 9 closed, 6 and 12 opened
Pass 4:  1 0 0  1 1 1  1 1 0  0 1 0 //4 and 8 opened, 12 closed
Pass 5:  1 0 0  1 0 1  1 1 0  1 1 0 //5 closed, 10 opened
Pass 6:  1 0 0  1 0 0  1 1 0  1 1 1 //6 closed, 12 opened
Pass 7:  1 0 0  1 0 0  0 1 0  1 1 1 //7 closed
Pass 8:  1 0 0  1 0 0  0 0 0  1 1 1 //8 closed
Pass 9:  1 0 0  1 0 0  0 0 1  1 1 1 //9 opened
Pass 10: 1 0 0  1 0 0  0 0 1  0 1 1 //10 closed
Pass 11: 1 0 0  1 0 0  0 0 1  0 0 1 //11 closed
Pass 12: 1 0 0  1 0 0  0 0 1  0 0 0 //12 closed



It's a factor detector!

It detects whether for each positive integer \$N\$ or lower whether its divisible an even or uneven amount of times by its possible factors.

That is, 12 can be factorized as \$1\times 12\$, \$2\times 6\$, \$3\times 4\$, \$4\times 3\$, \$6\times 2\$, \$12\times 1\$. That's even, so the door ends up at 0, which is closed. 9 can be factorized as \$1\times 9\$, \$3\times 3\$ and \$9\times 1\$. That's uneven, so the door ends up at 1, which is opened.

Now, for any factorization \$x\times y\$ of a number, there exists an inverse factorization: \$y\times x\$. Unless \$x\$ equals \$y\$. If that's the case, then there is no inverse factorization because the inverse is the same!

So it's a square root detector! (Any number that has a positive integer as a square root has an uneven number of factorizations, the rest have an even number).

Now, this doesn't implement the algorithm that your problem statement describes, but it does end up with the same result:

public static void printDoorsOpened(final int passes)
{
    int j = 1;
    for(int i = 1; i &lt;= passes; i++)
    {
        if(j*j == i){
            j++;
            System.out.println("The door number "+i+" is Opened");
        } else {
            System.out.println("The door number "+i+" is Closed");
        }
    }
}