Problem overview
A contest accepts children whose age lies between minAge and maxAge. The method allowToContest receives minAge, maxAge and the child's age, and returns true if the child may take part and false otherwise.
In the first example, minAge = 7, maxAge = 12 and age = 7. The age equals the lower limit, and the answer is true: the limits are inclusive. In the second, minAge = 3, maxAge = 8 and age = 10. The age is above the upper limit, so the answer is false.
Approach
An age is allowed when two things are true together: it is not below minAge and it is not above maxAge. The two checks are joined with the and operator &&, which is true only when both sides are true.
The statement's hint describes three ways to write this:
- Check each failure and return
falseearly (age < minAge, thenage > maxAge), then returntrue. - Use one
ifwith both conditions, returningtrueorfalse. - Skip the
ifand return the combined condition, because it already is a boolean.
This lesson uses the third, the shortest. All three behave the same. The idea behind the third is that an expression like minAge <= age && age <= maxAge evaluates to true or false, so an if that only returns those two values adds nothing.
For comparison, here is the first way as a method body. It is longer but easy to read, and it returns the same results:
allowToContest(minAge: number, maxAge: number, age: number): boolean {
if (age < minAge) {
return false;
}
if (age > maxAge) {
return false;
}
return true;
}
Each early return rules out one way of being outside the range, and whatever is left is inside it. The combined expression says the opposite thing in one line: inside means not below and not above.
Step by step
- Write the lower bound check:
minAge <= age. It uses<=, not<, because a child who is exactlyminAgeis allowed. - Write the upper bound check:
age <= maxAge, inclusive for the same reason. - Join them with
&&and return the result.
Writing the checks as minAge <= age && age <= maxAge follows a number line: the age sits between the two limits, in the same left-to-right order as on paper.
The solution in TypeScript
class Solution {
allowToContest(minAge: number, maxAge: number, age: number): boolean {
return minAge <= age && age <= maxAge;
}
}
Some TypeScript details about this code:
- There is no chained comparison. Mathematics lets you write
minAge <= age <= maxAge. TypeScript reads it from left to right as(minAge <= age) <= maxAge, which compares a boolean with a number. The compiler reports that the operator cannot be applied tobooleanandnumber, and the JavaScript still runs and gives a wrong answer. WithminAge = 3,maxAge = 8andage = 10, the chained form returnstrue, while the correct answer isfalse. The first comparison givestrue, which is converted to 1 for the second one, and1 <= 8holds. Always write the two comparisons separately. - Precedence. Comparison operators bind tighter than
&&, so no parentheses are needed around either comparison. - Annotations are erased.
: numberand: booleanhelp the compiler and disappear in the generated JavaScript.
Edge cases and common mistakes
- Exact limits.
ageequal tominAgeor tomaxAgemust returntrue. With<in place of<=, the first example would wrongly returnfalse. - Using
||instead of&&. With or, almost every age passes, because any number is either above the lower limit or below the upper one. - A single-age range. When
minAgeequalsmaxAge, only that age is allowed, and the expression handles it without special code. - Swapped limits. If
minAgeis larger thanmaxAge, no age satisfies both checks and the result is alwaysfalse. The lesson does not ask you to repair such input. - Mixing up the parameter order. The method takes
minAge, thenmaxAge, thenage. Passing the age first compares the wrong numbers.
Testing
const solution = new Solution();
console.log(solution.allowToContest(7, 12, 7));
console.log(solution.allowToContest(3, 8, 10));
console.log(solution.allowToContest(3, 8, 8));
console.log(solution.allowToContest(3, 8, 2));
true
false
true
false