Reputation: 1417
My friend gave me a riddle to solve. It goes like this:
There are 100 people. Each one of them, in his turn, does the following:
The first person opens all the boxes. The second person change the state to all the boxes whose number is divided by 2, without remainders. For instance, if a box is open and its number is divided by 2, it is closed. The same goes for a closed box.
The third person change the state to all the boxes whose number is divided by 3, without remainders. The "i" person change the state to all the boxes whose number is divided by i, without remainders.
Now, at then end of the process, I need to display all the boxes(their numbers) who are open.
I tried to implement a solution but I think it's not efficient. Here it is:
public class BoxesExc {
public static void main(String[] args) {
Box[] boxes = new Box[100];
// Inflating the array with boxes
for(int i=0; i<boxes.length; i++) {
boxes[i] = new Box(i, false);
}
// Main part:
for(int i=1; i<=boxes.length; i++) {
for(int j=1; j<=i; j++) {
// If the number is even
if(i%2 == 0) {
if(j%i == 0) {
boxes[j].setOpen(!boxes[j].isOpen);
}
}
// If the number is odd
else {
if(j%2 != 0) {
if(j%i == 0) {
boxes[j].setOpen(!boxes[j].isOpen);
}
}
}
}
}
//Displaying the opened boxes:
for(Box box : boxes) {
if(box.isOpen)
System.out.println(box.getNum()+",");
}
}
public static class Box {
private int num;
private boolean isOpen;
public Box(int num, boolean isOpen) {
this.isOpen = isOpen;
}
public int getNum() {
return num;
}
public boolean isOpen() {
return isOpen;
}
public void setOpen(boolean isOpen) {
this.isOpen = isOpen;
}
}
}
I haven't tried that yet but I just by looking at it, it looks awful. I need your help guys with finding a better solution.
EDIT: Alright guys I managed to solve this. Here is the solution:
public class BoxesExc {
public static void main(String[] args) {
int[] boxes = new int[101];
// Inflating the array with boxes
for(int i=1; i<boxes.length; i++) {
boxes[i] = i;
}
int counter = 0;
for(int i=1; i<boxes.length; i++) {
for(int j=1; j<=i; j++) {
if(i%j == 0)
counter++;
}
if(counter%2 != 0)
System.out.print(""+i+", ");
counter = 0;
}
}
}
Upvotes: 2
Views: 1778
Reputation: 756
Since you only need to print the numbers, I think following is enough:
public class BoxesExc {
public static void main(String[] args) {
int boxNum = 100;
for(int i = 1; i*i <= boxNum; i++) {
System.out.print(i*i+",");
}
}
}
Upvotes: 0
Reputation: 93
it has very simple solution
the boxes which will be opened will be all the boxes which thier place is square exponentiation of a number.
for example in your question its between 1-100 so the answer will be:
1 4 9 16 25 36 49 64 81 100
also my solution is faster than yours because its order is θ(√n)
Upvotes: 2
Reputation: 39403
Here is a quick implementation of what I described in the comment:
public class BoxesExc {
public static void main(String[] args) {
Box[] boxes = new Box[100];
// Inflating the array with boxes
for(int i=0; i<boxes.length; i++) {
boxes[i] = new Box(i, false);
}
// Main part:
for (int i=1; i < boxes.length; i++) {
// j+=i goes 3,6,9... for i = 3
for (int j = i; j < boxes.length; j+=i) {
boxes[j].setOpen(!boxes[j].isOpen);
}
}
//Displaying the opened boxes:
for(Box box : boxes) {
if(box.isOpen)
System.out.println(box.getNum()+",");
}
}
}
Nota: you can init the box status to open
and skip the first iteration (start with i = 2
)
Upvotes: 0
Reputation: 2809
Iterate through all the boxes and modulate by your current indices. Do a switch to set the box open or closed depending on it's previous state. Then after you're done doing the 100 loop; do a secondary loop through the 100 boxes to see which ones are open and print them out.
Upvotes: 0