This series of problem solving exercises are based on problems found on Codewars https://www.codewars.com/ or Hackerank https://www.hackerrank.com/dashboard.
You should have attended the previous session on problem solving where we introduced the concepts of abstraction and decomposition. We will revisit these concepts again today.
No specific tools are required, although you will need to make notes so either pencil and paper or a text editor on your laptop.
You will be presented with a problem. You will learn how to understand the problem and break the problem down into steps that help you work towards a solution.
Todays problem can be found here: https://www.codewars.com/kata/5c374b346a5d0f77af500a5a.
After the class finishes, you should submit a solution to the problem using the link above.
Closest Elevator. Given the floors of 2 elevators and a calling floor, return the elevator closest to the calling floor.
Given 2 elevators (named "left" and "right") in a building with 3 floors (numbered 0 to 2), write a function accepting 3 arguments (in order):
left
- The current floor of the left elevatorright
- The current floor of the right elevatorcall
- The floor that called an elevatorYour function should return
the name of the elevator closest to the called floor ("left"/"right").
In the case where both elevators are equally distant from the called floor, choose the elevator to the right.
You can assume that the inputs will always be valid integers between 0-2.
Here are some examples of the input with the result that is returned in each case:
left right call result
0 1 0 "left"
0 1 1 "right"
0 1 2 "right"
0 0 0 "right"
0 2 1 "right"
function elevator(left, right, call){
// Your code will go here
}
The first step in solving any problem is understanding that problem.
We are not solving the problem here, we are just ensuring we understand what the problem is before we think about solving it.
Discuss your solution to this step as a group. Does everyone have the same list of important elements or are there differences? Resolve your differences so everyone agrees what is important.
In this problem, there are really only three pieces of information that are important:
These three numbers correspond to our input.
The return value will be one of two different strings; "left"
or "right"
.
Reducing the problem to our three input values, which are all numbers in the range 0 to 2, is an example of abstraction. We can "forget" the stuff about elevators and floors, we are reducing the problem to a comparison of three numbers.
How we do that comparison is something we will look at in the next steps.
The instructions provide us with no less than five examples. Here they are again:
left right call result
0 1 0 "left"
0 1 1 "right"
0 1 2 "right"
0 0 0 "right"
0 2 1 "right"
left right call result
0 1 0 "left"
In this example, left
and call
are equal, right
is larger than call
, so "left"
is returned because the left lift is closest (in this case the same as) the calling floor.
This example is important because it allows us to see three example input numbers and we should have noticed that we need to find whether call
is closer to left
or closer to right
. We can perform the following two calculations that will help us:
call - left = 0
call - right = -1
We should make a note that if the result of either calculation is 0, it means the lift is being called from the same floor. Therefore, we return "left"
in this case because the value of call
and left
are identical.
left right call result
0 1 1 "right"
Lets do the same calculations:
call - left = 1
call - right = 0
We get a value of 0 from the second calculation so, the returned value is "right"
.
left right call result
0 1 2 "right"
The calculations this time give us:
call - left = 2
call - right = 1
The values show that the right hand lift is closest so we return "right"
.
left right call result
0 0 0 "right"
The calculations this time are:
call - left = 0
call - right = 0
Both calculations give us the same value, 0
. In this case, a condition of the problem comes into play. The problem description says:
In the case where both elevators are equally distant from the called floor, choose the elevator to the right.
so for this case, we should return "right"
.
left right call result
0 2 1 "right"
Our calculations this time give us the following values:
call - left = 1
call - right = -1
In terms of "how far away", 1
and -1
are actually identical. A value of 1
means "one floor down" and a value of -1
means "one floor up.
This example is important. It tells us TWO things:
1
compared with 1
. The two elevators are equally distant, so the right elevator should be chosen.We should return "right"
in this example.
There are actually two steps to the solution to this problem and these are:
call
and left
and call
and right
. This gives us two numbers, and we will refer to them as differenceLeft
and differenceRight
.differenceLeft
with differenceRight
and return either "left"
or "right"
.In step 1 the names we chose to refer the the results of the calculations are not important. What is important is that we read the name and know immediately what it is referring to.
Breaking down the problem into these TWO steps is important because we can solve each step independently. Each step is a simpler problem than the whole problem.
differenceLeft
and differenceRight
. Be sure to remember everything we discovered when we looked at the examples.Here is the code you should have written:
const differenceLeft = Math.abs(call - left);
const differenceRight = Math.abs(call - right);
We might add a console.log
statement to print out the values of the two variables so we can check they look correct.
After a few minutes to allow everyone to come to their own conclusions, go around the class and get answers to the following:
differenceLeft
and differenceRight
that needs to be made in order to determine whether the returned result should be "left"
or "right"
? if
statement.The decision is this.
IF the value of differenceRight is less than or equal to the value of differenceLeft THEN return "right" ELSE return "left"
Here is a translation of our design into code:
if (differenceRight <= differenceLeft) {
return "right";
} else {
return "left";
}
Be sure to submit your solution on codewars.