Problem
I came across a question where I had to find the floor by using given room no. And given no data structure to hold the data. What we know is distribution of the rooms across the floors.
I have given below solution for it but, I think it may break as number of floors increases.
int queryRoom = 37;
int totalFloor = 6;
int currentRm = 0;
int floorInQuestion = 1; // staring floor
while (floorInQuestion != totalFloor) {
if (floorInQuestion % 2 != 0) {
currentRm = currentRm + 5;
} else {
currentRm = currentRm + 10;
}
if (queryRoom <= currentRm)
break;
floorInQuestion++;
}
System.out.println(floorInQuestion);
Solution
When presented with problems that require and input value set, and an output value set, it’s always best to express the problem as a function. In your case, the problem is: “Given an input room number, what floor is it on?”
This type of question can then be expressed as a single function:
public static int whichFloor(int room) {
....
}
That function is the result of a process called “function extraction”, taking a piece of logic, and extracting just that piece in to its own function.
This makes the code logic more visible, and it also helps you to organize your thoughts. It also makes some logic expression more simple (early return values).
So, taking your code in to a function, you get:
System.out.println(whichFloor(37));
And, now we implement whichFloor
as:
public static int whichFloor(int queryRoom) {
int totalFloor = 6;
int currentRm = 0;
int floorInQuestion = 1; // staring floor
while (floorInQuestion != totalFloor) {
if (floorInQuestion % 2 != 0) {
currentRm = currentRm + 5;
} else {
currentRm = currentRm + 10;
}
if (queryRoom <= currentRm) {
return floorInQuestion;
}
floorInQuestion++;
}
return -1;
}
There are some changes in that logic. Specifically, I have:
- Added
{...}
braces on the last condition… - … which is now a
return
statement, and not abreak
- returns
-1
if there’s no matching floor.
Now, that while
-statement should be a for
loop:
public static int whichFloor(int queryRoom) {
int totalFloor = 6;
int currentRm = 0;
for (int floorInQuestion = 1; floorInQuestion != totalFloor, floorInQuestion++) {
if (floorInQuestion % 2 != 0) {
currentRm = currentRm + 5;
} else {
currentRm = currentRm + 10;
}
if (queryRoom <= currentRm) {
return floorInQuestion;
}
}
return -1;
}
Now, as a looping system, that’s how you should have presented your solution.
Note that your logic is clear enough, your variables are well named, and the logic looks sound enough. On the whole, your answer is good, and just needed some tweaks.
… but… is there a better solution that does not use looping?
Consider the pattern in the rooms/floors…
Odd floors have 5 rooms, even floors have 10 rooms. Can we exploit this better? Well, yes, we can treat the floors in pairs and have 15 rooms per pair… and then figure out whether it’s in the first of the pair, or the second. Note that using division and remainder operations works best as a 0-based system, not a 1-based system like the input values are in, so we “map” each room to be 1 less, and each floor too, so we treat room 1 as if it was room 0, and floor 1 as if it was floor 0, and then shift the results back afterwards too. I have named zero-based variables with the prefix zero...
public static int whichFloor(int queryRoom) {
int zeroRoom = queryRoom - 1; // convert to zero-based room
int zeroPair = zeroRoom / 15; // get which 15-room floor-pair the room is in
int zeroOffset = zeroRoom % 15; // get which room in the pair
int zeroFloor = zeroPair * 2; // convert the pairs back to floors.
if (zeroOffset >= 5) {
// the room in the pair is in the upper floor of the pair.
zeroFloor += 1;
}
int resultFloor = zeroFloor + 1; // convert back to one-based system.
return resultFloor;
}